L3 Logging Package

L3 Logging Package

The l3 package provides a flexible and efficient logging system for Go applications. L3 stands for “Lightweight Levelled Logger” and offers multiple logging levels, various output destinations, and extensive configuration options.

Features

  • Multiple Log Levels: Support for OFF, ERROR, WARN, INFO, DEBUG, and TRACE levels
  • Flexible Output Destinations: Console and file-based logging with custom paths for each level
  • Package-Specific Configuration: Set different log levels for different packages
  • Asynchronous Logging: Optional non-blocking log operations for improved performance
  • Multiple Output Formats: Support for both text and JSON formatted logs
  • Detailed Context: Options to include function names, line numbers, and timestamps in log entries
  • Configurable: Set up via configuration files, environment variables, or programmatically

Core Components

Log Levels

L3 supports the following log levels in descending order of severity:

  • OFF: No logging
  • ERROR: Critical errors that prevent normal operation
  • WARN: Unexpected situations that don’t prevent normal operation
  • INFO: Informational messages about normal operation
  • DEBUG: Detailed information for debugging
  • TRACE: Very detailed tracing information

Logger Interface

The primary interface for logging is the Logger interface, which provides methods for logging at different levels:

type Logger interface {
    Error(msg string, err ...error)
    Warn(msg string, err ...error)
    Info(msg string, args ...interface{})
    Debug(msg string, args ...interface{})
    Trace(msg string, args ...interface{})
    // Other methods omitted for brevity
}

Writers

L3 provides different types of writers to output log messages:

  • ConsoleWriter: Writes log messages to stdout and stderr
  • FileWriter: Writes log messages to files, with options for different files per log level

Usage Examples

Basic Logging

package main

import (
    "errors"
    "oss.nandlabs.io/golly/l3"
)

// Create a package-level logger
var logger l3.Logger = l3.Get()

func main() {
    // Log at different levels
    logger.Info("Application started successfully")
    logger.Debug("Processing request with ID: 12345")
    logger.Warn("Resource usage above 80%")
    logger.Error("Failed to connect to database", errors.New("connection timeout"))

    // Log with additional context
    logger.Info("User logged in", "userId", 123, "role", "admin")
}

Configuration via File

L3 can be configured using a JSON configuration file. By default, it looks for log-config.json in the application directory, but this can be customized.

{
  "format": "json",
  "async": true,
  "defaultLvl": "INFO",
  "includeFunction": true,
  "includeLineNum": true,
  "pkgConfigs": [
    {
      "pkgName": "main",
      "level": "INFO"
    },
    {
      "pkgName": "myapp/data",
      "level": "DEBUG"
    }
  ],
  "writers": [
    {
      "console": {
        "errToStdOut": false,
        "warnToStdOut": false
      }
    },
    {
      "file": {
        "defaultPath": "/var/log/myapp.log",
        "errorPath": "/var/log/myapp-errors.log"
      }
    }
  ]
}

Environment Variables

L3 can be configured using environment variables:

# Set default log level to DEBUG
export GC_LOG_DEF_LEVEL=DEBUG

# Use JSON format for logs
export GC_LOG_FMT=json

# Enable asynchronous logging
export GC_LOG_ASYNC=true

# Customize timestamp format
export GC_LOG_TIME_FMT="2006-01-02 15:04:05"

Programmatic Configuration

You can configure L3 programmatically at runtime:

package main

import (
    "oss.nandlabs.io/golly/l3"
)

func main() {
    // Create a custom log configuration
    config := &l3.LogConfig{
        Format:          "json",
        Async:           true,
        DefaultLvl:      "DEBUG",
        IncludeFunction: true,
        IncludeLineNum:  true,
        Writers: []l3.WriterConfig{
            {
                Console: &l3.ConsoleConfig{
                    ErrToStdOut:  false,
                    WarnToStdOut: true,
                },
            },
        },
    }

    // Apply the configuration
    l3.Configure(config)

    // Get a logger with the new configuration
    logger := l3.Get()
    logger.Info("Logging system configured programmatically")
}

Installation

go get oss.nandlabs.io/golly/l3