blog

package
v2.0.1 Latest Latest
Warning

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

Go to latest
Published: Nov 6, 2024 License: MIT Imports: 12 Imported by: 0

Documentation

Overview

Package blog is a simple async logger with file rotation and console logging.

Usage:

// Init blog.
//
// Parameters:
//   - DirPath: Path for log files. "." for current working directory or "" to disable file logging.
//   - Level: Desired logging level for filtering messages.
//   - IncludeLocation: When true, adds source file and line number to log messages (e.g., "main.go:42").
//   - EnableConsole: When true, enables logging to the console in addition to files.
//
if err := blog.Init("logs", blog.INFO, false, true); err != nil {
	log.Printf("Error initializing logger: %v", err)
}

// Log messages from anywhere in the program
blog.Info("This is an info message.")

// Log messages with formatting
blog.Warnf("This is an warn message with a format string: %v", err)

// Synchronously cleanup the logger with a timeout; 0 means block indefinitely.
// This should be called at the end of the program.
blog.Cleanup(0)

// for all other functions see `blog.go`. For access to the raw logger, see `logger.go`.

Performance Notes

Defaults; All of these are modifiable at runtime via the public functions:

  • Max buffer size: 4 KB.
  • Max log file size: 1 GB. When this is reached the file is rotated.
  • Flush interval: 15 seconds. For automatic flushing in low traffic scenarios.

A single thread is used to handle all logging operations. The channel that feeds it messages is buffered to 255 in the instance managed by the public functions. If you need control over it, you can create your own instance of the raw logger. Note interfacing with the raw logger is is different from the simplified public functions.

For contributors

The approach is pretty straightforward. There is a slightly lower abstraction level logger in logger.go. This file creates and manages an instance of it for the common use case of a high abstraction singleton logger.

The logger is a struct with a few channels for communication and vars for configuration. When created it starts a goroutine that listens for messages/config updates via the chans then handles them. The logger's public functions don't interact with it's state directly, they do so through the channels. This makes it thread-safe and more performant, as relying on go's event system is better than mutexes in this case.

This has some nice benefits:

  • Easily test multiple logger instances in parallel.
  • Users don't need to manage the logger instance themselves.

Index

Constants

View Source
const (
	MaxBufferSizeBytes  = 4096               // 4 KB
	MaxLogFileSizeBytes = 1024 * 1024 * 1024 // 1 GB
	FlushInterval       = 15 * time.Second
)

Defaults for configuration settings.

Variables

View Source
var (
	ErrAlreadyInitialized = fmt.Errorf("blog: already initialized")
	ErrInvalidLogLevel    = fmt.Errorf("blog: invalid log level")
	ErrUninitialized      = fmt.Errorf("blog: uninitialized")
	ErrShutdown           = fmt.Errorf("blog: logger has been shut down")
	ErrInvalidPath        = fmt.Errorf("blog: invalid path")
)

Functions

func Cleanup

func Cleanup(timeout time.Duration) error

Cleanup flushes the log write buffer and exits the logger. If timeout is 0, Cleanup blocks indefinitely.

func CopyNotNil

func CopyNotNil[T any](dst, src *T)

CopyNotNil copies the value of src to dst if src is not nil.

func Debug

func Debug(msg string) error

func Debugf

func Debugf(format string, args ...any) error

func Error

func Error(msg string) error

func Errorf

func Errorf(format string, args ...any) error

func Fatal

func Fatal(exitCode int, timeout time.Duration, msg string) error

Fatal logs a fatal message and exits with the given exit code. This function will not return, it will exit the program after attempting to log the message.

func Fatalf

func Fatalf(exitCode int, timeout time.Duration, format string, args ...any) error

Fatalf logs a fatal message with a format string and exits with the given exit code. This function will not return, it will exit the program after attempting to log the message.

func Flush

func Flush() error

Flush manually flushes the log write buffer.

func GenRandomString

func GenRandomString(size int) (string, error)

func Info

func Info(msg string) error

func Infof

func Infof(format string, args ...any) error

func Init

func Init(
	DirPath string,
	Level LogLevel,
	IncludeLocation bool,
	EnableConsole bool,
) error

Init sets up the logger with the specified configuration parameters.

Parameters:

  • DirPath: Directory path for log files. Use "." for current working directory or "" to disable file logging.
  • Level: Desired logging level for filtering messages.
  • IncludeLocation: When true, adds source file and line number to log messages (e.g., "main.go:42").
  • EnableConsole: When true, enables logging to the console in addition to files.

Returns:

  • ErrAlreadyInitialized if logger was previously initialized,
  • ErrInvalidPath if the directory path is invalid for any reason,

func PadString

func PadString(s string, length int) string

func SetConsole

func SetConsole(enable bool) error

SetConsole enables or disables console logging.

func SetDirectoryPath

func SetDirectoryPath(path string) error

SetDirectoryPath sets the directory path for the log files. To disable file logging, use an empty string.

func SetFlushInterval

func SetFlushInterval(d time.Duration) error

SetFlushInterval sets the interval at which the log write buffer is automatically flushed to the log file. This happens regardless of the buffer size. A value of 0 disables automatic flushing.

func SetLevel

func SetLevel(level LogLevel) error

