Files
zwift-activity-loader/main.go
Thomas Klaehn f496eebe2a Initial commit
Signed-off-by: Thomas Klaehn <thomas.klaehn@perinet.io>
2026-02-10 13:27:42 +01:00

107 lines
2.6 KiB
Go

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
}