logging

package module
v0.0.0-...-2ef827d Latest Latest
Warning

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

Go to latest
Published: Jan 27, 2024 License: MIT Imports: 13 Imported by: 5

README

Go Report Card

logging

Overview

A central logging module that acts as a custom wrapper around logrus. It provides definitions of logging levels, trace injection, and global logger creation and level setting.

This logger should be used for ALL go microservices so that logging consistency is maintained.

Understanding log levels

Each log level in the custom logger here also has a preceding comment explaining how it is defined. Make sure to know and follow these definitions so that log levels are consistent across all microservices.

For example:

// Warn - Definition:
// something that's concerning but not causing the operation to abort;
// # of connections in the DB pool getting low, an unusual-but-expected timeout in an operation, etc.
// Think of 'WARN' as something that's useful in aggregate; e.g. grep, group,
// and count them to get a picture of what's affecting the system health
func (l *CustomLogger) Warn(args ...interface{}) {
    l.entry.Warn(args...)
}

Usage

Implementing the logger is very simple. The main thing to keep in mind is that this logger should ALWAYS be used as a global logger passed down from main.go into the handler layer at instantiation, and then passed down from each handler function into the service and dao layers at call time.

Documentation

Overview

Credit: https://github.com/banzaicloud/logrus-runtime-formatter

Index

Constants

View Source
const FileKey = "file"

FileKey holds the file field

View Source
const FunctionKey = "function"

FunctionKey holds the function field

View Source
const LineKey = "line"

LineKey holds the line field

View Source
const PackageKey = "package"

PackageKey holds the package field

Variables

This section is empty.

Functions

func CreateLogger

func CreateLogger(level string, service string) *logger

CreateLogger creates a service level logger. The level is the log level to instantiate the logger with. Possible values for level are "panic", "fatal", "error", "warn", "warning", "info", "debug", and "trace". The service is the name of the service to include with all logs.

func CreateNullLogger

func CreateNullLogger() (*logger, *test.Hook)

CreateNullLogger creates a logger for testing that wraps the null logger provided by logrus

func GinMiddleware

func GinMiddleware(quietRoutes []string) gin.HandlerFunc

GinMiddleware injects the custom logger with traces and http data fields

func NewError

func NewError(err error, message string) error

NewError creates a standard Go error from a given error and message. This is useful when returning a standard Go error from a third party module that you don't control but want to add a custom message to the error before calling logger.WrapError().

func RegisterHTTPEndpointsWithGin

func RegisterHTTPEndpointsWithGin(router *gin.Engine)

RegisterHTTPEndpointsWithGin registers the log changing and viewing endpoints with the Gin router Possible values for level are "panic", "fatal", "error", "warn", "warning", "info", "debug", and "trace" - POST to set log level: /log?level=<LEVEL> - GET to retrieve the current log level

Types

type Error

type Error interface {
	error
	// Unwrap returns the underlying error. If wrapping has occurred it will take the shape of:
	//   "[main.FunctionA]->[module/package1.FunctionB]->[module/package2.FunctionC]->[original error message]"
	Unwrap() error
	// Fields returns the logger fields from the context of the root error (the lowest `logger.WrapError()` call on the call stack).
	// This preserves the logger context which will have logger fields added throughout the call stack down to where the error was created.
	Fields() Fields
}

Error extends the standard Go error interface with a custom implementation of Error() and Unwrap() to build out a call stack and keep logger fields from the root of the call stack

type Fields

type Fields map[string]interface{}

Fields is used to pass to the WithFields() interface method

type Formatter

type Formatter struct {
	ChildFormatter logrus.Formatter
	// When true, line number will be tagged to fields as well
	Line bool
	// When true, package name will be tagged to fields as well
	Package bool
	// When true, file name will be tagged to fields as well
	File bool
	// When true, only base name of the file will be tagged to fields
	BaseNameOnly bool
}