SetLevel sets the log level.

func SetMaxBufferSizeBytes

func SetMaxBufferSizeBytes(size int) error

SetMaxBufferSizeBytes sets the maximum size of the log write buffer. Larger values will increase memory usage and reduce the frequency of disk writes.

func SetMaxFileSizeBytes

func SetMaxFileSizeBytes(size int) error

SetMaxFileSizeBytes sets the maximum size of the log file. When the log file reaches this size, it is renamed to the current timestamp and a new log file is created.

func SyncFlush

func SyncFlush(timeout time.Duration) error

SyncFlush synchronously flushes the log write buffer and blocks until the flush is complete or the timeout is reached. If timeout is 0, SyncFlush blocks indefinitely.

func Ternary

func Ternary[T any](condition bool, a, b T) T

func Warn

func Warn(msg string) error

func Warnf

func Warnf(format string, args ...any) error

Types

type Config

type Config struct {
	Level              *LogLevel      // the minimum log level to write. Default is INFO.
	MaxBufferSizeBytes *int           // the maximum size of the write buffer before it is flushed. Default is 4 KB.
	MaxFileSizeBytes   *int           // the maximum size of the log file before it is rotated. Default is 1 GB.
	FlushInterval      *time.Duration // the interval at which the write buffer is flushed. Default is 15 seconds.
	DirectoryPath      *string        // the directory path where the log file is stored. Default is the current working directory ("."). To disable file logging, set this to an empty string.
	ConsoleOut         *ConsoleLogger // the logger to write to the console. Default is ConsoleLogger{l: nil}. When l is nil, console logging is disabled. This is configurable for easy testing.
}

Config holds the configuration settings for the Logger.

type ConsoleLogger

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

ConsoleLogger wraps *log.Logger to allow nil value semantics for disabled state

type LogLevel

type LogLevel int
const (
	NONE LogLevel = iota
	ERROR
	WARN
	INFO
	DEBUG
	FATAL
)

func (*LogLevel) FromString

func (l *LogLevel) FromString(levelStr string) error

FromString sets a LogLevel from a string, returning ErrInvalidLogLevel if the string is invalid. Case-insensitive. Example: "ERROR" -> ERROR, "error" -> ERROR, "Error" -> ERROR, etc.

func (*LogLevel) String

func (l *LogLevel) String() string

String returns the string representation of a LogLevel.

type LogMessage

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

LogMessage represents a single log message.

type Logger

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

Logger is a simple, thread-safe logger. It supports various log levels, file and or console logging, basic performance tuning, automatic flushing, and size based log rotation.

func NewLogger

func NewLogger(cfg Config, msgChanSize int, LocationSkip int) (*Logger, error)

NewLogger creates a new Logger instance with the provided configuration. It initializes all channels and starts the background logging goroutine.

The msgChanSize parameter controls the buffer size of the message channel, where 0 means unbuffered. LocationSkip controls the number of stack frames to skip when including the location in log messages (-1 to disable). For normal usage, LocationSkip should be set to 2.

Returns an error if the log directory path cannot be set.

func (*Logger) Debug

func (l *Logger) Debug(msg string)

func (*Logger) Debugf

func (l *Logger) Debugf(format string, args ...any)

func (*Logger) Error

func (l *Logger) Error(msg string)

func (*Logger) Errorf

func (l *Logger) Errorf(format string, args ...any)

func (*Logger) Fatal

func (l *Logger) Fatal(exitCode int, timeout time.Duration, msg string)

Fatal attempts to log a message and exits the program. It exits with the given exit code either when the message is logged or the timeout duration is reached. A timeout of 0 means block indefinitely.

func (*Logger) Fatalf

func (l *Logger) Fatalf(exitCode int, timeout time.Duration, format string, args ...any)

Fatalf is a convenience function that calls Fatal with a format string.

func (*Logger) Flush

func (l *Logger) Flush()

Flush asynchronously flushes the log write buffer.

func (*Logger) GetConfigCopy

func (l *Logger) GetConfigCopy() Config

GetConfigCopy returns a copy of the current logger configuration.

func (*Logger) Info

func (l *Logger) Info(msg string)

func (*Logger) Infof

func (l *Logger) Infof(format string, args ...any)

func (*Logger) Shutdown

func (l *Logger) Shutdown(timeout time.Duration) error

Shutdown synchronously flushes and waits for the logger to shutdown it's goroutine for the given timeout duration. A timeout of 0 means block indefinitely. You may want to time.Sleep(20 * time.Millisecond) before calling this function to ensure all log messages are buffered.

func (*Logger) Start

func (l *Logger) Start()

Start restarts the logger goroutine after a shutdown.

func (*Logger) SyncFlush

func (l *Logger) SyncFlush(timeout time.Duration)

SyncFlush synchronously flushes the log write buffer with the given timeout duration. A timeout of 0 means block indefinitely.

func (*Logger) UpdateConfig

func (l *Logger) UpdateConfig(cfg Config)

UpdateConfig updates the logger configuration with the provided settings. Nil fields are ignored.

func (*Logger) Warn

func (l *Logger) Warn(msg string)

func (*Logger) Warnf

func (l *Logger) Warnf(format string, args ...any)

Jump to

Keyboard shortcuts

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