From e9b8d970d185c90f17e5eb4ea54be6db2692c7a5 Mon Sep 17 00:00:00 2001 From: Harvey Tindall Date: Wed, 31 Jul 2024 17:45:05 +0100 Subject: [PATCH] logging: start consolidating log lines log messages are very fragmented and are often repeated many times throughout the software with small differences. Messages will be listed in logmessages/, which are simply strings with formatting directives if necessary. So far, only main.go has been completed. --- go.mod | 7 ++- logmessages/go.mod | 3 ++ logmessages/logmessages.go | 62 +++++++++++++++++++++ main.go | 108 +++++++++++++++++++------------------ 4 files changed, 127 insertions(+), 53 deletions(-) create mode 100644 logmessages/go.mod create mode 100644 logmessages/logmessages.go diff --git a/go.mod b/go.mod index de1d06d..13d721a 100644 --- a/go.mod +++ b/go.mod @@ -1,6 +1,6 @@ module github.com/hrfee/jfa-go -go 1.20 +go 1.22.4 replace github.com/hrfee/jfa-go/docs => ./docs @@ -10,6 +10,8 @@ replace github.com/hrfee/jfa-go/ombi => ./ombi replace github.com/hrfee/jfa-go/logger => ./logger +replace github.com/hrfee/jfa-go/logmessages => ./logmessages + replace github.com/hrfee/jfa-go/linecache => ./linecache replace github.com/hrfee/jfa-go/api => ./api @@ -35,7 +37,7 @@ require ( github.com/hrfee/jfa-go/docs v0.0.0-20230626224816-f72960635dc3 github.com/hrfee/jfa-go/easyproxy v0.0.0-00010101000000-000000000000 github.com/hrfee/jfa-go/linecache v0.0.0-20230626224816-f72960635dc3 - github.com/hrfee/jfa-go/logger v0.0.0-20230626224816-f72960635dc3 + github.com/hrfee/jfa-go/logger v0.0.0-20240731152135-2d066ea7cd32 github.com/hrfee/jfa-go/ombi v0.0.0-20230626224816-f72960635dc3 github.com/hrfee/mediabrowser v0.3.13 github.com/itchyny/timefmt-go v0.1.5 @@ -91,6 +93,7 @@ require ( github.com/gorilla/mux v1.8.0 // indirect github.com/gorilla/websocket v1.5.0 // indirect github.com/hrfee/jfa-go/jellyseerr v0.0.0-00010101000000-000000000000 // indirect + github.com/hrfee/jfa-go/logmessages v0.0.0-00010101000000-000000000000 // indirect github.com/josharian/intern v1.0.0 // indirect github.com/json-iterator/go v1.1.12 // indirect github.com/klauspost/compress v1.16.6 // indirect diff --git a/logmessages/go.mod b/logmessages/go.mod new file mode 100644 index 0000000..7d50aed --- /dev/null +++ b/logmessages/go.mod @@ -0,0 +1,3 @@ +module github.com/hrfee/logmessages + +go 1.22.4 diff --git a/logmessages/logmessages.go b/logmessages/logmessages.go new file mode 100644 index 0000000..cd7e9bd --- /dev/null +++ b/logmessages/logmessages.go @@ -0,0 +1,62 @@ +package logmessages + +const ( + FailedLogging = "Failed to start log wrapper: %v\n" + + NoConfig = "Couldn't find default config file" + FailedWriting = "Failed to write to \"%s\": %v" + FailedReading = "Failed to read from \"%s\": %v" + FailedOpen = "Failed to open \"%s\": %v" + + CopyConfig = "Copied default configuration to \"%s\"" + FailedCopyConfig = "Failed to copy default configuration to \"%s\": %v" + LoadConfig = "Loaded config file \"%s\"" + FailedLoadConfig = "Failed to load config file \"%s\": %v" + + SocketPath = "Socket Path: \"%s\"" + FailedSocketConnect = "Couldn't establish socket connection at \"%s\": %v" + SocketCheckRunning = "Make sure jfa-go is running." + FailedSocketRead = "Couldn't read message on socket \"%s\": %v" + SocketWrite = "Command sent." + FailedSocketWrite = "Coudln't write message on socket \"%s\": %v" + + FailedLangLoad = "Failed to load language files: %v" + + UsingTLS = "Using TLS/HTTP2" + + UsingOmbi = "Starting Ombi client" + UsingJellyseerr = "Starting Jellyseerr client" + UsingEmby = "Using Emby server type (EXPERIMENTAL: PWRs are not available, and support is limited.)" + UsingJellyfin = "Using Jellyfin server type" + UsingJellyfinAuth = "Using Jellyfin for authentication" + UsingLocalAuth = "Using local username/pw authentication (NOT RECOMMENDED)" + + AuthJellyfin = "Authenticated with Jellyfin @ \"%s\"" + FailedAuthJellyfin = "Failed to authenticate with Jellyfin @ \"%s\" (code %d): %v" + + InitDiscord = "Initialized Discord daemon" + FailedInitDiscord = "Failed to initialize Discord daemon: %v" + InitTelegram = "Initialized Telegram daemon" + FailedInitTelegram = "Failed to initialize Telegram daemon: %v" + InitMatrix = "Initialized Matrix daemon" + FailedInitMatrix = "Failed to initialize Matrix daemon: %v" + + InitRouter = "Initializing router" + LoadRoutes = "Loading Routes" + + LoadingSetup = "Loading setup @ \"%s\"" + ServingSetup = "Loaded, visit \"%s\" to start." + + InvalidSSLCert = "Failed loading SSL Certificate \"%s\": %v" + InvalidSSLKey = "Failed loading SSL Keyfile \"%s\": %v" + + FailServeSSL = "Failure serving with SSL/TLS: %v" + FailServe = "Failure serving: %v" + + Serving = "Loaded @ \"%s\"" + + QuitReceived = "Restart/Quit signal received, please be patient." + Quitting = "Shutting down..." + Quit = "Server shut down." + FailedQuit = "Server shutdown failed: %v" +) diff --git a/main.go b/main.go index 62407cc..acc9160 100644 --- a/main.go +++ b/main.go @@ -27,6 +27,7 @@ import ( "github.com/hrfee/jfa-go/easyproxy" "github.com/hrfee/jfa-go/jellyseerr" "github.com/hrfee/jfa-go/logger" + lm "github.com/hrfee/jfa-go/logmessages" "github.com/hrfee/jfa-go/ombi" "github.com/hrfee/mediabrowser" "github.com/lithammer/shortuuid/v3" @@ -213,22 +214,21 @@ func start(asDaemon, firstCall bool) { firstRun = true dConfig, err := fs.ReadFile(localFS, "config-default.ini") if err != nil { - app.err.Fatalf("Couldn't find default config file") + app.err.Fatalf(lm.NoConfig) } nConfig, err := os.Create(app.configPath) if err != nil && os.IsNotExist(err) { err = os.MkdirAll(filepath.Dir(app.configPath), 0760) } if err != nil { - app.err.Printf("Couldn't open config file for writing: \"%s\"", app.configPath) - app.err.Fatalf("Error: %s", err) + app.err.Fatalf(lm.FailedWriting, app.configPath, err) } defer nConfig.Close() _, err = nConfig.Write(dConfig) if err != nil { - app.err.Fatalf("Couldn't copy default config.") + app.err.Fatalf(lm.FailedCopyConfig, app.configPath, err) } - app.info.Printf("Copied default configuration to \"%s\"", app.configPath) + app.info.Printf(lm.CopyConfig, app.configPath) tempConfig, _ := ini.Load(app.configPath) tempConfig.Section("").Key("first_run").SetValue("true") tempConfig.SaveTo(app.configPath) @@ -237,8 +237,9 @@ func start(asDaemon, firstCall bool) { var debugMode bool var address string if err := app.loadConfig(); err != nil { - app.err.Fatalf("Failed to load config file \"%s\": %v", app.configPath, err) + app.err.Fatalf(lm.FailedLoadConfig, app.configPath, err) } + app.info.Printf(lm.LoadConfig, app.configPath) if app.config.Section("").Key("first_run").MustBool(false) { firstRun = true @@ -270,7 +271,7 @@ func start(asDaemon, firstCall bool) { os.Remove(SOCK) listener, err := net.Listen("unix", SOCK) if err != nil { - app.err.Fatalf("Couldn't establish socket connection at %s\n", SOCK) + app.err.Fatalf(lm.FailedSocketConnect, SOCK, err) } c := make(chan os.Signal, 1) signal.Notify(c, os.Interrupt, syscall.SIGTERM) @@ -286,13 +287,13 @@ func start(asDaemon, firstCall bool) { for { con, err := listener.Accept() if err != nil { - app.err.Printf("Couldn't read message on %s: %s", SOCK, err) + app.err.Printf(lm.FailedSocketRead, SOCK, err) continue } buf := make([]byte, 512) nr, err := con.Read(buf) if err != nil { - app.err.Printf("Couldn't read message on %s: %s", SOCK, err) + app.err.Printf(lm.FailedSocketRead, SOCK, err) continue } command := string(buf[0:nr]) @@ -317,13 +318,13 @@ func start(asDaemon, firstCall bool) { err = app.storage.loadLang(langFS, os.DirFS(externalLang)) } if err != nil { - app.info.Fatalf("Failed to load language files: %+v\n", err) + app.info.Fatalf(lm.FailedLangLoad, err) } if !firstRun { app.host = app.config.Section("ui").Key("host").String() if app.config.Section("advanced").Key("tls").MustBool(false) { - app.info.Println("Using TLS/HTTP2") + app.info.Println(lm.UsingTLS) app.port = app.config.Section("advanced").Key("tls_port").MustInt(8057) } else { app.port = app.config.Section("ui").Key("port").MustInt(8056) @@ -348,10 +349,8 @@ func start(asDaemon, firstCall bool) { } address = fmt.Sprintf("%s:%d", app.host, app.port) - app.debug.Printf("Loaded config file \"%s\"", app.configPath) - if app.config.Section("ombi").Key("enabled").MustBool(false) { - app.debug.Printf("Connecting to Ombi") + app.debug.Printf(lm.UsingOmbi) ombiServer := app.config.Section("ombi").Key("server").String() app.ombi = ombi.NewOmbi( ombiServer, @@ -362,7 +361,7 @@ func start(asDaemon, firstCall bool) { } if app.config.Section("jellyseerr").Key("enabled").MustBool(false) { - app.debug.Printf("Connecting to Jellyseerr") + app.debug.Printf(lm.UsingJellyseerr) jellyseerrServer := app.config.Section("jellyseerr").Key("server").String() app.js = jellyseerr.NewJellyseerr( jellyseerrServer, @@ -398,10 +397,9 @@ func start(asDaemon, firstCall bool) { if stringServerType == "emby" { serverType = mediabrowser.EmbyServer timeoutHandler = mediabrowser.NewNamedTimeoutHandler("Emby", "\""+server+"\"", true) - app.info.Println("Using Emby server type") - fmt.Println(warning("WARNING: Emby compatibility is experimental, and support is limited.\nPassword resets are not available.")) + app.info.Println(lm.UsingEmby) } else { - app.info.Println("Using Jellyfin server type") + app.info.Println(lm.UsingJellyfin) } app.jf, err = mediabrowser.NewServer( @@ -415,7 +413,7 @@ func start(asDaemon, firstCall bool) { cacheTimeout, ) if err != nil { - app.err.Fatalf("Failed to authenticate with Jellyfin @ \"%s\": %v", server, err) + app.err.Fatalf(lm.FailedAuthJellyfin, server, -1, err) } if debugMode { app.jf.Verbose = true @@ -433,9 +431,9 @@ func start(asDaemon, firstCall bool) { } _, status, err = app.jf.MustAuthenticate(app.config.Section("jellyfin").Key("username").String(), app.config.Section("jellyfin").Key("password").String(), retryOpts) if status != 200 || err != nil { - app.err.Fatalf("Failed to authenticate with Jellyfin @ \"%s\" (%d): %v", server, status, err) + app.err.Fatalf(lm.FailedAuthJellyfin, server, status, err) } - app.info.Printf("Authenticated with \"%s\"", server) + app.info.Printf(lm.AuthJellyfin, server) runMigrations(app) @@ -448,8 +446,9 @@ func start(asDaemon, firstCall bool) { user.Username = app.config.Section("ui").Key("username").String() user.Password = app.config.Section("ui").Key("password").String() app.adminUsers = append(app.adminUsers, user) + app.info.Println(lm.UsingLocalAuth) } else { - app.debug.Println("Using Jellyfin for authentication") + app.debug.Println(lm.UsingJellyfinAuth) app.authJf, _ = mediabrowser.NewServer(serverType, server, "jfa-go", app.version, "auth", "auth", timeoutHandler, cacheTimeout) if debugMode { app.authJf.Verbose = true @@ -515,9 +514,10 @@ func start(asDaemon, firstCall bool) { if telegramEnabled { app.telegram, err = newTelegramDaemon(app) if err != nil { - app.err.Printf("Failed to authenticate with Telegram: %v", err) + app.err.Printf(lm.FailedInitTelegram, err) telegramEnabled = false } else { + app.debug.Println(lm.InitTelegram) go app.telegram.run() defer app.telegram.Shutdown() } @@ -525,9 +525,10 @@ func start(asDaemon, firstCall bool) { if discordEnabled { app.discord, err = newDiscordDaemon(app) if err != nil { - app.err.Printf("Failed to authenticate with Discord: %v", err) + app.err.Printf(lm.FailedInitDiscord, err) discordEnabled = false } else { + app.debug.Println(lm.InitDiscord) go app.discord.run() defer app.discord.Shutdown() } @@ -535,9 +536,10 @@ func start(asDaemon, firstCall bool) { if matrixEnabled { app.matrix, err = newMatrixDaemon(app) if err != nil { - app.err.Printf("Failed to initialize Matrix daemon: %v", err) + app.err.Printf(lm.FailedInitMatrix, err) matrixEnabled = false } else { + app.debug.Println(lm.InitMatrix) go app.matrix.run() defer app.matrix.Shutdown() } @@ -558,7 +560,7 @@ func start(asDaemon, firstCall bool) { app.storage.lang.SetupPath = "setup" err := app.storage.loadLangSetup(langFS) if err != nil { - app.info.Fatalf("Failed to load language files: %+v\n", err) + app.info.Fatalf(lm.FailedLangLoad, err) } } @@ -566,14 +568,14 @@ func start(asDaemon, firstCall bool) { // workaround for potentially broken windows mime types mime.AddExtensionType(".js", "application/javascript") - app.info.Println("Initializing router") + app.info.Println(lm.InitRouter) router := app.loadRouter(address, debugMode) - app.info.Println("Loading routes") + app.info.Println(lm.LoadRoutes) if !firstRun { app.loadRoutes(router) } else { app.loadSetup(router) - app.info.Printf("Loading setup @ %s", address) + app.info.Printf(lm.LoadingSetup, address) } go func() { if app.config.Section("advanced").Key("tls").MustBool(false) { @@ -581,45 +583,45 @@ func start(asDaemon, firstCall bool) { key := app.config.Section("advanced").Key("tls_key").MustString("") if err := SRV.ListenAndServeTLS(cert, key); err != nil { filesToCheck := []string{cert, key} - fileNames := []string{"Certificate", "Key"} + fileNames := []string{lm.InvalidSSLCert, lm.InvalidSSLKey} for i, v := range filesToCheck { _, err := os.Stat(v) if err != nil { - app.err.Printf("SSL/TLS %s: %v\n", fileNames[i], err) + app.err.Printf(fileNames[i], v, err) } } if err == http.ErrServerClosed { - app.err.Printf("Failure serving with SSL/TLS: %s", err) + app.err.Printf(lm.FailServeSSL, err) } else { - app.err.Fatalf("Failure serving with SSL/TLS: %s", err) + app.err.Fatalf(lm.FailServeSSL, err) } } } else { if err := SRV.ListenAndServe(); err != nil { if err == http.ErrServerClosed { - app.err.Printf("Failure serving: %s", err) + app.err.Printf(lm.FailServe, err) } else { - app.err.Fatalf("Failure serving: %s", err) + app.err.Fatalf(lm.FailServe, err) } } } }() if firstRun { - app.info.Printf("Loaded, visit %s to start.", address) + app.info.Printf(lm.ServingSetup, address) } else { - app.info.Printf("Loaded @ %s", address) + app.info.Printf(lm.Serving, address) } waitForRestart() - app.info.Printf("Restart/Quit signal received, give me a second!") + app.info.Printf(lm.QuitReceived) ctx, cancel := context.WithTimeout(context.Background(), time.Second*5) defer cancel() if err := SRV.Shutdown(ctx); err != nil { - app.err.Fatalf("Server shutdown error: %s", err) + app.err.Fatalf(lm.FailedQuit, err) } - app.info.Println("Server shut down.") + app.info.Println(lm.Quit) return } @@ -631,7 +633,7 @@ func shutdown() { } func (app *appContext) shutdown() { - app.info.Println("Shutting down...") + app.info.Println(lm.Quitting) shutdown() } @@ -715,15 +717,17 @@ func printVersion() { fmt.Println(info("jfa-go version: %s (%s)%s\n", hiwhite(version), white(commit), tray)) } +const SYSTEMD_SERVICE = "jfa-go.service" + func main() { f, err := logOutput() if err != nil { - fmt.Printf("Failed to start logging: %v\n", err) + fmt.Printf(lm.FailedLogging, err) } defer f() printVersion() SOCK = filepath.Join(temp, SOCK) - fmt.Println("Socket:", SOCK) + fmt.Printf(lm.SocketPath+"\n", SOCK) if flagPassed("test") { TEST = true } @@ -752,21 +756,23 @@ func main() { } else if flagPassed("stop") { con, err := net.Dial("unix", SOCK) if err != nil { - fmt.Printf("Couldn't dial socket %s, are you sure jfa-go is running?\n", SOCK) + fmt.Printf(lm.FailedSocketConnect+"\n", SOCK, err) + fmt.Println(lm.SocketCheckRunning) os.Exit(1) } _, err = con.Write([]byte("stop")) if err != nil { - fmt.Printf("Couldn't send command to socket %s, are you sure jfa-go is running?\n", SOCK) + fmt.Printf(lm.FailedSocketWrite+"\n", SOCK, err) + fmt.Println(lm.SocketCheckRunning) os.Exit(1) } - fmt.Println("Sent.") + fmt.Println(lm.SocketWrite) } else if flagPassed("daemon") { start(true, true) } else if flagPassed("systemd") { - service, err := fs.ReadFile(localFS, "jfa-go.service") + service, err := fs.ReadFile(localFS, SYSTEMD_SERVICE) if err != nil { - fmt.Printf("Couldn't read jfa-go.service: %v\n", err) + fmt.Printf(lm.FailedReading+"\n", SYSTEMD_SERVICE, err) os.Exit(1) } absPath, err := filepath.Abs(os.Args[0]) @@ -780,13 +786,13 @@ func main() { } } service = []byte(strings.Replace(string(service), "{executable}", command, 1)) - err = os.WriteFile("jfa-go.service", service, 0666) + err = os.WriteFile(SYSTEMD_SERVICE, service, 0666) if err != nil { - fmt.Printf("Couldn't write jfa-go.service: %v\n", err) + fmt.Printf(lm.FailedWriting+"\n", SYSTEMD_SERVICE, err) os.Exit(1) } fmt.Println(info(`If you want to execute jfa-go with special arguments, re-run this command with them. -Move the newly created "jfa-go.service" file to ~/.config/systemd/user (Creating it if necessary). +Move the newly created SYSTEMD_SERVICE file to ~/.config/systemd/user (Creating it if necessary). Then run "systemctl --user daemon-reload". You can then run: