log

package module
v1.1.22 Latest Latest
Warning

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

Go to latest
Published: Aug 16, 2025 License: BSD-3-Clause Imports: 24 Imported by: 254

README

Lux Log Package

A unified logging package for the Lux ecosystem that provides a consistent logging interface across all projects while abstracting away the underlying implementation details.

Overview

The log package is designed to:

  • Provide a consistent logging API across all Lux projects
  • Abstract away the underlying logging implementation (currently zap)
  • Support both structured and unstructured logging
  • Maintain compatibility with different logging styles (geth-style, zap-style)
  • Enable easy configuration and customization

Features

1. Multiple Logging Styles
// Using the logger interface with zap-style fields
logger.Info("user logged in", 
    log.String("username", username),
    log.Int("user_id", userID),
    log.Duration("session_timeout", timeout),
)

// Error logging with stack trace
logger.Error("failed to process request",
    log.Error(err),
    log.String("request_id", reqID),
    log.Stack("stacktrace"),
)
Geth-Compatible Logging
// Using variadic key-value pairs
logger.Info("block processed", "number", blockNum, "hash", blockHash, "txs", txCount)

// Global logger functions
log.Info("application started", "version", version, "config", configPath)
log.Error("connection failed", "error", err, "retry_in", retryDelay)
Simple String Logging
// Basic logging without context
logger.Info("Starting server...")
logger.Warn("Deprecation warning: this feature will be removed")
logger.Error("Critical error occurred")
2. Global Logger

For quick logging without logger instantiation:

import "github.com/luxfi/log"

// Global logging functions
log.Info("server started", "port", 8080)
log.Debug("processing request", "method", "GET", "path", "/api/v1/status")
log.Error("database connection failed", "error", err)
log.Warn("high memory usage", "usage_mb", memUsage)
3. Logger Creation and Configuration
// Create a logger factory with configuration
logFactory := log.NewFactoryWithConfig(log.Config{
    RotatingWriterConfig: log.RotatingWriterConfig{
        Directory: "/var/log/myapp",
        MaxSize:   100, // 100 MB per file
        MaxFiles:  10,  // Keep 10 files
        MaxAge:    30,  // 30 days
        Compress:  true,
    },
    LogLevel:     log.Info,
    DisplayLevel: log.Info,
    LogFormat:    log.JSON, // or log.Console
})

// Create named loggers
mainLogger, _ := logFactory.Make("main")
apiLogger, _ := logFactory.Make("api")
dbLogger, _ := logFactory.Make("database")
4. Log Levels

Supported log levels (from lowest to highest severity):

  • Trace - Detailed debugging information
  • Debug - Debugging information
  • Info - Informational messages
  • Warn - Warning messages
  • Error - Error messages
  • Fatal/Crit - Critical errors (may terminate the program)
5. Field Types

The package provides type-safe field constructors that abstract away zap types:

// Basic types
log.String("key", "value")
log.Int("count", 42)
log.Bool("enabled", true)
log.Float64("ratio", 0.95)
log.Duration("elapsed", time.Second)
log.Time("timestamp", time.Now())

// Error handling
log.Error(err)
log.NamedError("cause", err)

// Complex types
log.Any("data", complexObject)
log.Reflect("object", anyValue)
log.Binary("payload", []byte{...})

// Structured data
log.Object("user", userMarshaler)
log.Array("items", itemArrayMarshaler)

// Namespacing
log.Namespace("http")
6. Context and Child Loggers
// Create a logger with context
requestLogger := logger.With(
    log.String("request_id", reqID),
    log.String("user_id", userID),
)

// All subsequent logs will include the context
requestLogger.Info("processing request")
requestLogger.Error("request failed", log.Error(err))
7. Performance Considerations
  • Field constructors are lazy - expensive operations are deferred
  • Use log.Skip() for conditional fields
  • Prefer typed field constructors over log.Any()
  • Use log.Stack() sparingly as it's expensive

Usage Guidelines

For New Projects
  1. Always use the structured logging approach with typed fields
  2. Create a logger factory at application startup
  3. Use named loggers for different components
  4. Include relevant context using With()
For Existing Projects

The package maintains backward compatibility:

  • Geth-style variadic logging works seamlessly
  • Global logger functions are available
  • No need to refactor existing code immediately
Best Practices
  1. Use Structured Logging: Prefer field constructors over variadic arguments

    // Good
    logger.Info("user action", log.String("action", "login"), log.String("user", username))
    
    // Less preferred
    logger.Info("user action", "action", "login", "user", username)
    
  2. Include Context: Add relevant context to loggers

    // In HTTP handlers
    logger = logger.With(
        log.String("method", r.Method),
        log.String("path", r.URL.Path),
        log.String("remote_addr", r.RemoteAddr),
    )
    
  3. Use Appropriate Levels:

    • Debug for detailed debugging info
    • Info for normal operations
    • Warn for recoverable issues
    • Error for errors that need attention
    • Fatal/Crit for unrecoverable errors
  4. Handle Errors Properly:

    if err != nil {
        logger.Error("operation failed", 
            log.Error(err),
            log.String("operation", "data_sync"),
            log.Stack("stacktrace"),
        )
        return err
    }
    

Configuration

Environment Variables
  • LOG_LEVEL - Set the minimum log level (trace, debug, info, warn, error, fatal)
  • LOG_FORMAT - Set output format (json, console)
  • LOG_DIR - Set log directory for file output
Programmatic Configuration
cfg := log.Config{
    LogLevel:     log.LevelFromString(os.Getenv("LOG_LEVEL")),
    DisplayLevel: log.Info,
    LogFormat:    log.JSON,
    RotatingWriterConfig: log.RotatingWriterConfig{
        Directory: "/var/log/myapp",
        MaxSize:   100,
        MaxFiles:  10,
        MaxAge:    30,
        Compress:  true,
    },
}

Migration Guide

From Direct Zap Usage

Replace zap imports and calls:

// Before
import "go.uber.org/zap"
logger.Info("message", zap.String("key", "value"))

// After  
import "github.com/luxfi/log"
logger.Info("message", log.String("key", "value"))
From Geth-style Logging

No changes required - the package supports geth-style logging:

// This continues to work
log.Info("Block validated", "number", block.Number, "hash", block.Hash)

Examples

Basic Application Setup
package main

import (
    "github.com/luxfi/log"
)

func main() {
    // Create logger factory
    logFactory := log.NewFactoryWithConfig(log.DefaultConfig())
    logger, _ := logFactory.Make("app")
    
    // Set as global logger
    log.SetGlobalLogger(logger)
    
    // Use throughout application
    log.Info("application started")
    
    // Create component loggers
    dbLogger, _ := logFactory.Make("database")
    apiLogger, _ := logFactory.Make("api")
    
    // Pass to components
    db := NewDatabase(dbLogger)
    api := NewAPI(apiLogger)
}
HTTP Middleware
func LoggingMiddleware(logger log.Logger) func(http.Handler) http.Handler {
    return func(next http.Handler) http.Handler {
        return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
            start := time.Now()
            
            // Create request-scoped logger
            reqLogger := logger.With(
                log.String("method", r.Method),
                log.String("path", r.URL.Path),
                log.String("remote_addr", r.RemoteAddr),
                log.String("request_id", generateRequestID()),
            )
            
            // Add logger to context
            ctx := context.WithValue(r.Context(), "logger", reqLogger)
            r = r.WithContext(ctx)
            
            // Log request start
            reqLogger.Info("request started")
            
            // Call next handler
            next.ServeHTTP(w, r)
            
            // Log request completion
            reqLogger.Info("request completed",
                log.Duration("duration", time.Since(start)),
            )
        })
    }
}
Database Operations
type Database struct {
    logger log.Logger
    conn   *sql.DB
}

func (db *Database) GetUser(ctx context.Context, userID string) (*User, error) {
    logger := db.logger.With(
        log.String("operation", "get_user"),
        log.String("user_id", userID),
    )
    
    logger.Debug("fetching user from database")
    
    var user User
    err := db.conn.QueryRowContext(ctx, "SELECT * FROM users WHERE id = ?", userID).Scan(&user)
    if err != nil {
        if err == sql.ErrNoRows {
            logger.Warn("user not found")
            return nil, ErrUserNotFound
        }
        logger.Error("database query failed", log.Error(err))
        return nil, err
    }
    
    logger.Debug("user fetched successfully")
    return &user, nil
}

Performance Tips

  1. Avoid Expensive Operations in Hot Paths:

    // Bad - formats string even if debug is disabled
    logger.Debug(fmt.Sprintf("Processing %d items", len(items)))
    
    // Good - lazy evaluation
    logger.Debug("Processing items", log.Int("count", len(items)))
    
  2. Use Sampling for High-Volume Logs:

    // Configure sampling in production
    cfg := log.Config{
        LogLevel: log.Info,
        SamplingConfig: &log.SamplingConfig{
            Initial:    100,  // Log first 100 of each message
            Thereafter: 1000, // Then every 1000th
        },
    }
    
  3. Pre-allocate Fields for Repeated Use:

    // Pre-compute common fields
    baseFields := []log.Field{
        log.String("service", "api"),
        log.String("version", "1.0.0"),
    }
    
    // Reuse in hot path
    logger.Info("request processed", append(baseFields, 
        log.String("endpoint", endpoint),
        log.Duration("duration", elapsed),
    )...)
    

Troubleshooting

Common Issues
  1. No log output: Check log level configuration
  2. Performance degradation: Ensure not logging in tight loops
  3. Large log files: Configure rotation properly
  4. Missing context: Use With() to add persistent fields
Debug Tips
// Enable debug logging for specific component
if debug {
    logger = logger.WithOptions(log.WithLevel(log.Debug))
}

// Add caller information
logger = logger.WithOptions(log.AddCaller())

// Add stack traces to errors
logger = logger.WithOptions(log.AddStacktrace(log.Error))

Contributing

When adding new features:

  1. Maintain backward compatibility
  2. Abstract implementation details
  3. Provide both structured and unstructured APIs
  4. Include comprehensive tests
  5. Update this documentation

Future Enhancements

  • OpenTelemetry integration
  • Metrics collection alongside logs
  • Log forwarding to external services
  • Enhanced sampling strategies
  • Performance profiling integration

Documentation

Index

Constants

View Source
const (
	LevelTrace slog.Level = -8
	LevelDebug            = slog.LevelDebug
	LevelInfo             = slog.LevelInfo
	LevelWarn             = slog.LevelWarn
	LevelError            = slog.LevelError
	LevelCrit  slog.Level = 12
	LevelFatal slog.Level = 16  // Added for Fatal
	LevelVerbo slog.Level = -10 // Added for Verbo (most verbose)
)

Re-export slog levels for compatibility

View Source
const (
	// DebugLevel logs debug messages.
	DebugLevel = LevelDebug

	// InfoLevel logs informational messages.
	InfoLevel = LevelInfo

	// WarnLevel logs warning messages.
	WarnLevel = LevelWarn

	// ErrorLevel logs error messages.
	ErrorLevel = LevelError

	// FatalLevel logs critical messages and exits.
	FatalLevel = LevelCrit
)

Level aliases for convenience.

Variables

View Source
var (
	// String constructs a field with the given key and value.
	String = zap.String
	// Strings constructs a field that carries a slice of strings.
	Strings = zap.Strings
	// Int constructs a field with the given key and value.
	Int = zap.Int
	// Int64 constructs a field with the given key and value.
	Int64 = zap.Int64
	// Int32 constructs a field with the given key and value.
	Int32 = zap.Int32
	// Int16 constructs a field with the given key and value.
	Int16 = zap.Int16
	// Int8 constructs a field with the given key and value.
	Int8 = zap.Int8
	// Uint constructs a field with the given key and value.
	Uint = zap.Uint
	// Uint64 constructs a field with the given key and value.
	Uint64 = zap.Uint64
	// Uint32 constructs a field with the given key and value.
	Uint32 = zap.Uint32
	// Uint16 constructs a field with the given key and value.
	Uint16 = zap.Uint16
	// Uint8 constructs a field with the given key and value.
	Uint8 = zap.Uint8
	// Uintptr constructs a field with the given key and value.
	Uintptr = zap.Uintptr
	// Float64 constructs a field with the given key and value.
	Float64 = zap.Float64
	// Float32 constructs a field with the given key and value.
	Float32 = zap.Float32
	// Bool constructs a field that carries a bool.
	Bool = zap.Bool
	// Any takes a key and an arbitrary value and chooses the best way to represent
	// them as a field, falling back to a reflection-based approach only if necessary.
	Any = zap.Any
	// Err is shorthand for the common idiom NamedError("error", err).
	Err = zap.Error
	// NamedError constructs a field that lazily stores err.Error() under the
	// provided key. Errors which also implement fmt.Formatter (like those produced
	// by github.com/pkg/errors) will also have their verbose representation stored
	// under key+"Verbose". If passed a nil error, the field is a no-op.
	NamedError = zap.NamedError
	// Skip constructs a no-op field, which is often useful when handling invalid
	// inputs in other Field constructors.
	Skip = zap.Skip
	// Binary constructs a field that carries an opaque binary blob.
	Binary = zap.Binary
	// ByteString constructs a field that carries UTF-8 encoded text as a []byte.
	// To log opaque binary blobs (which aren't necessarily valid UTF-8), use
	// Binary.
	ByteString = zap.ByteString
	// Complex128 constructs a field that carries a complex number. Unlike most
	// numeric fields, this costs an allocation (to convert the complex128 to
	// interface{}).
	Complex128 = zap.Complex128
	// Complex64 constructs a field that carries a complex number. Unlike most
	// numeric fields, this costs an allocation (to convert the complex64 to
	// interface{}).
	Complex64 = zap.Complex64
	// Duration constructs a field with the given key and value. The encoder
	// controls how the duration is serialized.
	Duration = zap.Duration
	// Time constructs a field with the given key and value. The encoder
	// controls how the time is serialized.
	Time = zap.Time
	// Stack constructs a field that stores a stacktrace of the current goroutine
	// under provided key. Keep in mind that taking a stacktrace is eager and
	// expensive (relatively speaking); this function both makes an allocation and
	// takes about two microseconds.
	Stack = zap.Stack
	// StackSkip constructs a field similarly to Stack, but also skips the given
	// number of frames from the top of the stacktrace.
	StackSkip = zap.StackSkip
)

Field constructors - re-export commonly used ones from zap

View Source
var Discard io.WriteCloser = discard{}

Discard is a writer that discards all data

View Source
var ErrUnknownLevel = level.ErrUnknownLevel

Re-export level error

Functions

func ConsoleColorLevelEncoder added in v0.1.1

func ConsoleColorLevelEncoder(l zapcore.Level, enc zapcore.PrimitiveArrayEncoder)

func Crit

func Crit(msg string, ctx ...interface{})

Crit logs a message at critical level with context

func Crit0 added in v0.1.1

func Crit0(msg string)

Crit0 logs a message at critical level

func CritF added in v0.1.1

func CritF(msg string, fields ...zap.Field)

CritF logs a message at critical level with zap fields

func Debug

func Debug(msg string, ctx ...interface{})

Debug logs a message at debug level with context

func Debug0 added in v0.1.1

func Debug0(msg string)

Debug0 logs a message at debug level

func DebugF added in v0.1.1

func DebugF(msg string, fields ...zap.Field)

DebugF logs a message at debug level with zap fields

func DiscardHandler

func DiscardHandler() slog.Handler

DiscardHandler returns a no-op handler

func Error

func Error(msg string, ctx ...interface{})

Error logs a message at error level with context

func Error0 added in v0.1.1

func Error0(msg string)

Error0 logs a message at error level

func ErrorF added in v0.1.1

func ErrorF(msg string, fields ...zap.Field)

ErrorF logs a message at error level with zap fields

func FormatLogfmtUint64

func FormatLogfmtUint64(n uint64) string

FormatLogfmtUint64 formats n with thousand separators.

func FormatSlogValue

func FormatSlogValue(v slog.Value, tmp []byte) (result []byte)

FormatSlogValue formats a slog.Value for serialization to terminal.

func FromLegacyLevel

func FromLegacyLevel(lvl int) slog.Level

FromLegacyLevel converts from old Geth verbosity level constants to levels defined by slog

func Info

func Info(msg string, ctx ...interface{})

Info logs a message at info level with context

func Info0 added in v0.1.1

func Info0(msg string)

Info0 logs a message at info level

func InfoF added in v0.1.1

func InfoF(msg string, fields ...zap.Field)

InfoF logs a message at info level with zap fields

func JSONHandler

func JSONHandler(wr io.Writer) slog.Handler

JSONHandler returns a handler which prints records in JSON format.

func JSONHandlerWithLevel

func JSONHandlerWithLevel(wr io.Writer, level slog.Level) slog.Handler

JSONHandlerWithLevel returns a handler which prints records in JSON format that are less than or equal to the specified verbosity level.

func LevelAlignedString

func LevelAlignedString(l slog.Level) string

LevelAlignedString returns a 5-character aligned string for the level

func LevelString

func LevelString(l slog.Level) string

LevelString returns a string representation of the level

func LogfmtHandler

func LogfmtHandler(wr io.Writer) slog.Handler

LogfmtHandler returns a handler which prints records in logfmt format, an easy machine-parseable but human-readable format for key/value pairs.

For more details see: http://godoc.org/github.com/kr/logfmt

func LogfmtHandlerWithLevel

func LogfmtHandlerWithLevel(wr io.Writer, level slog.Level) slog.Handler

LogfmtHandlerWithLevel returns the same handler as LogfmtHandler but it only outputs records which are less than or equal to the specified verbosity level.

func RegisterInternalPackages added in v1.0.5

func RegisterInternalPackages(pkgs ...string)

RegisterInternalPackages lets applications add package prefixes that should be treated as "internal" (wrappers, adapters, etc.). Calls are concurrency-safe.

func SetDefault

func SetDefault(l Logger)

SetDefault sets the default root logger

func SetGlobalLogger added in v0.1.1

func SetGlobalLogger(l Logger)

SetGlobalLogger sets the global logger used by package-level functions

func Trace

func Trace(msg string, ctx ...interface{})

Trace logs a message at trace level with context

func Trace0 added in v0.1.1

func Trace0(msg string)

Trace0 logs a message at trace level

func TraceF added in v0.1.1

func TraceF(msg string, fields ...zap.Field)

TraceF logs a message at trace level with zap fields

func Warn

func Warn(msg string, ctx ...interface{})

Warn logs a message at warn level with context

func Warn0 added in v0.1.1

func Warn0(msg string)

Warn0 logs a message at warn level

func WarnF added in v0.1.1

func WarnF(msg string, fields ...zap.Field)

WarnF logs a message at warn level with zap fields

func WriterAt

func WriterAt(logger Logger, level slog.Level) io.Writer

WriterAt returns an io.Writer that writes to the logger at the specified level

Types

type ArrayMarshaler added in v1.0.3

type ArrayMarshaler = zapcore.ArrayMarshaler

ArrayMarshaler is an alias for zapcore.ArrayMarshaler

type Color added in v0.1.1

type Color string

Color represents ANSI color codes

const (
	Black       Color = "\033[0;30m"
	DarkGray    Color = "\033[1;30m"
	Red         Color = "\033[0;31m"
	LightRed    Color = "\033[1;31m"
	Green       Color = "\033[0;32m"
	LightGreen  Color = "\033[1;32m"
	Orange      Color = "\033[0;33m"
	Yellow      Color = "\033[1;33m"
	Blue        Color = "\033[0;34m"
	LightBlue   Color = "\033[1;34m"
	Purple      Color = "\033[0;35m"
	LightPurple Color = "\033[1;35m"
	Cyan        Color = "\033[0;36m"
	LightCyan   Color = "\033[1;36m"
	LightGray   Color = "\033[0;37m"
	White       Color = "\033[1;37m"

	Reset   Color = "\033[0;0m"
	Bold    Color = "\033[;1m"
	Reverse Color = "\033[;7m"
)

Colors

func (Color) Wrap added in v0.1.1

func (lc Color) Wrap(text string) string

Wrap wraps text with color

type Config added in v0.1.1

type Config struct {
	RotatingWriterConfig
	DisableWriterDisplaying bool   `json:"disableWriterDisplaying"`
	LogLevel                Level  `json:"logLevel"`
	DisplayLevel            Level  `json:"displayLevel"`
	LogFormat               Format `json:"logFormat"`
	MsgPrefix               string `json:"-"`
	LoggerName              string `json:"-"`
}

Config defines the configuration of a logger

func DefaultConfig added in v0.1.1

func DefaultConfig() Config

DefaultConfig returns a default configuration for the logger factory

type Factory

type Factory interface {
	// Make creates a new logger with name [name]
	Make(name string) (Logger, error)

	// MakeChain creates a new logger to log the events of chain [chainID]
	MakeChain(chainID string) (Logger, error)

	// SetLogLevel sets log levels for all loggers in factory with given logger name, level pairs.
	SetLogLevel(name string, level Level) error

	// SetDisplayLevel sets log display levels for all loggers in factory with given logger name, level pairs.
	SetDisplayLevel(name string, level Level) error

	// GetLogLevel returns all log levels in factory as name, level pairs
	GetLogLevel(name string) (Level, error)

	// GetDisplayLevel returns all log display levels in factory as name, level pairs
	GetDisplayLevel(name string) (Level, error)

	// GetLoggerNames returns the names of all logs created by this factory
	GetLoggerNames() []string

	// Close stops and clears all of a Factory's instantiated loggers
	Close()

	// Legacy methods for compatibility
	New(name string) Logger
	NewWithFields(name string, fields ...zap.Field) Logger
}

Factory interface for creating loggers - extended version with all methods needed by node

func NewFactoryWithConfig added in v0.1.1

func NewFactoryWithConfig(config Config) Factory

NewFactory creates a new logger factory with config

func NewSimpleFactory added in v0.1.1

func NewSimpleFactory(config zap.Config) Factory

NewSimpleFactory creates a simple logger factory from zap config This is a convenience function for simple use cases

type Field

type Field = zap.Field

Field is an alias for zap.Field for structured logging

func Array added in v1.0.3

func Array(key string, val ArrayMarshaler) Field

Array constructs a field with the given key and ArrayMarshaler. It provides a flexible, but still type-safe and efficient, way to add array-like types to the logging context. The struct's MarshalLogArray method is called lazily.

func Durationp added in v1.0.3

func Durationp(key string, val *time.Duration) Field

Durationp constructs a field that carries a *time.Duration. The returned Field will safely and explicitly represent `nil` when appropriate.

func Inline added in v1.0.3

func Inline(val ObjectMarshaler) Field

Inline constructs a Field that is similar to Object, but it will add the elements of the provided ObjectMarshaler to the current namespace.

func Namespace added in v1.0.3

func Namespace(key string) Field

Namespace creates a named, isolated scope within the logger's context. All subsequent fields will be added to the new namespace.

This helps prevent key collisions when injecting loggers into sub-components or third-party libraries.

func Object added in v1.0.3

func Object(key string, val ObjectMarshaler) Field

Object constructs a field with the given key and ObjectMarshaler. It provides a flexible, but still type-safe and efficient, way to add map- or struct-like user-defined types to the logging context. The struct's MarshalLogObject method is called lazily.

func Reflect added in v1.0.3

func Reflect(key string, val interface{}) Field

Reflect constructs a field with the given key and an arbitrary object. It uses an encoding-appropriate, reflection-based function to lazily serialize nearly any object into the logging context, but it's relatively slow and allocation-heavy. Outside tests, Any is always a better choice.

If encoding fails (e.g., trying to serialize a map[int]string to JSON), Reflect includes the error message in the final log output.

func Stringer added in v0.1.1

func Stringer(key string, val fmt.Stringer) Field

Stringer constructs a field with the given key and the output of the value's String method. The Stringer's String method is called lazily.

func Timep added in v1.0.3

func Timep(key string, val *time.Time) Field

Timep constructs a field that carries a *time.Time. The returned Field will safely and explicitly represent `nil` when appropriate.

func UserString added in v0.1.1

func UserString(key, val string) Field

UserString creates a field for user-provided strings that may need sanitization

func UserStrings added in v0.1.1

func UserStrings(key string, vals []string) Field

UserStrings creates a field for user-provided string slices that may need sanitization

type Format added in v0.1.1

type Format int

Format specifies the log format

const (
	Auto Format = iota
	Plain
	Colors
	JSON
)

func ToFormat added in v0.1.1

func ToFormat(h string, fd uintptr) (Format, error)

ToFormat converts a string to Format

func (Format) ConsoleEncoder added in v0.1.1

func (f Format) ConsoleEncoder() zapcore.Encoder

ConsoleEncoder returns a zapcore.Encoder for console output

func (Format) FileEncoder added in v0.1.1

func (f Format) FileEncoder() zapcore.Encoder

FileEncoder returns a zapcore.Encoder for file output

func (Format) MarshalJSON added in v0.1.1

func (f Format) MarshalJSON() ([]byte, error)

MarshalJSON marshals Format to JSON

func (Format) WrapPrefix added in v0.1.1

func (f Format) WrapPrefix(prefix string) string

WrapPrefix adds a prefix to messages if non-empty

type GlogHandler

type GlogHandler struct {
	// contains filtered or unexported fields
}

GlogHandler wraps a slog.Handler to provide glog-style verbosity and vmodule filtering.

func NewGlogHandler

func NewGlogHandler(h slog.Handler) *GlogHandler

NewGlogHandler returns a Handler that filters records according to glog-style severity and verbosity settings. By default, it logs messages with level >= LevelInfo and suppresses verbose logs (levels < LevelInfo) until Verbosity is called.

func (*GlogHandler) Enabled

func (g *GlogHandler) Enabled(ctx context.Context, level slog.Level) bool

Enabled reports whether records at the given level should be logged or passed to Handle for further verbose filtering.

func (*GlogHandler) Handle

func (g *GlogHandler) Handle(ctx context.Context, r slog.Record) error

Handle filters the record according to severity and verbosity (including vmodule) and forwards it to the underlying handler if allowed.

func (*GlogHandler) Verbosity

func (g *GlogHandler) Verbosity(v slog.Level)

Verbosity sets both the minimum severity and default verbosity levels. Messages with level >= v will be logged as severity; messages with level < LevelInfo will be logged if their level <= v.

func (*GlogHandler) Vmodule

func (g *GlogHandler) Vmodule(spec string) error

Vmodule sets a per-file verbosity level according to the spec string of the form "pattern=level". Multiple specs may be comma-separated.

func (*GlogHandler) WithAttrs

func (g *GlogHandler) WithAttrs(attrs []slog.Attr) slog.Handler

WithAttrs returns a new glogHandler with the given attributes added to the underlying handler.

func (*GlogHandler) WithGroup

func (g *GlogHandler) WithGroup(name string) slog.Handler

WithGroup returns a new glogHandler with the given group added to the underlying handler.

type Level

type Level = level.Level

Level is an alias for level.Level for backwards compatibility

func ToLevel added in v0.1.1

func ToLevel(l string) (Level, error)

Re-export ToLevel for backwards compatibility

type Logger

type Logger interface {
	// Original geth-style methods
	With(ctx ...interface{}) Logger
	New(ctx ...interface{}) Logger
	Log(level slog.Level, msg string, ctx ...interface{})
	Trace(msg string, ctx ...interface{})
	Debug(msg string, ctx ...interface{})
	Info(msg string, ctx ...interface{})
	Warn(msg string, ctx ...interface{})
	Error(msg string, ctx ...interface{})
	Crit(msg string, ctx ...interface{})
	WriteLog(level slog.Level, msg string, attrs ...any)
	Enabled(ctx context.Context, level slog.Level) bool
	Handler() slog.Handler

	// Additional methods for node compatibility
	Fatal(msg string, fields ...Field)
	Verbo(msg string, fields ...Field)
	WithFields(fields ...Field) Logger
	WithOptions(opts ...Option) Logger
	SetLevel(level slog.Level)
	GetLevel() slog.Level
	EnabledLevel(lvl slog.Level) bool
	StopOnPanic()
	RecoverAndPanic(f func())
	RecoverAndExit(f, exit func())
	Stop()

	// io.Writer
	io.Writer
}

Logger interface that supports both the geth-style interface and zap fields

func New

func New(ctx ...interface{}) Logger

New creates a new logger with the given context (alias for With)

func NewLogger

func NewLogger(prefix string, wrappedCores ...WrappedCore) Logger

NewLogger creates a logger with custom cores

func NewNoOpLogger

func NewNoOpLogger() Logger

NewNoOpLogger creates a logger that discards all output

func NewTestLogger added in v0.1.1

func NewTestLogger(lvl Level) Logger

NewTestLogger creates a logger suitable for testing

func NewZapLogger

func NewZapLogger(logger *zap.Logger) Logger

NewZapLogger creates a logger directly from a zap logger

func Root

func Root() Logger

Root returns the root logger

func With added in v0.1.1

func With(ctx ...interface{}) Logger

With creates a new logger with the given context

type LoggerWriter

type LoggerWriter struct {
	// contains filtered or unexported fields
}

LoggerWriter wraps a Logger to provide io.Writer interface

func (*LoggerWriter) Write

func (w *LoggerWriter) Write(p []byte) (n int, err error)

Write implements io.Writer

type NoLog added in v1.0.3

type NoLog struct{}

NoLog is a no-op logger for testing

func (NoLog) Crit added in v1.0.3

func (NoLog) Crit(msg string, ctx ...interface{})

func (NoLog) Debug added in v1.0.3

func (NoLog) Debug(msg string, ctx ...interface{})

func (NoLog) Enabled added in v1.0.3

func (NoLog) Enabled(ctx context.Context, level slog.Level) bool

func (NoLog) EnabledLevel added in v1.0.3

func (NoLog) EnabledLevel(lvl slog.Level) bool

func (NoLog) Error added in v1.0.3

func (NoLog) Error(msg string, ctx ...interface{})

func (NoLog) Fatal added in v1.0.3

func (NoLog) Fatal(msg string, fields ...Field)

func (NoLog) GetLevel added in v1.0.3

func (NoLog) GetLevel() slog.Level

func (NoLog) Handler added in v1.0.3

func (NoLog) Handler() slog.Handler

func (NoLog) Info added in v1.0.3

func (NoLog) Info(msg string, ctx ...interface{})

func (NoLog) Log added in v1.0.3

func (NoLog) Log(level slog.Level, msg string, ctx ...interface{})

func (NoLog) New added in v1.0.3

func (NoLog) New(ctx ...interface{}) Logger

func (NoLog) RecoverAndExit added in v1.0.3

func (NoLog) RecoverAndExit(f, exit func())

func (NoLog) RecoverAndPanic added in v1.0.3

func (NoLog) RecoverAndPanic(f func())

func (NoLog) SetLevel added in v1.0.3

func (NoLog) SetLevel(level slog.Level)

func (NoLog) Stop added in v1.0.3

func (NoLog) Stop()

func (NoLog) StopOnPanic added in v1.0.3

func (NoLog) StopOnPanic()

func (NoLog) Trace added in v1.0.3

func (NoLog) Trace(msg string, ctx ...interface{})

