diff options
author | Martin Fischer <martin@push-f.com> | 2025-04-06 22:16:04 +0200 |
---|---|---|
committer | Martin Fischer <martin@push-f.com> | 2025-04-13 23:18:01 +0200 |
commit | 35275699ade84abefbf0b1a6c82882d8d470c8ad (patch) | |
tree | 6edd7605d2caf9696485979f695c0424f451abf7 | |
parent | 8d834d04be72597fa8a9627af3b471ab65baaa0d (diff) |
feat: use structured logging
-rw-r--r-- | lex-serve/main.go | 40 | ||||
-rw-r--r-- | lex-serve/main_test.go | 3 | ||||
-rw-r--r-- | service.nix | 1 |
3 files changed, 31 insertions, 13 deletions
diff --git a/lex-serve/main.go b/lex-serve/main.go index 0a1403b..416104f 100644 --- a/lex-serve/main.go +++ b/lex-serve/main.go @@ -6,7 +6,7 @@ import ( "encoding/json" "html/template" "io/ioutil" - "log" + "log/slog" "net" "net/http" "net/url" @@ -18,35 +18,43 @@ import ( var countriesJSON []byte func main() { + log := slog.New(slog.NewTextHandler(os.Stderr, nil)) + socketPath := os.Getenv("SOCKET_PATH") if socketPath == "" { - log.Fatal("SOCKET_PATH must be set") + log.Error("SOCKET_PATH must be set") + os.Exit(1) } domain := os.Getenv("DOMAIN") if domain == "" { - log.Fatal("DOMAIN environment variable must be set") + log.Error("DOMAIN environment variable must be set") + os.Exit(1) } - var handler = handler{domain: domain, lawsByCC: map[string]map[string]law{}} + var handler = handler{logger: log, domain: domain, lawsByCC: map[string]map[string]law{}} err := json.Unmarshal(countriesJSON, &handler.countries) if err != nil { - log.Fatal("countries.json ", err) + log.Error("failed to parse countries.json", Error(err)) + os.Exit(1) } lawFiles, err := ioutil.ReadDir("laws") if err != nil { - log.Fatal(err) + log.Error("failed to read laws/ directory", Error(err)) + os.Exit(1) } for _, file := range lawFiles { text, err := ioutil.ReadFile("laws/" + file.Name()) if err != nil { - log.Fatal(file.Name(), err) + log.Error("failed to read file", Error(err), "path", "laws/"+file.Name()) + os.Exit(1) } var laws []law err = json.Unmarshal([]byte(text), &laws) if err != nil { - log.Fatal(file.Name(), err) + log.Error("failed to parse file", Error(err), "path", file.Name()) + os.Exit(1) } cc := strings.SplitN(file.Name(), ".", 2)[0] handler.lawsByCC[cc] = map[string]law{} @@ -59,13 +67,15 @@ func main() { http.HandleFunc("/", handler.handle) listener, err := net.Listen("unix", socketPath) if err != nil { - log.Fatal(err) + log.Error("failed to listen", Error(err)) + os.Exit(1) } if err := os.Chmod(socketPath, 0666); err != nil { - log.Fatalf("error setting socket permissions: %s", err) + log.Error("failed to set socket permissions", Error(err), "path", socketPath) return } - log.Fatal(http.Serve(listener, nil)) + err = http.Serve(listener, nil) + log.Error("failed to serve", Error(err)) } //go:embed templates @@ -76,6 +86,7 @@ var tpl, _ = template.New("").Funcs(template.FuncMap{ }).Option("missingkey=error").ParseFS(templates, "templates/*") type handler struct { + logger *slog.Logger domain string countries map[string]country lawsByCC map[string]map[string]law @@ -94,7 +105,7 @@ func (h *handler) handle(w http.ResponseWriter, r *http.Request) { "Domain": r.Host, }) if err != nil { - log.Printf("failed to execute index template: %s", err) + h.logger.Error("failed to execute index template", Error(err)) http.Error(w, "internal server error", http.StatusInternalServerError) return } @@ -104,6 +115,7 @@ func (h *handler) handle(w http.ResponseWriter, r *http.Request) { cc, isSubdomain := strings.CutSuffix(r.Host, "."+h.domain) if !isSubdomain { + h.logger.Error("request for unknown hosts", "host", r.Host) w.Write([]byte("unknown host")) return } @@ -141,7 +153,7 @@ func (h *handler) handle(w http.ResponseWriter, r *http.Request) { "HasJSONLaws": hasJSONLaws, }) if err != nil { - log.Printf("failed to execute search template: %s", err) + h.logger.Error("failed to execute search template", Error(err)) http.Error(w, "internal server error", http.StatusInternalServerError) return } @@ -164,3 +176,5 @@ type country struct { func (c country) HasPlaceholder() bool { return strings.Contains(c.SearchURL, "%s") } + +func Error(value error) slog.Attr { return slog.String("error", value.Error()) } diff --git a/lex-serve/main_test.go b/lex-serve/main_test.go index e647a2f..00cc3a3 100644 --- a/lex-serve/main_test.go +++ b/lex-serve/main_test.go @@ -1,7 +1,9 @@ package main import ( + "log/slog" "net/http/httptest" + "os" "strings" "testing" @@ -10,6 +12,7 @@ import ( func newHandler() handler { return handler{ + logger: slog.New(slog.NewTextHandler(os.Stderr, nil)), domain: "lex.example", countries: map[string]country{ "zu": country{ diff --git a/service.nix b/service.nix index 6024b5e..e1ebe1c 100644 --- a/service.nix +++ b/service.nix @@ -53,6 +53,7 @@ in DynamicUser = true; RuntimeDirectory = "lex-serve"; WorkingDirectory = lex_surf; + LogExtraFields = "LOG_FORMAT=logfmt"; }; environment = { |