Skip to content

Instantly share code, notes, and snippets.

@techygrrrl
Last active June 23, 2023 05:19
Show Gist options
  • Save techygrrrl/b7846ac18da7c1be878c2dea74712786 to your computer and use it in GitHub Desktop.
Save techygrrrl/b7846ac18da7c1be878c2dea74712786 to your computer and use it in GitHub Desktop.
Implementation structured logs with multiple outputs (console, file) in Go lang using zerolog
// internal/logging.go
package internal
import (
"fmt"
"io"
"os"
"path"
"path/filepath"
"strconv"
"github.com/rs/zerolog"
"github.com/rs/zerolog/log"
)
// initLogging creates a logger, sets the UNIX timestamp as the timestamp format
// and configures logger to output to file in ./data/my_file.log
// Usage:
// logger := initLogging(zerolog.InfoLevel)
func initLogging(logLevel zerolog.Level) zerolog.Logger {
// set the timestamp format. this is more performant than other formats
zerolog.TimeFieldFormat = zerolog.TimeFormatUnix
// write logs to file - TODO: Change this to your own file path
f, err := os.OpenFile(path.Join(appDataPath(""), "my_file.log"), os.O_RDWR|os.O_CREATE|os.O_APPEND, 0666)
if err != nil {
log.Fatal().Msg("error opening file for logging")
}
// Never close the file
//defer f.Close()
wrt := io.MultiWriter(zerolog.ConsoleWriter{Out: os.Stderr}, f)
// add caller info to logs.
// this custom [CallerMarshalFunc] logs only the file name instead of the default full absolute path.
// ref: https://github.com/rs/zerolog#add-file-and-line-number-to-log
zerolog.CallerMarshalFunc = func(pc uintptr, file string, line int) string {
short := file
for i := len(file) - 1; i > 0; i-- {
if file[i] == '/' {
short = file[i+1:]
break
}
}
file = short
return file + ":" + strconv.Itoa(line)
}
log.Logger = log.With().Caller().Logger()
fmt.Printf("Using log level: %s (%d)\n", logLevel.String(), logLevel)
zerolog.SetGlobalLevel(logLevel)
// create a logger copy from the global config
logger := log.Output(wrt)
return logger
}
// AppDataPath
// Returns the path relative to the executable, e.g. ./data
func appDataPath(pathPrefix string) string {
workingDir, err := os.Getwd()
if err != nil {
log.Fatal().Msg("Cannot get working directory")
}
return filepath.Join(workingDir, pathPrefix, "data")
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment