88 "encoding/hex"
99 "flag"
1010 "fmt"
11- "log"
11+ "log/slog "
1212 "net/http"
1313 "os"
1414 "os/signal"
@@ -63,6 +63,8 @@ func main() {
6363
6464 _ , _ = * oidcClientID , * oidcIssuer // surfaced for future integration
6565
66+ slog .SetDefault (slog .New (slog .NewJSONHandler (os .Stdout , & slog.HandlerOptions {Level : slog .LevelInfo })))
67+
6668 printBanner ()
6769
6870 // Load or generate the operator keypair.
@@ -71,31 +73,33 @@ func main() {
7173 if * operatorKeyHex != "" {
7274 privBytes , err := hex .DecodeString (* operatorKeyHex )
7375 if err != nil || len (privBytes ) != ed25519 .PrivateKeySize {
74- log .Fatalf ("invalid --operator-key: must be %d-byte hex" , ed25519 .PrivateKeySize )
76+ slog .Error ("invalid --operator-key" , "expected_bytes" , ed25519 .PrivateKeySize )
77+ os .Exit (1 )
7578 }
7679 operatorPriv = ed25519 .PrivateKey (privBytes )
7780 operatorPub = operatorPriv .Public ().(ed25519.PublicKey )
7881 } else {
7982 var err error
8083 operatorPub , operatorPriv , err = ed25519 .GenerateKey (rand .Reader )
8184 if err != nil {
82- log .Fatalf ("generate operator key: %v" , err )
85+ slog .Error ("generate operator key" , "error" , err )
86+ os .Exit (1 )
8387 }
84- log . Printf ("generated operator key (ephemeral — set --operator-key to persist) " )
88+ slog . Warn ("generated ephemeral operator key — set --operator-key to persist across restarts " )
8589 }
86- log . Printf ("operator public key: %s " , hex .EncodeToString (operatorPub ))
90+ slog . Info ("operator key loaded" , "public_key " , hex .EncodeToString (operatorPub ))
8791
8892 // Wire the signing backend.
8993 var receiptSigner signing.Signer
9094 switch * signingBackend {
9195 case "fulcio" :
92- log . Printf ("signing backend: fulcio (keyless) — OIDC issuer: %s " , * oidcIssuer )
96+ slog . Info ("signing backend: fulcio (keyless)" , "oidc_issuer " , * oidcIssuer )
9397 receiptSigner = signing .NewFulcioSigner (signing.FulcioOptions {
9498 FulcioURL : * fulcioURL ,
9599 RekorURL : * rekorURL ,
96100 })
97101 default :
98- log . Printf ("signing backend: ed25519" )
102+ slog . Info ("signing backend: ed25519" )
99103 receiptSigner = signing .NewEd25519Signer (operatorPriv )
100104 }
101105 _ = receiptSigner // passed to API in future integration
@@ -108,17 +112,19 @@ func main() {
108112 var builder interface { BuildAndSign () (* store.Checkpoint , error ) }
109113
110114 if * logBackend == "tessera" {
111- log . Printf ("using Tessera backend at %s " , * tesseraPath )
115+ slog . Info ("using Tessera backend" , "path " , * tesseraPath )
112116 ts , err := store .NewTesseraStore (ctx , * dbPath , * tesseraPath , * tesseraLogName , operatorPriv )
113117 if err != nil {
114- log .Fatalf ("open tessera store: %v" , err )
118+ slog .Error ("open tessera store" , "error" , err )
119+ os .Exit (1 )
115120 }
116121 st = ts
117122 builder = checkpoint .NewTesseraBuilder (st , operatorPriv , * maxBatch )
118123 } else {
119124 sqlite , err := store .Open (* dbPath )
120125 if err != nil {
121- log .Fatalf ("open store: %v" , err )
126+ slog .Error ("open store" , "error" , err )
127+ os .Exit (1 )
122128 }
123129 st = sqlite
124130 builder = checkpoint .NewBuilder (st , operatorPriv , * maxBatch )
@@ -151,9 +157,9 @@ func main() {
151157 case <- ticker .C :
152158 cp , err := builder .BuildAndSign ()
153159 if err != nil {
154- log . Printf ("batcher: build checkpoint: %v " , err )
160+ slog . Error ("batcher: build checkpoint failed" , "error " , err )
155161 } else if cp != nil {
156- log . Printf ("batcher: checkpoint %d built (tree_size=%d)" , cp .ID , cp .TreeSize )
162+ slog . Info ("batcher: checkpoint built" , "id" , cp .ID , "tree_size" , cp .TreeSize )
157163 }
158164 }
159165 }
@@ -163,11 +169,12 @@ func main() {
163169 if * rekorAnchor {
164170 ra , err := anchor .NewRekorAnchor (* rekorURL )
165171 if err != nil {
166- log .Fatalf ("create rekor anchor: %v" , err )
172+ slog .Error ("create rekor anchor" , "error" , err )
173+ os .Exit (1 )
167174 }
168175 sched := anchor .NewAnchorScheduler (ra , st , * rekorInterval )
169176 go sched .Run (ctx )
170- log . Printf ("rekor anchoring enabled: %s every %s" , * rekorURL , * rekorInterval )
177+ slog . Info ("rekor anchoring enabled" , "url" , * rekorURL , "interval" , * rekorInterval )
171178 }
172179
173180 // Optionally start discrepancy monitor.
@@ -199,18 +206,19 @@ func main() {
199206 signal .Notify (sigCh , syscall .SIGINT , syscall .SIGTERM )
200207 go func () {
201208 <- sigCh
202- log . Println ("shutting down..." )
209+ slog . Info ("shutting down..." )
203210 cancel ()
204211 shutCtx , shutCancel := context .WithTimeout (context .Background (), 10 * time .Second )
205212 defer shutCancel ()
206213 if err := httpSrv .Shutdown (shutCtx ); err != nil {
207- log . Printf ( " shutdown: %v " , err )
214+ slog . Error ( "graceful shutdown error" , "error " , err )
208215 }
209216 }()
210217
211- log . Printf ("siqlah %s (%s) listening on %s" , version , commitSHA , * addr )
218+ slog . Info ("siqlah listening" , "version" , version , "commit" , commitSHA , "addr" , * addr )
212219 if err := httpSrv .ListenAndServe (); err != nil && err != http .ErrServerClosed {
213- log .Fatalf ("listen: %v" , err )
220+ slog .Error ("listen failed" , "error" , err )
221+ os .Exit (1 )
214222 }
215223}
216224
@@ -223,12 +231,12 @@ func parseWitnesses(s string) map[string]ed25519.PublicKey {
223231 for _ , pair := range strings .Split (s , "," ) {
224232 parts := strings .SplitN (strings .TrimSpace (pair ), "=" , 2 )
225233 if len (parts ) != 2 {
226- log . Printf ( "warning: invalid witness pair %q , expected id=pubhex" , pair )
234+ slog . Warn ( " invalid witness pair, expected id=pubhex" , "pair " , pair )
227235 continue
228236 }
229237 b , err := hex .DecodeString (parts [1 ])
230238 if err != nil || len (b ) != ed25519 .PublicKeySize {
231- log . Printf ( "warning: invalid witness pubkey for %q " , parts [0 ])
239+ slog . Warn ( " invalid witness pubkey" , "id " , parts [0 ])
232240 continue
233241 }
234242 out [parts [0 ]] = ed25519 .PublicKey (b )
0 commit comments