1 // Package context provides several utilities for working with 2 // Go's context in http requests. Primarily, the focus is on logging relevant 3 // request information but this package is not limited to that purpose. 4 // 5 // The easiest way to get started is to get the background context: 6 // 7 // ctx := context.Background() 8 // 9 // The returned context should be passed around your application and be the 10 // root of all other context instances. If the application has a version, this 11 // line should be called before anything else: 12 // 13 // ctx := context.WithVersion(context.Background(), version) 14 // 15 // The above will store the version in the context and will be available to 16 // the logger. 17 // 18 // # Logging 19 // 20 // The most useful aspect of this package is GetLogger. This function takes 21 // any context.Context interface and returns the current logger from the 22 // context. Canonical usage looks like this: 23 // 24 // GetLogger(ctx).Infof("something interesting happened") 25 // 26 // GetLogger also takes optional key arguments. The keys will be looked up in 27 // the context and reported with the logger. The following example would 28 // return a logger that prints the version with each log message: 29 // 30 // ctx := context.Context(context.Background(), "version", version) 31 // GetLogger(ctx, "version").Infof("this log message has a version field") 32 // 33 // The above would print out a log message like this: 34 // 35 // INFO[0000] this log message has a version field version=v2.0.0-alpha.2.m 36 // 37 // When used with WithLogger, we gain the ability to decorate the context with 38 // loggers that have information from disparate parts of the call stack. 39 // Following from the version example, we can build a new context with the 40 // configured logger such that we always print the version field: 41 // 42 // ctx = WithLogger(ctx, GetLogger(ctx, "version")) 43 // 44 // Since the logger has been pushed to the context, we can now get the version 45 // field for free with our log messages. Future calls to GetLogger on the new 46 // context will have the version field: 47 // 48 // GetLogger(ctx).Infof("this log message has a version field") 49 // 50 // This becomes more powerful when we start stacking loggers. Let's say we 51 // have the version logger from above but also want a request id. Using the 52 // context above, in our request scoped function, we place another logger in 53 // the context: 54 // 55 // ctx = context.WithValue(ctx, "http.request.id", "unique id") // called when building request context 56 // ctx = WithLogger(ctx, GetLogger(ctx, "http.request.id")) 57 // 58 // When GetLogger is called on the new context, "http.request.id" will be 59 // included as a logger field, along with the original "version" field: 60 // 61 // INFO[0000] this log message has a version field http.request.id=unique id version=v2.0.0-alpha.2.m 62 // 63 // Note that this only affects the new context, the previous context, with the 64 // version field, can be used independently. Put another way, the new logger, 65 // added to the request context, is unique to that context and can have 66 // request scoped variables. 67 // 68 // # HTTP Requests 69 // 70 // This package also contains several methods for working with http requests. 71 // The concepts are very similar to those described above. We simply place the 72 // request in the context using WithRequest. This makes the request variables 73 // available. GetRequestLogger can then be called to get request specific 74 // variables in a log line: 75 // 76 // ctx = WithRequest(ctx, req) 77 // GetRequestLogger(ctx).Infof("request variables") 78 // 79 // Like above, if we want to include the request data in all log messages in 80 // the context, we push the logger to a new context and use that one: 81 // 82 // ctx = WithLogger(ctx, GetRequestLogger(ctx)) 83 // 84 // The concept is fairly powerful and ensures that calls throughout the stack 85 // can be traced in log messages. Using the fields like "http.request.id", one 86 // can analyze call flow for a particular request with a simple grep of the 87 // logs. 88 package context 89