-
Notifications
You must be signed in to change notification settings - Fork 6
/
Copy pathdoc.go
321 lines (244 loc) · 9.66 KB
/
doc.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
// Copyright 2024 FishGoddess. All Rights Reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
/*
Package logit provides an easy way to use foundation for your logging operations.
1. basic:
// Use default logger to log.
// By default, logs will be output to stdout.
// logit.Default() returns the default logger, but we also provide some common logging functions.
logit.Info("hello from logit", "key", 123)
logit.Default().Info("hello from logit", "key", 123)
// Use a new logger to log.
// By default, logs will be output to stdout.
logger := logit.NewLogger()
logger.Debug("new version of logit", "version", "1.5.0-alpha", "date", 20231122)
logger.Error("new version of logit", "version", "1.5.0-alpha", "date", 20231122)
type user struct {
ID int64 `json:"id"`
Name string `json:"name"`
}
u := user{123456, "fishgoddess"}
logger.Info("user information", "user", u, "pi", 3.14)
// Yep, I know you want to output logs to a file, try WithFile option.
// The path in WithFile is where the log file will be stored.
// Also, it's a good choice to call logger.Close() when program shutdown.
logger = logit.NewLogger(logit.WithFile("./logit.log"))
defer logger.Close()
logger.Info("check where I'm logged", "file", "logit.log")
// What if I want to use default logger and output logs to a file? Try SetDefault.
// It sets a logger to default and you can use it by package functions or Default().
logit.SetDefault(logger)
logit.Warn("this is from default logger", "pi", 3.14, "default", true)
// If you want to change level of logger to info, try WithInfoLevel.
// Other levels is similar to info level.
logger = logit.NewLogger(logit.WithInfoLevel())
logger.Debug("debug logs will be ignored")
logger.Info("info logs can be logged")
// If you want to pass logger by context, use NewContext and FromContext.
ctx := logit.NewContext(context.Background(), logger)
logger = logit.FromContext(ctx)
logger.Info("logger from context", "from", "context")
// Don't want to panic when new a logger? Try NewLoggerGracefully.
logger, err := logit.NewLoggerGracefully(logit.WithFile(""))
if err != nil {
fmt.Println("new logger gracefully failed:", err)
}
2. logger:
// Default() will return the default logger.
// You can new a logger or just use the default logger.
logger := logit.Default()
logger.Info("nothing carried")
// Use With() to carry some args in logger.
// All logs output by this logger will carry these args.
logger = logger.With("carry", 666, "who", "me")
logger.Info("see what are carried")
logger.Error("error carried", "err", io.EOF)
// Use WithGroup() to group args in logger.
// All logs output by this logger will group args.
logger = logger.WithGroup("xxx")
logger.Info("what group")
logger.Error("error group", "err", io.EOF)
// If you want to check if one level can be logged, try this:
if logger.DebugEnabled() {
logger.Debug("debug enabled")
}
// We provide some old-school logging methods.
// They are using info level by default.
// If you want to change the level, see defaults.LevelPrint.
logger.Printf("printf %s log", "formatted")
logger.Print("print log")
logger.Println("println log")
// Some useful method:
logger.Sync()
logger.Close()
3. handler:
// By default, logit uses tape handler to output logs.
logger := logit.NewLogger()
logger.Info("default handler logging")
// You can change it to other handlers by options.
// For example, use json handler:
logger = logit.NewLogger(logit.WithJsonHandler())
logger.Info("using json handler")
// Or you want to use customized handlers, try Register.
newHandler := func(w io.Writer, opts *slog.HandlerOptions) slog.Handler {
return slog.NewTextHandler(w, opts)
}
if err := handler.Register("demo", newHandler); err != nil {
panic(err)
}
logger = logit.NewLogger(logit.WithHandler("demo"))
logger.Info("using demo handler")
// As you can see, our handler is slog's handler, so you can use any handlers implement this interface.
newHandler = func(w io.Writer, opts *slog.HandlerOptions) slog.Handler {
return slog.NewJSONHandler(w, opts)
}
4. writer:
// A new logger outputs logs to stdout.
logger := logit.NewLogger()
logger.Debug("log to stdout")
// What if I want to output logs to stderr? Try WithStderr.
logger = logit.NewLogger(logit.WithStderr())
logger.Debug("log to stderr")
// Also, you can use WithWriter to specify your own writer.
logger = logit.NewLogger(logit.WithWriter(os.Stdout))
logger.Debug("log to writer")
// How to output logs to a file? Try WithFile and WithRotateFile.
// Rotate file is useful in production, see _examples/file.go.
logger = logit.NewLogger(logit.WithFile("logit.log"))
logger.Debug("log to file")
logger = logit.NewLogger(logit.WithRotateFile("logit.log"))
logger.Debug("log to rotate file")
5. file:
// AS we know, you can use WithFile to output logs to a file.
logger := logit.NewLogger(logit.WithFile("logit.log"))
logger.Debug("debug to file")
// However, a single file stored all logs isn't enough in production.
// Sometimes we want a log file has a limit size and count of files not greater than a number.
// So we provide a rotate file to do this thing.
logger = logit.NewLogger(logit.WithRotateFile("logit.log"))
defer logger.Close()
logger.Debug("debug to rotate file")
// Maybe you have noticed that WithRotateFile can pass some rotate.Option.
// These options are used to setup the rotate file.
opts := []rotate.Option{
rotate.WithMaxSize(128 * rotate.MB),
rotate.WithMaxAge(30 * rotate.Day),
rotate.WithMaxBackups(60),
}
logger = logit.NewLogger(logit.WithRotateFile("logit.log", opts...))
defer logger.Close()
logger.Debug("debug to rotate file with rotate options")
// See rotate.File if you want to use this magic in other scenes.
file, err := rotate.New("logit.log")
if err != nil {
panic(err)
}
defer file.Close()
6. option:
// As you can see, NewLogger can use some options to create a logger.
logger := logit.NewLogger(logit.WithDebugLevel())
logger.Debug("debug log")
// We provide some options for different scenes and all options have prefix "With".
// Change logger level:
logit.WithDebugLevel()
logit.WithInfoLevel()
logit.WithWarnLevel()
logit.WithDebugLevel()
// Change logger handler:
logit.WithHandler("xxx")
logit.WithTapeHandler()
logit.WithTextHandler()
logit.WithJsonHandler()
// Change handler writer:
logit.WithWriter(os.Stdout)
logit.WithStdout()
logit.WithStderr()
logit.WithFile("")
logit.WithRotateFile("")
// Some useful flags:
logit.WithSource()
logit.WithPID()
// More options can be found in logit package which have prefix "With".
// What's more? We provide a options pack that we think it's useful in production.
opts := logit.ProductionOptions()
logger = logit.NewLogger(opts...)
defer logger.Close()
logger.Info("log from production options")
logger.Error("error log from production options")
7. context:
// We provide a way for getting logger from a context.
// By default, the default logger will be returned if there is no logit.Logger in context.
ctx := context.Background()
logger := logit.FromContext(ctx)
logger.Debug("logger from context debug")
if logger == logit.Default() {
logger.Info("logger from context is default logger")
}
// Use NewContext to set a logger to context.
// We use WithGroup here to make a difference to default logger.
logger = logit.NewLogger().WithGroup("context").With("user_id", 123456)
ctx = logit.NewContext(ctx, logger)
// Then you can get the logger from context.
logger = logit.FromContext(ctx)
logger.Debug("logger from context debug", "key", "value")
8. default:
// We set a defaults package that setups all shared fields.
// For example, if you want to customize the time getter:
defaults.CurrentTime = func() time.Time {
// Return a fixed time for example.
return time.Unix(666, 0).In(time.Local)
}
logit.Print("println log is info level")
// If you want change the level of old-school logging methods:
defaults.LevelPrint = slog.LevelDebug
logit.Print("println log is debug level now")
// More fields see defaults package.
defaults.HandleError = func(label string, err error) {
fmt.Printf("%s: %+n\n", label, err)
}
9. config:
// newConfig reads config from a json file.
func newConfig() (*config.Config, error) {
conf := new(config.Config)
bs, err := os.ReadFile("config.json")
if err != nil {
return nil, err
}
err = json.Unmarshal(bs, conf)
if err != nil {
return nil, err
}
return conf, err
}
// We know you may use a configuration file in your program to setup some resources including logging.
// After thinking about serval kinds of configurations like "yaml", "toml" and "json", we decide to support all of them.
// As you can see, there are many tags on Config's fields like "yaml" and "toml", so you can unmarshal to a config from one of them.
conf, err := newConfig()
if err != nil {
panic(err)
}
opts, err := conf.Options()
if err != nil {
panic(err)
}
// Use options to create a logger.
logger := logit.NewLogger(opts...)
defer logger.Close()
logger.Info("logging from config", "conf", conf)
*/
package logit // import "github.com/FishGoddess/logit"
const (
// Version is the version string representation of logit.
Version = "v1.5.10"
)