rlog

package
v1.4.13 Latest Latest
Warning

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

Go to latest
Published: Aug 31, 2025 License: Apache-2.0 Imports: 11 Imported by: 35

README

RLog - Structured Logging for ROR

Why RLog

Rlog is a wrapper for the Uber Zap logging framework. The reason we want to wrap zap and not use it directly is that it makes it easier to change logger in the future if necessary. RLog was made when we wanted to switch from Logrus to Zap and encountered this exact problem.

What RLog offers

Rlog offers a global logger with both context (go context) and non context aware logging functions. Context aware functions will add certain predefined fields from a context and also correlate any trace information with the logs.

Rlog offers leveled and structured logging in the same manner as Zap does. The levels supported are Info, Debug, Warn, Error and Fatal. Logs are normally output as JSON but can be output in a more readable form when developing, its important to note that in prod all logs shall be in the JSON format.

Features

  • Structured Logging: Log entries include structured fields for better filtering and analysis
  • Context-Aware Logging: Automatically extract trace IDs and context values for correlated logs
  • OpenTelemetry Integration: Correlate logs with OpenTelemetry traces
  • Multiple Output Targets: Send logs to files, stdout/stderr, or other targets
  • Environment-Based Configuration: Easy configuration via environment variables
  • HTTP Request Logging: Built-in middleware for Gin web framework
  • Field Helpers: Convenience functions for adding typed fields to log entries

Configuration

Rlog is configured using environment variables, from either an env file or the environment its running in.

LOG_LEVEL

Sets the minimum log level to output. Valid values are:

  • debug: Most verbose level, includes detailed diagnostic information
  • trace: Alias for debug level
  • info: Standard information messages (default)
  • warn: Warning messages
  • error: Error messages only

Example:

LOG_LEVEL=debug
LOG_OUTPUT

Set where the logs should be sent, defaults to stderr. Logs can be sent to a file an url or stdout/stderr. Logs can be sent to multiple locations with a comma separated string.

Example:

LOG_OUTPUT="/home/user/foo/.ror/log,stderr"

This example logs to both a file and stderr

LOG_OUTPUT_ERROR

Set where error level logs should be sent, works the same as LOG_OUTPUT. If not specified, error logs will go to the same destination as regular logs.

Example:

LOG_OUTPUT_ERROR="/home/user/foo/.ror/error.log"
LOG_DEVELOP

Set whether or not logs should be in JSON format or a more human-readable format.

  • false or unset: JSON format (default for production)
  • true: Human-readable console format (for development)

Example:

LOG_DEVELOP=true

Usage Examples

Basic Logging
package main

import (
    "github.com/yourusername/ror/pkg/rlog"
)

func main() {
    // Basic logging at different levels
    rlog.Debug("Debug message", rlog.String("component", "example"))
    rlog.Info("Information message", rlog.Int("count", 42))
    rlog.Warn("Warning message")
    rlog.Error("Error occurred", err, rlog.String("operation", "file_read"))
    
    // CAUTION: This will terminate the program
    // rlog.Fatal("Fatal error", err)
}
Context-Aware Logging
package main

import (
    "context"
    
    "github.com/yourusername/ror/pkg/rlog"
)

func processRequest(ctx context.Context, userID string) {
    // Add context keys that should be included in all logs
    rlog.AddContextKeyField("request_id")
    rlog.AddContextKeyField("user_id")
    
    // Context with values
    ctx = context.WithValue(ctx, "request_id", "req-123")
    ctx = context.WithValue(ctx, "user_id", userID)
    
    // Log with context - will include request_id and user_id automatically
    rlog.Infoc(ctx, "Processing request", rlog.String("action", "user_login"))
}
HTTP Middleware
package main

import (
    "github.com/gin-gonic/gin"
    "github.com/yourusername/ror/pkg/rlog"
)

func setupRouter() *gin.Engine {
    router := gin.New()
    
    // Add the rlog middleware for HTTP request logging
    router.Use(rlog.LogMiddleware())
    
    // Add routes
    router.GET("/ping", func(c *gin.Context) {
        c.JSON(200, gin.H{"message": "pong"})
    })
    
    return router
}
Formatted Logging
package main

import (
    "github.com/yourusername/ror/pkg/rlog"
)

func main() {
    // Printf-style logging (at info level)
    rlog.Infof("User %s logged in from %s", "john_doe", "192.168.1.1")
}

Integration with OpenTelemetry

Rlog automatically correlates logs with OpenTelemetry traces when using context-aware logging functions. When a span is active in the provided context, the following trace information is added to log entries:

  • trace_id: The OpenTelemetry trace ID
  • trace_flags: The OpenTelemetry trace flags
  • span_id: The OpenTelemetry span ID (if the span is recording)

Additionally, log entries are recorded as span events in the active span.

Best Practices

  1. Use Structured Logging: Always include relevant fields using the field helpers rather than embedding them in the message string
  2. Use Context-Aware Logging: When a context is available, prefer the context-aware logging functions (Infoc, Debugc, etc.)
  3. Log Levels: Use appropriate log levels based on the importance and severity of the message
  4. Error Handling: Always include the error object when logging errors using the Error or Fatal functions
  5. Sensitive Data: Never log sensitive information such as passwords, tokens, or personal identifiable information

Documentation

Overview

Package rlog provides a structured logging library for the ROR project.

rlog is a wrapper around the uber-go/zap logging package that provides: - Structured logging with strongly typed fields - Context-aware logging with automatic extraction of request IDs and trace data - OpenTelemetry integration for distributed tracing - Configurable outputs via environment variables - Support for both development (human-readable) and production (JSON) formats - HTTP middleware for Gin web framework

The package is configured via environment variables: - LOG_LEVEL: Sets the minimum log level (debug, info, warn, error) - LOG_OUTPUT: Specifies where logs are written (stderr by default, can be files or multiple targets) - LOG_OUTPUT_ERROR: Specifies where error logs are written - LOG_DEVELOP: When "true", outputs human-readable logs instead of JSON

Basic usage:

rlog.Info("This is an informational message", rlog.String("key", "value"))
rlog.Error("An error occurred", err, rlog.Int("status", 500))

// With context (includes trace IDs and context values automatically)
rlog.Infoc(ctx, "Processing request", rlog.String("user", "admin"))

Index

Constants

View Source
const (
	RequestIdKey CorrelationIdType = iota
	SessionIdKey
	LOG_LEVEL        = "LOG_LEVEL"
	LOG_OUTPUT       = "LOG_OUTPUT"
	LOG_OUTPUT_ERROR = "LOG_OUTPUT_ERROR"
	LOG_DEVELOP      = "LOG_DEVELOP"
)

Variables

This section is empty.

Functions

func AddContextKeyField added in v0.0.11

func AddContextKeyField(key string) error

AddContextKeyField adds a key to look for in contexts so that we can add the context value as a persistent field to all logs. This allows automatic inclusion of specified context values in log entries.

Parameters:

  • key: The context key to extract values from. Must be non-empty.

Returns:

  • An error if the key is empty, nil otherwise.

func Debug

func Debug(msg string, fields ...Field)

Debug logs a message at DebugLevel. The message includes any fields passed at the log site.

Parameters:

  • msg: The log message
  • fields: Optional fields to add context to the log entry

func Debugc

func Debugc(ctx context.Context, msg string, fields ...Field)

Debugc logs a message at DebugLevel with context. The message includes any fields passed at the log site and any tracing fields in the attached context, if the context contains known fields these are also added.

Parameters:

  • ctx: The context which may contain trace information
  • msg: The log message
  • fields: Optional fields to add context to the log entry

func Error

func Error(msg string, err error, fields ...Field)

Error logs a message at ErrorLevel. The message includes any fields passed at the log site and the error.

Parameters:

  • msg: The log message
  • err: The error to log
  • fields: Optional fields to add context to the log entry

func Errorc

func Errorc(ctx context.Context, msg string, err error, fields ...Field)

Errorc logs a message at ErrorLevel with context. The message includes any fields passed at the log site and any tracing fields in the attached context, if the context contains known fields these are also added.

Parameters:

  • ctx: The context which may contain trace information
  • msg: The log message
  • err: The error to log
  • fields: Optional fields to add context to the log entry

func Fatal

func Fatal(msg string, err error, fields ...Field)

Fatal logs a message at FatalLevel. The message includes any fields passed at the log site and the error. The logger then calls os.Exit(1), even if logging at FatalLevel is disabled.

Parameters:

  • msg: The log message
  • err: The error to log
  • fields: Optional fields to add context to the log entry

func Fatalc

func Fatalc(ctx context.Context, msg string, err error, fields ...Field)

