67 lines
2.3 KiB
Markdown
67 lines
2.3 KiB
Markdown
# Contract: Logging (Go Web Applications)
|
|
|
|
Version: 1.0
|
|
|
|
## Core Rule
|
|
|
|
**All logging goes to the server binary's stdout/stderr — never to the browser console.**
|
|
|
|
- `console.log`, `console.error`, `console.warn` in JavaScript are for debugging only.
|
|
Remove them before committing. They are not a substitute for server-side logging.
|
|
- Diagnostic information (errors, slow queries, ingest results, background task status) must be
|
|
logged server-side so it is visible in the terminal where the binary runs.
|
|
|
|
## Go Logging Standard
|
|
|
|
Use the standard library `log/slog` (Go 1.21+) or `log` for simpler projects.
|
|
|
|
```go
|
|
// correct — structured, visible in binary console
|
|
slog.Info("export started", "user", userID, "rows", count)
|
|
slog.Error("db query failed", "err", err)
|
|
|
|
// wrong — goes to browser devtools, invisible in production
|
|
// (JS template rendered in HTML)
|
|
// console.log("export started")
|
|
```
|
|
|
|
## Log Levels
|
|
|
|
| Level | When to use |
|
|
|---------|-------------|
|
|
| `Debug` | Detailed flow tracing; disabled in production builds |
|
|
| `Info` | Normal operation milestones: server start, request handled, export done |
|
|
| `Warn` | Recoverable anomaly: retry, fallback used, deprecated path |
|
|
| `Error` | Operation failed; always include `"err", err` as a structured attribute |
|
|
|
|
## What to Always Log
|
|
|
|
- Server startup: address, port, config source.
|
|
- Background task start/finish/error with task name and duration.
|
|
- CSV/file export: scope, row count, duration.
|
|
- Ingest/import: file name, rows accepted, rows rejected, error summary.
|
|
- Any `500` response: handler name + error.
|
|
|
|
## What Not to Log
|
|
|
|
- Do not log full request bodies or CSV content — can contain PII or large payloads.
|
|
- Do not log passwords, tokens, or secrets even partially.
|
|
- Do not add `fmt.Println` for debugging and leave it in committed code.
|
|
|
|
## htmx / Browser-rendered Responses
|
|
|
|
- Handler errors that result in an htmx partial re-render must still log the error server-side.
|
|
- Do not rely on the browser network tab as the only visibility into server errors.
|
|
|
|
## Format
|
|
|
|
- Use structured key-value attributes, not concatenated strings.
|
|
|
|
```go
|
|
// correct
|
|
slog.Error("sync failed", "component", comp.Serial, "err", err)
|
|
|
|
// wrong — hard to grep, hard to parse
|
|
log.Printf("sync failed for component %s: %v", comp.Serial, err)
|
|
```
|