mirror of
https://gitee.com/johng/gf
synced 2026-06-06 02:25:47 +08:00
improve color feature for package glog
This commit is contained in:
15
.example/os/glog/glog_color.go
Normal file
15
.example/os/glog/glog_color.go
Normal file
@ -0,0 +1,15 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"github.com/gogf/gf/frame/g"
|
||||
)
|
||||
|
||||
func main() {
|
||||
g.Log().Print("Print")
|
||||
g.Log().Debug("Debug")
|
||||
g.Log().Info("Info")
|
||||
g.Log().Notice("Notice")
|
||||
g.Log().Warning("Warning")
|
||||
g.Log().Error("Error")
|
||||
g.Log().Critical("Critical")
|
||||
}
|
||||
@ -16,7 +16,7 @@ import (
|
||||
)
|
||||
|
||||
var (
|
||||
// Buffer size for reading file content.
|
||||
// DefaultReadBuffer is the buffer size for reading file content.
|
||||
DefaultReadBuffer = 1024
|
||||
)
|
||||
|
||||
|
||||
@ -78,7 +78,7 @@ func StackWithFilter(filter string) *Logger {
|
||||
return logger.StackWithFilter(filter)
|
||||
}
|
||||
|
||||
// StdPrint is a chaining function,
|
||||
// Stdout is a chaining function,
|
||||
// which enables/disables stdout for the current logging content output.
|
||||
// It's enabled in default.
|
||||
func Stdout(enabled ...bool) *Logger {
|
||||
|
||||
@ -7,7 +7,6 @@
|
||||
package glog
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"context"
|
||||
"fmt"
|
||||
"github.com/gogf/gf/container/gtype"
|
||||
@ -119,6 +118,7 @@ func (l *Logger) print(ctx context.Context, level int, values ...interface{}) {
|
||||
index: -1,
|
||||
Ctx: ctx,
|
||||
Time: now,
|
||||
Color: defaultLevelColor[level],
|
||||
Level: level,
|
||||
}
|
||||
)
|
||||
@ -219,30 +219,48 @@ func (l *Logger) print(ctx context.Context, level int, values ...interface{}) {
|
||||
}
|
||||
}
|
||||
|
||||
// printToWriter writes buffer to writer.
|
||||
func (l *Logger) printToWriter(ctx context.Context, input *HandlerInput) {
|
||||
// doPrint outputs the logging content according configuration.
|
||||
func (l *Logger) doPrint(ctx context.Context, input *HandlerInput) {
|
||||
if l.config.Writer == nil {
|
||||
// Output content to disk file.
|
||||
if l.config.Path != "" {
|
||||
l.printToFile(ctx, input.Time, input.Buffer())
|
||||
l.printToFile(ctx, input.Time, input)
|
||||
}
|
||||
// Allow output to stdout?
|
||||
if l.config.StdoutPrint {
|
||||
if err := input.Stdout(); err != nil {
|
||||
intlog.Error(ctx, err)
|
||||
}
|
||||
l.printToStdout(ctx, input)
|
||||
}
|
||||
} else {
|
||||
if _, err := l.config.Writer.Write(input.Buffer().Bytes()); err != nil {
|
||||
// panic(err)
|
||||
// Output to custom writer.
|
||||
l.printToWriter(ctx, input)
|
||||
}
|
||||
}
|
||||
|
||||
// printToWriter writes buffer to writer.
|
||||
func (l *Logger) printToWriter(ctx context.Context, input *HandlerInput) {
|
||||
if l.config.Writer != nil {
|
||||
var (
|
||||
buffer = input.getBuffer(l.config.WriterColorEnable)
|
||||
)
|
||||
if _, err := l.config.Writer.Write(buffer.Bytes()); err != nil {
|
||||
intlog.Error(ctx, err)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// printToStdout outputs logging content to stdout.
|
||||
func (l *Logger) printToStdout(ctx context.Context, input *HandlerInput) {
|
||||
if l.config.StdoutPrint {
|
||||
if _, err := os.Stdout.Write(input.getBuffer(true).Bytes()); err != nil {
|
||||
intlog.Error(ctx, err)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// printToFile outputs logging content to disk file.
|
||||
func (l *Logger) printToFile(ctx context.Context, t time.Time, buffer *bytes.Buffer) {
|
||||
func (l *Logger) printToFile(ctx context.Context, t time.Time, input *HandlerInput) {
|
||||
var (
|
||||
buffer = input.getBuffer(l.config.WriterColorEnable)
|
||||
logFilePath = l.getFilePath(t)
|
||||
memoryLockKey = memoryLockPrefixForPrintingToFile + logFilePath
|
||||
)
|
||||
|
||||
@ -8,7 +8,6 @@ package glog
|
||||
|
||||
import (
|
||||
"context"
|
||||
"github.com/fatih/color"
|
||||
"github.com/gogf/gf/internal/intlog"
|
||||
"io"
|
||||
|
||||
@ -246,16 +245,3 @@ func (l *Logger) Async(enabled ...bool) *Logger {
|
||||
}
|
||||
return logger
|
||||
}
|
||||
|
||||
// Color is a chaining function,
|
||||
// which set level prefix color logging output feature.
|
||||
func (l *Logger) Color(color color.Attribute) *Logger {
|
||||
logger := (*Logger)(nil)
|
||||
if l.parent == nil {
|
||||
logger = l.Clone()
|
||||
} else {
|
||||
logger = l
|
||||
}
|
||||
logger.config.currentColor = color
|
||||
return logger
|
||||
}
|
||||
|
||||
41
os/glog/glog_logger_color.go
Normal file
41
os/glog/glog_logger_color.go
Normal file
@ -0,0 +1,41 @@
|
||||
// Copyright GoFrame Author(https://goframe.org). All Rights Reserved.
|
||||
//
|
||||
// This Source Code Form is subject to the terms of the MIT License.
|
||||
// If a copy of the MIT was not distributed with this file,
|
||||
// You can obtain one at https://github.com/gogf/gf.
|
||||
|
||||
package glog
|
||||
|
||||
import "github.com/fatih/color"
|
||||
|
||||
const (
|
||||
COLOR_BLACK = 30 + iota
|
||||
COLOR_RED
|
||||
COLOR_GREEN
|
||||
COLOR_YELLOW
|
||||
COLOR_BLUE
|
||||
COLOR_MAGENTA
|
||||
COLOR_CYAN
|
||||
COLOR_WHITE
|
||||
)
|
||||
|
||||
// defaultLevelColor defines the default level and its mapping prefix string.
|
||||
var defaultLevelColor = map[int]int{
|
||||
LEVEL_DEBU: COLOR_YELLOW,
|
||||
LEVEL_INFO: COLOR_GREEN,
|
||||
LEVEL_NOTI: COLOR_CYAN,
|
||||
LEVEL_WARN: COLOR_YELLOW,
|
||||
LEVEL_ERRO: COLOR_RED,
|
||||
LEVEL_CRIT: COLOR_RED,
|
||||
LEVEL_PANI: COLOR_RED,
|
||||
LEVEL_FATA: COLOR_RED,
|
||||
}
|
||||
|
||||
// getColoredStr returns a string that is colored by given color.
|
||||
func (l *Logger) getColoredStr(c int, s string) string {
|
||||
return color.New(color.Attribute(c)).Sprint(s)
|
||||
}
|
||||
|
||||
func (l *Logger) getColorByLevel(level int) int {
|
||||
return defaultLevelColor[level]
|
||||
}
|
||||
@ -7,7 +7,6 @@
|
||||
package glog
|
||||
|
||||
import (
|
||||
"github.com/fatih/color"
|
||||
"io"
|
||||
"strings"
|
||||
"time"
|
||||
@ -21,28 +20,27 @@ import (
|
||||
|
||||
// Config is the configuration object for logger.
|
||||
type Config struct {
|
||||
Handlers []Handler `json:"-"` // Logger handlers which implement feature similar as middleware.
|
||||
Writer io.Writer `json:"-"` // Customized io.Writer.
|
||||
Flags int `json:"flags"` // Extra flags for logging output features.
|
||||
Path string `json:"path"` // Logging directory path.
|
||||
File string `json:"file"` // Format for logging file.
|
||||
Level int `json:"level"` // Output level.
|
||||
Prefix string `json:"prefix"` // Prefix string for every logging content.
|
||||
StSkip int `json:"stSkip"` // Skip count for stack.
|
||||
StStatus int `json:"stStatus"` // Stack status(1: enabled - default; 0: disabled)
|
||||
StFilter string `json:"stFilter"` // Stack string filter.
|
||||
CtxKeys []interface{} `json:"ctxKeys"` // Context keys for logging, which is used for value retrieving from context.
|
||||
HeaderPrint bool `json:"header"` // Print header or not(true in default).
|
||||
StdoutPrint bool `json:"stdout"` // Output to stdout or not(true in default).
|
||||
LevelPrefixes map[int]string `json:"levelPrefixes"` // Logging level to its prefix string mapping.
|
||||
RotateSize int64 `json:"rotateSize"` // Rotate the logging file if its size > 0 in bytes.
|
||||
RotateExpire time.Duration `json:"rotateExpire"` // Rotate the logging file if its mtime exceeds this duration.
|
||||
RotateBackupLimit int `json:"rotateBackupLimit"` // Max backup for rotated files, default is 0, means no backups.
|
||||
RotateBackupExpire time.Duration `json:"rotateBackupExpire"` // Max expire for rotated files, which is 0 in default, means no expiration.
|
||||
RotateBackupCompress int `json:"rotateBackupCompress"` // Compress level for rotated files using gzip algorithm. It's 0 in default, means no compression.
|
||||
RotateCheckInterval time.Duration `json:"rotateCheckInterval"` // Asynchronizely checks the backups and expiration at intervals. It's 1 hour in default.
|
||||
FileColorEnable bool `json:"fileColorEnable"` // Logging level prefix with color or not (false in default).
|
||||
currentColor color.Attribute `json:"-"`
|
||||
Handlers []Handler `json:"-"` // Logger handlers which implement feature similar as middleware.
|
||||
Writer io.Writer `json:"-"` // Customized io.Writer.
|
||||
Flags int `json:"flags"` // Extra flags for logging output features.
|
||||
Path string `json:"path"` // Logging directory path.
|
||||
File string `json:"file"` // Format for logging file.
|
||||
Level int `json:"level"` // Output level.
|
||||
Prefix string `json:"prefix"` // Prefix string for every logging content.
|
||||
StSkip int `json:"stSkip"` // Skip count for stack.
|
||||
StStatus int `json:"stStatus"` // Stack status(1: enabled - default; 0: disabled)
|
||||
StFilter string `json:"stFilter"` // Stack string filter.
|
||||
CtxKeys []interface{} `json:"ctxKeys"` // Context keys for logging, which is used for value retrieving from context.
|
||||
HeaderPrint bool `json:"header"` // Print header or not(true in default).
|
||||
StdoutPrint bool `json:"stdout"` // Output to stdout or not(true in default).
|
||||
LevelPrefixes map[int]string `json:"levelPrefixes"` // Logging level to its prefix string mapping.
|
||||
RotateSize int64 `json:"rotateSize"` // Rotate the logging file if its size > 0 in bytes.
|
||||
RotateExpire time.Duration `json:"rotateExpire"` // Rotate the logging file if its mtime exceeds this duration.
|
||||
RotateBackupLimit int `json:"rotateBackupLimit"` // Max backup for rotated files, default is 0, means no backups.
|
||||
RotateBackupExpire time.Duration `json:"rotateBackupExpire"` // Max expire for rotated files, which is 0 in default, means no expiration.
|
||||
RotateBackupCompress int `json:"rotateBackupCompress"` // Compress level for rotated files using gzip algorithm. It's 0 in default, means no compression.
|
||||
RotateCheckInterval time.Duration `json:"rotateCheckInterval"` // Asynchronously checks the backups and expiration at intervals. It's 1 hour in default.
|
||||
WriterColorEnable bool `json:"writerColorEnable"` // Logging level prefix with color to writer or not (false in default).
|
||||
}
|
||||
|
||||
// DefaultConfig returns the default configuration for logger.
|
||||
|
||||
@ -9,9 +9,6 @@ package glog
|
||||
import (
|
||||
"bytes"
|
||||
"context"
|
||||
"github.com/fatih/color"
|
||||
"github.com/gogf/gf/internal/intlog"
|
||||
"os"
|
||||
"time"
|
||||
)
|
||||
|
||||
@ -23,6 +20,7 @@ type HandlerInput struct {
|
||||
Ctx context.Context
|
||||
Time time.Time
|
||||
TimeFormat string
|
||||
Color int
|
||||
Level int
|
||||
LevelFormat string
|
||||
CallerFunc string
|
||||
@ -35,52 +33,34 @@ type HandlerInput struct {
|
||||
|
||||
// defaultHandler is the default handler for logger.
|
||||
func defaultHandler(ctx context.Context, input *HandlerInput) {
|
||||
input.logger.printToWriter(ctx, input)
|
||||
input.logger.doPrint(ctx, input)
|
||||
}
|
||||
|
||||
func (i *HandlerInput) addStringToBuffer(buffer *bytes.Buffer, s string) {
|
||||
if buffer.Len() > 0 {
|
||||
buffer.WriteByte(' ')
|
||||
func (i *HandlerInput) addStringToBuffer(buffer *bytes.Buffer, strings ...string) {
|
||||
for _, s := range strings {
|
||||
if buffer.Len() > 0 {
|
||||
buffer.WriteByte(' ')
|
||||
}
|
||||
buffer.WriteString(s)
|
||||
}
|
||||
buffer.WriteString(s)
|
||||
}
|
||||
|
||||
func (i *HandlerInput) Buffer() *bytes.Buffer {
|
||||
return i.getBuffer(false)
|
||||
}
|
||||
|
||||
func (i *HandlerInput) getBuffer(withColor bool) *bytes.Buffer {
|
||||
buffer := bytes.NewBuffer(nil)
|
||||
buffer.WriteString(i.TimeFormat)
|
||||
levelString := i.LevelFormat
|
||||
if i.logger.config.FileColorEnable {
|
||||
fg := i.getLevelFormatColor()
|
||||
levelString = color.New(fg).Sprintf(i.LevelFormat)
|
||||
if i.LevelFormat != "" {
|
||||
if withColor {
|
||||
i.addStringToBuffer(buffer, i.logger.getColoredStr(
|
||||
i.logger.getColorByLevel(i.Level), i.LevelFormat,
|
||||
))
|
||||
} else {
|
||||
i.addStringToBuffer(buffer, i.LevelFormat)
|
||||
}
|
||||
}
|
||||
i.addStringToBuffer(buffer, levelString)
|
||||
msg := i.GetContent()
|
||||
i.addStringToBuffer(buffer, msg.String())
|
||||
return buffer
|
||||
}
|
||||
|
||||
// Stdout print log to console
|
||||
func (i *HandlerInput) Stdout() error {
|
||||
if _, err := os.Stdout.Write([]byte(i.TimeFormat)); err != nil {
|
||||
intlog.Error(i.Ctx, err)
|
||||
return err
|
||||
}
|
||||
fg := i.getLevelFormatColor()
|
||||
if _, err := color.New(fg).Print(" " + i.LevelFormat + " "); err != nil {
|
||||
intlog.Error(i.Ctx, err)
|
||||
return err
|
||||
}
|
||||
msg := i.GetContent()
|
||||
if _, err := os.Stdout.Write(msg.Bytes()); err != nil {
|
||||
intlog.Error(i.Ctx, err)
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// GetContent returns the primary content.
|
||||
func (i *HandlerInput) GetContent() *bytes.Buffer {
|
||||
buffer := bytes.NewBuffer(nil)
|
||||
if i.CallerFunc != "" {
|
||||
i.addStringToBuffer(buffer, i.CallerFunc)
|
||||
}
|
||||
@ -100,15 +80,6 @@ func (i *HandlerInput) GetContent() *bytes.Buffer {
|
||||
return buffer
|
||||
}
|
||||
|
||||
// getLevelFormatColor returns the prefix string color.
|
||||
func (i *HandlerInput) getLevelFormatColor() color.Attribute {
|
||||
fg := defaultLevelColor[i.Level]
|
||||
if i.logger.config.currentColor != 0 {
|
||||
fg = i.logger.config.currentColor
|
||||
}
|
||||
return fg
|
||||
}
|
||||
|
||||
func (i *HandlerInput) String() string {
|
||||
return i.Buffer().String()
|
||||
}
|
||||
|
||||
@ -7,7 +7,6 @@
|
||||
package glog
|
||||
|
||||
import (
|
||||
"github.com/fatih/color"
|
||||
"github.com/gogf/gf/errors/gerror"
|
||||
"strings"
|
||||
)
|
||||
@ -29,17 +28,6 @@ const (
|
||||
LEVEL_FATA // 1024
|
||||
)
|
||||
|
||||
const (
|
||||
COLOR_BLACK = 30 + iota
|
||||
COLOR_RED
|
||||
COLOR_GREEN
|
||||
COLOR_YELLOW
|
||||
COLOR_BLUE
|
||||
COLOR_MAGENTA
|
||||
COLOR_CYAN
|
||||
COLOR_WHITE
|
||||
)
|
||||
|
||||
// defaultLevelPrefixes defines the default level and its mapping prefix string.
|
||||
var defaultLevelPrefixes = map[int]string{
|
||||
LEVEL_DEBU: "DEBU",
|
||||
@ -52,18 +40,6 @@ var defaultLevelPrefixes = map[int]string{
|
||||
LEVEL_FATA: "FATA",
|
||||
}
|
||||
|
||||
// defaultLevelColor defines the default level and its mapping prefix string.
|
||||
var defaultLevelColor = map[int]color.Attribute{
|
||||
LEVEL_DEBU: COLOR_YELLOW,
|
||||
LEVEL_INFO: COLOR_GREEN,
|
||||
LEVEL_NOTI: COLOR_CYAN,
|
||||
LEVEL_WARN: COLOR_YELLOW,
|
||||
LEVEL_ERRO: COLOR_RED,
|
||||
LEVEL_CRIT: COLOR_RED,
|
||||
LEVEL_PANI: COLOR_RED,
|
||||
LEVEL_FATA: COLOR_RED,
|
||||
}
|
||||
|
||||
// levelStringMap defines level string name to its level mapping.
|
||||
var levelStringMap = map[string]int{
|
||||
"ALL": LEVEL_DEBU | LEVEL_INFO | LEVEL_NOTI | LEVEL_WARN | LEVEL_ERRO | LEVEL_CRIT,
|
||||
@ -125,8 +101,9 @@ func (l *Logger) GetLevelPrefix(level int) string {
|
||||
|
||||
// getLevelPrefixWithBrackets returns the prefix string with brackets for specified level.
|
||||
func (l *Logger) getLevelPrefixWithBrackets(level int) string {
|
||||
levelStr := ""
|
||||
if s, ok := l.config.LevelPrefixes[level]; ok {
|
||||
return "[" + s + "]"
|
||||
levelStr = "[" + s + "]"
|
||||
}
|
||||
return ""
|
||||
return levelStr
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user