balogan

package module
v1.1.1 Latest Latest
Warning

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

Go to latest
Published: Jul 31, 2025 License: MIT Imports: 11 Imported by: 0

README ΒΆ

balogan

Release Go Version Go Reference codecov

The balogan package provides a powerful yet simple logger with extensive customization capabilities and modern structured logging support. Designed for developers who need flexibility without complexity.

Key Features:

  • πŸš€ Fast start - works out of the box with zero configuration
  • πŸ“Š 7 log levels from TRACE to PANIC with proper filtering
  • πŸ—οΈ Structured logging with fields (JSON, logfmt, key=value formats)
  • 🎯 Conditional logging - smart filtering with 20+ predefined conditions
  • πŸ”§ Highly extensible - custom prefixes, writers, and formatters
  • ⚑ Concurrent logging to multiple destinations
  • πŸ›‘οΈ Error handling for robust logging operations
  • 🧡 Thread-safe with immutable logger instances

I am following a concept that colorful logs and other visual extensions are redundant and that's why balogan will never support such things out of the box. However, I strive to make the logger as extensible as possible, so that anyone can create an addon with the functionality they need.

Why Choose balogan?

πŸš€ Zero Configuration Start

Works immediately without any setup - just import and use!

πŸ“Š Complete Logging Solution
  • 7 log levels: TRACE (-1) β†’ DEBUG (0) β†’ INFO (1) β†’ WARNING (2) β†’ ERROR (3) β†’ FATAL (4) β†’ PANIC (5)
  • Smart filtering: Only logs at or above your configured level
  • Critical handling: FATAL exits program, PANIC causes panic
πŸ—οΈ Modern Structured Logging
  • Multiple formats: JSON, logfmt, key=value (default)
  • Convenient API: .WithJSON(), .WithLogfmt(), .WithField()
  • Chainable methods: logger.WithJSON().WithField("user", "john").Info("message")
πŸ”§ Maximum Flexibility
  • Custom prefixes: timestamps, tags, or your own functions
  • Multiple writers: stdout, files, or custom destinations
  • Extensible formatters: implement your own field formatting
⚑ Performance & Safety
  • Concurrent logging: parallel writes to multiple destinations
  • Thread-safe: use from multiple goroutines safely
  • Immutable loggers: each method returns new instance
  • Error handling: robust error handling for all operations

Installation

go get -u github.com/dr3dnought/balogan

Quick Start

1. Basic Logging
package main

import "github.com/dr3dnought/balogan"

func main() {
    // Create logger - works immediately!
    logger := balogan.New(balogan.InfoLevel, balogan.DefaultWriter)
    
    // Basic logging
    logger.Info("Application started")
    logger.Warning("This is a warning")
    logger.Error("Something went wrong")
    
    // Format strings
    logger.Infof("User %s logged in", "john")
}
2. Structured Logging (Modern Approach)
// Add context with fields
logger.WithField("user_id", 123).Info("User action")
// Output: INFO user_id=123 User action

// Multiple fields
logger.WithFields(balogan.Fields{
    "request_id": "req-456",
    "method":     "POST",
    "duration":   "150ms",
}).Info("Request processed")
// Output: INFO duration=150ms method=POST request_id=req-456 Request processed

// Different formats
logger.WithJSON().WithField("event", "login").Info("User event")
// Output: INFO {"event":"login"} User event

logger.WithLogfmt().WithField("service", "api server").Info("Service started")  
// Output: INFO service="api server" Service started
3. Enhanced Logging with Prefixes
// Add timestamps and tags
logger := balogan.New(
    balogan.InfoLevel,
    balogan.DefaultWriter,
    balogan.WithTimeStamp(),
    balogan.WithTag("[API]"),
)

logger.Info("Server started")
// Output: INFO 2024-12-13T15:30:45Z [API] Server started

// Combine with structured fields
logger.WithField("port", 8080).Info("Listening on port")
// Output: INFO 2024-12-13T15:30:45Z [API] port=8080 Listening on port

πŸ’‘ Default Behavior:

  • Uses stdout for output
  • KeyValueFormatter for fields (key=value format)
  • Shows logs at configured level and above

Every log function has format alternative. It works like Sprintf function in fmt package.

Log Levels

balogan supports 7 different log levels with increasing severity:

Level Value Description Behavior
TraceLevel -1 Most detailed information, typically only for diagnosing problems Standard logging
DebugLevel 0 Information useful for debugging Standard logging
InfoLevel 1 General informational messages Standard logging
WarningLevel 2 Warning messages for potentially harmful situations Standard logging
ErrorLevel 3 Error messages for error conditions Standard logging
FatalLevel 4 Critical errors that cause program termination Calls os.Exit(1) after logging
PanicLevel 5 Most severe errors that cause program panic Calls panic() after logging
Level Filtering

When you set a log level, only messages at that level or higher will be output:

package main

import "github.com/dr3dnought/balogan"

func main() {
    // Logger with InfoLevel will show INFO, WARNING, ERROR, FATAL, PANIC
    // but will skip TRACE and DEBUG
    logger := balogan.New(balogan.InfoLevel, balogan.DefaultWriter)
    
    logger.Trace("This won't be shown")   // Skipped
    logger.Debug("This won't be shown")   // Skipped
    logger.Info("This will be shown")     // Output: INFO This will be shown
    logger.Warning("This will be shown")  // Output: WARNING This will be shown
    logger.Error("This will be shown")    // Output: ERROR This will be shown
}
All Available Methods
// Standard logging methods
logger.Trace("trace message")
logger.Tracef("trace with %s", "parameters")

logger.Debug("debug message")
logger.Debugf("debug with %s", "parameters")

logger.Info("info message")
logger.Infof("info with %s", "parameters")

logger.Warning("warning message")
logger.Warningf("warning with %s", "parameters")

logger.Error("error message")
logger.Errorf("error with %s", "parameters")

// Critical methods (terminate program)
logger.Fatal("fatal message")        // Logs and calls os.Exit(1)
logger.Fatalf("fatal with %s", "parameters")

logger.Panic("panic message")        // Logs and calls panic()
logger.Panicf("panic with %s", "parameters")

⚠️ Important: Fatal and Panic methods will terminate your program after logging! Use them only for truly critical errors.

Structured Logging

balogan supports structured logging with fields (key-value pairs) that can be formatted in different ways. This allows you to add context to your logs in a machine-readable format.

Basic Structured Logging
package main

import "github.com/dr3dnought/balogan"

