package main import ( "fmt" "log/slog" "os" "os/signal" "syscall" "git.savin.nyc/alex/go-receipt-tracker/app" "git.savin.nyc/alex/go-receipt-tracker/bus" "git.savin.nyc/alex/go-receipt-tracker/config" "git.savin.nyc/alex/go-receipt-tracker/database" "git.savin.nyc/alex/go-receipt-tracker/hooks/debug" "git.savin.nyc/alex/go-receipt-tracker/workers" ) // var log = *slog.Logger var cfg = &config.Config{} const ( LoggingOutputJson = "JSON" LoggingOutputText = "TEXT" ) func configureLogging(config *config.Logging) *slog.Logger { //nolint:unparam if config == nil { return nil } var level slog.Level if err := level.UnmarshalText([]byte(config.Level)); err != nil { slog.Warn(err.Error()) slog.Warn(fmt.Sprintf("logging level not recognized, defaulting to level %s", slog.LevelInfo.String())) level = slog.LevelInfo } var handler slog.Handler switch config.Output { case LoggingOutputJson: handler = slog.NewJSONHandler(os.Stdout, &slog.HandlerOptions{AddSource: cfg.Logging.Source, Level: level}) case LoggingOutputText: handler = slog.NewTextHandler(os.Stdout, &slog.HandlerOptions{AddSource: cfg.Logging.Source, Level: level}) default: handler = slog.NewTextHandler(os.Stdout, &slog.HandlerOptions{AddSource: cfg.Logging.Source, Level: level}) } return slog.New(handler) } func main() { sigs := make(chan os.Signal, 1) done := make(chan bool, 1) signal.Notify(sigs, syscall.SIGINT, syscall.SIGTERM) go func() { <-sigs done <- true }() var err error cfg, err = config.New() if err != nil { // Handle errors reading the config file slog.Error("Fatal error config file", "error", err.Error()) os.Exit(1) } // LOGGER logger := configureLogging(cfg.Logging) logger.Debug("CONFIG", "config", cfg) // BUS evBus := bus.New(cfg.Bus, logger) // DATABASE db, err := database.NewDB(cfg.DataBase, logger) if err != nil { logger.Error(err.Error()) os.Exit(1) } app := app.New(cfg, evBus, db, logger) for _, opts := range cfg.Parsers { if opts.Type == "openai" { openai := workers.NewOpenAi(opts, evBus) err = app.AddWorker(openai) if err != nil { app.Log.Error(err.Error()) } } // if opts.Type == "claude" { // claude := workers.NewClaude(opts, evBus) // err = app.AddWorker(claude) // if err != nil { // app.Log.Error(err.Error()) // } // } // if opts.Type == "gemini" { // gemini := workers.NewGemini(opts, evBus) // err = app.AddWorker(gemini) // if err != nil { // app.Log.Error(err.Error()) // } // } } tb := workers.NewTelegramBot(cfg.Telegram, evBus) err = app.AddWorker(tb) if err != nil { app.Log.Error(err.Error()) os.Exit(1) } // if len(cfg.Listeners) > 0 { // for name, opts := range cfg.Listeners { // listener := listeners.NewHTTPStats(name, ":"+strconv.Itoa(opts.Port), nil, app.Info) // err = app.AddListener(listener) // if err != nil { // app.Log.Error(err.Error()) // } // } // } err = app.AddHook(new(debug.Hook), nil) if err != nil { app.Log.Error(err.Error()) } // err = app.AddHook(new(consul.Hook), &consul.Options{ // Hostname: cfg.Consul.Host, // Port: cfg.Consul.Port, // DC: cfg.Consul.DataCenter, // ServiceID: "srv-mysubaru-01", // NodeName: "mysubaru", // Tags: []string{"mysubaru", "hassio", "mqtt"}, // LocalHost: cfg.Consul.Interfaces.WAN, // LocalPort: cfg.Listeners["stats"].Port, // }) // if err != nil { // app.Log.Error(err.Error()) // } go func() { err := app.Serve() if err != nil { app.Log.Error(err.Error()) } }() <-done app.Log.Warn("caught signal, stopping...") _ = app.Close() app.Log.Info("main.go finished") }