Documentation
¶
Overview ¶
Package it provides utility functions for error handling and logging, simplifying common patterns while adhering to Go's best practices.
This package includes functions that help manage errors by panicking on unrecoverable errors, logging errors while continuing execution, and other utilities for robust error handling.
Example usage:
import "github.com/theHamdiz/it"
func main() {
hardResult := it.Must(SomeFunction())
softResult := it.Should(SomeFunction())
fmt.Println(hardResult)
fmt.Println(softResult)
}
Index ¶
- Constants
- func Attempt(err error)
- func Audit(message string)
- func CheckError(err error)
- func CheckErrorf(err error, format string, args ...interface{})
- func Debug(message string)
- func Debugf(format string, args ...interface{})
- func DeferWithLog(message string) func()
- func Ensure(err error)
- func Error(message string)
- func Errorf(format string, args ...interface{})
- func GracefulRestart(ctx context.Context, server interface{ ... }, timeout time.Duration, ...)
- func GracefulShutdown(ctx context.Context, server interface{ ... }, timeout time.Duration, ...)
- func Info(message string)
- func Infof(format string, args ...interface{})
- func InitFromEnv()
- func LogError(err error)
- func LogErrorWithStack(err error)
- func LogOnce(message string)
- func LogStackTrace()
- func Must[T any](x T, err error) T
- func RateLimiter(rate time.Duration, fn interface{}) interface{}
- func RecoverPanicAndContinue()
- func RecoverPanicAndExit()
- func Retry(attempts int, delay time.Duration, fn func() error) error
- func RetryExponential(attempts int, initialDelay time.Duration, fn func() error) error
- func RetryExponentialWithContext(ctx context.Context, attempts int, initialDelay time.Duration, fn func() error) error
- func RetryWithContext(ctx context.Context, attempts int, delay time.Duration, fn func() error) error
- func SetLogLevel(level int)
- func SetLogOutput(output *os.File)
- func Should[T any](x T, err error) T
- func StructuredDebug(message string, data interface{})
- func StructuredError(message string, data interface{})
- func StructuredInfo(message string, data any)
- func StructuredLog(level string, message string, data any)
- func StructuredWarning(message string, data interface{})
- func TimeBlock(name string) func()
- func TimeFunction(name string, f func())
- func Trace(message string)
- func Tracef(format string, args ...interface{})
- func WaitFor(timeout time.Duration, condition func() bool) bool
- func Warn(message string)
- func Warnf(format string, args ...interface{})
- func WrapError(err error, message string) error
- func WrapErrorWithContext(err error, message string, context map[string]string) error
- func WrapErrorf(err error, format string, args ...interface{}) error
- type BufferedLogger
- type Logger
- type LoggerOption
- type LoggerOptions
- type StructuredLogEntry
Constants ¶
const ( LevelTrace = iota LevelDebug LevelInfo LevelWarning LevelError LevelFatal LevelAudit )
Define log levels
Variables ¶
This section is empty.
Functions ¶
func Attempt ¶
func Attempt(err error)
Attempt logs the error with filename and line number if err is not nil, but allows the program to continue, much like Should but for methods that only return an error.
Example usage:
it.Attempt(SomeErrorOnlyFunction())
func Audit ¶
func Audit(message string)
Audit logs a message with the custom Audit level. Use Audit for logging audit-related information.
Example usage:
it.Audit("User login attempt recorded")
func CheckError ¶
func CheckError(err error)
CheckError logs the error and exits the program if err is not nil. Use CheckError when an error is unrecoverable and the program should terminate.
Example usage:
it.CheckError(err)
func CheckErrorf ¶
CheckErrorf logs a formatted error message and exits the program if err is not nil. Use CheckErrorf when an error is unrecoverable and the program should terminate.
Example usage:
it.CheckErrorf(err, "Failed to start server on port %d", port)
func Debug ¶
func Debug(message string)
Debug logs a debug-level message. Use Debug to log detailed information useful for debugging.
Example usage:
it.Debug("Loaded configuration successfully")
func Debugf ¶
func Debugf(format string, args ...interface{})
Debugf logs a formatted debug-level message. Use Debugf to log detailed formatted information useful for debugging.
Example usage:
it.Debugf("User %s has %d pending messages", username, messageCount)
func DeferWithLog ¶
func DeferWithLog(message string) func()
DeferWithLog defers a function with an optional log message. Useful for managing complex defer chains with logs.
Example usage:
defer it.DeferWithLog("Cleanup complete")()
func Ensure ¶
func Ensure(err error)
Ensure panics if err is not nil. Use Ensure for critical operations where an error is unacceptable, much like Must but for methods that only return error.
Example usage:
it.Ensure(SomeErrorOnlyFunction())
func Error ¶
func Error(message string)
Error logs an error message. Use Error to log errors that occurred during execution.
Example usage:
it.Error("Failed to connect to the database")
func Errorf ¶
func Errorf(format string, args ...interface{})
Errorf logs a formatted error message. Use Errorf to log formatted errors that occurred during execution.
Example usage:
it.Errorf("Failed to connect to the database: %v", err)
func GracefulRestart ¶
func GracefulRestart(ctx context.Context, server interface{ Shutdown(context.Context) error }, timeout time.Duration, done chan<- bool, action func())
GracefulRestart listens for a signal to restart the server gracefully. It can be used with any server that has a Shutdown method.
Example usage:
go it.GracefulRestart(context.Background(), server, 5*time.Second)
GracefulRestart listens for a signal to restart the server gracefully. It attempts to shut down the given server within the specified timeout and then optionally performs an action before signaling completion on the `done` channel, if provided.
Example usage:
it.GracefulRestart(context.Background(), server, 5*time.Second, nil, nil)
Or with a done channel and an action function:
done := make(chan bool)
restartAction := func() { log.Println("Performing custom restart actions...") }
go it.GracefulRestart(context.Background(), server, 5*time.Second, done, restartAction)
<-done
func GracefulShutdown ¶
func GracefulShutdown(ctx context.Context, server interface{ Shutdown(context.Context) error }, timeout time.Duration, done chan<- bool, action func())
GracefulShutdown listens for an interrupt signal (e.g., SIGINT or SIGTERM) and attempts to gracefully shut down the given server within the specified timeout. If an `action` function is provided, it will be executed after shutdown completes. If a `done` channel is provided, it will signal completion on the channel after shutdown and executing the action.
Example usage:
it.GracefulShutdown(context.Background(), server, 5*time.Second, nil, nil)
Or with a done channel and an action function:
done := make(chan bool)
cleanupAction := func() { log.Println("Performing post-shutdown cleanup...") }
go it.GracefulShutdown(context.Background(), server, 5*time.Second, done, cleanupAction)
<-done
func Info ¶
func Info(message string)
Info logs an informational message. Use Info to log general information about the program's execution.
Example usage:
it.Info("Starting the application")
func Infof ¶
func Infof(format string, args ...interface{})
Infof logs a formatted informational message. Use Infof to log formatted information about the program's execution.
Example usage:
it.Infof("Starting the application version %s", version)
func InitFromEnv ¶
func InitFromEnv()
InitFromEnv initializes the logger settings from environment variables. Supported environment variables: - LOG_LEVEL: TRACE, DEBUG, INFO, WARN, ERROR, FATAL - LOG_FILE: Path to a file to write logs to
Example usage:
it.InitFromEnv()
func LogError ¶
func LogError(err error)
LogError logs the error with the filename and line number if err is not nil. Use LogError when you want to log an error but handle it manually.
Example usage:
if err != nil {
it.LogError(err)
// Additional error handling...
}
func LogErrorWithStack ¶
func LogErrorWithStack(err error)
LogErrorWithStack logs an error along with the current stack trace. Use LogErrorWithStack to provide detailed error information.
Example usage:
if err != nil {
it.LogErrorWithStack(err)
}
func LogOnce ¶
func LogOnce(message string)
LogOnce logs a message only once. Useful in scenarios where a repeated log would clutter output.
Example usage:
it.LogOnce("This message will only be logged once")
func LogStackTrace ¶
func LogStackTrace()
LogStackTrace logs the current stack trace. Use LogStackTrace to debug complex issues.
Example usage:
it.LogStackTrace()
func Must ¶
Must returns the value x if err is nil. If err is not nil, Must panics with the error. Use Must when an error is unrecoverable and should halt the program execution.
Example usage:
result := it.Must(SomeFunction())
func RateLimiter ¶
RateLimiter returns a rate-limited version of any handler function. The handler will only be allowed to execute once per specified `rate` interval. It supports handlers with any number of input arguments and return values.
Example usage:
limitedHandler := it.RateLimiter(1*time.Second, handler) result := limitedHandler(arg1, arg2)
func RecoverPanicAndContinue ¶
func RecoverPanicAndContinue()
RecoverPanicAndContinue returns a function suitable for use with defer. It recovers from a panic, logs the error and stack trace.
func RecoverPanicAndExit ¶
func RecoverPanicAndExit()
RecoverPanicAndExit recovers from a panic, logs the error and stack trace, and exits. Use RecoverPanic with defer to handle panics gracefully.
Example usage:
defer it.RecoverPanic()
func Retry ¶
Retry retries the given function `fn` up to `attempts` times with a delay between attempts. Returns the error from the last attempt if all attempts fail.
Example usage:
err := it.Retry(3, time.Second, SomeErrorOnlyFunction)
func RetryExponential ¶
RetryExponential retries the given function `fn` up to `attempts` times with an exponential backoff delay between attempts. The delay starts at `initialDelay` and doubles with each attempt. Returns the error from the last attempt if all attempts fail.
Example usage:
err := it.RetryExponential(5, time.Second, SomeErrorOnlyFunction)
func RetryExponentialWithContext ¶
func RetryExponentialWithContext(ctx context.Context, attempts int, initialDelay time.Duration, fn func() error) error
RetryExponentialWithContext retries the given function `fn` up to `attempts` times with an exponential backoff delay between attempts. The delay starts at `initialDelay` and doubles with each attempt. If the context is canceled, it stops retrying and returns the context error.
Example usage:
ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second) defer cancel() err := it.RetryExponentialWithContext(ctx, 5, time.Second, SomeErrorOnlyFunction)
func RetryWithContext ¶
func RetryWithContext(ctx context.Context, attempts int, delay time.Duration, fn func() error) error
RetryWithContext retries a function while respecting context cancellation. It tries up to `attempts` times with a delay between each try and cancels if the context is done.
Example usage:
err := it.RetryWithContext(ctx, 3, time.Second, SomeErrorOnlyFunction)
func SetLogLevel ¶
func SetLogLevel(level int)
SetLogLevel sets the minimum log level for logging. Messages below this level will not be logged.
Available log levels:
it.LevelTrace
it.LevelDebug
it.LevelInfo
it.LevelWarn
it.LevelError
it.LevelFatal
it.LevelAudit
Example usage:
it.SetLogLevel(it.LevelDebug)
func SetLogOutput ¶
SetLogOutput sets the output destination for logs. It can be a file, os.Stdout, os.Stderr, or any io.Writer.
Example usage:
file, err := os.OpenFile("app.log", os.O_APPEND|os.O_CREATE|os.O_WRONLY, 0644)
if err != nil {
it.Fatalf("Failed to open log file: %v", err)
}
defer file.Close()
it.SetLogOutput(file)
func Should ¶
Should returns the value x regardless of whether err is nil. If err is not nil, Should logs the error with the filename and line number. Use Should when you want to log an error but continue execution.
Note: Be cautious when using Should, as x may be in an invalid state if err is not nil. Ensure that the returned value is safe to use in such cases.
Example usage:
result := it.Should(SomeFunction())
func StructuredDebug ¶
func StructuredDebug(message string, data interface{})
func StructuredError ¶
func StructuredError(message string, data interface{})
StructuredError logs an error message in a structured format. Use StructuredError to log errors with additional data for better analysis.
Example usage:
it.StructuredError("File not found", map[string]string{"filename": "config.yaml"})
func StructuredInfo ¶
StructuredInfo logs an informational message in a structured (e.g., JSON) format. Use StructuredInfo to log messages with additional data in a structured format for easier parsing and analysis.
Example usage:
it.StructuredInfo("User logged in", map[string]string{"username": "johndoe", "ip": "192.168.1.1"})
func StructuredLog ¶
StructuredLog logs a message with a specified level in a structured format. Use StructuredLog to log messages with additional data for any log level.
Example usage:
it.StructuredLog("ERROR", "Failed to process request", map[string]interface{}{"requestID": "abc123", "error": err})
func StructuredWarning ¶
func StructuredWarning(message string, data interface{})
func TimeBlock ¶
func TimeBlock(name string) func()
TimeBlock starts a timer and returns a function to stop the timer and log the duration. Use TimeBlock with defer to measure the execution time of a code block.
Example usage:
defer it.TimeBlock("main")()
func TimeFunction ¶
func TimeFunction(name string, f func())
TimeFunction measures and logs the execution time of a function. Use TimeFunction to profile the performance of specific functions.
Example usage:
it.TimeFunction("compute", compute)
func Trace ¶
func Trace(message string)
Trace logs a trace-level message. Use Trace to log very detailed information for tracing program execution.
Example usage:
it.Trace("Entering function X")
func Tracef ¶
func Tracef(format string, args ...interface{})
Tracef logs a formatted trace-level message. Use Tracef to log formatted detailed tracing information.
Example usage:
it.Tracef("Processing item %d of %d", currentItem, totalItems)
func WaitFor ¶
WaitFor waits until the provided function returns true or times out after `timeout` duration. Useful for waiting on certain conditions in concurrent environments.
Example usage:
it.WaitFor(time.Second * 10, func() bool { return someCondition() })
func Warn ¶
func Warn(message string)
Warn logs a warning message. Use Warn to log non-critical issues that should be addressed.
Example usage:
it.Warn("Configuration file not found, using defaults")
func Warnf ¶
func Warnf(format string, args ...interface{})
Warnf logs a formatted warning message. Use Warnf to log formatted non-critical issues.
Example usage:
it.Warnf("Configuration file %s not found, using defaults", configFile)
func WrapError ¶
WrapError wraps an error with a message. Use WrapError to add context to an error.
Example usage:
return it.WrapError(err, "failed to open file")
func WrapErrorWithContext ¶ added in v1.1.0
WrapErrorWithContext wraps an error with additional contextual information. Useful for adding more details to errors without losing the original error.
Example usage:
err := it.WrapErrorWithContext(err, "processing file", map[string]string{"file": filename})
func WrapErrorf ¶ added in v1.0.1
WrapErrorf wraps an error with a formatted message. Use WrapErrorf to add formatted context to an error.
Example usage:
return it.WrapErrorf(err, "failed to open file %s", filename)
Types ¶
type BufferedLogger ¶
type BufferedLogger struct {
// contains filtered or unexported fields
}
BufferedLogger provides a buffered logging mechanism, allowing logs to be written to any io.Writer.
func NewBufferedLogger ¶
func NewBufferedLogger(output io.Writer) *BufferedLogger
NewBufferedLogger creates a new BufferedLogger that writes to the specified io.Writer.
Example usage:
file, _ := os.OpenFile("app.log", os.O_APPEND|os.O_CREATE|os.O_WRONLY, 0644)
defer file.Close()
logger := it.NewBufferedLogger(file)
logger.Log("Logging to a file")
func (*BufferedLogger) Flush ¶
func (b *BufferedLogger) Flush() error
Flush forces any buffered data to be written out to the underlying writer. Useful for ensuring all logs are written at program exit.
Example usage:
logger.Flush()
func (*BufferedLogger) Log ¶
func (b *BufferedLogger) Log(message string)
Log writes a message to the buffered writer and flushes the buffer.
Example usage:
logger := it.NewBufferedLogger(os.Stdout)
logger.Log("Logging to standard output")
type Logger ¶
type Logger struct {
// contains filtered or unexported fields
}
Logger struct to manage log level
func NewLogger ¶
func NewLogger(options ...LoggerOption) *Logger
NewLogger creates a logger with configurable options.
Example usage:
logger := it.NewLogger(it.WithLogLevel(it.LevelDebug), it.WithTimestamp(true))
type LoggerOption ¶
type LoggerOption func(*LoggerOptions)
LoggerOption is a functional option type for configuring Logger.
func WithLogLevel ¶
func WithLogLevel(level int) LoggerOption
WithLogLevel sets the log level for Logger.
func WithTimestamp ¶
func WithTimestamp(enabled bool) LoggerOption
WithTimestamp enables timestamp logging.
type LoggerOptions ¶
type LoggerOptions struct {
// contains filtered or unexported fields
}
type StructuredLogEntry ¶
type StructuredLogEntry struct {
Level string `json:"level"`
Message string `json:"message"`
Data any `json:"data,omitempty"`
}
StructuredLogEntry represents a structured log message.