func main() {
    logger := balogan.New(balogan.InfoLevel, balogan.DefaultWriter)
    
    // Add single field
    logger.WithField("user_id", 123).Info("User logged in")
    // Output: INFO user_id=123 User logged in
    
    // Add multiple fields
    logger.WithFields(balogan.Fields{
        "request_id": "req-456",
        "method":     "POST", 
        "duration":   "42ms",
    }).Info("Request processed")
    // Output: INFO duration=42ms method=POST request_id=req-456 Request processed
}
Field Formatters

balogan provides three built-in field formatters:

1. Key-Value Formatter (Default)

This is the default formatter - used when no specific formatter is set.

// Default behavior - no need to specify formatter
logger.WithField("key", "value").Info("message")
// Output: INFO key=value message

// Explicit usage (same result)
logger.WithKeyValue().WithField("key", "value").Info("message")
// Output: INFO key=value message

// Custom separator
logger.WithKeyValueSeparator(" | ").WithFields(balogan.Fields{
    "user": "john",
    "role": "admin",
}).Info("User info")
// Output: INFO role=admin | user=john User info
2. JSON Formatter
// Long way (still supported)
jsonLogger := logger.WithFieldsFormatter(&balogan.JSONFormatter{})

// Short way (recommended)
logger.WithJSON().WithFields(balogan.Fields{
    "user_id": 123,
    "action":  "login",
}).Info("User action")
// Output: INFO {"action":"login","user_id":123} User action
3. Logfmt Formatter
// Long way (still supported)
logfmtLogger := logger.WithFieldsFormatter(&balogan.LogfmtFormatter{})

// Short way (recommended)
logger.WithLogfmt().WithFields(balogan.Fields{
    "service": "api",
    "message": "request processed",
}).Info("Service event")
// Output: INFO service=api message="request processed" Service event
Quick Format Switching

balogan provides convenient methods for quick format switching:

// Switch to JSON format
jsonLogger := logger.WithJSON()

// Switch to logfmt format  
logfmtLogger := logger.WithLogfmt()

// Switch to key-value format (default)
kvLogger := logger.WithKeyValue()

// Key-value with custom separator
customLogger := logger.WithKeyValueSeparator(" | ")

// You can chain format switches
logger.WithJSON().
    WithField("step", 1).
    Info("Step 1") // JSON format

logger.WithLogfmt().
    WithField("step", 2).
    Info("Step 2") // Logfmt format
Changing Default Formatter Globally

You can change the default formatter for all new loggers:

package main

import "github.com/dr3dnought/balogan"

func init() {
    // Set JSON as default formatter for all loggers
    balogan.DefaultFieldsFormatter = &balogan.JSONFormatter{}
    
    // Or logfmt
    // balogan.DefaultFieldsFormatter = &balogan.LogfmtFormatter{}
    
    // Or key-value with custom separator
    // balogan.DefaultFieldsFormatter = &balogan.KeyValueFormatter{Separator: " | "}
}

func main() {
    // This logger will now use JSON by default
    logger := balogan.New(balogan.InfoLevel, balogan.DefaultWriter)
    logger.WithField("user", "john").Info("User logged in")
    // Output: INFO {"user":"john"} User logged in
}
Persistent Fields

Create loggers with persistent fields for components:

// Component logger with persistent fields
dbLogger := logger.WithFields(balogan.Fields{
    "component": "database",
    "host":      "localhost",
})

dbLogger.Info("Connection established")
// Output: INFO component=database host=localhost Connection established

dbLogger.WithField("query_time", "15ms").Debug("Query executed") 
// Output: DEBUG component=database host=localhost query_time=15ms Query executed
Combining with Prefixes

Structured fields work seamlessly with traditional prefixes:

logger := balogan.New(
    balogan.InfoLevel,
    balogan.DefaultWriter,
    balogan.WithTimeStamp(),
    balogan.WithTag("[API]"),
)

logger.WithField("endpoint", "/users").Info("Request received")
// Output: INFO 2024-12-13T03:10:56+03:00 [API] endpoint=/users Request received
Custom Field Formatters

You can create custom field formatters by implementing the FieldsFormatter interface:

package main

import (
    "fmt"
    "strings"
    "github.com/dr3dnought/balogan"
)

// Custom formatter that formats fields as XML
type XMLFormatter struct{}

func (f *XMLFormatter) Format(fields balogan.Fields) string {
    if len(fields) == 0 {
        return ""
    }
    
    var parts []string
    for key, value := range fields {
        parts = append(parts, fmt.Sprintf("<%s>%v</%s>", key, value, key))
    }
    
    return "<fields>" + strings.Join(parts, "") + "</fields>"
}

func main() {
    logger := balogan.New(balogan.InfoLevel, balogan.DefaultWriter)
    xmlLogger := logger.WithFieldsFormatter(&XMLFormatter{})
    
    xmlLogger.WithFields(balogan.Fields{
        "user": "john",
        "age":  30,
    }).Info("User data")
    // Output: INFO <fields><age>30</age><user>john</user></fields> User data
}

Conditional Logging

balogan supports powerful conditional logging that allows you to control when log messages are written based on various criteria. This is useful for performance optimization, debugging, and environment-specific logging.

Basic Conditional Logging
package main

import "github.com/dr3dnought/balogan"

func main() {
    logger := balogan.New(balogan.InfoLevel, balogan.DefaultWriter)
    
    // Environment-based logging
    logger.When(balogan.InDevelopment).Debug("This only logs in development")
    logger.When(balogan.InProduction).Error("This only logs in production")
    
    // Debug mode logging
    logger.When(balogan.DebugEnabled).Info("Debug mode is on")
    
    // Time-based logging
    logger.When(balogan.WorkingHours).Info("Business hours only")
    logger.When(balogan.Weekend).Debug("Weekend debugging")
}
Rate Limiting and Sampling
// Rate limiting - prevent log spam
rateLimitedLogger := logger.When(balogan.RateLimit(10)) // Max 10 logs per second
for i := 0; i < 100; i++ {
    rateLimitedLogger.Error("This won't spam your logs")
}

// Random sampling - log only a percentage
sampledLogger := logger.When(balogan.RandomSample(10)) // Log 10% of messages
for i := 0; i < 1000; i++ {
    sampledLogger.Debug("Only ~100 of these will be logged")
}

// Deterministic sampling - every Nth message
everyTenthLogger := logger.When(balogan.SampleEveryN(10)) // Every 10th message
for i := 0; i < 100; i++ {
    everyTenthLogger.Info("Message %d", i) // Logs messages 1, 11, 21, 31, etc.
}

// Count-based limiting - total limit
limitedLogger := logger.When(balogan.CountBased(5)) // Only 5 messages total
for i := 0; i < 20; i++ {
    limitedLogger.Warning("Only first 5 will be logged")
}
Complex Conditions with Combinators
// Combine multiple conditions with logical operators
complexLogger := logger.When(balogan.And(
    balogan.Or(balogan.InDevelopment, balogan.InTesting),
    balogan.DebugEnabled,
    balogan.Not(balogan.Weekend),
))
complexLogger.Debug("Logs only in dev/test, with debug enabled, on weekdays")