Fatalc logs a message at FatalLevel with context. The message includes any fields passed at the log site and any tracing fields in the attached context, if the context contains known fields these are also added. The logger then calls os.Exit(1), even if logging at FatalLevel is disabled.

Parameters:

  • ctx: The context which may contain trace information
  • msg: The log message
  • err: The error to log
  • fields: Optional fields to add context to the log entry

func GetLogLevel added in v1.0.0

func GetLogLevel() string

GetLogLevel returns the current log level as a string. The log level indicates the minimum severity of messages that will be logged.

func Info

func Info(msg string, fields ...Field)

Info logs a message at InfoLevel. The message includes any fields passed at the log site.

Parameters:

  • msg: The log message
  • fields: Optional fields to add context to the log entry

func Infoc

func Infoc(ctx context.Context, msg string, fields ...Field)

Infoc logs a message at InfoLevel with context. The message includes any fields passed at the log site and any tracing fields in the attached context, if the context contains known fields these are also added.

Parameters:

  • ctx: The context which may contain trace information
  • msg: The log message
  • fields: Optional fields to add context to the log entry

func Infof

func Infof(format string, v ...any)

Infof logs a message at InfoLevel with context. The message is formated with sprintf.

Parameters:

  • format: A format string for the message
  • v: Values to be formatted into the message

func InitializeRlog

func InitializeRlog()

InitializeRlog initializes the global logger based on configuration. It creates either a default or development logger configuration depending on environment settings and initializes a global logger instance. If initialization fails, it will panic with an error message.

func LogMiddleware

func LogMiddleware() gin.HandlerFunc

LogMiddleware is a Gin middleware function for logging HTTP requests. It logs detailed information about any requests that result in error status codes (3xx, 4xx, 5xx), including method, status code, path, latency, user agent, client IP, forwarded address, response size, and any errors that occurred during request processing.

Usage:

router := gin.New()
router.Use(rlog.LogMiddleware())

Returns:

  • A Gin HandlerFunc that can be used in middleware chains

func Warn

func Warn(msg string, fields ...Field)

Warn logs a message at WarnLevel. The message includes any fields passed at the log site.

Parameters:

  • msg: The log message
  • fields: Optional fields to add context to the log entry

func Warnc

func Warnc(ctx context.Context, msg string, fields ...Field)

Warnc logs a message at WarnLevel with context. The message includes any fields passed at the log site and any tracing fields in the attached context, if the context contains known fields these are also added.

Parameters:

  • ctx: The context which may contain trace information
  • msg: The log message
  • fields: Optional fields to add context to the log entry

Types

type CorrelationIdType

type CorrelationIdType int

type Field

type Field = zap.Field

func Any

func Any(key string, value interface{}) Field

Any creates a field with the given key and arbitrary value. Any handles JSON marshaling for arbitrary objects.

Parameters:

  • key: The field key
  • value: The value to be logged (will be marshaled to JSON)

Returns:

  • A Field object that can be used in logging functions

func ByteString

func ByteString(key string, value []byte) Field

ByteString creates a field with the given key and byte slice value.

Parameters:

  • key: The field key
  • value: The byte slice value

Returns:

  • A Field object that can be used in logging functions

func Int

func Int(key string, value int) Field

Int creates a field with the given key and integer value.

Parameters:

  • key: The field key
  • value: The integer value

Returns:

  • A Field object that can be used in logging functions

func Int64

func Int64(key string, value int64) Field

Int64 creates a field with the given key and int64 value.

Parameters:

  • key: The field key
  • value: The int64 value

Returns:

  • A Field object that can be used in logging functions

func String

func String(key, value string) Field

String creates a field with the given key and string value.

Parameters:

  • key: The field key
  • value: The string value

Returns:

  • A Field object that can be used in logging functions

func Strings

func Strings(key string, value []string) Field

Strings creates a field with the given key and string slice value.

Parameters:

  • key: The field key
  • value: The string slice value

Returns:

  • A Field object that can be used in logging functions

func Uint

func Uint(key string, value uint) Field

Uint creates a field with the given key and unsigned integer value.

Parameters:

  • key: The field key
  • value: The unsigned integer value

Returns:

  • A Field object that can be used in logging functions

type Logger

type Logger struct {
	*zap.Logger
	ContextKeyFields []string
}

Jump to

Keyboard shortcuts

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