logger

package
v1.2.0 Latest Latest
Warning

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

Go to latest
Published: Aug 1, 2025 License: MIT Imports: 10 Imported by: 0

README

TypoSentinel Enhanced Logging System

This package provides a comprehensive, configurable logging system for TypoSentinel with support for structured logging, multiple output formats, log rotation, and flexible configuration.

Features

  • Multiple Log Levels: DEBUG, INFO, WARN, ERROR
  • Structured Logging: Support for key-value pairs and JSON output
  • Configurable Output: Console (stdout/stderr) or file output
  • Log Rotation: Automatic log file rotation with size and age limits
  • Global and Instance Loggers: Use global functions or create custom logger instances
  • Field Loggers: Create loggers with predefined fields for consistent context
  • Configuration Integration: Seamless integration with TypoSentinel's configuration system

Quick Start

Basic Usage
import "typosentinel/pkg/logger"

// Simple logging
logger.Info("Application started")
logger.Error("Something went wrong")

// Formatted logging
logger.Infof("Processing %d packages", count)
logger.Errorf("Failed to connect to %s", endpoint)
Structured Logging
// Logging with structured fields
logger.Info("Package scan completed", map[string]interface{}{
    "package_name": "lodash",
    "version": "4.17.21",
    "scan_duration": "2.5s",
    "findings_count": 3,
})

logger.Error("Database connection failed", map[string]interface{}{
    "error": err.Error(),
    "host": "localhost",
    "port": 5432,
    "retry_count": 3,
})
Field Loggers
// Create a logger with predefined fields
scanLogger := logger.GetGlobalLogger().WithFields(map[string]interface{}{
    "scan_id": "scan-123",
    "component": "static-analyzer",
})

// All log messages will include the predefined fields
scanLogger.Info("Starting analysis")
scanLogger.Error("Analysis failed")

Configuration

YAML Configuration

Add the following to your config.yaml:

logging:
  level: "info"              # debug, info, warn, error
  format: "text"             # text or json
  output: "stdout"           # stdout, stderr, or file path
  timestamp: true            # include timestamps
  caller: false              # include caller information
  prefix: "[TYPOSENTINEL]"   # log prefix
  rotation:
    enabled: false           # enable log rotation
    max_size: 100           # maximum size in MB
    max_backups: 3          # number of backup files
    max_age: 28             # maximum age in days
    compress: true          # compress rotated files
Programmatic Configuration
// Initialize with custom configuration
config := logger.Config{
    Level:     logger.INFO,
    Format:    "json",
    Output:    os.Stdout,
    Timestamp: true,
    Caller:    true,
    Prefix:    "[MYAPP]",
}

customLogger := logger.NewWithConfig(config)
File Output with Rotation
logging:
  level: "info"
  format: "json"
  output: "/var/log/typosentinel/app.log"
  rotation:
    enabled: true
    max_size: 100    # 100MB per file
    max_backups: 5   # keep 5 backup files
    max_age: 30      # delete files older than 30 days
    compress: true   # compress old files

Log Levels

Level Description Use Case
DEBUG Detailed diagnostic information Development, troubleshooting
INFO General informational messages Normal application flow
WARN Warning messages for potentially harmful situations Recoverable errors, deprecated usage
ERROR Error messages for serious problems Application errors, failures

Output Formats

Text Format (Default)
2024-01-15 10:30:45 [TYPOSENTINEL] INFO: Package scan completed package_name=lodash version=4.17.21
2024-01-15 10:30:46 [TYPOSENTINEL] ERROR: Database connection failed error="connection refused" host=localhost
JSON Format
{"timestamp":"2024-01-15T10:30:45Z","level":"INFO","message":"Package scan completed","package_name":"lodash","version":"4.17.21"}
{"timestamp":"2024-01-15T10:30:46Z","level":"ERROR","message":"Database connection failed","error":"connection refused","host":"localhost"}

Command Line Integration

The logging system integrates with TypoSentinel's command line flags:

# Enable debug logging
typosentinel scan --debug lodash

# Enable verbose logging
typosentinel scan --verbose lodash

# Use custom config file
typosentinel scan --config /path/to/config.yaml lodash

Advanced Usage

Dynamic Log Level Changes
// Change global log level at runtime
logger.SetGlobalLevel(logger.DEBUG)

// Change global format at runtime
logger.SetGlobalFormat("json")
Custom Logger Instances
// Create a logger for a specific component
config := logger.DefaultConfig()
config.Prefix = "[SCANNER]"
config.Level = logger.DEBUG

scannerLogger := logger.NewWithConfig(config)
scannerLogger.Info("Scanner initialized")
Testing Setup
// Initialize logger for testing
logger.InitForTesting()

// Or with custom test configuration
logger.InitWithLevel(logger.DEBUG)

Performance Considerations

  • Structured Fields: Only computed when the log level is enabled
  • File I/O: Buffered writes for better performance
  • Log Rotation: Handled asynchronously to avoid blocking
  • JSON Marshaling: Optimized for common field types

Best Practices

  1. Use Appropriate Log Levels:

    • DEBUG: Detailed tracing information
    • INFO: Important business logic events
    • WARN: Recoverable errors or deprecated usage
    • ERROR: Serious application errors
  2. Include Relevant Context:

    logger.Info("Package analysis started", map[string]interface{}{
        "package_name": pkg.Name,
        "version": pkg.Version,
        "registry": pkg.Registry,
        "scan_id": scanID,
    })
    
  3. Use Field Loggers for Components:

    componentLogger := logger.GetGlobalLogger().WithFields(map[string]interface{}{
        "component": "ml-analyzer",
        "version": "1.0.0",
    })
    
  4. Log Performance Metrics:

    start := time.Now()
    // ... do work ...
    logger.Info("Operation completed", map[string]interface{}{
        "operation": "package_scan",
        "duration": time.Since(start).String(),
        "success": true,
    })
    
  5. Handle Errors Gracefully:

    if err != nil {
        logger.Error("Operation failed", map[string]interface{}{
            "error": err.Error(),
            "operation": "fetch_package",
            "package_name": pkgName,
        })
        return err
    }
    

Migration from Standard Log

If you're migrating from Go's standard log package:

// Old
log.Printf("Processing package: %s", pkgName)
log.Printf("Error: %v", err)

// New
logger.Infof("Processing package: %s", pkgName)
logger.Error("Operation failed", map[string]interface{}{
    "error": err.Error(),
    "package_name": pkgName,
})

Dependencies

  • gopkg.in/natefinch/lumberjack.v2: Log rotation support
  • Standard library packages: log, fmt, encoding/json, io, os

Examples

See examples/logging_example.go for comprehensive usage examples.

Documentation

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

func Debug

func Debug(msg string, fields ...map[string]interface{})

func DebugWithContext

func DebugWithContext(msg string, extraFields ...map[string]interface{})

Global debug functions

func Debugf

func Debugf(format string, v ...interface{})

func Error

func Error(msg string, fields ...map[string]interface{})

func Errorf

func Errorf(format string, v ...interface{})

func Fatal

func Fatal(msg string, fields ...map[string]interface{})

func Fatalf

func Fatalf(format string, v ...interface{})

func Info

func Info(msg string, fields ...map[string]interface{})

Global logging functions

func Infof

func Infof(format string, v ...interface{})

func InitDefault

func InitDefault()

InitDefault initializes the logger with default settings

func InitForTesting

func InitForTesting()

InitForTesting initializes a logger suitable for testing

func InitFromConfig

func InitFromConfig(config LoggerConfig) error

InitFromConfig initializes the global logger from configuration

func InitWithLevel

func InitWithLevel(level LogLevel)

InitWithLevel initializes the logger with a specific log level

func IsDebugEnabled

func IsDebugEnabled() bool

IsDebugEnabled checks if debug logging is enabled

func IsTraceEnabled

func IsTraceEnabled() bool

IsTraceEnabled checks if trace logging is enabled

func IsVerboseEnabled

func IsVerboseEnabled() bool

IsVerboseEnabled checks if verbose logging is enabled

func SetGlobalDebugMode

func SetGlobalDebugMode(mode DebugMode)

SetGlobalDebugMode sets the debug mode for the global debug logger

func SetGlobalDebugModeFromString

func SetGlobalDebugModeFromString(mode string)

SetGlobalDebugModeFromString sets the debug mode from string

func SetGlobalFormat

func SetGlobalFormat(format string)

SetGlobalFormat sets the format for the global logger

func SetGlobalLevel

func SetGlobalLevel(level LogLevel)

SetGlobalLevel sets the log level for the global logger

func Trace

func Trace(msg string, fields ...map[string]interface{})

func TraceFunction

func TraceFunction(funcName string) func()

func TraceWithContext

func TraceWithContext(msg string, extraFields ...map[string]interface{})

func Tracef

func Tracef(format string, v ...interface{})

func Verbose

func Verbose(msg string, fields ...map[string]interface{})

func VerboseWithContext

func VerboseWithContext(msg string, extraFields ...map[string]interface{})

func Verbosef

func Verbosef(format string, v ...interface{})

func Warn

func Warn(msg string, fields ...map[string]interface{})

func Warnf

func Warnf(format string, v ...interface{})

Types

type Config

type Config struct {
	Level     LogLevel
	Format    string // "text" or "json"
	Output    io.Writer
	Timestamp bool
	Caller    bool
	Prefix    string
}

Config represents logger configuration

func DefaultConfig

func DefaultConfig() *Config

DefaultConfig returns a default logger configuration

type DebugConfig

type DebugConfig struct {
	Mode          DebugMode
	ShowCaller    bool
	ShowTimestamp bool
	ShowGoroutine bool
	ShowMemStats  bool
	IncludeStack  bool
	MaxStackDepth int
}

DebugConfig contains debug-specific configuration

func DefaultDebugConfig

func DefaultDebugConfig() *DebugConfig

DefaultDebugConfig returns a default debug configuration

type DebugLogger

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

DebugLogger provides enhanced debugging capabilities

func GetGlobalDebugLogger

func GetGlobalDebugLogger() *DebugLogger

GetGlobalDebugLogger returns the global debug logger

func NewDebugLogger

func NewDebugLogger(logger *Logger, config *DebugConfig) *DebugLogger

NewDebugLogger creates a new debug logger

func (*DebugLogger) DebugWithContext

func (dl *DebugLogger) DebugWithContext(msg string, extraFields ...map[string]interface{})

DebugWithContext logs a debug message with enhanced context

func (*DebugLogger) IsEnabled

func (dl *DebugLogger) IsEnabled(level LogLevel) bool

IsEnabled checks if debug logging is enabled for the given level

func (*DebugLogger) SetDebugMode

func (dl *DebugLogger) SetDebugMode(mode DebugMode)

SetDebugMode sets the debug mode

func (*DebugLogger) TraceFunction

func (dl *DebugLogger) TraceFunction(funcName string) func()

TraceFunction logs function entry and exit

func (*DebugLogger) TraceWithContext

func (dl *DebugLogger) TraceWithContext(msg string, extraFields ...map[string]interface{})

TraceWithContext logs a trace message with enhanced context

func (*DebugLogger) VerboseWithContext

func (dl *DebugLogger) VerboseWithContext(msg string, extraFields ...map[string]interface{})

VerboseWithContext logs a verbose message with enhanced context

type DebugMode

type DebugMode int

DebugMode represents different debug modes

const (
	DebugModeOff DebugMode = iota
	DebugModeBasic
	DebugModeVerbose
	DebugModeTrace
)

func ParseDebugMode

func ParseDebugMode(mode string) DebugMode

ParseDebugMode parses a string into a DebugMode

func (DebugMode) String

func (d DebugMode) String() string

String returns the string representation of debug mode

type FieldLogger

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

FieldLogger wraps Logger with predefined fields

func (*FieldLogger) Debug

func (fl *FieldLogger) Debug(msg string)

Debug logs a debug message with predefined fields

func (*FieldLogger) Debugf

func (fl *FieldLogger) Debugf(format string, v ...interface{})

Debugf logs a formatted debug message with predefined fields

func (*FieldLogger) Error

func (fl *FieldLogger) Error(msg string)

Error logs an error message with predefined fields

func (*FieldLogger) Errorf

func (fl *FieldLogger) Errorf(format string, v ...interface{})

Errorf logs a formatted error message with predefined fields

func (*FieldLogger) Fatal

func (fl *FieldLogger) Fatal(msg string)

Fatal logs a fatal message with predefined fields and exits

func (*FieldLogger) Fatalf

func (fl *FieldLogger) Fatalf(format string, v ...interface{})

Fatalf logs a formatted fatal message with predefined fields and exits

func (*FieldLogger) Info

func (fl *FieldLogger) Info(msg string)

Info logs an info message with predefined fields

func (*FieldLogger) Infof

func (fl *FieldLogger) Infof(format string, v ...interface{})

