mirror of
https://github.com/awalsh128/cache-apt-pkgs-action.git
synced 2026-01-22 11:09:16 +00:00
146 lines
4 KiB
Go
146 lines
4 KiB
Go
package logging
|
|
|
|
import (
|
|
"encoding/json"
|
|
"io"
|
|
"log"
|
|
"os"
|
|
"sync"
|
|
)
|
|
|
|
// loggerWrapper encapsulates a standard logger with additional functionality.
|
|
type loggerWrapper struct {
|
|
wrapped *log.Logger // The underlying standard logger
|
|
}
|
|
|
|
// DebugEnabled controls whether debug messages are logged.
|
|
// When true, Debug() calls will output messages; when false, they are ignored.
|
|
var DebugEnabled = false
|
|
|
|
var (
|
|
loggerMu sync.Mutex // Protects logger operations
|
|
logger = createDefault()
|
|
)
|
|
|
|
// create instantiates a new logger with the specified output writers.
|
|
// Multiple writers can be provided to output logs to multiple destinations.
|
|
func create(writers ...io.Writer) loggerWrapper {
|
|
loggerMu.Lock()
|
|
defer loggerMu.Unlock()
|
|
return loggerWrapper{
|
|
wrapped: log.New(io.MultiWriter(writers...), "", log.LstdFlags),
|
|
}
|
|
}
|
|
|
|
// createDefault provides the default behavior for the log Go module
|
|
func createDefault() loggerWrapper {
|
|
return create(os.Stderr)
|
|
}
|
|
|
|
// SetOutput overrides the default output destination for the logger.
|
|
// This affects all subsequent log messages from this package.
|
|
// Thread-safe operation that can be called at any time.
|
|
func SetOutput(writer io.Writer) {
|
|
loggerMu.Lock()
|
|
defer loggerMu.Unlock()
|
|
logger.wrapped.SetOutput(writer)
|
|
}
|
|
|
|
func recreateFileWriter() *os.File {
|
|
logFilepath := os.Args[0] + ".log"
|
|
// Ignore error if file doesn't exist
|
|
_ = os.Remove(logFilepath)
|
|
file, err := os.OpenFile(logFilepath, os.O_CREATE|os.O_WRONLY, 0644)
|
|
if err != nil {
|
|
log.Fatal(err)
|
|
}
|
|
return file
|
|
}
|
|
|
|
// InitDefault resets the logger to its default state, writing only to stderr.
|
|
// Any existing log files or custom writers are discarded.
|
|
func InitDefault() {
|
|
DebugEnabled = false
|
|
logger = createDefault()
|
|
}
|
|
|
|
// Init initializes a new logger that writes to both a file and stderr.
|
|
// The log file is named after the binary with a .log extension.
|
|
// Previous log file content is discarded.
|
|
//
|
|
// Parameters:
|
|
// - debug: Enable or disable debug logging
|
|
func Init(debug bool) {
|
|
file := recreateFileWriter()
|
|
DebugEnabled = debug
|
|
logger = create(file, os.Stderr)
|
|
}
|
|
|
|
// InitWithWriter initializes a new logger with custom output writers.
|
|
// Writes to both a log file and the specified writer.
|
|
//
|
|
// Parameters:
|
|
// - debug: Enable or disable debug logging
|
|
// - writer: Additional output destination besides the log file
|
|
func InitWithWriter(debug bool, writer io.Writer) {
|
|
file := recreateFileWriter()
|
|
DebugEnabled = debug
|
|
logger = create(file, writer)
|
|
}
|
|
|
|
// DebugLazy logs a debug message using a lazy evaluation function.
|
|
// The message generator function is only called if debug logging is enabled,
|
|
// making it efficient for expensive debug message creation.
|
|
//
|
|
// The getLine function should return the message to be logged.
|
|
func DebugLazy(getLine func() string) {
|
|
if DebugEnabled {
|
|
logger.wrapped.Println(getLine())
|
|
}
|
|
}
|
|
|
|
// Debug logs a formatted debug message if debug logging is enabled.
|
|
// Uses fmt.Printf style formatting. No-op if debug is disabled.
|
|
//
|
|
// Parameters:
|
|
// - format: Printf-style format string
|
|
// - a: Arguments for the format string
|
|
func Debug(format string, a ...any) {
|
|
if DebugEnabled {
|
|
logger.wrapped.Printf(format, a...)
|
|
}
|
|
}
|
|
|
|
// DumpVars logs the JSON representation of variables if debug is enabled.
|
|
// Each variable is converted to JSON format before logging.
|
|
// Continues to next variable if one fails to convert.
|
|
func DumpVars(a ...any) {
|
|
if DebugEnabled {
|
|
for _, v := range a {
|
|
content, err := json.MarshalIndent(v, "", " ")
|
|
if err != nil {
|
|
Info("warning: unable to dump variable: %v", err)
|
|
continue
|
|
}
|
|
logger.wrapped.Println(content)
|
|
}
|
|
}
|
|
}
|
|
|
|
// Info logs a formatted message at info level.
|
|
// Always logs regardless of debug setting.
|
|
// Adds a newline to the end of the message.
|
|
func Info(format string, a ...any) {
|
|
logger.wrapped.Printf(format+"\n", a...)
|
|
}
|
|
|
|
// Fatal logs an error message and terminates the program.
|
|
// Calls os.Exit(1) after logging the error.
|
|
func Fatal(err error) {
|
|
logger.wrapped.Fatal(err)
|
|
}
|
|
|
|
func Fatalf(format string, a ...any) {
|
|
logger.wrapped.Fatalf(format+"\n", a...)
|
|
}
|