Codebase list golang-github-go-logr-logr / a9e0cd7
Slightly better godocs and examples What `godoc` renders is not quite the same as what pkg.go.dev renders wrt whole-file examples and output comments, but this seems better all around. Tim Hockin 2 years ago
5 changed file(s) with 163 addition(s) and 108 deletion(s). Raw diff Collapse all Expand all
1616 package logr_test
1717
1818 import (
19 "fmt"
20
2119 "github.com/go-logr/logr"
22 "github.com/go-logr/logr/funcr"
2320 )
24
25 // NewStdoutLogger returns a logr.Logger that prints to stdout.
26 func NewStdoutLogger() logr.Logger {
27 return funcr.New(func(prefix, args string) {
28 if prefix != "" {
29 _ = fmt.Sprintf("%s: %s\n", prefix, args)
30 } else {
31 fmt.Println(args)
32 }
33 }, funcr.Options{})
34 }
3521
3622 // ObjectRef references a Kubernetes object
3723 type ObjectRef struct {
0 /*
1 Copyright 2021 The logr Authors.
2
3 Licensed under the Apache License, Version 2.0 (the "License");
4 you may not use this file except in compliance with the License.
5 You may obtain a copy of the License at
6
7 http://www.apache.org/licenses/LICENSE-2.0
8
9 Unless required by applicable law or agreed to in writing, software
10 distributed under the License is distributed on an "AS IS" BASIS,
11 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 See the License for the specific language governing permissions and
13 limitations under the License.
14 */
15
16 package logr_test
17
18 import (
19 "fmt"
20
21 "github.com/go-logr/logr"
22 "github.com/go-logr/logr/funcr"
23 )
24
25 // NewStdoutLogger returns a logr.Logger that prints to stdout.
26 func NewStdoutLogger() logr.Logger {
27 return funcr.New(func(prefix, args string) {
28 if prefix != "" {
29 _ = fmt.Sprintf("%s: %s\n", prefix, args)
30 } else {
31 fmt.Println(args)
32 }
33 }, funcr.Options{})
34 }
35
36 func Example() {
37 l := NewStdoutLogger()
38 l.Info("default info log", "stringVal", "value", "intVal", 12345)
39 l.V(0).Info("V(0) info log", "stringVal", "value", "intVal", 12345)
40 l.Error(fmt.Errorf("an error"), "error log", "stringVal", "value", "intVal", 12345)
41 // Output:
42 // "level"=0 "msg"="default info log" "stringVal"="value" "intVal"=12345
43 // "level"=0 "msg"="V(0) info log" "stringVal"="value" "intVal"=12345
44 // "msg"="error log" "error"="an error" "stringVal"="value" "intVal"=12345
45 }
0 /*
1 Copyright 2021 The logr Authors.
2
3 Licensed under the Apache License, Version 2.0 (the "License");
4 you may not use this file except in compliance with the License.
5 You may obtain a copy of the License at
6
7 http://www.apache.org/licenses/LICENSE-2.0
8
9 Unless required by applicable law or agreed to in writing, software
10 distributed under the License is distributed on an "AS IS" BASIS,
11 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 See the License for the specific language governing permissions and
13 limitations under the License.
14 */
15
16 package funcr_test
17
18 import (
19 "fmt"
20 "strings"
21
22 "github.com/go-logr/logr"
23 "github.com/go-logr/logr/funcr"
24 )
25
26 // NewStdoutLogger returns a logr.Logger that prints to stdout.
27 // It demonstrates how to implement a custom With* function which
28 // controls whether INFO or ERROR are printed in front of the log
29 // message.
30 func NewStdoutLogger() logr.Logger {
31 l := &stdoutlogger{
32 Formatter: funcr.NewFormatter(funcr.Options{}),
33 }
34 return logr.New(l)
35 }
36
37 type stdoutlogger struct {
38 funcr.Formatter
39 logMsgType bool
40 }
41
42 func (l stdoutlogger) WithName(name string) logr.LogSink {
43 l.Formatter.AddName(name)
44 return &l
45 }
46
47 func (l stdoutlogger) WithValues(kvList ...interface{}) logr.LogSink {
48 l.Formatter.AddValues(kvList)
49 return &l
50 }
51
52 func (l stdoutlogger) WithCallDepth(depth int) logr.LogSink {
53 l.Formatter.AddCallDepth(depth)
54 return &l
55 }
56
57 func (l stdoutlogger) Info(level int, msg string, kvList ...interface{}) {
58 prefix, args := l.FormatInfo(level, msg, kvList)
59 l.write("INFO", prefix, args)
60 }
61
62 func (l stdoutlogger) Error(err error, msg string, kvList ...interface{}) {
63 prefix, args := l.FormatError(err, msg, kvList)
64 l.write("ERROR", prefix, args)
65 }
66
67 func (l stdoutlogger) write(msgType, prefix, args string) {
68 var parts []string
69 if l.logMsgType {
70 parts = append(parts, msgType)
71 }
72 if prefix != "" {
73 parts = append(parts, prefix)
74 }
75 parts = append(parts, args)
76 fmt.Println(strings.Join(parts, ": "))
77 }
78
79 // WithLogMsgType returns a copy of the logger with new settings for
80 // logging the message type. It returns the original logger if the
81 // underlying LogSink is not a stdoutlogger.
82 func WithLogMsgType(log logr.Logger, logMsgType bool) logr.Logger {
83 if l, ok := log.GetSink().(*stdoutlogger); ok {
84 clone := *l
85 clone.logMsgType = logMsgType
86 log = log.WithSink(&clone)
87 }
88 return log
89 }
90
91 // Assert conformance to the interfaces.
92 var _ logr.LogSink = &stdoutlogger{}
93 var _ logr.CallDepthLogSink = &stdoutlogger{}
94
95 func ExampleFormatter() {
96 l := NewStdoutLogger()
97 l.Info("no message type")
98 WithLogMsgType(l, true).Info("with message type")
99 // Output:
100 // "level"=0 "msg"="no message type"
101 // INFO: "level"=0 "msg"="with message type"
102 }
1717
1818 import (
1919 "fmt"
20 "strings"
2120
2221 "github.com/go-logr/logr"
2322 "github.com/go-logr/logr/funcr"
3433 }
3534 // Output: hello world
3635 }
37
38 // NewStdoutLogger returns a logr.Logger that prints to stdout.
39 // It demonstrates how to implement a custom With* function which
40 // controls whether INFO or ERROR are printed in front of the log
41 // message.
42 func NewStdoutLogger() logr.Logger {
43 l := &stdoutlogger{
44 Formatter: funcr.NewFormatter(funcr.Options{}),
45 }
46 return logr.New(l)
47 }
48
49 type stdoutlogger struct {
50 funcr.Formatter
51 logMsgType bool
52 }
53
54 func (l stdoutlogger) WithName(name string) logr.LogSink {
55 l.Formatter.AddName(name)
56 return &l
57 }
58
59 func (l stdoutlogger) WithValues(kvList ...interface{}) logr.LogSink {
60 l.Formatter.AddValues(kvList)
61 return &l
62 }
63
64 func (l stdoutlogger) WithCallDepth(depth int) logr.LogSink {
65 l.Formatter.AddCallDepth(depth)
66 return &l
67 }
68
69 func (l stdoutlogger) Info(level int, msg string, kvList ...interface{}) {
70 prefix, args := l.FormatInfo(level, msg, kvList)
71 l.write("INFO", prefix, args)
72 }
73
74 func (l stdoutlogger) Error(err error, msg string, kvList ...interface{}) {
75 prefix, args := l.FormatError(err, msg, kvList)
76 l.write("ERROR", prefix, args)
77 }
78
79 func (l stdoutlogger) write(msgType, prefix, args string) {
80 var parts []string
81 if l.logMsgType {
82 parts = append(parts, msgType)
83 }
84 if prefix != "" {
85 parts = append(parts, prefix)
86 }
87 parts = append(parts, args)
88 fmt.Println(strings.Join(parts, ": "))
89 }
90
91 // WithLogMsgType returns a copy of the logger with new settings for
92 // logging the message type. It returns the original logger if the
93 // underlying LogSink is not a stdoutlogger.
94 func WithLogMsgType(log logr.Logger, logMsgType bool) logr.Logger {
95 if l, ok := log.GetSink().(*stdoutlogger); ok {
96 clone := *l
97 clone.logMsgType = logMsgType
98 log = log.WithSink(&clone)
99 }
100 return log
101 }
102
103 // Assert conformance to the interfaces.
104 var _ logr.LogSink = &stdoutlogger{}
105 var _ logr.CallDepthLogSink = &stdoutlogger{}
106
107 func ExampleFormatter() {
108 l := NewStdoutLogger()
109 l.Info("no message type")
110 WithLogMsgType(l, true).Info("with message type")
111 // Output:
112 // "level"=0 "msg"="no message type"
113 // INFO: "level"=0 "msg"="with message type"
114 }
2020 // to back that API. Packages in the Go ecosystem can depend on this package,
2121 // while callers can implement logging with whatever backend is appropriate.
2222 //
23 // # Usage
23 // Usage
2424 //
2525 // Logging is done using a Logger instance. Logger is a concrete type with
2626 // methods, which defers the actual logging to a LogSink interface. The main
4444 // LogSink implementations can choose to do things like attach additional
4545 // information (such as stack traces) on calls to Error().
4646 //
47 // # Verbosity
47 // Verbosity
4848 //
4949 // Often we want to log information only when the application in "verbose
5050 // mode". To write log lines that are more verbose, Logger has a V() method.
6161 // We can write:
6262 // logger.V(2).Info("an unusual thing happened")
6363 //
64 // # Logger Names
64 // Logger Names
6565 //
6666 // Logger instances can have name strings so that all messages logged through
6767 // that instance have additional context. For example, you might want to add
7878 // joining operation (e.g. whitespace, commas, periods, slashes, brackets,
7979 // quotes, etc).
8080 //
81 // # Saved Values
81 // Saved Values
8282 //
8383 // Logger instances can store any number of key/value pairs, which will be
8484 // logged alongside all messages logged through that instance. For example,
9696 // // later on...
9797 // obj.logger.Info("setting foo", "value", targetValue)
9898 //
99 // # Best Practices
99 // Best Practices
100100 //
101101 // Logger has very few hard rules, with the goal that LogSink implementations
102102 // might have a lot of freedom to differentiate. There are, however, some
111111 // may be any Go value, but how the value is formatted is determined by the
112112 // LogSink implementation.
113113 //
114 // # Key Naming Conventions
114 // Key Naming Conventions
115115 //
116116 // Keys are not strictly required to conform to any specification or regex, but
117117 // it is recommended that they:
128128 // While users are generally free to use key names of their choice, it's
129129 // generally best to avoid using the following keys, as they're frequently used
130130 // by implementations:
131 //
132 // * "caller": the calling information (file/line) of a particular log line.
133 // * "error": the underlying error value in the `Error` method.
134 // * "level": the log level.
135 // * "logger": the name of the associated logger.
136 // * "msg": the log message.
131 // * "caller": the calling information (file/line) of a particular log line
132 // * "error": the underlying error value in the `Error` method
133 // * "level": the log level
134 // * "logger": the name of the associated logger
135 // * "msg": the log message
137136 // * "stacktrace": the stack trace associated with a particular log line or
138 // error (often from the `Error` message).
139 // * "ts": the timestamp for a log line.
137 // error (often from the `Error` message)
138 // * "ts": the timestamp for a log line
140139 //
141140 // Implementations are encouraged to make use of these keys to represent the
142141 // above concepts, when necessary (for example, in a pure-JSON output form, it
143142 // would be necessary to represent at least message and timestamp as ordinary
144143 // named values).
145144 //
146 // # Break Glass
145 // Break Glass
147146 //
148147 // Implementations may choose to give callers access to the underlying
149148 // logging implementation. The recommended pattern for this is: