context

package
v2.0.0-alpha.3+incompa... Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Mar 7, 2015 License: Apache-2.0 Imports: 10 Imported by: 0

Documentation

Overview

Package context provides several utilities for working with golang.org/x/net/context in http requests. Primarily, the focus is on logging relevent request information but this package is not limited to that purpose.

Logging

The most useful aspect of this package is GetLogger. This function takes any context.Context interface and returns the current logger from the context. Canonical usage looks like this:

GetLogger(ctx).Infof("something interesting happened")

GetLogger also takes optional key arguments. The keys will be looked up in the context and reported with the logger. The following example would return a logger that prints the version with each log message:

ctx := context.Context(context.Background(), "version", version)
GetLogger(ctx, "version").Infof("this log message has a version field")

The above would print out a log message like this:

INFO[0000] this log message has a version field        version=v2.0.0-alpha.2.m

When used with WithLogger, we gain the ability to decorate the context with loggers that have information from disparate parts of the call stack. Following from the version example, we can build a new context with the configured logger such that we always print the version field:

ctx = WithLogger(ctx, GetLogger(ctx, "version"))

Since the logger has been pushed to the context, we can now get the version field for free with our log messages. Future calls to GetLogger on the new context will have the version field:

GetLogger(ctx).Infof("this log message has a version field")

This becomes more powerful when we start stacking loggers. Let's say we have the version logger from above but also want a request id. Using the context above, in our request scoped function, we place another logger in the context:

ctx = context.WithValue(ctx, "http.request.id", "unique id") // called when building request context
ctx = WithLogger(ctx, GetLogger(ctx, "http.request.id"))

When GetLogger is called on the new context, "http.request.id" will be included as a logger field, along with the original "version" field:

INFO[0000] this log message has a version field        http.request.id=unique id version=v2.0.0-alpha.2.m

Note that this only affects the new context, the previous context, with the version field, can be used independently. Put another way, the new logger, added to the request context, is unique to that context and can have request scoped varaibles.

HTTP Requests

This package also contains several methods for working with http requests. The concepts are very similar to those described above. We simply place the request in the context using WithRequest. This makes the request variables available. GetRequestLogger can then be called to get request specific variables in a log line:

ctx = WithRequest(ctx, req)
GetRequestLogger(ctx).Infof("request variables")

Like above, if we want to include the request data in all log messages in the context, we push the logger to a new context and use that one:

ctx = WithLogger(ctx, GetRequestLogger(ctx))

The concept is fairly powerful and ensures that calls throughout the stack can be traced in log messages. Using the fields like "http.request.id", one can analyze call flow for a particular request with a simple grep of the logs.

Index

Constants

This section is empty.

Variables

View Source
var (
	ErrNoRequestContext = errors.New("no http request in context")
)

Common errors used with this package.

Functions

func GetRequest

func GetRequest(ctx context.Context) (*http.Request, error)

GetRequest returns the http request in the given context. Returns ErrNoRequestContext if the context does not have an http request associated with it.

func GetRequestID

func GetRequestID(ctx context.Context) string

GetRequestID attempts to resolve the current request id, if possible. An error is return if it is not available on the context.

func GetStringValue

func GetStringValue(ctx context.Context, key string) (value string)

GetStringValue returns a string value from the context. The empty string will be returned if not found.

func Since

func Since(ctx context.Context, key interface{}) time.Duration

Since looks up key, which should be a time.Time, and returns the duration since that time. If the key is not found, the value returned will be zero. This is helpful when inferring metrics related to context execution times.

func WithLogger

func WithLogger(ctx context.Context, logger Logger) context.Context

WithLogger creates a new context with provided logger.

func WithRequest

func WithRequest(ctx context.Context, r *http.Request) context.Context

WithRequest places the request on the context. The context of the request is assigned a unique id, available at "http.request.id". The request itself is available at "http.request". Other common attributes are available under the prefix "http.request.". If a request is already present on the context, this method will panic.

func WithResponseWriter

func WithResponseWriter(ctx context.Context, w http.ResponseWriter) (context.Context, http.ResponseWriter)

WithResponseWriter returns a new context and response writer that makes interesting response statistics available within the context.

func WithVars

func WithVars(ctx context.Context, r *http.Request) context.Context

WithVars extracts gorilla/mux vars and makes them available on the returned context. Variables are available at keys with the prefix "vars.". For example, if looking for the variable "name", it can be accessed as "vars.name". Implementations that are accessing values need not know that the underlying context is implemented with gorilla/mux vars.

Types

type Logger

type Logger interface {
	// standard logger methods
	Print(args ...interface{})
	Printf(format string, args ...interface{})
	Println(args ...interface{})

	Fatal(args ...interface{})
	Fatalf(format string, args ...interface{})
	Fatalln(args ...interface{})

	Panic(args ...interface{})
	Panicf(format string, args ...interface{})
	Panicln(args ...interface{})

	// Leveled methods, from logrus
	Debug(args ...interface{})
	Debugf(format string, args ...interface{})
	Debugln(args ...interface{})

	Error(args ...interface{})
	Errorf(format string, args ...interface{})
	Errorln(args ...interface{})

	Info(args ...interface{})
	Infof(format string, args ...interface{})
	Infoln(args ...interface{})

	Warn(args ...interface{})
	Warnf(format string, args ...interface{})
	Warnln(args ...interface{})
}

Logger provides a leveled-logging interface.

func GetLogger

func GetLogger(ctx context.Context, keys ...interface{}) Logger

GetLogger returns the logger from the current context, if present. If one or more keys are provided, they will be resolved on the context and included in the logger. While context.Value takes an interface, any key argument passed to GetLogger will be passed to fmt.Sprint when expanded as a logging key field. If context keys are integer constants, for example, its recommended that a String method is implemented.

func GetRequestLogger

func GetRequestLogger(ctx context.Context) Logger

GetRequestLogger returns a logger that contains fields from the request in the current context. If the request is not available in the context, no fields will display. Request loggers can safely be pushed onto the context.

func GetResponseLogger

func GetResponseLogger(ctx context.Context) Logger

GetResponseLogger reads the current response stats and builds a logger. Because the values are read at call time, pushing a logger returned from this function on the context will lead to missing or invalid data. Only call this at the end of a request, after the response has been written.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL