log

package
v0.1.0 Latest Latest
Warning

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

Go to latest
Published: Mar 15, 2021 License: Apache-2.0 Imports: 8 Imported by: 0

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/taegis-sdk-go/log"
	"github.com/secureworks/taegis-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

Examples

Constants

View Source
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
)
View Source
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

func CtxWithEntry(ctx context.Context, e Entry) context.Context

CtxWithEntry returns a context with Entry e as its value.

func CtxWithLogger

func CtxWithLogger(ctx context.Context, l Logger) context.Context

CtxWithLogger returns a context with Logger l as its value.

func Register

func Register(name string, nl NewLogger)

Register registers the provided NewLogger function under the given name for use with Open. Note, this method is not concurreny safe, nil NewLoggers or duplicate registration will cause a panic.

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

func DefaultConfig(env func(string) string) *Config

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

func EntryFromCtx(ctx context.Context) Entry

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"
)

func (EnvKey) String

func (ek EnvKey) String() string

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

func LevelFromString(str string) (lvl Level)

LevelFromString parses str and returns the closest level. If one isn't found the default level is returned.

func (Level) IsEnabled

func (l Level) IsEnabled(en Level) bool

IsEnabled checks if the level l is enabled relative to en.

func (Level) IsValid

func (l Level) IsValid() bool

IsValid checks if the current level is valid relative to known values.

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

func LoggerFromCtx(ctx context.Context) Logger

LoggerFromCtx returns the Logger in ctx, or nil if none exists.

func Noop

func Noop() Logger

Noop returns an implementation of Logger that does nothing when its methods are called. This can also be retrieved using "noop" with "Open", though in that case any configuration is ignored.

func Open

func Open(name string, conf *Config, opts ...Option) (Logger, error)

Open returns a new instance of the selected Logger with config and options.

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 NewLogger

type NewLogger func(*Config, ...Option) (Logger, error)

NewLogger is a function type for Logger implemenations to register themselves.

type Option

type Option func(interface{}) error

Option is a function type that accepts an interface value and returns an error.

func CustomOption

func CustomOption(name string, val interface{}) Option

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.

Directories

Path Synopsis
internal

Jump to

Keyboard shortcuts

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