Formatter decorates log entries with function name and package name (optional) and line number (optional)

func (*Formatter) Format

func (f *Formatter) Format(entry *logrus.Entry) ([]byte, error)

Format the current log entry by adding the function name and line number of the caller.

type Logger

type Logger interface {
	// AddGlobalField adds a key:value pair to every log written with this logger
	// This is helpful for service-wide values
	AddGlobalField(key string, val string)
	// SetLevel sets the logging level for the logger
	SetLevel(level logrus.Level)
	// GetEntry returns a copy of the logrus Entry used in the logger
	// NOTE: Only use the base logrus.Entry when absolutely necessary.
	// Logging should really be done through the CustomLogger wrapper,
	// NOT through logrus directly.
	GetEntry() *logrus.Entry
	// WrapError wraps a standard Go error (OR `logging.Error`) into a custom error with the
	// additional context of current logger fields and call stack information.
	WrapError(error) Error
	// WithError - Add an error as single field (using the key defined in ErrorKey) to the Entry.
	WithError(err error) *logger
	// WithContext - Add a context to the Entry.
	WithContext(ctx context.Context) *logger
	// WithField - Add a single field to the Entry.
	WithField(key string, value interface{}) *logger
	// WithFields - Add a map of fields to the Entry.
	WithFields(fields Fields) *logger
	// WithTime - Overrides the time of the Entry.
	WithTime(t time.Time) *logger
	// Trace - Definition:
	// "Seriously, WTF is going on here?!?!
	// I need to log every single statement I execute to find this @#$@ing memory corruption bug before I go insane"
	Trace(msg string)
	// Debug - Definition:
	// Off by default, able to be turned on for debugging specific unexpected problems.
	// This is where you might log detailed information about key method parameters or
	// other information that is useful for finding likely problems in specific 'problematic' areas of the code.
	Debug(msg string)
	// Info - Definition:
	// Normal logging that's part of the normal operation of the app;
	// diagnostic stuff so you can go back and say 'how often did this broad-level operation happen?',
	// or 'how did the user's data get into this state?'
	Info(msg string)
	// Warn - Definition:
	// something that's concerning but not causing the operation to abort;
	// # of connections in the DB pool getting low, an unusual-but-expected timeout in an operation, etc.
	// Think of 'WARN' as something that's useful in aggregate; e.g. grep, group,
	// and count them to get a picture of what's affecting the system health
	Warn(msg string)
	// Error - Definition:
	// something that the app's doing that it shouldn't.
	// This isn't a user error ('invalid search query');
	// it's an assertion failure, network problem, etc etc.,
	// probably one that is going to abort the current operation
	Error(msg string)
	// WrappedError - Definition:
	// this is a convenience method that calls Error() but makes sure to wrap the error a final time
	// so that all current call context is included in the error. This has the same output as:
	//   logger.WithFields(logger.WrapError(err).Fields()).WithError(logger.WrapError(err)).Error("failed to process request")
	// but instead has a much simpler oneliner of:
	//   logger.WrappedError(err, "failed to process request")
	WrappedError(Error, string)
	// Fatal - Definition:
	// the app (or at the very least a thread) is about to die horribly.
	// This is where the info explaining why that's happening goes.
	Fatal(msg string)
	// Panic - Definition:
	// Be careful about calling this vs Fatal:
	// - For Fatal level, the log message goes to the configured log output, while panic is only going to write to stderr.
	// - Panic will print a stack trace, which may not be relevant to the error at all.
	// - Defers will be executed when a program panics, but calling os.Exit exits immediately, and deferred functions can't be run.
	// In general, only use panic for programming errors, where the stack trace is important to the context of the error.
	// If the message isn't targeted at the programmer, you're simply hiding the message in superfluous data.
	Panic(msg string)
}

Logger is an interface wrapping around logrus to provide context based logging for tracing and wrapped error handling while simplifying the logrus interface

Jump to

Keyboard shortcuts

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