logm

package module
v0.2.3 Latest Latest
Warning

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

Go to latest
Published: May 22, 2023 License: MIT Imports: 11 Imported by: 0

README

LogM

GoDoc Build Status Code Coverage Go Report Card

LogM is a Go log management package providing facilities to deal with logs and trace context.

Features

  1. Provides simple methods to expose a slog.Logger using logfmt as format:
    • DefaultLogger: A logger ready for production.
    • DebugLogger: A logger exposing debug record for development.
    • DiscardLogger: Another to discard any logs (test purposes or no space left on disk).
  2. Provides a File with automatic rotating, maximum file size, zip archives, etc. Thanks to lumberjack.
  3. Provides a Trace structure to uniquely identified actions, like an HTTP request. See NewTraceFromContext to easily propagate or retrieve trace context.
  4. Exposes HTTP middlewares to handle log and tracing:to create a trace context on each request.
    • LogHandler: a logging middleware to log detail about the request and the response.
    • RecoverHandler: a middleware to recover on panic, log the message as ERROR and the stack trace as DEBUG.
    • TraceHandler: a middleware to retrieve request header X-Trace-Id (see NewTraceFromHTTPRequest) and propagate its value through the request context.
  5. Provides TimeElapsed to log in defer the time elapsed of a function.
  6. Offers a testing sub-package named logmtest to verify the data logged.
Installation
$ go get -u github.com/rvflash/logm
Prerequisite

logm uses the Go modules, debug.BuildSetting and the slog package that required Go 1.18 or later.

Exemples

Create a logger for an application named app that store records in a file named app.log, ignoring DEBUG ones.

By default, the NewFile function returns a self rolling file as soon as it reaches the size of 100 Mo. The rotated log files is compressed using gzip and retained forever. Each log is prefixed by the local time. Customization is available by using File directly. By default, each record has the name and the current version of the application as attributes.

The version is provided on build by the debug.ReadBuildInfo package. It's the revision identifier for the current commit or checkout.

log := logm.DefaultLogger("app", logm.NewFile("app.log"))
log.Info("hello")
$ cat app.log
time=2023-03-25T00:04:35.287+01:00 level=INFO msg=hello app=app version=d1da844711730f2f5cbd08be93e62e71475f7d4e
Create a logger to debug on standard output.
log := logm.DebugLogger("app", os.Stdout)
log.Debug("hello")
time=2023-03-25T10:57:51.772+01:00 level=DEBUG msg=hello app=app version=d1da844711730f2f5cbd08be93e62e71475f7d4e
Propagate a trace identifier through the context.

NewTrace can create a new trace context with an UUID v4 as identifier. It's also possible to create a custom one by directly using Trace and propagate it through a context.Context.

var (
    t   = logm.Trace{ID: "myID"}
    ctx = t.NewContext(context.Background())
)
Add the trace context on each log.
var (
    l = logm.DefaultLogger("app", os.Stdout)
    t = logm.NewTrace()
)
log := l.With(t.LogAttr())
log.Info("hello")
log.Warn("world")
time=2023-03-25T13:06:37.322+01:00 level=INFO msg=hello app=app version=d1da844711730f2f5cbd08be93e62e71475f7d4e trace.id=0a02e16c-7418-4558-9dcc-718c007162b6
time=2023-03-25T13:06:37.322+01:00 level=WARN msg=world app=app version=d1da844711730f2f5cbd08be93e62e71475f7d4e trace.id=0a02e16c-7418-4558-9dcc-718c007162b6
Monitor the time elapsed by a function on defer.
var (
    log = logm.DefaultLogger("app", os.Stdout)
    ctx = context.Background()
)
func(ctx context.Context, log *slog.Logger) {
    defer logm.TimeElapsed(ctx, log, slog.LevelInfo, "example")()
    time.Sleep(time.Millisecond)
}(ctx, log)
time=2023-03-25T12:06:17.605+01:00 level=INFO msg=example app=app version=d1da844711730f2f5cbd08be93e62e71475f7d4e trace.id=ccc05db1-68d2-4442-9353-0789e0b8ca55 trace.time_elapsed_ms=1
Test whether the data is logged in order and contains expected contents.

Testing the logged data sometimes seems useless, but it can be reassuring to quickly check a stream to preserve. The logmtest.NewRecorder provides an in-memory log writer useful for that, with a method Expect to check each Record. Two options to adjust the verification:

  • ExpectAnyOrder to match all expectations in the order they were set or not. By default, it expects in order.
  • ExpectUnexpected to ignore not matching records. By default, if a record is not expected, an error will be triggered.
var (
    rec = logmtest.NewRecorder()
    log = logm.DefaultLogger("testing", rec)
)
log.Info("hello")
log.Warn("beautiful")
log.Error("world")

err := rec.Expect(
    logmtest.Record{Contains: "hello"},
    logmtest.Record{Contains: "beau"},
    logmtest.Record{Contains: "world"},
)
// Will return no error.

Documentation

Overview

Package logm is a Go log management providing facilities to deal with logs and trace context.

Index

Constants

