223 lines
8.6 KiB
Go
223 lines
8.6 KiB
Go
package lx
|
||
|
||
import (
|
||
"strings"
|
||
"time"
|
||
)
|
||
|
||
// Formatting constants for log output.
|
||
// These constants define the characters used to format log messages, ensuring consistency
|
||
// across handlers (e.g., text, JSON, colorized). They are used to construct namespace paths,
|
||
// level indicators, and field separators in log entries.
|
||
const (
|
||
Space = " " // Single space for separating elements (e.g., between level and message)
|
||
DoubleSpace = " " // Double space for indentation (e.g., for hierarchical output)
|
||
Slash = "/" // Separator for namespace paths (e.g., "parent/child")
|
||
Arrow = "→" // Arrow for NestedPath style namespaces (e.g., [parent]→[child])
|
||
LeftBracket = "[" // Opening bracket for namespaces and fields (e.g., [app])
|
||
RightBracket = "]" // Closing bracket for namespaces and fields (e.g., [app])
|
||
Colon = ":" // Separator after namespace or level (e.g., [app]: INFO:)
|
||
Dot = "." // Separator for namespace paths (e.g., "parent.child")
|
||
Newline = "\n" // Newline for separating log entries or stack trace lines
|
||
)
|
||
|
||
// DefaultEnabled defines the default logging state (disabled).
|
||
// It specifies whether logging is enabled by default for new Logger instances in the ll package.
|
||
// Set to false to prevent logging until explicitly enabled.
|
||
const (
|
||
DefaultEnabled = false // Default state for new loggers (disabled)
|
||
)
|
||
|
||
// Log level constants, ordered by increasing severity.
|
||
// These constants define the severity levels for log messages, used to filter logs based
|
||
// on the logger’s minimum level. They are ordered to allow comparison (e.g., LevelDebug < LevelWarn).
|
||
const (
|
||
LevelNone LevelType = iota // Debug level for detailed diagnostic information
|
||
LevelInfo // Info level for general operational messages
|
||
LevelWarn // Warn level for warning conditions
|
||
LevelError // Error level for error conditions requiring attention
|
||
LevelDebug // None level for logs without a specific severity (e.g., raw output)
|
||
LevelUnknown // None level for logs without a specific severity (e.g., raw output)
|
||
)
|
||
|
||
// String constants for each level
|
||
const (
|
||
DebugString = "DEBUG"
|
||
InfoString = "INFO"
|
||
WarnString = "WARN"
|
||
ErrorString = "ERROR"
|
||
NoneString = "NONE"
|
||
UnknownString = "UNKNOWN"
|
||
|
||
TextString = "TEXT"
|
||
JSONString = "JSON"
|
||
DumpString = "DUMP"
|
||
SpecialString = "SPECIAL"
|
||
RawString = "RAW"
|
||
)
|
||
|
||
// Log class constants, defining the type of log entry.
|
||
// These constants categorize log entries by their content or purpose, influencing how
|
||
// handlers process them (e.g., text, JSON, hex dump).
|
||
const (
|
||
ClassText ClassType = iota // Text entries for standard log messages
|
||
ClassJSON // JSON entries for structured output
|
||
ClassDump // Dump entries for hex/ASCII dumps
|
||
ClassSpecial // Special entries for custom or non-standard logs
|
||
ClassRaw // Raw entries for unformatted output
|
||
ClassUnknown // Raw entries for unformatted output
|
||
)
|
||
|
||
// Namespace style constants.
|
||
// These constants define how namespace paths are formatted in log output, affecting the
|
||
// visual representation of hierarchical namespaces.
|
||
const (
|
||
FlatPath StyleType = iota // Formats namespaces as [parent/child]
|
||
NestedPath // Formats namespaces as [parent]→[child]
|
||
)
|
||
|
||
// LevelType represents the severity of a log message.
|
||
// It is an integer type used to define log levels (Debug, Info, Warn, Error, None), with associated
|
||
// string representations for display in log output.
|
||
type LevelType int
|
||
|
||
// String converts a LevelType to its string representation.
|
||
// It maps each level constant to a human-readable string, returning "UNKNOWN" for invalid levels.
|
||
// Used by handlers to display the log level in output.
|
||
// Example:
|
||
//
|
||
// var level lx.LevelType = lx.LevelInfo
|
||
// fmt.Println(level.String()) // Output: INFO
|
||
func (l LevelType) String() string {
|
||
switch l {
|
||
case LevelDebug:
|
||
return DebugString
|
||
case LevelInfo:
|
||
return InfoString
|
||
case LevelWarn:
|
||
return WarnString
|
||
case LevelError:
|
||
return ErrorString
|
||
case LevelNone:
|
||
return NoneString
|
||
default:
|
||
return UnknownString
|
||
}
|
||
}
|
||
|
||
// LevelParse converts a string to its corresponding LevelType.
|
||
// It parses a string (case-insensitive) and returns the corresponding LevelType, defaulting to
|
||
// LevelUnknown for unrecognized strings. Supports "WARNING" as an alias for "WARN".
|
||
func LevelParse(s string) LevelType {
|
||
switch strings.ToUpper(s) {
|
||
case DebugString:
|
||
return LevelDebug
|
||
case InfoString:
|
||
return LevelInfo
|
||
case WarnString, "WARNING": // Allow both "WARN" and "WARNING"
|
||
return LevelWarn
|
||
case ErrorString:
|
||
return LevelError
|
||
case NoneString:
|
||
return LevelNone
|
||
default:
|
||
return LevelUnknown
|
||
}
|
||
}
|
||
|
||
// StyleType defines how namespace paths are formatted in log output.
|
||
// It is an integer type used to select between FlatPath ([parent/child]) and NestedPath
|
||
// ([parent]→[child]) styles, affecting how handlers render namespace hierarchies.
|
||
type StyleType int
|
||
|
||
// Entry represents a single log entry passed to handlers.
|
||
// It encapsulates all information about a log message, including its timestamp, severity,
|
||
// content, namespace, metadata, and formatting style. Handlers process Entry instances
|
||
// to produce formatted output (e.g., text, JSON). The struct is immutable once created,
|
||
// ensuring thread-safety in handler processing.
|
||
type Entry struct {
|
||
Timestamp time.Time // Time the log was created
|
||
Level LevelType // Severity level of the log (Debug, Info, Warn, Error, None)
|
||
Message string // Log message content
|
||
Namespace string // Namespace path (e.g., "parent/child")
|
||
Fields map[string]interface{} // Additional key-value metadata (e.g., {"user": "alice"})
|
||
Style StyleType // Namespace formatting style (FlatPath or NestedPath)
|
||
Error error // Associated error, if any (e.g., for error logs)
|
||
Class ClassType // Type of log entry (Text, JSON, Dump, Special, Raw)
|
||
Stack []byte // Stack trace data (if present)
|
||
Id int `json:"-"` // Unique ID for the entry, ignored in JSON output
|
||
}
|
||
|
||
// Handler defines the interface for processing log entries.
|
||
// Implementations (e.g., TextHandler, JSONHandler) format and output log entries to various
|
||
// destinations (e.g., stdout, files). The Handle method returns an error if processing fails,
|
||
// allowing the logger to handle output failures gracefully.
|
||
// Example (simplified handler implementation):
|
||
//
|
||
// type MyHandler struct{}
|
||
// func (h *MyHandler) Handle(e *Entry) error {
|
||
// fmt.Printf("[%s] %s: %s\n", e.Namespace, e.Level.String(), e.Message)
|
||
// return nil
|
||
// }
|
||
type Handler interface {
|
||
Handle(e *Entry) error // Processes a log entry, returning any error
|
||
}
|
||
|
||
// Timestamper defines an interface for handlers that support timestamp configuration.
|
||
// It includes a method to enable or disable timestamp logging and optionally set the timestamp format.
|
||
type Timestamper interface {
|
||
// Timestamped enables or disables timestamp logging and allows specifying an optional format.
|
||
// Parameters:
|
||
// enable: Boolean to enable or disable timestamp logging
|
||
// format: Optional string(s) to specify the timestamp format
|
||
Timestamped(enable bool, format ...string)
|
||
}
|
||
|
||
// ClassType represents the type of a log entry.
|
||
// It is an integer type used to categorize log entries (Text, JSON, Dump, Special, Raw),
|
||
// influencing how handlers process and format them.
|
||
type ClassType int
|
||
|
||
// String converts a ClassType to its string representation.
|
||
// It maps each class constant to a human-readable string, returning "UNKNOWN" for invalid classes.
|
||
// Used by handlers to indicate the entry type in output (e.g., JSON fields).
|
||
// Example:
|
||
//
|
||
// var class lx.ClassType = lx.ClassText
|
||
// fmt.Println(class.String()) // Output: TEST
|
||
func (t ClassType) String() string {
|
||
switch t {
|
||
case ClassText:
|
||
return TextString
|
||
case ClassJSON:
|
||
return JSONString
|
||
case ClassDump:
|
||
return DumpString
|
||
case ClassSpecial:
|
||
return SpecialString
|
||
case ClassRaw:
|
||
return RawString
|
||
default:
|
||
return UnknownString
|
||
}
|
||
}
|
||
|
||
// ParseClass converts a string to its corresponding ClassType.
|
||
// It parses a string (case-insensitive) and returns the corresponding ClassType, defaulting to
|
||
// ClassUnknown for unrecognized strings.
|
||
func ParseClass(s string) ClassType {
|
||
switch strings.ToUpper(s) {
|
||
case TextString:
|
||
return ClassText
|
||
case JSONString:
|
||
return ClassJSON
|
||
case DumpString:
|
||
return ClassDump
|
||
case SpecialString:
|
||
return ClassSpecial
|
||
case RawString:
|
||
return ClassRaw
|
||
default:
|
||
return ClassUnknown
|
||
}
|
||
}
|