// Alternative syntax using Any/All aliases
smartLogger := logger.When(balogan.All(
    balogan.Any(balogan.InDevelopment, balogan.InTesting),
    balogan.DebugEnabled,
    balogan.Weekday,
))
Custom Environment Conditions
// Check specific environment variables
logger.When(balogan.EnvEquals("LOG_LEVEL", "verbose")).Debug("Verbose logging")
logger.When(balogan.EnvExists("FEATURE_FLAG")).Info("Feature is enabled")

// Time-based conditions
logger.When(balogan.TimeRange(9, 17)).Info("Business hours: 9 AM to 5 PM")
logger.When(balogan.TimeRange(22, 6)).Error("Night shift: 10 PM to 6 AM")
Field-Based Conditions
// Log only when specific fields exist or have certain values
userLogger := logger.WithLevelCondition(balogan.HasField("user_id"))
userLogger.WithField("user_id", 123).Info("This will log")
userLogger.Info("This won't log - no user_id field")

// Log only for specific field values
prodLogger := logger.WithLevelCondition(balogan.FieldEquals("environment", "production"))
prodLogger.WithField("environment", "production").Error("Production error")
prodLogger.WithField("environment", "development").Error("Won't log - not production")
Context-Aware Conditions
import "context"

// Define custom context key type (recommended)
type userRoleKey string
const UserRole userRoleKey = "user_role"

// Create context-aware logger
adminLogger := logger.WithContextCondition(balogan.ContextValueEquals(UserRole, "admin"))

// Use with context
ctx := context.WithValue(context.Background(), UserRole, "admin")
adminLogger.WithContext(ctx).Info("Admin action") // This will log

ctx = context.WithValue(context.Background(), UserRole, "user")
adminLogger.WithContext(ctx).Info("User action") // This won't log
Predefined Conditions Reference

Environment Conditions:

  • InProduction - ENV=production
  • InDevelopment - ENV=development
  • InTesting - ENV=test
  • InStaging - ENV=staging

Debug Conditions:

  • DebugEnabled - DEBUG=true
  • VerboseMode - VERBOSE=true

Time Conditions:

  • WorkingHours - 9 AM to 5 PM
  • Weekend - Saturday and Sunday
  • Weekday - Monday to Friday

Utility Conditions:

  • Always() - Always log
  • Never() - Never log
  • EnvEquals(key, value) - Environment variable equals value
  • EnvExists(key) - Environment variable exists
  • TimeRange(start, end) - Hour range (supports overnight)

Sampling Conditions:

  • RandomSample(percentage) - Random sampling (0-100%)
  • SampleEveryN(n) - Every Nth message
  • CountBased(max) - Maximum total count
  • RateLimit(perSecond) - Rate limiting

Field Conditions:

  • OnlyLevel(level) - Specific log level only
  • MinLevel(level) - Minimum log level
  • HasField(name) - Field exists
  • FieldEquals(name, value) - Field equals value

Context Conditions:

  • HasContextValue(key) - Context key exists
  • ContextValueEquals(key, value) - Context value equals

Combinators:

  • And(conditions...) - All conditions must be true
  • Or(conditions...) - Any condition must be true
  • Not(condition) - Invert condition
  • Any(conditions...) - Alias for Or
  • All(conditions...) - Alias for And
Performance Considerations

Conditional logging is designed to be fast:

// Condition evaluation benchmarks:
// Always():         0.32 ns/op
// RandomSample():   39.61 ns/op  
// RateLimit():      56.83 ns/op
// Complex combination: 42.89 ns/op

All conditions are thread-safe and can be used safely across multiple goroutines.

Using prefixes

So, now our log message is not informative. Let's improve it.

package main

import "github.com/dr3dnought/balogan"

func main() {
  // Define logger with log level and prefixes
  logger := balogan.New(
      balogan.InfoLevel,
      balogan.DefaultWriter,
      balogan.WithTimeStamp(),
      balogan.WithTag("[APP]"),
  )
  logger.Info("Application started") // Output: INFO 2024-12-13T03:10:56+03:00 [APP] Application started
}

Now, it looks like good log string.

You can use other standart prefixes, here's the whole list:

  • WithLogLevel(level balogan.LogLevel) accepts the log level and prints it's string version.
  • WithTimeStamp() prints time.Now() and prints it in RFC3339 format
  • WithTag(tag string) accepts string and prints it.

The sequence of prefixes depends on the order in which their functions are called

Custom prefixes

You can easily write your own prefix, just create a function which type is balogan.PrefixBuilderFunc

Let's create a prefix, which will print GOOS as an example:

package main

import (
  "github.com/dr3dnought/balogan"
  "runtime"
)

func WithGOOS() balogan.PrefixBuilderFunc {
  return func(args ...any) string {
    return runtime.GOOS
  }
}

func main() {
  // Define logger with custom prefix
  logger := balogan.New(
      balogan.InfoLevel,
      balogan.DefaultWriter,
      WithGOOS(),
      balogan.WithTag("[SYSTEM]"),
  )
  logger.Info("System information") // Output: INFO darwin [SYSTEM] System information
}

Temporary prefixes

Let's imagine case, when you need to print prefix without configuring new logger.

So, every balogan instance has method WithTemporaryPrefix that accepts addition prefixes and produces new instance of your logger with new prefixes.

Here's sample:

package main

import "github.com/dr3dnought/balogan"

func main() {
  // Define base logger
  logger := balogan.New(
      balogan.InfoLevel,
      balogan.DefaultWriter,
      balogan.WithTimeStamp(),
  )
  logger.Info("Application message") // Output: INFO 2024-12-13T03:10:56+03:00 Application message

  // Add temporary prefix for database operations
  dbLogger := logger.WithTemporaryPrefix(balogan.WithTag("[DB]"))
  dbLogger.Info("Database connected") // Output: INFO 2024-12-13T03:10:56+03:00 [DB] Database connected
  
  // Add temporary prefix for API operations
  apiLogger := logger.WithTemporaryPrefix(balogan.WithTag("[API]"))
  apiLogger.Warning("Rate limit exceeded") // Output: WARNING 2024-12-13T03:10:56+03:00 [API] Rate limit exceeded
}

Like you can see, it's very extandable!

Integration context.Context

balogan provides functions for putting logger and sub-logger in context.Context

package main

import (
	"context"

	"github.com/dr3dnought/balogan"
)