View Source
const (
	// AppNameKey is the name of the application in structured log.
	AppNameKey = "app"
	// AppVersionKey is the version of the application in structured log.
	AppVersionKey = "version"
	// HTTPRequestKey is the HTTP request name in structured log.
	HTTPRequestKey = "req"
	// HTTPPathKey is the HTTP request path in structured log.
	HTTPPathKey = "path"
	// HTTPMethodKey is the HTTP request method in structured log.
	HTTPMethodKey = "method"
	// HTTPRemoteAddrKey is the HTTP remote address in structured log.
	HTTPRemoteAddrKey = "remote_addr"
	// HTTPQueryKey is the HTTP request query in structured log.
	HTTPQueryKey = "query"
	// HTTPResponseKey is the HTTP response name in structured log.
	HTTPResponseKey = "resp"
	// HTTPStatusKey is the HTTP response status in structured log.
	HTTPStatusKey = "status"
	// HTTPSizeKey is the HTTP response size in structured log.
	HTTPSizeKey = "size"
	// PanicKey is a panic in structured log.
	PanicKey = "panic"
	// TraceKey is the name of the trace in structured log.
	TraceKey = "trace"
	// TraceIDKey is the name of the trace ID in structured log.
	TraceIDKey = "id"
	// TraceSpanIDKey is the name of the trace span ID in structured log.
	TraceSpanIDKey = "span_id"
	// TraceTimeElapsedKey is the name of the trace time in structured log.
	TraceTimeElapsedKey = "time_elapsed_ms"
)

List of standard key to use to qualify structured log.

View Source
const TraceIDHTTPHeader = "X-Trace-Id"

TraceIDHTTPHeader is the name of the HTTP header used to share a trace context ID.

Variables

This section is empty.

Functions

func DebugLogger

func DebugLogger(name string, w io.Writer) *slog.Logger

DebugLogger returns a new instance of Logger dedicated to debug or test environment. Debug messages are included and each message will include the application name and version.

func DefaultLogger

func DefaultLogger(name string, w io.Writer) *slog.Logger

DefaultLogger returns a new instance of Logger, ready to be use in production mode. Debug messages are ignored and each message will include the application name and version.

func DiscardLogger

func DiscardLogger() *slog.Logger

DiscardLogger is a logger doing anything. Useful for test purpose and default behavior.

func LogHandler

func LogHandler(l *slog.Logger, next http.Handler) http.Handler

LogHandler is an HTTP middleware designed to log every request and response.

func NewLogger

func NewLogger(name string, w io.Writer, level slog.Level) *slog.Logger

NewLogger returns a new instance of Logger where the level is the minimum log level to consider. Each message will include the application name and version.

func RecoverHandler

func RecoverHandler(msg string, l *slog.Logger, next http.Handler) http.Handler

RecoverHandler is an HTTP middleware designed to recover on panic, log the error and debug the stack trace.

func TimeElapsed

func TimeElapsed(ctx context.Context, l *slog.Logger, level slog.Level, msg string, attrs ...slog.Attr) func()

TimeElapsed allows to monitor the execution time of a function. Example:

defer t.TimeElapsed(ctx, logger, slog.LevelDebug, "func")()

It offers a useful interface to be called in defer statement.

func TraceHandler

func TraceHandler(next http.Handler) http.Handler

TraceHandler is an HTTP middleware designed to share the trace context in the request context.

Types

type File

type File = lumberjack.Logger

File is a log file.

func NewFile

func NewFile(name string) *File

NewFile returns a file with this name. This file will be automatically rotated if it its size exceeds the 100 Mo. The newly created file will have this format `name-timestamp.ext` and will be compressed. timestamp is the time at which the log was rotated formatted with the time.Time format of `2006-01-02T15-04-05.000` and the extension is the original extension. For example, with `/data/log/server.log` as name, a backup created at 6:30pm on Nov 11 2016 would use the filename `/data/log/server-2016-11-04T18-30-00.000.log` Each record will have a local time.

type Middleware added in v0.2.1

type Middleware struct {
	Logger       *slog.Logger
	ErrorMessage string
}

Middleware provides some standard HTTP handlers to deal with logs.

func (Middleware) LogHandler added in v0.2.1

func (m Middleware) LogHandler(next http.Handler) http.Handler

LogHandler is an HTTP middleware designed to log every request and response.

func (Middleware) RecoverHandler added in v0.2.1

func (m Middleware) RecoverHandler(next http.Handler) http.Handler

RecoverHandler is an HTTP middleware designed to recover on panic, log the error and debug the stack trace. If no error message is provided, we used the default internal error message.

type Trace

type Trace struct {
	TimeElapsedMs int64
	StartTime     time.Time
	ID            string
	SpanID        string
}

Trace represents a trace context.

func NewTrace

func NewTrace() *Trace

NewTrace creates a new Trace with a new generated UUID v4 as identifier.

func NewTraceFromContext

func NewTraceFromContext(ctx context.Context) *Trace

NewTraceFromContext returns a new Trace based on the context.Context. If the trace ID value is not found or blank, a new one is created. Otherwise, we create a trace span with this trace identifier as parent identifier.

func NewTraceFromHTTPRequest

func NewTraceFromHTTPRequest(req *http.Request) *Trace

NewTraceFromHTTPRequest returns a new Trace based on the http.Request. If the trace ID value is not found or blank, a new one is created. Otherwise, we create a trace span with this trace identifier as parent identifier.

func NewTraceSpan

func NewTraceSpan(parentID string) *Trace

NewTraceSpan creates a trace span based on the Trace.

func (*Trace) End

func (t *Trace) End()

End ends the context trace and calculates the time elapsed since its starting.

func (*Trace) LogAttr

func (t *Trace) LogAttr() slog.Attr

LogAttr returns the trace as a slog.Attr.

func (*Trace) LogValue

func (t *Trace) LogValue() slog.Value

LogValue implements the slog.logValuer interface.

func (*Trace) NewContext

func (t *Trace) NewContext(ctx context.Context) context.Context

NewContext creates a new trace context.Context to carry the trace identifier.

func (*Trace) Start

func (t *Trace) Start()

Start adds a start time to the trace.

Directories

Path Synopsis
Package logmtest provides utilities for Log testing.
Package logmtest provides utilities for Log testing.

Jump to

Keyboard shortcuts

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