106
main.go
Normal file
106
main.go
Normal file
@@ -0,0 +1,106 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"os"
|
||||
"os/signal"
|
||||
"syscall"
|
||||
|
||||
"zwift-activity-loader/internal/config"
|
||||
"zwift-activity-loader/internal/service"
|
||||
|
||||
"go.uber.org/zap"
|
||||
"go.uber.org/zap/zapcore"
|
||||
)
|
||||
|
||||
func main() {
|
||||
// Load configuration
|
||||
cfg, err := config.Load()
|
||||
if err != nil {
|
||||
fmt.Fprintf(os.Stderr, "Failed to load configuration: %v\n", err)
|
||||
os.Exit(1)
|
||||
}
|
||||
|
||||
// Set up logging
|
||||
logger, err := setupLogger(cfg.LogLevel, cfg.LogFile)
|
||||
if err != nil {
|
||||
fmt.Fprintf(os.Stderr, "Failed to setup logger: %v\n", err)
|
||||
os.Exit(1)
|
||||
}
|
||||
defer logger.Sync()
|
||||
|
||||
// Create service
|
||||
svc, err := service.New(cfg, logger)
|
||||
if err != nil {
|
||||
logger.Fatal("Failed to create service", zap.Error(err))
|
||||
}
|
||||
|
||||
// Set up signal handling for graceful shutdown
|
||||
sigChan := make(chan os.Signal, 1)
|
||||
signal.Notify(sigChan, syscall.SIGINT, syscall.SIGTERM)
|
||||
|
||||
// Start service in goroutine
|
||||
errChan := make(chan error, 1)
|
||||
go func() {
|
||||
errChan <- svc.Run()
|
||||
}()
|
||||
|
||||
// Wait for shutdown signal or error
|
||||
select {
|
||||
case sig := <-sigChan:
|
||||
logger.Info("Received signal", zap.String("signal", sig.String()))
|
||||
if err := svc.Shutdown(); err != nil {
|
||||
logger.Error("Error during shutdown", zap.Error(err))
|
||||
os.Exit(1)
|
||||
}
|
||||
case err := <-errChan:
|
||||
if err != nil {
|
||||
logger.Error("Service error", zap.Error(err))
|
||||
os.Exit(1)
|
||||
}
|
||||
}
|
||||
|
||||
logger.Info("Service exited successfully")
|
||||
}
|
||||
|
||||
// setupLogger creates a zap logger based on configuration
|
||||
func setupLogger(logLevel, logFile string) (*zap.Logger, error) {
|
||||
// Parse log level
|
||||
var level zapcore.Level
|
||||
if err := level.UnmarshalText([]byte(logLevel)); err != nil {
|
||||
level = zapcore.InfoLevel
|
||||
}
|
||||
|
||||
// Create encoder config
|
||||
encoderConfig := zap.NewProductionEncoderConfig()
|
||||
encoderConfig.TimeKey = "time"
|
||||
encoderConfig.EncodeTime = zapcore.ISO8601TimeEncoder
|
||||
|
||||
// Create core
|
||||
var core zapcore.Core
|
||||
|
||||
if logFile != "" {
|
||||
// Log to both file and stdout
|
||||
file, err := os.OpenFile(logFile, os.O_APPEND|os.O_CREATE|os.O_WRONLY, 0644)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to open log file: %w", err)
|
||||
}
|
||||
|
||||
fileEncoder := zapcore.NewJSONEncoder(encoderConfig)
|
||||
consoleEncoder := zapcore.NewConsoleEncoder(encoderConfig)
|
||||
|
||||
core = zapcore.NewTee(
|
||||
zapcore.NewCore(fileEncoder, zapcore.AddSync(file), level),
|
||||
zapcore.NewCore(consoleEncoder, zapcore.AddSync(os.Stdout), level),
|
||||
)
|
||||
} else {
|
||||
// Log to stdout only
|
||||
consoleEncoder := zapcore.NewConsoleEncoder(encoderConfig)
|
||||
core = zapcore.NewCore(consoleEncoder, zapcore.AddSync(os.Stdout), level)
|
||||
}
|
||||
|
||||
// Create logger
|
||||
logger := zap.New(core, zap.AddCaller(), zap.AddStacktrace(zapcore.ErrorLevel))
|
||||
|
||||
return logger, nil
|
||||
}
|
||||
Reference in New Issue
Block a user