func main() {
	logger := balogan.New(
		balogan.InfoLevel, 
		balogan.DefaultWriter, 
		balogan.WithTimeStamp(),
		balogan.WithTag("[MAIN]"),
	)
	logger.Info("Application started") // Output: INFO 2024-12-13T03:10:56+03:00 [MAIN] Application started

	ctx := context.Background()
	ctx = logger.WithTemporaryPrefix(balogan.WithTag("[WORKER]")).WithContext(ctx)
	processWithCtx(ctx) // Output: INFO 2024-12-13T03:10:56+03:00 [MAIN] [WORKER] Processing task
}

func processWithCtx(ctx context.Context) {
	logger, _ := balogan.FromContext(ctx)
	logger.Info("Processing task") 
}

That's way we put modificated logger into context and use it from context in logWithCtx func.

Real-World Examples

Web Application Logging
package main

import (
    "net/http"
    "time"
    "github.com/dr3dnought/balogan"
)

func main() {
    // Create base logger with timestamps
    logger := balogan.New(
        balogan.InfoLevel,
        balogan.DefaultWriter,
        balogan.WithTimeStamp(),
        balogan.WithTag("[WEB]"),
    )
    
    // HTTP request handler
    http.HandleFunc("/api/users", func(w http.ResponseWriter, r *http.Request) {
        start := time.Now()
        
        // Create request-specific logger with structured fields
        reqLogger := logger.WithJSON().WithFields(balogan.Fields{
            "request_id": generateRequestID(),
            "method":     r.Method,
            "path":       r.URL.Path,
            "ip":         r.RemoteAddr,
            "user_agent": r.UserAgent(),
        })
        
        reqLogger.Info("Request received")
        
        // Process request...
        time.Sleep(50 * time.Millisecond) // Simulate processing
        
        // Log response with additional fields
        reqLogger.WithFields(balogan.Fields{
            "status":   200,
            "duration": time.Since(start).String(),
            "size":     "1.2KB",
        }).Info("Request completed")
    })
    
    logger.Info("Server starting on :8080")
    http.ListenAndServe(":8080", nil)
}

func generateRequestID() string {
    return "req-" + time.Now().Format("20060102150405")
}
Microservice with Different Components
package main

import "github.com/dr3dnought/balogan"

func main() {
    // Base application logger
    logger := balogan.New(
        balogan.InfoLevel,
        balogan.DefaultWriter,
        balogan.WithTimeStamp(),
    )
    
    // Database component logger (JSON for machine processing)
    dbLogger := logger.WithJSON().WithFields(balogan.Fields{
        "component": "database",
        "version":   "1.0.0",
    })
    
    // API component logger (logfmt for human readable)
    apiLogger := logger.WithLogfmt().WithFields(balogan.Fields{
        "component": "api",
        "version":   "2.1.0",
    })
    
    // Cache component logger (key-value with custom separator)
    cacheLogger := logger.WithKeyValueSeparator(" | ").WithFields(balogan.Fields{
        "component": "cache",
        "type":      "redis",
    })
    
    // Usage examples
    dbLogger.WithField("query_time", "15ms").Info("Query executed")
    // Output: INFO 2024-12-13T15:30:45Z {"component":"database","query_time":"15ms","version":"1.0.0"} Query executed
    
    apiLogger.WithField("endpoint", "/users").Info("API call")  
    // Output: INFO 2024-12-13T15:30:45Z component=api endpoint=/users version=2.1.0 API call
    
    cacheLogger.WithField("hit_rate", "95%").Info("Cache stats")
    // Output: INFO 2024-12-13T15:30:45Z component=cache | hit_rate=95% | type=redis Cache stats
}
Error Handling and Monitoring
package main

import (
    "fmt"
    "github.com/dr3dnought/balogan"
)

func processPayment(logger *balogan.Logger, paymentID string) {
    // Create payment-specific logger
    paymentLogger := logger.WithFields(balogan.Fields{
        "payment_id": paymentID,
        "service":    "payment_processor",
    })
    
    paymentLogger.Info("Processing payment")
    
    // Simulate payment processing
    if err := validatePayment(paymentID); err != nil {
        // Log error with detailed context
        paymentLogger.WithJSON().WithFields(balogan.Fields{
            "error_code":    "VALIDATION_FAILED",
            "error_message": err.Error(),
            "retry_count":   0,
            "amount":        "99.99",
            "currency":      "USD",
        }).Error("Payment validation failed")
        return
    }
    
    // Success logging
    paymentLogger.WithField("status", "completed").Info("Payment processed successfully")
}

func validatePayment(paymentID string) error {
    // Simulation
    return fmt.Errorf("insufficient funds")
}

func main() {
    logger := balogan.New(balogan.InfoLevel, balogan.DefaultWriter)
    processPayment(logger, "pay-12345")
}

API Reference Summary

Logger Creation
// Basic logger
logger := balogan.New(level, writer, prefixes...)

// From configuration
logger := balogan.NewFromConfig(&balogan.BaloganConfig{...})
Log Levels (in order)
balogan.TraceLevel   // -1 (most verbose)
balogan.DebugLevel   //  0
balogan.InfoLevel    //  1  
balogan.WarningLevel //  2
balogan.ErrorLevel   //  3
balogan.FatalLevel   //  4 (calls os.Exit(1))
balogan.PanicLevel   //  5 (calls panic())
Logging Methods
logger.Trace("message")   logger.Tracef("format", args...)
logger.Debug("message")   logger.Debugf("format", args...)
logger.Info("message")    logger.Infof("format", args...)
logger.Warning("message") logger.Warningf("format", args...)
logger.Error("message")   logger.Errorf("format", args...)
logger.Fatal("message")   logger.Fatalf("format", args...)
logger.Panic("message")   logger.Panicf("format", args...)
Structured Logging
// Single field
logger.WithField("key", "value")

// Multiple fields
logger.WithFields(balogan.Fields{"key1": "value1", "key2": "value2"})

// Format switching
logger.WithJSON()              // {"key":"value"}
logger.WithLogfmt()            // key=value or key="value with spaces"
logger.WithKeyValue()          // key=value (default)
logger.WithKeyValueSeparator(" | ") // key=value | key2=value2

// Formatter methods (long form)
logger.WithFieldsFormatter(&balogan.JSONFormatter{})
logger.WithFieldsFormatter(&balogan.LogfmtFormatter{})
logger.WithFieldsFormatter(&balogan.KeyValueFormatter{Separator: " | "})
Prefixes
balogan.WithTimeStamp()           // RFC3339 timestamp
balogan.WithTag("tag")            // Custom tag
balogan.WithLogLevel(level)       // Log level in output

// Custom prefix
func WithCustom() balogan.PrefixBuilderFunc {
    return func(args ...any) string { return "custom" }
}
Conditional Logging
// Basic conditions
logger.When(condition)                 // Apply condition
logger.WithLevelCondition(condition)   // Level-based condition
logger.WithContextCondition(condition) // Context-based condition

// Predefined conditions
balogan.InProduction                   // Environment conditions
balogan.InDevelopment
balogan.DebugEnabled                   // Debug conditions
balogan.VerboseMode
balogan.WorkingHours                   // Time conditions
balogan.Weekend
balogan.Weekday

// Condition builders
balogan.Always()                       // Always true
balogan.Never()                        // Always false
balogan.EnvEquals(key, value)          // Environment variable
balogan.EnvExists(key)
balogan.RandomSample(percentage)       // Sampling
balogan.SampleEveryN(n)
balogan.CountBased(max)                // Limiting
balogan.RateLimit(perSecond)
balogan.TimeRange(start, end)          // Time range
balogan.HasField(name)                 // Field conditions
balogan.FieldEquals(name, value)
balogan.HasContextValue(key)           // Context conditions
balogan.ContextValueEquals(key, value)
balogan.OnlyLevel(level)               // Level conditions
balogan.MinLevel(level)

// Combinators
balogan.And(conditions...)             // Logical AND
balogan.Or(conditions...)              // Logical OR
balogan.Not(condition)                 // Logical NOT
balogan.Any(conditions...)             // Alias for Or
balogan.All(conditions...)             // Alias for And
Temporary Extensions
logger.WithTemporaryPrefix(prefix...)  // Add prefixes
logger.WithContext(ctx)                // Put in context
balogan.FromContext(ctx)               // Get from context

balogan - Simple, powerful, and extensible logging for Go! πŸš€

Documentation ΒΆ

Index ΒΆ

Constants ΒΆ

This section is empty.

Variables ΒΆ

View Source
var (

	// InProduction evaluates to true when ENV environment variable equals "production"
	InProduction = func() bool { return os.Getenv("ENV") == "production" }

	// InDevelopment evaluates to true when ENV environment variable equals "development"
	InDevelopment = func() bool { return os.Getenv("ENV") == "development" }

	// InTesting evaluates to true when ENV environment variable equals "test"
	InTesting = func() bool { return os.Getenv("ENV") == "test" }

	// InStaging evaluates to true when ENV environment variable equals "staging"
	InStaging = func() bool { return os.Getenv("ENV") == "staging" }

	// DebugEnabled evaluates to true when DEBUG environment variable equals "true"
	DebugEnabled = func() bool { return os.Getenv("DEBUG") == "true" }

	// VerboseMode evaluates to true when VERBOSE environment variable equals "true"
	VerboseMode = func() bool { return os.Getenv("VERBOSE") == "true" }

	// WorkingHours evaluates to true during business hours (9 AM to 5 PM)
	WorkingHours = func() bool {
		hour := time.Now().Hour()
		return hour >= 9 && hour <= 17
	}

	// Weekend evaluates to true on Saturday and Sunday
	Weekend = func() bool {
		day := time.Now().Weekday()
		return day == time.Saturday || day == time.Sunday
	}

	// Weekday evaluates to true on Monday through Friday (opposite of Weekend)
	Weekday = func() bool { return !Weekend() }
)

Predefined conditions for common logging scenarios. These conditions can be used directly without additional configuration.

View Source
var DefaultWriter = NewStdOutLogWriter()

Functions ΒΆ

This section is empty.

Types ΒΆ

type BaloganConfig ΒΆ

type BaloganConfig struct {
	Level    LogLevel
	Writers  []LogWriter
	Prefixes []PrefixBuilderFunc

	Concurrency bool

	// Structured logging configuration
	Fields          Fields
	FieldsFormatter FieldsFormatter
}

type Condition ΒΆ

type Condition func() bool

Condition represents a function that determines whether logging should occur. It takes no parameters and returns a boolean indicating if the log message should be processed. This is the most basic type of condition used for simple true/false logic.

Example usage:

condition := func() bool { return os.Getenv("DEBUG") == "true" }
logger.When(condition).Debug("Conditional debug message")

func All ΒΆ

func All(conditions ...Condition) Condition

All returns a condition that evaluates to true only when all provided conditions are true. This is an alias for And() provided for better readability in some contexts.

Parameters:

conditions: Variable number of conditions that must all be true.

Example:

logger.When(All(InProduction, HasField("user_id"))).Info("Production user action")

func Always ΒΆ

func Always() Condition

Always returns a condition that always evaluates to true. This condition will allow all log messages to pass through.

Example:

logger.When(Always()).Info("This will always log")

func And ΒΆ

func And(conditions ...Condition) Condition

And returns a condition that evaluates to true only when all provided conditions are true. The condition uses short-circuit evaluation, stopping at the first false condition.

Parameters:

conditions: Variable number of conditions that must all be true.

Example:

logger.When(And(InDevelopment, DebugEnabled, WorkingHours)).Debug("Complex condition")

func Any ΒΆ

func Any(conditions ...Condition) Condition

Any returns a condition that evaluates to true when at least one of the provided conditions is true. This is an alias for Or() provided for better readability in some contexts.

Parameters:

conditions: Variable number of conditions where at least one must be true.

Example:

logger.When(Any(Weekend, After(18))).Info("Leisure time logging")

func CountBased ΒΆ

func CountBased(maxCount int) Condition

CountBased returns a condition that allows only a specific number of log messages total. Once the maximum count is reached, the condition will always return false. This is useful for limiting debug output to a specific number of occurrences.

Parameters:

maxCount: Maximum total number of log messages to allow.

Example:

logger.When(CountBased(5)).Debug("This will only log 5 times total")

Note: This condition is thread-safe and maintains state across multiple calls.

func EnvEquals ΒΆ

func EnvEquals(key, value string) Condition

EnvEquals returns a condition that checks if an environment variable equals a specific value. The condition evaluates to true only when the environment variable matches the expected value.

Parameters:

key: The name of the environment variable to check.
value: The expected value of the environment variable.

Example:

logger.When(EnvEquals("LOG_LEVEL", "debug")).Debug("Debug message")

func EnvExists ΒΆ

func EnvExists(key string) Condition

EnvExists returns a condition that checks if an environment variable is set. The condition evaluates to true when the environment variable exists, regardless of its value.

Parameters:

key: The name of the environment variable to check for existence.

Example:

logger.When(EnvExists("DEBUG")).Info("Debug mode is enabled")

func Never ΒΆ

func Never() Condition

Never returns a condition that always evaluates to false. This condition will block all log messages from being written.

Example:

logger.When(Never()).Info("This will never log")

func Not ΒΆ

func Not(condition Condition) Condition

Not returns a condition that inverts the result of the provided condition. The condition evaluates to true when the provided condition is false, and vice versa.

Parameters:

