Enhanced slog package with invoke skip support to enable accurate source location reporting in Go logging assist functions.
🎯 Invoke Skip Support: Provides WithCallerSkip function like zap.AddCallerSkip
📍 Accurate Source Location: Maintains correct invoke information in nested assist functions
🔗 1:1 API Support: 100% compatible with slog.Log Instance API
🍬 SugaredLogger Support: Includes zap.SugaredLogger-like flattened argument logging
⚡ Worldwide Variables: Available LOG and SUG worldwide loggers
go get github.com/yylego/slogxpackage main
import (
"github.com/yylego/slogx"
)
func main() {
// Use worldwide LOG with structured logging
slogx.LOG.Info("application started", "version", "1.0.0", "mode", "production")
// Use worldwide SUG with flattened arguments
slogx.SUG.Info("client", "alice", "logged in")
// SUG with Infoln adds spaces between arguments
slogx.SUG.Infoln("Processing", "item", 123, "of", 456)
// Debug level logging with structured data
slogx.LOG.Debug("database query", "table", "clients", "duration", "45ms")
// Warning level with flattened arguments
slogx.SUG.Warn("high", "memory", "usage", 85, "%")
}⬆️ Source: Source
package main
import (
"log/slog"
"os"
"github.com/yylego/slogx"
)
// logHelper demonstrates stack-frame skip in assist functions
func logHelper(instance *slogx.Logger, message string) {
// Skip 1 frame to show logHelper invoke point instead of this function
instance.Skip(1).Info(message, "from", "assist function")
}
// nestedLogHelper demonstrates multiple level stack-frame skip
func nestedLogHelper(instance *slogx.Logger, operation string) {
// Skip 2 frames to show the original invoke point
instance.Skip(2).Info("nested operation", "op", operation)
}
func main() {
// Create custom slog log instance with JSON handler
jsonHandler := slog.NewJSONHandler(os.Stdout, &slog.HandlerOptions{
AddSource: true,
Level: slog.LevelDebug,
})
baseLogger := slog.New(jsonHandler)
// Wrap with slogx to enable stack-frame skip support
instance := slogx.New(baseLogger)
// Use in assist function with correct source location
logHelper(instance, "message from main")
// Direct logging without skip shows current location
instance.Info("direct message", "level", "info")
// Use WithCallerSkip as alternative to Skip
instance.WithCallerSkip(1).Warn("warning from main", "skip", 1)
// Chain with other slog methods
instance.With("request_id", "12345").
WithGroup("app").
Info("chained logging", "status", "success")
// Demonstrate nested assist with multiple skip levels
func() {
nestedLogHelper(instance, "cleanup")
}()
}⬆️ Source: Source
package main
import (
"context"
"log/slog"
"os"
"github.com/yylego/slogx"
)
// processData demonstrates SugaredLogger in business logic
func processData(sugar *slogx.SugaredLogger, itemID int) {
sugar.Info("Start", "processing", "item", itemID)
sugar.Infoln("Completed", "item", itemID, "status", "success")
}
// contextLogger demonstrates context-aware logging
func contextLogger(sugar *slogx.SugaredLogger, ctx context.Context) {
sugar.InfoContext(ctx, "Processing", "with", "context", "data")
sugar.InfolnContext(ctx, "Status", "check", "complete")
}
func main() {
// Create custom handler with text output
textHandler := slog.NewTextHandler(os.Stdout, &slog.HandlerOptions{
AddSource: false,
Level: slog.LevelInfo,
})
baseLogger := slog.New(textHandler)
// Create Log Instance and convert to SugaredLogger
instance := slogx.New(baseLogger)
sugar := instance.Sugar()
// Sprint-style concatenation without extra spaces
sugar.Info("Processing", "item", 123, "of", 456)
// Output: "Processingitem123of456"
// Sprintln-style with spaces between each argument
sugar.Infoln("Processing", "item", 123, "of", 456)
// Output: "Processing item 123 of 456"
// Warning with numeric data
sugar.Warn("Memory", "usage", 85.5, "%", "threshold", 80)
// Use in business logic function
processData(sugar, 42)
// Context-aware logging
ctx := context.Background()
contextLogger(sugar, ctx)
// Create SugaredLogger from worldwide LOG
globalSugar := slogx.LOG.Sugar()
globalSugar.Infoln("Using", "worldwide", "LOG", "instance")
// Combine different logging styles
globalSugar.Info("Event", 1, "Type", "startup")
globalSugar.Infoln("Event", 2, "Type", "ready")
}⬆️ Source: Source
Lightweight package around slog.LogInstance with invoke skip support:
// Create new Log Instance package
logInstance := slogx.New(slogLogger)
// Skip extra stack frames
logInstance.Skip(1).Info("message")
logInstance.WithCallerSkip(2).Warn("warning message")
// Each slog.LogInstance method supported
logInstance.Info(msg, args...)
logInstance.Debug(msg, args...)
logInstance.Warn(msg, args...)
logInstance.Warn(msg, args...)
logInstance.InfoContext(ctx, msg, args...)
logInstance.With(args...)
logInstance.WithGroup(name)Provides flattened argument logging like zap.SugaredLogger:
// Create SugaredLogger
sugar := slogx.NewSugaredLogger(logInstance)
// And from Log Instance
sugar := logInstance.Sugar()
// Sprint-style concatenation
sugar.Info("client", 123, "action") // "user123 action"
sugar.Debug("1", 2, 3, 4, "5", 6) // "12 3 456"
// Sprintln-style with spaces
sugar.Infoln("client", 123, "action") // "client 123 action"
sugar.Debugln("1", 2, 3, 4, "5", 6) // "1 2 3 4 5 6"
// Context methods
sugar.InfoContext(ctx, args...)
sugar.InfolnContext(ctx, args...)// LOG - Worldwide Log Instance with structured logging
slogx.LOG.Info("message", "key", "value")
// SUG - Worldwide SugaredLog Instance with flattened arguments
slogx.SUG.Info("multiple", "arguments", 123)
// SetLog - Configure worldwide loggers with custom slog instance
customLogger := slog.New(customHandler)
slogx.SetLog(customLogger)
// NewDefault - Create Log Instance with default JSON configuration
logInstance := slogx.NewDefault()func serviceMethod() {
// Will show serviceMethod as source
logWithContext("operation", "data")
}
func logWithContext(op string, data string) {
// Skip 1 to show serviceMethod instead of logWithContext
slogx.LOG.Skip(1).Info("processing", "op", op, "data", data)
}logInstance := slogx.New(slogLogger)
.WithGroup("app")
.With("request_id", "123")
.Skip(1)
logInstance.Info("chained log instance prepared")ctx := context.Background()
if slogx.LOG.Enabled(ctx, slog.LevelDebug) {
slogx.LOG.Debug("debug mode enabled")
}MIT License - see LICENSE.
Contributions are welcome! Report bugs, suggest features, and contribute code:
- 🐛 Mistake reports? Open an issue on GitHub with reproduction steps
- 💡 Fresh ideas? Create an issue to discuss
- 📖 Documentation confusing? Report it so we can enhance it
- 🚀 Need new features? Share the use cases to help us understand requirements
- ⚡ Performance issue? Help us optimize via reporting slow operations
- 🔧 Configuration problem? Ask questions about complex setups
- 📢 Track project progress? Watch the repo to get new releases and features
- 🌟 Success stories? Share how this package enhanced the workflow
- 💬 Feedback? We welcome suggestions and comments
New code contributions, follow this process:
- Fork: Fork the repo on GitHub (using the webpage UI).
- Clone: Clone the forked project (
git clone https://github.com/yourname/repo-name.git). - Navigate: Navigate to the cloned project (
cd repo-name) - Branch: Create a feature branch (
git checkout -b feature/xxx). - Code: Implement the changes with comprehensive tests
- Testing: (Golang project) Ensure tests pass (
go test ./...) and adhere to Go code style conventions - Documentation: Update documentation to support client-facing changes
- Stage: Stage changes (
git add .) - Commit: Commit changes (
git commit -m "Add feature xxx") ensuring backward compatible code - Push: Push to the branch (
git push origin feature/xxx). - PR: Open a merge request on GitHub (on the GitHub webpage) with detailed description.
Please ensure tests pass and include relevant documentation updates.
Welcome to contribute to this project via submitting merge requests and reporting issues.
Project Support:
- ⭐ Give GitHub stars if this project helps you
- 🤝 Share with teammates and (golang) programming friends
- 📝 Write tech blogs about development tools and workflows - we provide content writing support
- 🌟 Join the ecosystem - committed to supporting open source and the (golang) development scene
Have Fun Coding with this package! 🎉🎉🎉