logging

package
v0.15.0 Latest Latest
Warning

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

Go to latest
Published: Nov 16, 2018 License: Apache-2.0 Imports: 7 Imported by: 0

README

Logging

This package supports extended settings for request scoped logging. Specifically, the log level (severity below which to suppress) and a custom log field can be set with the context logger, based on http Header values with the grpc-gateway or via grpc metadata. The context logger should then be used inside grpc method implementations instead of a global logger.

The custom field log-trace-key value is intended to be used for simplifying the process of isolating logs for a single request or a set of requests. This is a similar goal to request-ids, but request-ids are randomly generated for uniqueness, making them less versatile for debugging purposes.

Enabling request-scoped logger settings

To enable these features, the LogLevelInterceptor and the grpc_logrus.UnaryServerInterceptor have to be included in the server's middleware chain.

The LogLevelInterceptor needs to be placed after the grpc_logrus.UnaryServerInterceptor in the chain, and accepts its own default logging level, so that the grpc_logrus interceptor (and the interceptors between it and this one) can be allowed to log at a different level than the proceeding ones even without setting it in the request (for example, to always/never log the Info message in the ctxlogrus interceptor, despite having a higher/lower log level). Note that the LogLevelInterceptor cannot effect whether or not the Info level message in the grpc_logrus.UnaryServerInterceptor is printed or not.

The middleware chain code should look something like this:

import (
	"github.com/infobloxopen/atlas-app-toolkit/logging"
	"github.com/sirupsen/logrus"
	"google.golang.org/grpc"
)

func main() {
	server := grpc.NewServer(
		grpc.UnaryInterceptor(
			grpc_middleware.ChainUnaryServer( // middleware chain
				grpc_logrus.UnaryServerInterceptor(logrus.NewEntry(logger)),
				logging.LogLevelInterceptor(logger.Level), // Request-scoped logging middleware
				...
			),
		),
	)
	...
}

For grpc-gateway support, the MetadataAnnotator should also be added to the gateway. Using the toolkit's server package, that setup looks something like this:

import (
	"github.com/grpc-ecosystem/grpc-gateway/runtime"
	"github.com/infobloxopen/atlas-app-toolkit/gateway"
	"github.com/infobloxopen/atlas-app-toolkit/logging"
	"github.com/infobloxopen/atlas-app-toolkit/server"
)

func main() {
	gatewayOptions := []runtime.ServeMuxOption{
		runtime.WithMetadata(logging.MetadataAnnotator),
		...
	}

	server.NewServer(
		server.WithGrpcServer(grpcServer),
		server.WithGateway(
			gateway.WithGatewayOptions(gatewayOptions...),
			...
		),
	)
}

Using the request-scoped logger settings

When using the metadata annotator and the grpc-gateway, http requests using headers -H "log-trace-key: <value>" and -H "log-level: <level>" will be stored in the grpc metadata for consumption by the interceptor.

Without the grpc-gateway, the metadata has to be added to the request context directly.

ctx := metadata.AppendToOutgoingContext(ctx, "log-level", "debug", "log-trace-key", "foobar")

// make unary RPC
response, err := client.SomeRPC(ctx, someRequest)

Other functions

The helper function CopyLoggerWithLevel can be used to make a deep copy of a logger at a new level, or using CopyLoggerWithLevel(entry.Logger, level).WithFields(entry.Data) can copy a logrus.Entry.

Documentation

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

func Annotator

func Annotator(ctx context.Context, req *http.Request) metadata.MD

Annotator is a function that reads the http headers of incoming requests searching for special logging arguments

func CopyLoggerWithLevel

func CopyLoggerWithLevel(logger *logrus.Logger, lvl logrus.Level) *logrus.Logger

CopyLoggerWithLevel makes a copy of the given (logrus) logger at the logger level. If copying an entry, use CopyLoggerWithLevel(entry.Logger, level).WithFields(entry.Data) on the result (changes to these entries' fields will not affect each other).

func LogLevelInterceptor

func LogLevelInterceptor(defaultLevel logrus.Level) grpc.UnaryServerInterceptor

LogLevelInterceptor sets the level of the logger in the context to either the default or the value set in the context via grpc metadata. Also sets the custom log tag if present for pseudo-tracing purposes

Types

This section is empty.

Jump to

Keyboard shortcuts

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