Infof logs a formatted info message with predefined fields

func (*FieldLogger) Trace

func (fl *FieldLogger) Trace(msg string)

Trace logs a trace message with predefined fields

func (*FieldLogger) Tracef

func (fl *FieldLogger) Tracef(format string, v ...interface{})

Tracef logs a formatted trace message with predefined fields

func (*FieldLogger) Verbose

func (fl *FieldLogger) Verbose(msg string)

Verbose logs a verbose message with predefined fields

func (*FieldLogger) Verbosef

func (fl *FieldLogger) Verbosef(format string, v ...interface{})

Verbosef logs a formatted verbose message with predefined fields

func (*FieldLogger) Warn

func (fl *FieldLogger) Warn(msg string)

Warn logs a warning message with predefined fields

func (*FieldLogger) Warnf

func (fl *FieldLogger) Warnf(format string, v ...interface{})

Warnf logs a formatted warning message with predefined fields

type LogLevel

type LogLevel int

LogLevel represents the logging level

const (
	TRACE LogLevel = iota
	DEBUG
	VERBOSE
	INFO
	WARN
	ERROR
	FATAL
)

func ParseLogLevel

func ParseLogLevel(level string) LogLevel

ParseLogLevel parses a string into a LogLevel

func (LogLevel) String

func (l LogLevel) String() string

String returns the string representation of the log level

type Logger

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

Logger provides a configurable logging interface

func GetGlobalLogger

func GetGlobalLogger() *Logger

GetGlobalLogger returns the global logger instance

func New

func New() *Logger

New creates a new logger instance with default configuration

func NewWithConfig

func NewWithConfig(config *Config) *Logger

NewWithConfig creates a new logger instance with custom configuration

func (*Logger) Debug

func (l *Logger) Debug(msg string, fields ...map[string]interface{})

Debug logs a debug message

func (*Logger) Debugf

func (l *Logger) Debugf(format string, v ...interface{})

Debugf logs a formatted debug message

func (*Logger) Error

func (l *Logger) Error(msg string, fields ...map[string]interface{})

Error logs an error message

func (*Logger) Errorf

func (l *Logger) Errorf(format string, v ...interface{})

Errorf logs a formatted error message

func (*Logger) Fatal

func (l *Logger) Fatal(msg string, fields ...map[string]interface{})

Fatal logs a fatal message and exits

func (*Logger) Fatalf

func (l *Logger) Fatalf(format string, v ...interface{})

Fatalf logs a formatted fatal message and exits

func (*Logger) Info

func (l *Logger) Info(msg string, fields ...map[string]interface{})

Info logs an info message

func (*Logger) Infof

func (l *Logger) Infof(format string, v ...interface{})

Infof logs a formatted info message

func (*Logger) SetFormat

func (l *Logger) SetFormat(format string)

SetFormat sets the logging format ("text" or "json")

func (*Logger) SetLevel

func (l *Logger) SetLevel(level LogLevel)

SetLevel sets the logging level

func (*Logger) Trace

func (l *Logger) Trace(msg string, fields ...map[string]interface{})

Trace logs a trace message

func (*Logger) Tracef

func (l *Logger) Tracef(format string, v ...interface{})

Tracef logs a formatted trace message

func (*Logger) Verbose

func (l *Logger) Verbose(msg string, fields ...map[string]interface{})

Verbose logs a verbose message

func (*Logger) Verbosef

func (l *Logger) Verbosef(format string, v ...interface{})

Verbosef logs a formatted verbose message

func (*Logger) Warn

func (l *Logger) Warn(msg string, fields ...map[string]interface{})

Warn logs a warning message

func (*Logger) Warnf

func (l *Logger) Warnf(format string, v ...interface{})

Warnf logs a formatted warning message

func (*Logger) WithFields

func (l *Logger) WithFields(fields map[string]interface{}) *FieldLogger

WithFields creates a logger with predefined fields

type LoggerConfig

type LoggerConfig struct {
	Level     string
	Format    string
	Output    string
	Timestamp bool
	Caller    bool
	Prefix    string
	Rotation  RotationConfig
}

LoggerConfig represents the configuration structure for logger initialization

type RotationConfig

type RotationConfig struct {
	Enabled    bool
	MaxSize    int
	MaxBackups int
	MaxAge     int
	Compress   bool
}

RotationConfig represents log rotation configuration

Jump to

Keyboard shortcuts

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