func (NoLog) Verbo added in v1.0.3

func (NoLog) Verbo(msg string, fields ...Field)

func (NoLog) Warn added in v1.0.3

func (NoLog) Warn(msg string, ctx ...interface{})

func (NoLog) With added in v1.0.3

func (NoLog) With(ctx ...interface{}) Logger

Implement all Logger interface methods as no-ops

func (NoLog) WithFields added in v1.0.3

func (NoLog) WithFields(fields ...Field) Logger

func (NoLog) WithOptions added in v1.0.3

func (NoLog) WithOptions(opts ...Option) Logger

func (NoLog) Write added in v1.0.3

func (NoLog) Write(p []byte) (n int, err error)

func (NoLog) WriteLog added in v1.0.3

func (NoLog) WriteLog(level slog.Level, msg string, attrs ...any)

type ObjectMarshaler added in v1.0.3

type ObjectMarshaler = zapcore.ObjectMarshaler

ObjectMarshaler is an alias for zapcore.ObjectMarshaler

type Option added in v1.0.3

type Option = zap.Option

Option is an alias for zap.Option

type RotatingWriterConfig added in v0.1.1

type RotatingWriterConfig struct {
	MaxSize   int    `json:"maxSize"` // in megabytes
	MaxFiles  int    `json:"maxFiles"`
	MaxAge    int    `json:"maxAge"` // in days
	Directory string `json:"directory"`
	Compress  bool   `json:"compress"`
}

RotatingWriterConfig defines rotating log file configuration

type TerminalHandler

type TerminalHandler struct {
	// contains filtered or unexported fields
}

func NewTerminalHandler

func NewTerminalHandler(wr io.Writer, useColor bool) *TerminalHandler

NewTerminalHandler returns a handler which formats log records at all levels optimized for human readability on a terminal with color-coded level output and terser human friendly timestamp. This format should only be used for interactive programs or while developing.

[LEVEL] [TIME] MESSAGE key=value key=value ...

Example:

[DBUG] [May 16 20:58:45] remove route ns=haproxy addr=127.0.0.1:50002

func NewTerminalHandlerWithLevel

func NewTerminalHandlerWithLevel(wr io.Writer, lvl slog.Level, useColor bool) *TerminalHandler

NewTerminalHandlerWithLevel returns the same handler as NewTerminalHandler but only outputs records which are less than or equal to the specified verbosity level.

func (*TerminalHandler) Enabled

func (h *TerminalHandler) Enabled(_ context.Context, level slog.Level) bool

func (*TerminalHandler) Handle

func (h *TerminalHandler) Handle(_ context.Context, r slog.Record) error

func (*TerminalHandler) ResetFieldPadding

func (h *TerminalHandler) ResetFieldPadding()

ResetFieldPadding zeroes the field-padding for all attribute pairs.

func (*TerminalHandler) WithAttrs

func (h *TerminalHandler) WithAttrs(attrs []slog.Attr) slog.Handler

func (*TerminalHandler) WithGroup

func (h *TerminalHandler) WithGroup(name string) slog.Handler

type TerminalStringer

type TerminalStringer interface {
	TerminalString() string
}

TerminalStringer is an analogous interface to the stdlib stringer, allowing own types to have custom shortened serialization formats when printed to the screen.

type WrappedCore added in v0.1.1

type WrappedCore struct {
	zapcore.Core
	AtomicLevel    zap.AtomicLevel
	Writer         zapcore.WriteSyncer
	WriterDisabled bool
}

WrappedCore wraps a zapcore.Core with additional functionality

func NewWrappedCore added in v0.1.1

func NewWrappedCore(lvl Level, writer zapcore.WriteSyncer, encoder zapcore.Encoder) *WrappedCore

NewWrappedCore creates a wrapped core with atomic level

func (*WrappedCore) Check added in v0.1.1

Check implements zapcore.Core

func (*WrappedCore) Enabled added in v0.1.1

func (c *WrappedCore) Enabled(level zapcore.Level) bool

Enabled implements zapcore.Core

func (*WrappedCore) Sync added in v0.1.1

func (c *WrappedCore) Sync() error

Sync implements zapcore.Core

func (*WrappedCore) With added in v0.1.1

func (c *WrappedCore) With(fields []zapcore.Field) zapcore.Core

With implements zapcore.Core

func (*WrappedCore) Write added in v0.1.1

func (c *WrappedCore) Write(ent zapcore.Entry, fields []zapcore.Field) error

Write implements zapcore.Core

Directories

Path Synopsis

Jump to

Keyboard shortcuts

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