|
| 1 | +// Package logger provides a structured logging interface for Go applications. |
| 2 | +// It uses the standard library's log/slog package as the default implementation, |
| 3 | +// with support for structured fields and multiple log levels. |
| 4 | +// |
| 5 | +// The package defines Logger and FieldLogger interfaces that are used throughout |
| 6 | +// Buffalo apps and other systems. The default implementation writes to stdout |
| 7 | +// in a human-readable but parseable format. |
| 8 | +// |
| 9 | +// Basic usage: |
| 10 | +// |
| 11 | +// log := logger.New(logger.InfoLevel) |
| 12 | +// log.Info("Server starting") |
| 13 | +// log.WithField("port", 8080).Info("Server started") |
| 14 | +// |
| 15 | +// For users who prefer the logrus backend, import the logrus subpackage: |
| 16 | +// |
| 17 | +// import "github.com/gobuffalo/logger/logrus" |
| 18 | +// log := logrus.New(logrus.InfoLevel) |
1 | 19 | package logger |
2 | 20 |
|
3 | 21 | import ( |
4 | | - "os" |
5 | | - |
6 | | - "github.com/sirupsen/logrus" |
| 22 | + "fmt" |
| 23 | + "log/slog" |
7 | 24 | ) |
8 | 25 |
|
9 | | -// FieldLogger interface |
10 | 26 | type FieldLogger interface { |
11 | 27 | Logger |
12 | | - WithField(string, interface{}) FieldLogger |
13 | | - WithFields(map[string]interface{}) FieldLogger |
| 28 | + WithField(string, any) FieldLogger |
| 29 | + WithFields(map[string]any) FieldLogger |
14 | 30 | } |
15 | 31 |
|
16 | | -// Logger interface is used throughout Buffalo |
17 | | -// apps to log a whole manner of things. |
18 | 32 | type Logger interface { |
19 | | - Debugf(string, ...interface{}) |
20 | | - Infof(string, ...interface{}) |
21 | | - Printf(string, ...interface{}) |
22 | | - Warnf(string, ...interface{}) |
23 | | - Errorf(string, ...interface{}) |
24 | | - Fatalf(string, ...interface{}) |
25 | | - Debug(...interface{}) |
26 | | - Info(...interface{}) |
27 | | - Warn(...interface{}) |
28 | | - Error(...interface{}) |
29 | | - Fatal(...interface{}) |
30 | | - Panic(...interface{}) |
| 33 | + Debugf(string, ...any) |
| 34 | + Infof(string, ...any) |
| 35 | + Printf(string, ...any) |
| 36 | + Warnf(string, ...any) |
| 37 | + Errorf(string, ...any) |
| 38 | + Fatalf(string, ...any) |
| 39 | + Debug(...any) |
| 40 | + Info(...any) |
| 41 | + Warn(...any) |
| 42 | + Error(...any) |
| 43 | + Fatal(...any) |
| 44 | + Panic(...any) |
31 | 45 | } |
32 | 46 |
|
| 47 | +// ParseLevel parses a string level into a Level. |
33 | 48 | func ParseLevel(level string) (Level, error) { |
34 | | - l, err := logrus.ParseLevel(level) |
35 | | - return Level(l), err |
| 49 | + switch level { |
| 50 | + case "panic": |
| 51 | + return PanicLevel, nil |
| 52 | + case "fatal": |
| 53 | + return FatalLevel, nil |
| 54 | + case "error": |
| 55 | + return ErrorLevel, nil |
| 56 | + case "warn", "warning": |
| 57 | + return WarnLevel, nil |
| 58 | + case "info": |
| 59 | + return InfoLevel, nil |
| 60 | + case "debug": |
| 61 | + return DebugLevel, nil |
| 62 | + } |
| 63 | + |
| 64 | + var l Level |
| 65 | + return l, fmt.Errorf("not a valid Level: %q", level) |
36 | 66 | } |
37 | 67 |
|
38 | 68 | // NewLogger based on the specified log level, defaults to "debug". |
39 | 69 | // See `New` for more details. |
40 | 70 | func NewLogger(level string) FieldLogger { |
41 | | - lvl, err := logrus.ParseLevel(level) |
| 71 | + lvl, err := ParseLevel(level) |
42 | 72 | if err != nil { |
43 | | - lvl = logrus.DebugLevel |
| 73 | + lvl = DebugLevel |
44 | 74 | } |
45 | 75 | return New(lvl) |
46 | 76 | } |
47 | 77 |
|
48 | 78 | // New based on the specified log level, defaults to "debug". |
49 | 79 | // This logger will log to the STDOUT in a human readable, |
50 | 80 | // but parseable form. |
51 | | -/* |
52 | | - Example: time="2016-12-01T21:02:07-05:00" level=info duration=225.283µs human_size="106 B" method=GET path="/" render=199.79µs request_id=2265736089 size=106 status=200 |
53 | | -*/ |
| 81 | +// |
| 82 | +// Example: time="2016-12-01T21:02:07-05:00" level=info duration=225.283µs human_size="106 B" method=GET path="/" render=199.79µs request_id=2265736089 size=106 status=200 |
54 | 83 | func New(lvl Level) FieldLogger { |
55 | | - e := os.Getenv("GO_ENV") |
56 | | - if len(e) == 0 { |
57 | | - e = "development" |
58 | | - } |
59 | | - dev := e == "development" |
60 | | - l := logrus.New() |
61 | | - l.SetOutput(os.Stdout) |
62 | | - l.Level = lvl |
63 | | - l.Formatter = &textFormatter{ |
64 | | - ForceColors: dev, |
| 84 | + return newSlog(lvl) |
| 85 | +} |
| 86 | + |
| 87 | +// toSlogLevel converts our Level to slog.Level. |
| 88 | +func toSlogLevel(l Level) slog.Level { |
| 89 | + switch l { |
| 90 | + case PanicLevel, FatalLevel: |
| 91 | + return slog.Level(12) // custom level above error |
| 92 | + case ErrorLevel: |
| 93 | + return slog.LevelError |
| 94 | + case WarnLevel: |
| 95 | + return slog.LevelWarn |
| 96 | + case InfoLevel: |
| 97 | + return slog.LevelInfo |
| 98 | + case DebugLevel: |
| 99 | + return slog.LevelDebug |
65 | 100 | } |
66 | | - return Logrus{l} |
| 101 | + return slog.LevelDebug |
67 | 102 | } |
0 commit comments