106 lines
3.0 KiB
Go
106 lines
3.0 KiB
Go
package masterlog
|
|
|
|
import (
|
|
"encoding/json"
|
|
"fmt"
|
|
"time"
|
|
)
|
|
|
|
// getShortFile extracts the filename from a full path
|
|
func getShortFile(file string) string {
|
|
for i := len(file) - 1; i >= 0; i-- {
|
|
if file[i] == '/' {
|
|
return file[i+1:]
|
|
}
|
|
}
|
|
return file
|
|
}
|
|
|
|
// FormattedEncoder encodes entries in the formatted text format
|
|
type FormattedEncoder struct {
|
|
useColors bool
|
|
}
|
|
|
|
// NewFormattedEncoder creates a new FormattedEncoder
|
|
func NewFormattedEncoder(useColors bool) *FormattedEncoder {
|
|
return &FormattedEncoder{useColors: useColors}
|
|
}
|
|
|
|
func (e *FormattedEncoder) Encode(entry Entry) ([]byte, error) {
|
|
// Format: 2022-09-01T10:05:03+01:00 TRC main.go:23 trace message go_version=go1.19 pid=2620043
|
|
format := entry.Timestamp.Format(time.RFC3339)
|
|
levelStr := levelNames[entry.Level]
|
|
shortFile := getShortFile(entry.File)
|
|
|
|
var result string
|
|
if e.useColors {
|
|
// Timestamp in light gray
|
|
timestampColor := colorLightGray
|
|
// Level in its specific color
|
|
levelColor := levelColors[entry.Level]
|
|
// File:line in light gray
|
|
fileColor := colorLightGray
|
|
// Separator in light gray
|
|
separator := ">"
|
|
// Message in white
|
|
messageColor := colorWhite
|
|
|
|
result = fmt.Sprintf("%s%s%s %s%s%s %s%s%s:%d %s%s%s %s%s%s",
|
|
timestampColor, format, colorReset,
|
|
levelColor, levelStr, colorReset,
|
|
fileColor, shortFile, colorReset, entry.Line,
|
|
fileColor, separator, colorReset,
|
|
messageColor, entry.Message, colorReset)
|
|
} else {
|
|
result = fmt.Sprintf("%s %s %s:%d > %s", format, levelStr, shortFile, entry.Line, entry.Message)
|
|
}
|
|
|
|
// Add fields - first custom fields, then default fields
|
|
// Custom fields (user-provided)
|
|
for key, value := range entry.CustomFields {
|
|
if e.useColors {
|
|
// Field key in turquoise, value in white
|
|
result += fmt.Sprintf(" %s%s%s=%s%v%s", colorTurquoise, key, colorReset, colorWhite, value, colorReset)
|
|
} else {
|
|
result += fmt.Sprintf(" %s=%v", key, value)
|
|
}
|
|
}
|
|
// Default fields (go_version, pid)
|
|
for key, value := range entry.DefaultFields {
|
|
if e.useColors {
|
|
// Field key in turquoise, value in white
|
|
result += fmt.Sprintf(" %s%s%s=%s%v%s", colorTurquoise, key, colorReset, colorWhite, value, colorReset)
|
|
} else {
|
|
result += fmt.Sprintf(" %s=%v", key, value)
|
|
}
|
|
}
|
|
|
|
result += "\n"
|
|
return []byte(result), nil
|
|
}
|
|
|
|
// JSONEncoder encodes entries in JSON format
|
|
type JSONEncoder struct{}
|
|
|
|
func (e *JSONEncoder) Encode(entry Entry) ([]byte, error) {
|
|
type LogEntry struct {
|
|
Timestamp string `json:"timestamp"`
|
|
Level string `json:"level"`
|
|
File string `json:"file"`
|
|
Line int `json:"line"`
|
|
Message string `json:"message"`
|
|
Fields map[string]interface{} `json:"fields,omitempty"`
|
|
}
|
|
|
|
logEntry := LogEntry{
|
|
Timestamp: entry.Timestamp.Format(time.RFC3339),
|
|
Level: levelNames[entry.Level],
|
|
File: getShortFile(entry.File),
|
|
Line: entry.Line,
|
|
Message: entry.Message,
|
|
Fields: entry.Fields,
|
|
}
|
|
|
|
return json.Marshal(logEntry)
|
|
}
|