Documentation ¶
Overview ¶
Package log provides a unified interface for loggers such as logrus or zerolog, along with Sentry support and other custom options. Look to the design doc here for more information: https://code.8labs.io/project/designs/-/tree/platform-ctpx-sdk-logging/platform/ctpx-sdk-logging
Example ¶
package main import ( "fmt" "net/http" "os" "time" "github.com/secureworks/tdr-sdk-go/log" "github.com/secureworks/tdr-sdk-go/log/middleware" ) var ( //these are UNUSED and only for making this example compile e http.Handler ) func main() { //if config is passed as nil to log.Open then this is used config := log.DefaultConfig(nil) //various other options //config.EnableErrStack = true //config.LocalDevel = true //optional custom options, passing nothing for this is fine, look to log.CustomOption for more info //var opts []log.Option //opts = append(opts, log.CustomOption("Sample", mySamplerInterfaceType)) //Zerolog implementation underscore imported logger, err := log.Open("zerolog", config) //logger, err := log.Open("zerolog", config, opts...) if err != nil { //handle error fmt.Fprintf(os.Stderr, "Unable to setup logger: %v", err) os.Exit(1) } //where e is your base handler, echo and buffalo have adapters handler := middleware.NewHTTPRequestMiddleware(logger, 0)(e) //... //setup logger for use by http.Server or anything that can use an io.Writer //wc := logger.WriteCloser(log.WARN) //defer wc.Close() errc := make(chan error) listenAddr := ":8080" //or create new http.Server with logger as base context for use by request handlers //and ErrorLog set to write to logger at WARN level srv, c := middleware.NewHTTPServer(logger, log.WARN) defer c.Close() //more options you should be setting srv.Addr = listenAddr srv.Handler = handler srv.WriteTimeout = time.Second * 15 srv.ReadTimeout = time.Second * 10 logger.Info().Msgf("Starting server on: %s", listenAddr) go func() { errc <- srv.ListenAndServe() }() //block on sig term || int || etc, whatever else }
Output:
Index ¶
- Constants
- func CtxWithEntry(ctx context.Context, e Entry) context.Context
- func CtxWithLogger(ctx context.Context, l Logger) context.Context
- func Register(name string, nl NewLogger)
- type Config
- type Entry
- type EnvKey
- type Level
- type Logger
- type LoggerFormat
- type NewLogger
- type Option
- type UnderlyingLogger
Examples ¶
Constants ¶
const ( //LoggerKey is the key value to use with context.Context for Logger put and retrieval. LoggerKey ctxKey = iota + 1 //EntryKey is the key value to use with context.Context for Logger put and retrieval. EntryKey )
const ( //ReqDuration is a key for Logger data. ReqDuration = `request_duration` //PanicStack is a key for Logger data. PanicStack = `panic_stack` //PanicValue is a key for Logger data. PanicValue = `panic_value` //CallerField is a key for Logger data. CallerField = `caller` //StackField is a key for Logger data. StackField = `stack` //XRequestID is a common field and header from API calls. XRequestID = `X-Request-Id` //XTraceID is a common field and header from API calls. XTraceID = `X-Trace-Id` //XSpanID is a common field and header from API calls. XSpanID = `X-Span-Id` )
Variables ¶
This section is empty.
Functions ¶
func CtxWithEntry ¶
CtxWithEntry returns a context with Entry e as its value.
func CtxWithLogger ¶
CtxWithLogger returns a context with Logger l as its value.
Types ¶
type Config ¶
type Config struct { //Level is the level at which returned Logger's will be considered enabled. //For example, setting WARN then logging and sending a Debug entry will cause //the entry to not be logged. Level Level //LocalDevel, may be used by some Logger's for local debugging changes. LocalDevel bool //Format is the format the Logger should log in. Format LoggerFormat //EnableErrStack enables error stack gathering and logging. EnableErrStack bool //Output is the io.Writer the Logger will write messages to. Output io.Writer //Sentry is a sub-config type for configurating Sentry if desired. //No other portion of this struct is considered if DSN is not set and valid. Sentry struct { //DSN is the Sentry DSN. DSN string //Release is the program release or revision. Release string //Env is the deployment environment; "prod", "dev", etc. Env string //Server is the server or hostname. Server string //Levels are the log levels that will trigger an event to be sent to Sentry. Levels []Level //Debug is a passthrough for Sentry debugging. Debug bool } }
Config defines common logger configuration options.
func DefaultConfig ¶
DefaultConfig returns a Config instance with sane defaults. env is a callback for looking up EnvKeys, it is set to os.Getenv if nil. Fields and values returned by this function can be altered.
type Entry ¶
type Entry interface { //Async flips the current Entry to be asynchronous, or back if called more than once. //If set to asynchronous an Entry implementation should not log its final message until Send is called. Async() Entry //Caller embeds a caller value into the existing Entry. //A caller value is a filepath followed by line number. //Skip determines the number of additional stack frames to ascend when //determining the value. By default the caller of the method is the value used //and skip does not need to be supplied in that case. //Caller may be called multiple times on the Entry to build a stack or execution trace. Caller(skip ...int) Entry WithError(errs ...error) Entry WithField(key string, val interface{}) Entry WithFields(fields map[string]interface{}) Entry WithBool(key string, bls ...bool) Entry WithDur(key string, durs ...time.Duration) Entry WithInt(key string, is ...int) Entry WithUint(key string, us ...uint) Entry WithStr(key string, strs ...string) Entry //WithTime adds the respective time values to the Entry at the given key. //Note that many loggers add a "time" key automatically and time formatting //may be dependant on configuration or logger choice. WithTime(key string, ts ...time.Time) Entry Trace() Entry Debug() Entry Info() Entry Warn() Entry Error() Entry Panic() Entry Fatal() Entry //Msgf formats and sets the final log message for this Entry. //It will also send the message if Async has not been set. Msgf(string, ...interface{}) //Msg sets the final log message for this Entry. //It will also send the message if Async has not been set. Msg(msg string) //Send sends the final log entry. //This interface does not define the behavior of calling this method more than once. Send() }
Entry is the primary interface by which individual log entries are made.
func EntryFromCtx ¶
EntryFromCtx returns the Entry in ctx, or nil if none exists.
type EnvKey ¶
type EnvKey string
EnvKey is a publicly documented string type for environment lookups performed for DefaultConfig. It is otherwise unspecial.
const ( //LogLevel is the EnvKey used for looking up the log level. LogLevel EnvKey = "LOG_LEVEL" //ErrStack is the EnvKey used for looking up error/stack trace logging; Value should be true || True || TRUE. ErrStack EnvKey = "ERROR_STACK" //SentryDSN is the EnvKey used for looking up the Sentry project DNS; Empty value disables Sentry. SentryDSN EnvKey = "SENTRY_DSN" //SentryLevels is the EnvKey used for looking up which log levels will be sent to Sentry; Values should be comma separated. SentryLevels EnvKey = "SENTRY_LEVELS" //Environment is the EnvKey used for looking up the current deployment environment; Values commonly dev || prod. Environment EnvKey = "ENVIRONMENT" )
type Level ¶
type Level int
Level is the base type for logging levels supported by this package.
const ( //TRACE Level. TRACE Level = iota + -2 //DEBUG Level. DEBUG //INFO Level; this is the default (zero value). INFO //WARN Level. WARN //ERROR Level. ERROR //PANIC Level; note, depending on usage this will cause the logger to panic. PANIC //FATAL Level; note, depending on usage this will cause the logger to force a program exit. FATAL )
func AllLevels ¶
func AllLevels() []Level
AllLevels is a convenience function returning all levels as a slice.
func LevelFromString ¶
LevelFromString parses str and returns the closest level. If one isn't found the default level is returned.
type Logger ¶
type Logger interface { //WithError inserts the given error into a new Entry and returns the Entry. WithError(err error) Entry //WithField inserts key & val into a new Entry and returns the Entry. WithField(key string, val interface{}) Entry //WithFields inserts the given set of fields into a new Entry and returns the Entry. WithFields(fields map[string]interface{}) Entry //Entry returns a new Entry at the provided log level. Entry(Level) Entry //Trace returns a new Entry at TRACE level. Trace() Entry //Debug returns a new Entry at DEBUG level. Debug() Entry //Info returns a new Entry at INFO level. Info() Entry //Warn returns a new Entry at WARN level. Warn() Entry //Error returns a new Entry at ERROR level. Error() Entry //Panic returns a new Entry at PANIC level. //Implementations should panic once the final message for the Entry is logged. Panic() Entry //Fatal returns a new Entry at FATAL level. //Implementations should exit non-zero once the final message for the Entry is logged. Fatal() Entry //WriteCloser returns an io.Writer that when written to writes logs at the given level. //It is the callers responsibility to call Close when finished. //This is particularly useful for redirecting the output of other loggers or even Readers //with the help of io.TeeReader. WriteCloser(Level) io.WriteCloser }
Logger is the minimum interface loggers should implement when used with CTPx packages.
func LoggerFromCtx ¶
LoggerFromCtx returns the Logger in ctx, or nil if none exists.
type LoggerFormat ¶
type LoggerFormat int
LoggerFormat is the base type for logging formats supported by this package
const ( //ImplementationDefaultFormat leaves the format up to the logger implementation default. ImplementationDefaultFormat LoggerFormat = iota - 1 //JSONFormat is the default (zero value) format for loggers registered with this package. JSONFormat )
func (LoggerFormat) IsValid ¶
func (l LoggerFormat) IsValid() bool
IsValid checks if a logger format is valid.
type Option ¶
type Option func(interface{}) error
Option is a function type that accepts an interface value and returns an error.
func CustomOption ¶
CustomOption takes the name of a method on the UnderlyingLogger of a Logger implementation as well as a value, and returns an Option. name is the case sensitive name of a method while val should be a single value needed as input to the named method. If several values are needed as input then val should be a function that accepts no input and returns values to be used as input to the named method. If val is a function and returns an error as its only or last value it will be checked and returned if non nil, otherwise remaining values are fed to the named method. A nil val is valid so long as the named method expects nil input or no input. If the named method returns an instance of itself it will be set back as the new UnderlyingLogger. If the named method returns an error that error will be checked and returned. Look to the CustomOption tests and package level example for basic usage.
type UnderlyingLogger ¶
type UnderlyingLogger interface { GetLogger() interface{} SetLogger(interface{}) }
UnderlyingLogger is an escape hatch allowing Loggers registered with this package the option to return their underlying implementation, as well as reset it. Note this is currently required for CustomOption's to work.