| name | structured-error-logger |
| description | logger is a structured error logger that integrates well with github.com/rohanthewiz/serr. logger.LogErr will write out all the context stored in the SErr. |
Logger Package
A structured logging package for Go that wraps logrus with enhanced support for github.com/rohanthewiz/serr structured errors.
Installation
import "github.com/rohanthewiz/logger"
Initialization
Initialize the logger at application startup:
logger.InitLog(logger.LogConfig{
Formatter: "json",
LogLevel: "debug",
})
defer logger.CloseLog()
Core Functions
Basic Logging with Key-Value Pairs
The Log function accepts a level, message, and optional key-value pairs:
logger.Log("info", "Conveying some info", "attribute1", "value1", "attribute2", "value2")
Convenience Wrappers
Use wrapper functions for cleaner code:
logger.Info("Simple info message", "key1", "value1", "key2", "value2")
logger.Debug("Simple debug message", "key1", "value1")
logger.Warn("Simple warning message", "key1", "value1")
logger.Error("Simple error message", "key1", "value1")
Formatted Logging
Printf-style formatting is available:
logger.F("Number: %d String: %s", 42, "test")
logger.InfoF("Info message with %s and %d", "string", 123)
logger.DebugF("Debug message with %.2f", 3.14159)
logger.WarnF("Warning: %s occurred %d times", "event", 5)
logger.ErrorF("Error code: %x", 255)
Error Logging with SErr Integration
The key feature of this package is its awareness of github.com/rohanthewiz/serr structured errors. When logging errors, use LogErr or its alias Err:
Standard Error Logging
err := errors.New("This is the original error")
logger.LogErr(err)
logger.LogErr(err, "info", "message2", "key1", "value1", "key2", "value2")
logger.Err(err, "message2", "key1", "value1")
SErr Structured Error Logging
When logging a serr.SErr, all embedded context is automatically extracted and included in the log output:
ser := serr.New("This is the original error", "errFld1", "errVal1", "errFld2", "errVal2")
logger.Err(ser)
logger.Err(ser, "error", "Err: from my point of view")
logger.Err(ser, "info", "message2", "key1", "value1", "key2", "value2")
Key Behavior Notes
LogErr and Err automatically append caller context (function name and location)
- All attributes stored in a
serr.SErr are unpacked into log fields
- Multiple values for the same attribute are joined with
->
UserMsg and UserMsgSeverity keys are excluded (reserved for UI)
- Logging a
nil error logs an info message about the nil error instead
Async Logging
For non-blocking logging:
logger.LogAsync("info", "An Async message")
logger.LogAsync("error", "An Async error message", "key1", "value1")
logger.Async("info", "An Async message")
Configuration Options
type LogConfig struct {
EnvPrefix string
Formatter string
LogLevel string
LogChanSize int
TeamsLogCfg TeamsLogCfg
SlackAPICfg SlackAPICfg
LogChanCfg LogChanCfg
}
Microsoft Teams Integration
logger.InitLog(logger.LogConfig{
Formatter: "json",
LogLevel: "debug",
TeamsLogCfg: logger.TeamsLogCfg{
Enabled: true,
Endpoint: "https://your-teams-webhook-url",
LogLevel: "warn",
},
})
Slack Integration
logger.InitLog(logger.LogConfig{
Formatter: "json",
LogLevel: "debug",
SlackAPICfg: logger.SlackAPICfg{
Enabled: true,
Token: "xoxb-your-token",
Channel: "C086K...",
LogLevel: "warn",
UseBlocks: true,
},
})
LogChan Hook (Send Logs to a Channel)
Route logrus-text-formatted log lines to a chan string for custom processing
(e.g. forwarding to a UI, writing to a database, or bridging to another system).
logCh := make(chan string, 100)
logger.InitLog(logger.LogConfig{
Formatter: "text",
LogLevel: "debug",
LogChanCfg: logger.LogChanCfg{
Enabled: true,
Ch: logCh,
LogLevel: "warn",
},
})
defer logger.CloseLog()
go func() {
for msg := range logCh {
fmt.Print("received log: ", msg)
}
}()
logger.Warn("disk usage high", "percent", "92")
The hook uses a non-blocking send โ if the channel is full, messages are dropped
rather than blocking the logging goroutine.
Log Levels
Available via logger.LogLevel:
logger.LogLevel.Debug
logger.LogLevel.Info
logger.LogLevel.Warn
logger.LogLevel.Error
Or use string constants:
logger.StrLevelDebug
logger.StrLevelInfo
logger.StrLevelWarn
logger.StrLevelError
Utility Functions
Stack Trace
Print the current stack trace for debugging:
logger.PrintStackTrace()
Location Helper
Add location context to log messages:
logger.Log("error", "Some error occurred", "location", serr.FunctionLoc(serr.FrameLevels.FrameLevel1))
Best Practices
- Always call
defer logger.CloseLog() after InitLog() to ensure async logs are flushed
- Use
logger.LogErr(err) or logger.Err(err) for error logging to capture full context
- Prefer
serr.Wrap(err) to wrap errors before logging for maximum context
- Use structured key-value pairs instead of string formatting for searchable logs
- Set appropriate log levels for different environments (debug for dev, info/warn for prod)