Skip to content

Commit e97da8a

Browse files
authored
Log build info on startup in every run mode (#406)
Emit a single "Duckgres build info." slog line right after logging is initialized, tagged with the run mode (standalone / control-plane / duckdb-service / ...). This makes it trivial to grep a K8s worker's logs and confirm which image it's actually running — especially useful when correlating a bug to a specific commit across many worker pods. version/commit/date have existed as ldflag-set package vars for a while (Dockerfile, release workflow and justfile all pass -X flags), but only the standalone path referenced them, and only `version`. The control plane and duckdb-service workers never surfaced build info at all. The ldflags-based flow stays authoritative. When the binary is built without ldflags (local `go run`, `go build`, editor runs) enrichBuildInfo backfills commit and date from runtime/debug.BuildInfo VCS settings (Go 1.18+ embeds these automatically from the surrounding git checkout) and appends "-dirty" when vcs.modified is true. The fallback only fires when ldflags left the sentinel values in place — a release-built binary with an explicit -X main.commit never gets mutated. Verified locally: - go build -ldflags "-X main.version=1.2.3 -X main.commit=deadbeef ..." → "duckgres version 1.2.3 (commit: deadbeef, built: ...)" - plain go build → "duckgres version dev (commit: 815063d-dirty, built: ...)" And the log line appears as the first INFO line under --mode duckdb-service and --mode control-plane.
1 parent 815063d commit e97da8a

2 files changed

Lines changed: 68 additions & 1 deletion

File tree

‎main.go‎

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -359,6 +359,8 @@ func main() {
359359
loggingShutdown := initLogging()
360360
defer loggingShutdown()
361361

362+
logBuildInfo(*mode)
363+
362364
if fileCfg != nil {
363365
slog.Info("Loaded configuration from " + *configFile)
364366
}

‎version.go‎

Lines changed: 66 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,78 @@
11
package main
22

3-
import "fmt"
3+
import (
4+
"fmt"
5+
"log/slog"
6+
"runtime/debug"
7+
"sync"
8+
)
49

10+
// version, commit and date are populated at link time via -ldflags -X by the
11+
// Dockerfile, justfile and release workflow. When the binary is built without
12+
// those flags (local `go run`/`go build`), enrichBuildInfo backfills commit
13+
// and date from runtime/debug.BuildInfo VCS settings, which the go toolchain
14+
// embeds automatically from the local git checkout (Go 1.18+). ldflags values
15+
// always win — the fallback only fires when the default sentinel is still set.
516
var (
617
version = "dev"
718
commit = "unknown"
819
date = "unknown"
920
)
1021

22+
var enrichBuildInfoOnce sync.Once
23+
24+
func enrichBuildInfo() {
25+
enrichBuildInfoOnce.Do(func() {
26+
info, ok := debug.ReadBuildInfo()
27+
if !ok {
28+
return
29+
}
30+
// Only backfill commit from VCS when ldflags did not provide one.
31+
// The dirty marker is scoped to the VCS-backfilled case too — if
32+
// ldflags injected a commit, the release pipeline owns that value
33+
// and we should not mutate it.
34+
commitFromVCS := commit == "unknown"
35+
var dirty bool
36+
for _, s := range info.Settings {
37+
switch s.Key {
38+
case "vcs.revision":
39+
if commitFromVCS && s.Value != "" {
40+
commit = s.Value
41+
if len(commit) > 12 {
42+
commit = commit[:12]
43+
}
44+
}
45+
case "vcs.time":
46+
if date == "unknown" && s.Value != "" {
47+
date = s.Value
48+
}
49+
case "vcs.modified":
50+
if s.Value == "true" {
51+
dirty = true
52+
}
53+
}
54+
}
55+
if dirty && commitFromVCS && commit != "unknown" {
56+
commit += "-dirty"
57+
}
58+
})
59+
}
60+
1161
func versionString() string {
62+
enrichBuildInfo()
1263
return fmt.Sprintf("duckgres version %s (commit: %s, built: %s)", version, commit, date)
1364
}
65+
66+
// logBuildInfo emits a single startup line identifying the binary's version,
67+
// git commit and build time, tagged with the run mode. Call once per process
68+
// at startup so log readers can quickly correlate behavior with a specific
69+
// build, especially in K8s where worker pods inherit the control plane image.
70+
func logBuildInfo(mode string) {
71+
enrichBuildInfo()
72+
slog.Info("Duckgres build info.",
73+
"mode", mode,
74+
"version", version,
75+
"commit", commit,
76+
"built", date,
77+
)
78+
}

0 commit comments

Comments
 (0)