OSDN Git Service

new repo
[bytom/vapor.git] / vendor / github.com / go-kit / kit / log / doc.go
1 // Package log provides a structured logger.
2 //
3 // Structured logging produces logs easily consumed later by humans or
4 // machines. Humans might be interested in debugging errors, or tracing
5 // specific requests. Machines might be interested in counting interesting
6 // events, or aggregating information for off-line processing. In both cases,
7 // it is important that the log messages are structured and actionable.
8 // Package log is designed to encourage both of these best practices.
9 //
10 // Basic Usage
11 //
12 // The fundamental interface is Logger. Loggers create log events from
13 // key/value data. The Logger interface has a single method, Log, which
14 // accepts a sequence of alternating key/value pairs, which this package names
15 // keyvals.
16 //
17 //    type Logger interface {
18 //        Log(keyvals ...interface{}) error
19 //    }
20 //
21 // Here is an example of a function using a Logger to create log events.
22 //
23 //    func RunTask(task Task, logger log.Logger) string {
24 //        logger.Log("taskID", task.ID, "event", "starting task")
25 //        ...
26 //        logger.Log("taskID", task.ID, "event", "task complete")
27 //    }
28 //
29 // The keys in the above example are "taskID" and "event". The values are
30 // task.ID, "starting task", and "task complete". Every key is followed
31 // immediately by its value.
32 //
33 // Keys are usually plain strings. Values may be any type that has a sensible
34 // encoding in the chosen log format. With structured logging it is a good
35 // idea to log simple values without formatting them. This practice allows
36 // the chosen logger to encode values in the most appropriate way.
37 //
38 // Contextual Loggers
39 //
40 // A contextual logger stores keyvals that it includes in all log events.
41 // Building appropriate contextual loggers reduces repetition and aids
42 // consistency in the resulting log output. With and WithPrefix add context to
43 // a logger. We can use With to improve the RunTask example.
44 //
45 //    func RunTask(task Task, logger log.Logger) string {
46 //        logger = log.With(logger, "taskID", task.ID)
47 //        logger.Log("event", "starting task")
48 //        ...
49 //        taskHelper(task.Cmd, logger)
50 //        ...
51 //        logger.Log("event", "task complete")
52 //    }
53 //
54 // The improved version emits the same log events as the original for the
55 // first and last calls to Log. Passing the contextual logger to taskHelper
56 // enables each log event created by taskHelper to include the task.ID even
57 // though taskHelper does not have access to that value. Using contextual
58 // loggers this way simplifies producing log output that enables tracing the
59 // life cycle of individual tasks. (See the Contextual example for the full
60 // code of the above snippet.)
61 //
62 // Dynamic Contextual Values
63 //
64 // A Valuer function stored in a contextual logger generates a new value each
65 // time an event is logged. The Valuer example demonstrates how this feature
66 // works.
67 //
68 // Valuers provide the basis for consistently logging timestamps and source
69 // code location. The log package defines several valuers for that purpose.
70 // See Timestamp, DefaultTimestamp, DefaultTimestampUTC, Caller, and
71 // DefaultCaller. A common logger initialization sequence that ensures all log
72 // entries contain a timestamp and source location looks like this:
73 //
74 //    logger := log.NewLogfmtLogger(log.NewSyncWriter(os.Stdout))
75 //    logger = log.With(logger, "ts", log.DefaultTimestampUTC, "caller", log.DefaultCaller)
76 //
77 // Concurrent Safety
78 //
79 // Applications with multiple goroutines want each log event written to the
80 // same logger to remain separate from other log events. Package log provides
81 // two simple solutions for concurrent safe logging.
82 //
83 // NewSyncWriter wraps an io.Writer and serializes each call to its Write
84 // method. Using a SyncWriter has the benefit that the smallest practical
85 // portion of the logging logic is performed within a mutex, but it requires
86 // the formatting Logger to make only one call to Write per log event.
87 //
88 // NewSyncLogger wraps any Logger and serializes each call to its Log method.
89 // Using a SyncLogger has the benefit that it guarantees each log event is
90 // handled atomically within the wrapped logger, but it typically serializes
91 // both the formatting and output logic. Use a SyncLogger if the formatting
92 // logger may perform multiple writes per log event.
93 //
94 // Error Handling
95 //
96 // This package relies on the practice of wrapping or decorating loggers with
97 // other loggers to provide composable pieces of functionality. It also means
98 // that Logger.Log must return an error because some
99 // implementations—especially those that output log data to an io.Writer—may
100 // encounter errors that cannot be handled locally. This in turn means that
101 // Loggers that wrap other loggers should return errors from the wrapped
102 // logger up the stack.
103 //
104 // Fortunately, the decorator pattern also provides a way to avoid the
105 // necessity to check for errors every time an application calls Logger.Log.
106 // An application required to panic whenever its Logger encounters
107 // an error could initialize its logger as follows.
108 //
109 //    fmtlogger := log.NewLogfmtLogger(log.NewSyncWriter(os.Stdout))
110 //    logger := log.LoggerFunc(func(keyvals ...interface{}) error {
111 //        if err := fmtlogger.Log(keyvals...); err != nil {
112 //            panic(err)
113 //        }
114 //        return nil
115 //    })
116 package log