condition: The condition to invert.

Example:

logger.When(Not(InProduction)).Debug("Debug in non-production environments")

func Or ΒΆ

func Or(conditions ...Condition) Condition

Or returns a condition that evaluates to true when at least one of the provided conditions is true. The condition uses short-circuit evaluation, stopping at the first true condition.

Parameters:

conditions: Variable number of conditions where at least one must be true.

Example:

logger.When(Or(InDevelopment, InTesting, DebugEnabled)).Debug("Debug in dev, test, or debug mode")

func RandomSample ΒΆ

func RandomSample(percentage int) Condition

RandomSample returns a condition that randomly samples log messages based on percentage. The condition uses pseudo-random sampling based on current time to determine if logging should occur.

Parameters:

percentage: The percentage (0-100) of messages that should be logged.
            Values <= 0 will never log, values >= 100 will always log.

Example:

logger.When(RandomSample(10)).Debug("Only 10% of these will be logged")

func RateLimit ΒΆ

func RateLimit(maxPerSecond int) Condition

RateLimit creates a condition that limits the number of log messages per second. The condition maintains internal state to track message count and resets every second. This is useful for preventing log spam in high-frequency scenarios.

Parameters:

maxPerSecond: Maximum number of log messages allowed per second.
              Values <= 0 will never allow logging.

Example:

logger.When(RateLimit(10)).Error("Rate limited error message")

Note: This condition is thread-safe and can be used across multiple goroutines.

func SampleEveryN ΒΆ

func SampleEveryN(n int) Condition

SampleEveryN returns a condition that allows every Nth log message to pass through. This provides deterministic sampling with better distribution than random sampling. The first message is always logged, then every Nth message after that.

Parameters:

n: The sampling interval. Every Nth message will be logged.
   Values <= 1 will allow all messages (same as Always()).

Example:

logger.When(SampleEveryN(10)).Debug("Every 10th debug message will be logged")

Note: This condition is thread-safe and maintains internal counter state.

func TimeRange ΒΆ

func TimeRange(startHour, endHour int) Condition

TimeRange creates a condition that allows logging only during specified time range. The condition evaluates the current hour and checks if it falls within the specified range. Supports both same-day ranges (9-17) and overnight ranges (22-6).

Parameters:

startHour: The starting hour (0-23) of the allowed time range.
endHour: The ending hour (0-23) of the allowed time range.

Example:

logger.When(TimeRange(9, 17)).Info("Business hours only")
logger.When(TimeRange(22, 6)).Error("Night shift logging")

type ContextCondition ΒΆ

type ContextCondition func(context.Context) bool

ContextCondition represents a function that determines whether logging should occur based on context. It receives a context.Context parameter and returns a boolean indicating if logging should proceed. This is useful for conditions that depend on request-specific or goroutine-local data.

Example usage:

condition := func(ctx context.Context) bool {
	return ctx.Value("user_role") == "admin"
}
logger.WithContextCondition(condition).Info("Admin-only message")

func ContextValueEquals ΒΆ

func ContextValueEquals(key interface{}, expectedValue interface{}) ContextCondition

ContextValueEquals returns a context condition that checks if a context value equals an expected value. The condition evaluates to true when the context contains the key and its value matches the expected value.

Parameters:

key: The context key to check.
expectedValue: The expected value for comparison.

Example:

logger.WithContextCondition(ContextValueEquals("user_role", "admin")).Info("Admin action")

func HasContextValue ΒΆ

func HasContextValue(key interface{}) ContextCondition

HasContextValue returns a context condition that checks if a specific key exists in the context. The condition evaluates to true when the context contains the specified key with any non-nil value.

Parameters:

key: The context key to check for existence.

Example:

logger.WithContextCondition(HasContextValue("request_id")).Info("Request logged")

type DefaultErrorHandler ΒΆ

type DefaultErrorHandler struct{}

func (*DefaultErrorHandler) Handle ΒΆ

func (h *DefaultErrorHandler) Handle(error)

type ErrorHandler ΒΆ

type ErrorHandler interface {
	Handle(err error)
}

type Fields ΒΆ

type Fields map[string]interface{}

Fields represents a map of key-value pairs for structured logging.

func (Fields) Copy ΒΆ

func (f Fields) Copy() Fields

Copy creates a deep copy of the fields.

func (Fields) With ΒΆ

func (f Fields) With(key string, value interface{}) Fields

With returns a new Fields with the given key-value pair added.

func (Fields) WithFields ΒΆ

func (f Fields) WithFields(fields Fields) Fields

WithFields returns a new Fields with all given fields merged.

type FieldsFormatter ΒΆ

type FieldsFormatter interface {
	Format(fields Fields) string
}

FieldsFormatter defines how fields should be formatted in log output.

var DefaultFieldsFormatter FieldsFormatter = &KeyValueFormatter{}

DefaultFieldsFormatter is the default formatter for fields.

type FileLogWriter ΒΆ

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

FileLogWriter writes log messages to a file.

func NewFileLogWriter ΒΆ

func NewFileLogWriter(filename string) (*FileLogWriter, error)

NewFileLogWriter creates a new FileLogWriter.

func (*FileLogWriter) Close ΒΆ

func (w *FileLogWriter) Close() error

func (*FileLogWriter) Write ΒΆ

func (w *FileLogWriter) Write(bytes []byte) (int, error)

type JSONFormatter ΒΆ

type JSONFormatter struct{}

JSONFormatter formats fields as JSON.

func (*JSONFormatter) Format ΒΆ

func (f *JSONFormatter) Format(fields Fields) string

type KeyValueFormatter ΒΆ

type KeyValueFormatter struct {
	Separator string
}

KeyValueFormatter formats fields as key=value pairs.

func (*KeyValueFormatter) Format ΒΆ

func (f *KeyValueFormatter) Format(fields Fields) string

type LevelCondition ΒΆ

type LevelCondition func(LogLevel, Fields) bool

LevelCondition represents a function that determines whether logging should occur based on log level and fields. It receives the log level and the current logger fields, returning a boolean for conditional logic. This is useful for complex conditions that depend on both the severity and the structured data.

Example usage:

condition := func(level LogLevel, fields Fields) bool {
	return level >= ErrorLevel && fields["service"] == "payment"
}
logger.WithLevelCondition(condition).Error("Payment service error")

func FieldEquals ΒΆ

func FieldEquals(fieldName string, expectedValue interface{}) LevelCondition

FieldEquals returns a level condition that checks if a field equals a specific value. The condition evaluates to true when the field exists and its value matches the expected value.

Parameters:

fieldName: The name of the field to check.
expectedValue: The expected value for comparison.

Example:

logger.WithLevelCondition(FieldEquals("environment", "production")).
	WithField("environment", "production").Info("Production log")

