Documentation
¶
Overview ¶
Package ulog is the Logging package.
package ulog provides an API wrapper around the logging library zap (https://github.com/uber-go/zap). package ulog uses the builder pattern to instantiate the logger. With LogBuilder you can perform pre-initialization setup by injecting configuration, custom logger, and log level prior to building the usable ulog.Log object.
ulog.Log interface provides a few benefits:
• Decouple services from the logger used underneath the framework
• Easy to use API for logging
• Easily swappable backend logger without changing the service
Sample usage
package main import "go.uber.org/fx/ulog" func main() { // Configure logger with configuration preferred by your service logConfig := ulog.Configuration{} logBuilder := ulog.Builder().WithConfiguration(&logConfig) // Build ulog.Log from logBuilder log := lobBuilder.Build() // Use logger in your service log.Info("Message describing logging reason", "key", "value") }
Context ¶
It is very common that in addition to logging a string message, it is desirable to provide additional information: customer uuid, tracing id, etc.
For that very reason, the logging methods (Info,Warn, Debug, etc) take additional parameters as key value pairs.
Retaining Context ¶
Sometimes the same context is used over and over in a logger. For example service name, shard id, module name, etc. For this very reason With()functionality exists which will return a new instance of the logger with that information baked in so it doesn't have to be provided for each logging call.
For example, the following piece of code:
package main import "go.uber.org/fx/ulog" func main() { log := ulog.Logger() log.Info("My info message") log.Info("Info with context", "customer_id", 1234) richLog := log.With("shard_id", 3, "levitation", true) richLog.Info("Rich info message") richLog.Info("Even richer", "more_info", []int{1, 2, 3}) }
Produces this output:
{"level":"info","ts":1479946972.102394,"msg":"My info message"} {"level":"info","ts":1479946972.1024208,"msg":"Info with context","customer_id":1234} {"level":"info","ts":1479946972.1024246,"msg":"Rich info message","shard_id":3,"levitation":true} {"level":"info","ts":1479946972.1024623,"msg":"Even richer","shard_id":3,"levitation":true,"more_info":[1,2,3]}
Configuration ¶
ulog configuration can be defined in multiple ways:
Writing the struct yourself
loggingConfig := ulog.Configuration{ Stdout: true, }
Configuration defined in YAML
logging: stdout: true level: debug
Benchmarks ¶
Current performance benchmark data with ulog interface, ulog baseLogger struct, and zap.Logger
BenchmarkUlogWithoutFields-8 10000000 223 ns/op 0 B/op 0 allocs/op BenchmarkUlogWithFieldsLogIFace-8 1000000 1237 ns/op 1005 B/op 18 allocs/op BenchmarkUlogWithFieldsBaseLoggerStruct-8 1000000 1096 ns/op 748 B/op 17 allocs/op BenchmarkUlogWithFieldsZapLogger-8 2000000 664 ns/op 514 B/op 1 allocs/op BenchmarkUlogLiteWithFields-8 3000000 489 ns/op 249 B/op 6 allocs/op BenchmarkUlogSentry-8 3000000 407 ns/op 128 B/op 4 allocs/op BenchmarkUlogSentryWith-8 1000000 1535 ns/op 1460 B/op 12 allocs/op
Sentry ¶
ulog has a seamless integration with Sentry. For out-of-the-box usage just include this in your configuration yaml:
logging: sentry: dsn: http://user:secret@your.sentry.dsn/project
If you'd like to take more control over the Sentry integration, see sentry.Configuration
For example, to turn off Stacktrace generation:
logging: sentry: dsn: http://user:secret@your.sentry.dsn/project trace: disabled: true
To set up Sentry in code use sentry.Hook. For example:
import ( "github.com/uber-go/zap" "go.uber.org/fx/ulog/ulog" "go.uber.org/fx/ulog/sentry" "go.uber.org/fx/service" ) func main() { h := sentry.New(MY_DSN, MinLevel(zap.InfoLevel), DisableTraces()) l := ulog.Builder().WithSentryHook(h).Build() svc, err := service.WithLogger(l).Build() }
Index ¶
- Variables
- func ContextWithLogger(ctx context.Context, log Log) context.Context
- func ContextWithTraceLogger(ctx context.Context, span opentracing.Span) context.Context
- func SetLogger(log Log)
- type Configuration
- type FileConfiguration
- type Log
- type LogBuilder
- func (lb *LogBuilder) Build() Log
- func (lb *LogBuilder) Configure() zap.Logger
- func (lb *LogBuilder) SetLogger(zap zap.Logger) *LogBuilder
- func (lb *LogBuilder) WithConfiguration(logConfig Configuration) *LogBuilder
- func (lb *LogBuilder) WithScope(s tally.Scope) *LogBuilder
- func (lb *LogBuilder) WithSentryHook(hook *sentry.Hook) *LogBuilder
Constants ¶
This section is empty.
Variables ¶
var NopLogger = nopLogger()
NopLogger should be used in tests if you wish to discard the output
Functions ¶
func ContextWithLogger ¶
ContextWithLogger sets the context with the context aware logger
func ContextWithTraceLogger ¶
ContextWithTraceLogger returns a new context with a context-aware logger
Types ¶
type Configuration ¶
type Configuration struct { Level string File *FileConfiguration Stdout bool Verbose bool // Do not automatically emit metrics for logging counts DisableMetrics bool Sentry *sentry.Configuration TextFormatter *bool // use TextFormatter (default json) // contains filtered or unexported fields }
Configuration for logging with UberFx
type FileConfiguration ¶
FileConfiguration describes the properties needed to log to a file
type Log ¶
type Log interface { // With creates a child logger with the provided parameters as key value pairs // ulog uses uber-go/zap library as its child logger which needs pairs of key value objects // in the form of zap.Fields(key, value). ulog performs field conversion from // supplied keyVals pair to zap.Fields format. // // **IMPORTANT**: With should never be used if the resulting logger // object is not being retained. If you need to add some context to // a logging message, use the Error, Info, etc. functions // and pass in additional interface{} pairs for logging. With(keyVals ...interface{}) Log // Check returns a zap.CheckedMessage if logging a message at the specified level is enabled. Check(level zap.Level, message string) *zap.CheckedMessage // Typed returns underlying logger implementation (zap.Logger) to get around the ulog.Log interface Typed() zap.Logger // Log at the provided zap.Level with message, and a sequence of parameters as key value pairs Log(level zap.Level, message string, keyVals ...interface{}) // Debug logs at Debug level with message, and parameters as key value pairs Debug(message string, keyVals ...interface{}) // Info logs at Info level with message, and parameters as key value pairs Info(message string, keyVals ...interface{}) // Warn ogs at Warn level with message, and parameters as key value pairs Warn(message string, keyVals ...interface{}) // Error logs at Error level with message, and parameters as key value pairs Error(message string, keyVals ...interface{}) // Panic logs at Panic level with message, and parameters as key value pairs Panic(message string, keyVals ...interface{}) // Fatal logs at Fatal level with message, and parameters as key value pairs Fatal(message string, keyVals ...interface{}) // DPanic logs at Debug level (Fatal for development) with message, and parameters as key value pairs DPanic(message string, keyVals ...interface{}) }
Log is the UberFx wrapper for underlying logging service
func TestingLogger ¶
TestingLogger returns basic logger and underlying sink for testing the messages WithInMemoryLogger testing helper can also be used to test actual outputted JSON bytes
type LogBuilder ¶
type LogBuilder struct {
// contains filtered or unexported fields
}
LogBuilder is the struct containing logger
func Builder ¶
func Builder() *LogBuilder
Builder creates an empty builder for building ulog.Log object
func (*LogBuilder) Build ¶
func (lb *LogBuilder) Build() Log
Build the ulog logger for use TODO: build should return `(Log, error)` in case we can't properly instantiate
func (*LogBuilder) Configure ¶
func (lb *LogBuilder) Configure() zap.Logger
Configure Log object with the provided log.Configuration
func (*LogBuilder) SetLogger ¶
func (lb *LogBuilder) SetLogger(zap zap.Logger) *LogBuilder
SetLogger allows users to set their own initialized logger to work with ulog APIs
func (*LogBuilder) WithConfiguration ¶
func (lb *LogBuilder) WithConfiguration(logConfig Configuration) *LogBuilder
WithConfiguration sets up configuration for the log builder
func (*LogBuilder) WithScope ¶
func (lb *LogBuilder) WithScope(s tally.Scope) *LogBuilder
WithScope sets up configuration for the log builder
func (*LogBuilder) WithSentryHook ¶
func (lb *LogBuilder) WithSentryHook(hook *sentry.Hook) *LogBuilder
WithSentryHook allows users to manually configure the sentry hook