Skip to content

Commit

Permalink
feat: Implement structured logging with zerolog
Browse files Browse the repository at this point in the history
Integrate zerolog for enhanced logging capabilities across the
application. Replace standard log package with custom logging
functions that provide structured logging and better error handling.
This change improves log readability, allows for easier log parsing,
and enables more granular control over log levels.
  • Loading branch information
pblittle committed Sep 11, 2024
1 parent f8785ca commit 3d3650c
Show file tree
Hide file tree
Showing 5 changed files with 126 additions and 11 deletions.
8 changes: 8 additions & 0 deletions go.mod
Original file line number Diff line number Diff line change
@@ -1,3 +1,11 @@
module albatross

go 1.21

require github.com/rs/zerolog v1.33.0

require (
github.com/mattn/go-colorable v0.1.13 // indirect
github.com/mattn/go-isatty v0.0.20 // indirect
golang.org/x/sys v0.25.0 // indirect
)
21 changes: 21 additions & 0 deletions go.sum
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
github.com/coreos/go-systemd/v22 v22.5.0/go.mod h1:Y58oyj3AT4RCenI/lSvhwexgC+NSVTIJ3seZv2GcEnc=
github.com/godbus/dbus/v5 v5.0.4/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA=
github.com/mattn/go-colorable v0.1.13 h1:fFA4WZxdEF4tXPZVKMLwD8oUnCTTo08duU7wxecdEvA=
github.com/mattn/go-colorable v0.1.13/go.mod h1:7S9/ev0klgBDR4GtXTXX8a3vIGJpMovkB8vQcUbaXHg=
github.com/mattn/go-isatty v0.0.16/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/yFXSvRLM=
github.com/mattn/go-isatty v0.0.19 h1:JITubQf0MOLdlGRuRq+jtsDlekdYPia9ZFsB8h/APPA=
github.com/mattn/go-isatty v0.0.19/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y=
github.com/mattn/go-isatty v0.0.20 h1:xfD0iDuEKnDkl03q4limB+vH+GxLEtL/jb4xVJSWWEY=
github.com/mattn/go-isatty v0.0.20/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y=
github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
github.com/rs/xid v1.5.0/go.mod h1:trrq9SKmegXys3aeAKXMUTdJsYXVwGY3RLcfgqegfbg=
github.com/rs/zerolog v1.31.0 h1:FcTR3NnLWW+NnTwwhFWiJSZr4ECLpqCm6QsEnyvbV4A=
github.com/rs/zerolog v1.31.0/go.mod h1:/7mN4D5sKwJLZQ2b/znpjC3/GQWY/xaDXUM0kKWRHss=
github.com/rs/zerolog v1.33.0 h1:1cU2KZkvPxNyfgEmhHAz/1A9Bz+llsdYzklWFzgp0r8=
github.com/rs/zerolog v1.33.0/go.mod h1:/7mN4D5sKwJLZQ2b/znpjC3/GQWY/xaDXUM0kKWRHss=
golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.12.0 h1:CM0HF96J0hcLAwsHPJZjfdNzs0gftsLfgKt57wWHJ0o=
golang.org/x/sys v0.12.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.25.0 h1:r+8e+loiHxRqhXVl6ML1nO3l1+oFoWbnlu2Ehimmi34=
golang.org/x/sys v0.25.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
59 changes: 59 additions & 0 deletions internal/logging/logger.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
// Package logging provides a robust logging system for the Albatross project.
package logging

import (
"os"
"time"

"github.com/rs/zerolog"
"github.com/rs/zerolog/log"
)

// InitLogger initializes the global logger with custom settings.
func InitLogger() {
// Set up the logger
zerolog.TimeFieldFormat = zerolog.TimeFormatUnix
log.Logger = log.Output(zerolog.ConsoleWriter{Out: os.Stderr, TimeFormat: time.RFC3339})

// Set the global log level (can be changed based on environment)
zerolog.SetGlobalLevel(zerolog.InfoLevel)
}

// Fields is a type alias for log field key-value pairs
type Fields map[string]interface{}

// Info logs an info level message with optional fields
func Info(message string, fields Fields) {
event := log.Info()
for k, v := range fields {
event = event.Interface(k, v)
}
event.Msg(message)
}

// Error logs an error level message with optional fields
func Error(message string, err error, fields Fields) {
event := log.Error().Err(err)
for k, v := range fields {
event = event.Interface(k, v)
}
event.Msg(message)
}

// Debug logs a debug level message with optional fields
func Debug(message string, fields Fields) {
event := log.Debug()
for k, v := range fields {
event = event.Interface(k, v)
}
event.Msg(message)
}

// Fatal logs a fatal level message with optional fields and then exits
func Fatal(message string, fields Fields) {
event := log.Fatal()
for k, v := range fields {
event = event.Interface(k, v)
}
event.Msg(message)
}
14 changes: 11 additions & 3 deletions internal/parsers/shot_data_parser.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,11 +5,11 @@ import (
"encoding/csv"
"fmt"
"io"
"log"
"os"
"regexp"
"strings"

"albatross/internal/logging"
"albatross/internal/models"
"albatross/internal/reader"
)
Expand Down Expand Up @@ -64,7 +64,9 @@ func ProcessShotData(inputFile string, launchMonitorType string) ([]models.Proce
if isHeader(row) {
headers = normalizeHeaders(row)
inDataBlock = true
log.Printf("Found headers: %v", headers)
logging.Debug("Found headers", logging.Fields{
"headers": headers,
})
continue
}

Expand All @@ -81,7 +83,9 @@ func ProcessShotData(inputFile string, launchMonitorType string) ([]models.Proce
// Parse and process the row data
rawData, err := launchMonitor.ParseRow(row, headers)
if err != nil {
log.Printf("Skipping row due to error: %v", err)
logging.Error("Skipping row due to error", err, logging.Fields{
"row": row,
})
continue
}

Expand All @@ -93,6 +97,10 @@ func ProcessShotData(inputFile string, launchMonitorType string) ([]models.Proce
return nil, fmt.Errorf("no valid data found in the file")
}

logging.Info("Processed shot data", logging.Fields{
"shotsProcessed": len(shotData),
})

return shotData, nil
}

Expand Down
35 changes: 27 additions & 8 deletions main.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,11 @@
package main

import (
"log"
"os"
"strings"

"albatross/internal/calculators"
"albatross/internal/logging"
"albatross/internal/parsers"
"albatross/internal/writer"
"albatross/utils"
Expand All @@ -16,40 +16,59 @@ import (
// main is the entry point of the application. It handles command-line arguments,
// processes shot data, calculates targets, and writes the results to a file.
func main() {
// Initialize the logger
logging.InitLogger()

// Parse command-line arguments
if len(os.Args) != 3 {
log.Fatal("Usage: go run main.go <launch_monitor_type> <input_csv_file>")
logging.Fatal("Usage: go run main.go <launch_monitor_type> <input_csv_file>", nil)
}

launchMonitorType := normalizeLaunchMonitorType(os.Args[1])
inputFile := os.Args[2]

// Validate launch monitor type
if !isValidLaunchMonitorType(launchMonitorType) {
log.Fatalf("Error: Invalid launch monitor type '%s'. Supported type is mlm2pro.", os.Args[1])
logging.Fatal("Error: Invalid launch monitor type. Supported type is mlm2pro.", logging.Fields{
"providedType": launchMonitorType,
})
}

// Process shot data from the input file
shotData, err := parsers.ProcessShotData(inputFile, launchMonitorType)
if err != nil {
log.Fatalf("Error processing shot data: %v", err)
logging.Error("Error processing shot data", err, logging.Fields{
"inputFile": inputFile,
"launchMonitorType": launchMonitorType,
})
os.Exit(1)
}

log.Printf("Processed shot data: %+v", shotData)
logging.Info("Processed shot data", logging.Fields{
"count": len(shotData),
})

// Calculate targets based on the processed shot data
calculators.CalculateTargets(&shotData)

log.Printf("Calculated targets: %+v", shotData)
logging.Debug("Calculated targets", logging.Fields{
"shotData": shotData,
})

// Write processed data to an output file
outputFile := utils.ReplaceFileExtension(inputFile, "_processed.csv")
writer := writer.ShotPatternWriter{}
if err := writer.Write(outputFile, shotData); err != nil {
log.Fatalf("Error writing output file: %v", err)
logging.Error("Error writing output file", err, logging.Fields{
"outputFile": outputFile,
})
os.Exit(1)
}

log.Printf("Successfully processed %d shots and saved results to %s", len(shotData), outputFile)
logging.Info("Successfully processed shots and saved results", logging.Fields{
"shotsProcessed": len(shotData),
"outputFile": outputFile,
})
}

// normalizeLaunchMonitorType converts the launch monitor type to lowercase for consistency.
Expand Down

0 comments on commit 3d3650c

Please sign in to comment.