func HasField ΒΆ

func HasField(fieldName string) LevelCondition

HasField returns a level condition that checks if a specific field exists in the log fields. The condition evaluates to true when the specified field is present, regardless of its value.

Parameters:

fieldName: The name of the field to check for existence.

Example:

logger.WithLevelCondition(HasField("user_id")).WithField("user_id", 123).Info("User action")

func MinLevel ΒΆ

func MinLevel(minLevel LogLevel) LevelCondition

MinLevel returns a level condition that allows logging for levels at or above the minimum level. The condition evaluates to true when the log level is greater than or equal to the minimum level.

Parameters:

minLevel: The minimum log level to allow.

Example:

logger.WithLevelCondition(MinLevel(WarningLevel)).Info("This won't log")
logger.WithLevelCondition(MinLevel(WarningLevel)).Error("This will log")

func OnlyLevel ΒΆ

func OnlyLevel(targetLevel LogLevel) LevelCondition

OnlyLevel returns a level condition that allows logging only for a specific log level. The condition evaluates to true only when the log level exactly matches the target level.

Parameters:

targetLevel: The specific log level to allow.

Example:

logger.WithLevelCondition(OnlyLevel(ErrorLevel)).Log(ErrorLevel, "Only errors")

type LogLevel ΒΆ

type LogLevel int
const (
	TraceLevel LogLevel = iota - 1
	DebugLevel
	InfoLevel
	WarningLevel
	ErrorLevel
	FatalLevel
	PanicLevel
)

func (LogLevel) Exit ΒΆ

func (level LogLevel) Exit()

Exit terminates the program with exit code 1. Used internally by Fatal level logging.

func (LogLevel) IsEnabled ΒΆ

func (level LogLevel) IsEnabled(minLevel LogLevel) bool

IsEnabled checks if the given level should be logged based on the minimum level.

func (LogLevel) Panic ΒΆ

func (level LogLevel) Panic(message string)

Panic causes a panic with the given message. Used internally by Panic level logging.

func (LogLevel) ShouldExit ΒΆ

func (level LogLevel) ShouldExit() bool

ShouldExit returns true if the log level should cause the program to exit.

func (LogLevel) ShouldPanic ΒΆ

func (level LogLevel) ShouldPanic() bool

ShouldPanic returns true if the log level should cause a panic.

func (LogLevel) String ΒΆ

func (level LogLevel) String() string

type LogWriter ΒΆ

type LogWriter interface {
	io.Writer
	io.Closer
}

LogWriter interface. All Balogan writers have to implements this interface.

type LogfmtFormatter ΒΆ

type LogfmtFormatter struct{}

LogfmtFormatter formats fields in logfmt style (key=value with proper escaping).

func (*LogfmtFormatter) Format ΒΆ

func (f *LogfmtFormatter) Format(fields Fields) string

type Logger ΒΆ

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

func FromContext ΒΆ

func FromContext(ctx context.Context) (*Logger, bool)

func New ΒΆ

func New(level LogLevel, writer LogWriter, prefixes ...PrefixBuilderFunc) *Logger

The simpliest way to create new Balogan Logger instance.

If writers accept nil, the StdOutLogWriter will be used as a default value.

Balogan does not provide prefixes which will be used as a default value.

func NewFromConfig ΒΆ

func NewFromConfig(cfg *BaloganConfig) *Logger

func (*Logger) Close ΒΆ

func (l *Logger) Close() error

Close closes all writers associated with the logger. It ensures that all log messages are flushed and resources are released.

If you use some Writer except StdOutLogWriter we highly recommend to call this method.

Returns:

An error if any of the writers fail to close.

func (*Logger) Debug ΒΆ

func (l *Logger) Debug(args ...interface{})

Debug logs a message at the DEBUG level. It calls the general Log method with the DEBUG level.

Parameters:

args: The arguments to be logged.

func (*Logger) Debugf ΒΆ

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

Debugf logs a formatted message at the DEBUG level. It calls the general Logf method with the DEBUG level.

Parameters:

format: The format string for the message.
args: The arguments for the format string.

func (*Logger) Error ΒΆ

func (l *Logger) Error(args ...interface{})

Error logs a message at the ERROR level. It calls the general Log method with the ERROR level.

Parameters:

args: The arguments to be logged.

func (*Logger) Errorf ΒΆ

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

Errorf logs a formatted message at the ERROR level. It calls the general Logf method with the ERROR level.

Parameters:

format: The format string for the message.
args: The arguments for the format string.

func (*Logger) Fatal ΒΆ

func (l *Logger) Fatal(args ...interface{})

Fatal logs a message at the FATAL level and then exits the program. It calls the general Log method with the FATAL level, then calls os.Exit(1).

Parameters:

args: The arguments to be logged.

func (*Logger) Fatalf ΒΆ

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

Fatalf logs a formatted message at the FATAL level and then exits the program. It calls the general Logf method with the FATAL level, then calls os.Exit(1).

Parameters:

format: The format string for the message.
args: The arguments for the format string.

func (*Logger) GetFields ΒΆ

func (l *Logger) GetFields() Fields

GetFields returns a copy of the current fields.

func (*Logger) Info ΒΆ

func (l *Logger) Info(args ...interface{})

Info logs a message at the INFO level. It calls the general Log method with the INFO level. Parameters:

args: The arguments to be logged.

func (*Logger) Infof ΒΆ

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

Infof logs a formatted message at the INFO level. It calls the general Logf method with the INFO level.

Parameters:

format: The format string for the message.
args: The arguments for the format string.

func (*Logger) Log ΒΆ

func (l *Logger) Log(level LogLevel, args ...interface{})

Log logs a message at the specified level. It checks if the log level is enabled, then writes the message with provided prefixes.

Parameters:

level: The log level of the message.
args: The arguments to be converted to a string message.

func (*Logger) Logf ΒΆ

func (l *Logger) Logf(level LogLevel, format string, args ...interface{})

Logf logs a formatted message at the specified level. It checks if the log level is enabled, then writes the message with provided prefixes.

Parameters:

level: The log level of the message.
format: The format string for the message.
args: The arguments for the format string.

func (*Logger) Panic ΒΆ

func (l *Logger) Panic(args ...interface{})

Panic logs a message at the PANIC level and then panics. It calls the general Log method with the PANIC level, then calls panic().

Parameters:

args: The arguments to be logged.

func (*Logger) Panicf ΒΆ

func (l *Logger) Panicf(format string, args ...interface{})

Panicf logs a formatted message at the PANIC level and then panics. It calls the general Logf method with the PANIC level, then calls panic().

Parameters:

format: The format string for the message.
args: The arguments for the format string.

func (*Logger) Trace ΒΆ

func (l *Logger) Trace(args ...interface{})

Trace logs a message at the TRACE level. It calls the general Log method with the TRACE level.

Parameters:

args: The arguments to be logged.

func (*Logger) Tracef ΒΆ

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

Tracef logs a formatted message at the TRACE level. It calls the general Logf method with the TRACE level.

Parameters:

format: The format string for the message.
args: The arguments for the format string.

func (*Logger) Warning ΒΆ

func (l *Logger) Warning(args ...interface{})

Warning logs a message at the WARNING level. It calls the general Log method with the WARNING level.

Parameters:

args: The arguments to be logged.

func (*Logger) Warningf ΒΆ

func (l *Logger) Warningf(format string, args ...interface{})

Warningf logs a formatted message at the WARNING level. It calls the general Logf method with the WARNING level.

Parameters:

format: The format string for the message.
args: The arguments for the format string.

func (*Logger) When ΒΆ added in v1.1.1

func (l *Logger) When(condition Condition) *Logger

When returns a new Logger instance that only logs when the condition is true. This is the main method for applying conditional logging.

Parameters:

condition: The condition that determines whether logging should occur.

Example:

logger.When(InDevelopment).Debug("This only logs in development")

func (*Logger) WithContext ΒΆ

func (l *Logger) WithContext(ctx context.Context) context.Context

func (*Logger) WithContextCondition ΒΆ added in v1.1.1

func (l *Logger) WithContextCondition(condition ContextCondition) *Logger

WithContextCondition returns a new Logger instance with a context-based condition. The condition receives the context for evaluation.

Parameters:

condition: The context condition that determines whether logging should occur.

Example:

logger.WithContextCondition(HasContextValue("user_id")).Info("User action")

func (*Logger) WithField ΒΆ

func (l *Logger) WithField(key string, value interface{}) *Logger

WithField returns a new Logger instance with the specified field added. The new logger inherits all configuration from the current logger.

Parameters:

key: The field key.
value: The field value.

func (*Logger) WithFields ΒΆ

func (l *Logger) WithFields(fields Fields) *Logger

WithFields returns a new Logger instance with the specified fields added. The new logger inherits all configuration from the current logger.

Parameters:

fields: A map of field key-value pairs to add.

func (*Logger) WithFieldsFormatter ΒΆ

func (l *Logger) WithFieldsFormatter(formatter FieldsFormatter) *Logger

WithFieldsFormatter returns a new Logger instance with the specified fields formatter. This allows changing how fields are formatted in log output.

Parameters:

formatter: The FieldsFormatter to use for formatting fields.

func (*Logger) WithJSON ΒΆ

func (l *Logger) WithJSON() *Logger

WithJSON returns a new Logger instance configured to format fields as JSON. This is a convenient shortcut for WithFieldsFormatter(&JSONFormatter{}).

Example:

logger.WithJSON().WithField("user", "john").Info("User logged in")
// Output: INFO {"user":"john"} User logged in

func (*Logger) WithKeyValue ΒΆ

func (l *Logger) WithKeyValue() *Logger

WithKeyValue returns a new Logger instance configured to format fields as key=value pairs. This is a convenient shortcut for WithFieldsFormatter(&KeyValueFormatter{}). This is the default format, so this method is mainly useful for explicitly switching back from another format.

Example:

logger.WithKeyValue().WithField("user", "john").Info("User logged in")
// Output: INFO user=john User logged in

func (*Logger) WithKeyValueSeparator ΒΆ

func (l *Logger) WithKeyValueSeparator(separator string) *Logger

WithKeyValueSeparator returns a new Logger instance configured to format fields as key=value pairs with a custom separator between pairs.

Parameters:

separator: The separator to use between key=value pairs.

Example:

logger.WithKeyValueSeparator(" | ").WithFields(Fields{"a": 1, "b": 2}).Info("Test")
// Output: INFO a=1 | b=2 Test

func (*Logger) WithLevelCondition ΒΆ added in v1.1.1

func (l *Logger) WithLevelCondition(condition LevelCondition) *Logger

WithLevelCondition returns a new Logger instance with a level-based condition. The condition receives the log level and fields for evaluation.

Parameters:

condition: The level condition that determines whether logging should occur.

Example:

logger.WithLevelCondition(OnlyLevel(ErrorLevel)).Error("Only error level")

func (*Logger) WithLogfmt ΒΆ

func (l *Logger) WithLogfmt() *Logger

WithLogfmt returns a new Logger instance configured to format fields in logfmt style. This is a convenient shortcut for WithFieldsFormatter(&LogfmtFormatter{}).

Example:

logger.WithLogfmt().WithField("user", "john doe").Info("User logged in")
// Output: INFO user="john doe" User logged in

func (*Logger) WithTemporaryPrefix ΒΆ

func (l *Logger) WithTemporaryPrefix(builder ...PrefixBuilderFunc) *Logger

Creates new Balogan Logger instance ith previous conifg except prefixes. Accept additional prefixes which will be added to the end of prefix part of log message.

Provided prefixes DO NOT APPLY for Balogan Logger instance from which the method was called.

type PrefixBuilderFunc ΒΆ

type PrefixBuilderFunc func(args ...any) string

func WithFields ΒΆ

func WithFields(fields Fields) PrefixBuilderFunc

WithFields returns a PrefixBuilderFunc that formats the given fields.

func WithFieldsFormatter ΒΆ

func WithFieldsFormatter(fields Fields, formatter FieldsFormatter) PrefixBuilderFunc

WithFieldsFormatter returns a PrefixBuilderFunc that formats fields using the specified formatter.

func WithJSONFields ΒΆ

func WithJSONFields(fields Fields) PrefixBuilderFunc

WithJSONFields returns a PrefixBuilderFunc that formats fields as JSON.

func WithLogLevel ΒΆ

func WithLogLevel(level LogLevel) PrefixBuilderFunc

func WithLogfmtFields ΒΆ

func WithLogfmtFields(fields Fields) PrefixBuilderFunc

WithLogfmtFields returns a PrefixBuilderFunc that formats fields in logfmt style.

func WithTag ΒΆ

func WithTag(tag string) PrefixBuilderFunc

func WithTimeStamp ΒΆ

func WithTimeStamp() PrefixBuilderFunc

type StdOutLogWriter ΒΆ

type StdOutLogWriter struct{}

func NewStdOutLogWriter ΒΆ

func NewStdOutLogWriter() *StdOutLogWriter

func (*StdOutLogWriter) Close ΒΆ

func (w *StdOutLogWriter) Close() error

func (*StdOutLogWriter) Write ΒΆ

func (w *StdOutLogWriter) Write(bytes []byte) (int, error)

Jump to

Keyboard shortcuts

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