glog

package module
v0.0.0-...-b3141fd Latest Latest
Warning

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

Go to latest
Published: Mar 2, 2025 License: MIT Imports: 14 Imported by: 0

README

Go Logging Library

glog is a powerful and flexible logging package for Go, built on top of the standard log/slog package. It provides additional features such as customizable output formats, file logging, memory statistics logging, and HTTP request logging middleware.

Features

  • Support for output formats: JSON, TEXT.
  • Logging to a file or standard output.
  • Context support for passing loggers between functions.
  • Flexible configuration of log levels and source addition.
  • Middleware for logging HTTP requests.
  • Helper for periodic memory statistics logging.

Installation

To install the package, use the following command:

go get github.com/kda47/glog

Usage

Creating a Logger

package main

import (
    "github.com/kda47/glog"
)

func main() {
    logger := glog.NewLogger(
    		glog.WithLevel("info"),
        glog.WithAddSource(false),
        glog.WithOutputFormat(glog.OutputFormatTEXT),
    )

    logger.Info("This is an informational message")

    logger.Info("Info", glog.IntAttr("value", 15), glog.StringAttr("status", "finished"))
}

HTTP Request Logging Middleware

package main

import (
	"net/http"

	"github.com/kda47/glog"
)

func main() {
	glog.NewLogger(
		glog.WithLevel("info"),
		glog.WithAddSource(false),
		glog.WithOutputFormat(glog.OutputFormatTEXT),
		glog.WithSetDefault(true),
	)
	middleware := glog.NewHttpAccessLogMiddleware("http-access")

	handler := http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
		w.WriteHeader(http.StatusOK)
		w.Write([]byte("Hello, world!"))
	})

	http.Handle("/", middleware(handler))

	http.ListenAndServe(":8080", nil)
}

Debug requests

package main

import (
	"fmt"
	"net/http"
	"slices"
	"strings"

	"github.com/kda47/glog"
)

const (
	loggingDebugHeaderKey   = "X-Log-Level-Debug-Enable"
	loggingDebugSecretToken = "my-super-debug-secret"
)

var defaultLoggerOptions = []glog.LoggerOption{
	glog.WithAddSource(false),
	glog.WithOutputFormat(glog.OutputFormatTEXT),
}

func debugRequestsMiddleware(next http.Handler) http.Handler {
	return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
		debug := r.Header.Get(loggingDebugHeaderKey)
		ctx := r.Context()
		if debug == loggingDebugSecretToken {
			r.Header.Del(loggingDebugHeaderKey)
			opts := slices.Concat(
				nil,
				[]glog.LoggerOption{glog.WithSetDefault(false), glog.WithLevel("debug")},
				defaultLoggerOptions,
			)
			logger := glog.NewLogger(opts...)
			ctx = glog.ContextWithLogger(ctx, logger)
		}
		next.ServeHTTP(w, r.WithContext(ctx))
	})
}

func rootHandler(w http.ResponseWriter, r *http.Request) {
	w.WriteHeader(http.StatusOK)
	logger := glog.L(r.Context())

	var headers []string
	for name, values := range r.Header {
		name = strings.ToLower(name)
		for _, h := range values {
			headers = append(headers, fmt.Sprintf("%v: %v", name, h))
		}
	}
	logger.Debug("Debug message", glog.StringAttr("headers", strings.Join(headers, "; ")))

	w.Write([]byte("Hello, world!"))
}

func main() {
	opts := slices.Concat(
		nil,
		[]glog.LoggerOption{glog.WithSetDefault(true), glog.WithLevel("info")},
		defaultLoggerOptions,
	)
	glog.NewLogger(opts...)

	logRequestsMiddleware := glog.NewHttpAccessLogMiddleware("http-access")

	http.Handle("/", logRequestsMiddleware(debugRequestsMiddleware((http.HandlerFunc(rootHandler)))))

	glog.Default().Info("HTTP Server started", glog.StringAttr("listen", ":"), glog.IntAttr("port", 8080))

	http.ListenAndServe(":8080", nil)
}

try to open http://127.0.0.1:88080/ from browser

If you want to debug query call

curl -H "X-Log-Level-Debug-Enable: my-super-debug-secret" -H "Test: Hello" -X GET http://127.0.0.1:8080/

Testing

Simple run tests

go test ./...

License

This project is licensed under the MIT License. See the LICENSE file for details.

Documentation

Index

Constants

View Source
const (
	LevelDebug = slog.LevelDebug
	LevelInfo  = slog.LevelInfo
	LevelWarn  = slog.LevelWarn
	LevelError = slog.LevelError

	TimeKey    = slog.TimeKey
	LevelKey   = slog.LevelKey
	SourceKey  = slog.SourceKey
	MessageKey = slog.MessageKey
	NameKey    = "name"

	KindTime      = slog.KindTime
	KindGroup     = slog.KindGroup
	KindString    = slog.KindString
	KindInt64     = slog.KindInt64
	KindUint64    = slog.KindUint64
	KindFloat64   = slog.KindFloat64
	KindBool      = slog.KindBool
	KindDuration  = slog.KindDuration
	KindAny       = slog.KindAny
	KindLogValuer = slog.KindLogValuer
)
View Source
const (
	AccessLogNameKey = "name"
)

Variables

View Source
var (
	NewTextHandler = slog.NewTextHandler
	NewJSONHandler = slog.NewJSONHandler
	New            = slog.New
	SetDefault     = slog.SetDefault
	GetDefault     = slog.Default

	StringAttr   = slog.String
	BoolAttr     = slog.Bool
	Float64Attr  = slog.Float64
	AnyAttr      = slog.Any
	DurationAttr = slog.Duration
	IntAttr      = slog.Int
	Int64Attr    = slog.Int64
	Uint64Attr   = slog.Uint64
	Time         = slog.Time
	Any          = slog.Any
	String       = slog.String

	GroupValue  = slog.GroupValue
	StringValue = slog.StringValue
	Group       = slog.Group
)
View Source
var Err = ErrAttr

Functions

func ContextWithLoggedHttpAuthInfo

func ContextWithLoggedHttpAuthInfo(ctx context.Context, authInfo LogValuer) context.Context

func ContextWithLogger

func ContextWithLogger(ctx context.Context, logger *Logger) context.Context

ContextWithLogger puts logger to context

func MemoryStatisticLogging

func MemoryStatisticLogging(logger *Logger, level Level)

func NewHttpAccessLogMiddleware

func NewHttpAccessLogMiddleware(name string) func(next http.Handler) http.Handler

func RunPeriodicMemoryLogging

func RunPeriodicMemoryLogging(ctx context.Context, logger *Logger, level Level, interval time.Duration, gcCall bool)

func StartPeriodicMemoryLogging

func StartPeriodicMemoryLogging(ctx context.Context, logger *Logger, level Level, interval time.Duration, gcCall bool)

Types

type Attr

type Attr = slog.Attr

func ErrAttr

func ErrAttr(err error) Attr

func Float32Attr

func Float32Attr(key string, val float32) Attr

func Int32Attr

func Int32Attr(key string, val int32) Attr

func TimeAttr

func TimeAttr(key string, time time.Time) Attr

func UInt32Attr

func UInt32Attr(key string, val uint32) Attr

type DiscardHandler

type DiscardHandler struct{}

func NewDiscardHandler

func NewDiscardHandler() *DiscardHandler

func (*DiscardHandler) Enabled

func (h *DiscardHandler) Enabled(_ context.Context, _ Level) bool

func (*DiscardHandler) Handle

func (h *DiscardHandler) Handle(_ context.Context, _ Record) error

func (*DiscardHandler) WithAttrs

func (h *DiscardHandler) WithAttrs(_ []Attr) Handler

func (*DiscardHandler) WithGroup

func (h *DiscardHandler) WithGroup(_ string) Handler

type Handler

type Handler = slog.Handler

type HandlerOptions

type HandlerOptions = slog.HandlerOptions

type Level

type Level = slog.Level

type Leveler

type Leveler = slog.Leveler

type LogValuer

type LogValuer = slog.LogValuer

type Logger

type Logger = slog.Logger

func Default

func Default() *Logger

func L

func L(ctx context.Context) *Logger

func LoggerFromContext

func LoggerFromContext(ctx context.Context) *Logger

LoggerFromContext returns logger from context

func NewDiscardLogger

func NewDiscardLogger() *Logger

func NewLogger

func NewLogger(opts ...LoggerOption) *Logger

func WithAttrs

func WithAttrs(ctx context.Context, attrs ...Attr) *Logger

WithAttrs returns logger with attributes

func WithDefaultAttrs

func WithDefaultAttrs(logger *Logger, attrs ...Attr) *Logger

WithDefaultAttrs returns logger with default attributes

func WithName

func WithName(logger *Logger, name string) *Logger

LoggerWithName returns logger with name attribute

type LoggerOption

type LoggerOption func(*LoggerOptions)

func WithAddSource

func WithAddSource(addSource bool) LoggerOption

WithAddSource logger option sets the add source option, which will add source file and line number to the log record

func WithCustomHandler

func WithCustomHandler(handler Handler) LoggerOption

WithCustomHandler logger option sets the custom handler

func WithLevel

func WithLevel(level string) LoggerOption

WithLevel logger option sets the log level, if not set, the default level is Info

func WithOutputFilePath

func WithOutputFilePath(path string) LoggerOption

WithOutputFilePath set output file path

func WithOutputFormat

func WithOutputFormat(format OutputFormat) LoggerOption

WithOutputFormat set output format

func WithSetDefault

func WithSetDefault(setDefault bool) LoggerOption

WithSetDefault logger option sets the set default option, which will set the created logger as default logger

type LoggerOptions

type LoggerOptions struct {
	Level         Level
	AddSource     bool
	OutputFormat  OutputFormat
	SetDefault    bool
	LogFilePath   string
	CustomHandler Handler
}

type OutputFormat

type OutputFormat uint8
const (
	OutputFormatJSON OutputFormat = iota
	OutputFormatTEXT
)

func ParseOutputFormat

func ParseOutputFormat(format string) (OutputFormat, error)

func (OutputFormat) String

func (of OutputFormat) String() string

type Record

type Record = slog.Record

type ResponseWriter

type ResponseWriter interface {
	http.ResponseWriter
	http.Hijacker
	http.Flusher
	Status() int
	Size() int
}

type Source

type Source = slog.Source

type Value

type Value = slog.Value

Jump to

Keyboard shortcuts

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