## Summary Closes #15 When `logging.json: true` (or `DLC_LOGGING_JSON=true`), the logger was unconditionally initialised to console/text format at the top of `LoadConfig()`, so early log lines — most visibly **"Config file loaded"** — were always written as human-readable text regardless of configuration. ## Root cause Classic chicken-and-egg: the format flag lives inside the config that is being loaded. The format-switch block only ran *after* `v.Unmarshal()`, too late for the config-file log. ## Changes ### `pkg/config/config.go` - Add `peekJSONLogging()`: resolves the JSON flag **before** any log is emitted by (1) checking `DLC_LOGGING_JSON` directly via `os.Getenv`, then (2) doing a minimal throwaway Viper pre-read of the config file for the `logging.json` key. This mirrors Viper's own priority order without parsing the full config twice. - Apply the resolved format immediately and emit **"Logging configured"** as the very first log line. - Remove the now-redundant format-switch block that ran after `Unmarshal()`. ### `scripts/start-server.sh`, `test-graceful-shutdown.sh`, `test-opentelemetry.sh` - Replace hardcoded `PROJECT_DIR` path with a dynamic `SCRIPTS_DIR=$(dirname $(realpath ${BASH_SOURCE[0]}))` derivation so scripts work from any worktree or clone location. ## Test plan - [x] `go test ./pkg/...` — all pass - [x] `scripts/test-graceful-shutdown.sh` — all JSON valid, all startup logs present - [x] Manual smoke test: first line is `{"level":"info",...,"message":"Logging configured"}`, every line is valid JSON Reviewed-on: #16 Co-authored-by: Gabriel Radureau <arcodange@gmail.com> Co-committed-by: Gabriel Radureau <arcodange@gmail.com>
100 lines
3.1 KiB
Markdown
100 lines
3.1 KiB
Markdown
# dance-lessons-coach
|
|
|
|
[](https://gitea.arcodange.fr/arcodange/dance-lessons-coach/actions/workflows/ci-cd.yaml)
|
|
[](https://gitea.arcodange.fr/arcodange/dance-lessons-coach/releases)
|
|
[](LICENSE)
|
|
|
|
Go web service demonstrating idiomatic package structure, versioned JSON API, and production-ready features.
|
|
|
|
## Features
|
|
|
|
- Versioned JSON API (`/api/v1`, `/api/v2`)
|
|
- Chi router with graceful shutdown
|
|
- Zerolog structured logging (console and JSON modes)
|
|
- Viper configuration (file + env vars)
|
|
- Readiness endpoint for Kubernetes / service mesh
|
|
- OpenTelemetry / Jaeger distributed tracing
|
|
- OpenAPI / Swagger UI (embedded in binary)
|
|
- PostgreSQL user service with JWT auth
|
|
- BDD + unit tests
|
|
|
|
## Quick Start
|
|
|
|
```bash
|
|
git clone https://gitea.arcodange.lab/arcodange/dance-lessons-coach.git
|
|
cd dance-lessons-coach
|
|
./scripts/build.sh # produces ./bin/server and ./bin/greet
|
|
./scripts/start-server.sh start
|
|
```
|
|
|
|
```bash
|
|
curl http://localhost:8080/api/health
|
|
curl http://localhost:8080/api/v1/greet/Alice
|
|
```
|
|
|
|
Stop: `./scripts/start-server.sh stop`
|
|
|
|
## Greet CLI
|
|
|
|
```bash
|
|
go run ./cmd/greet # Hello world!
|
|
go run ./cmd/greet Alice # Hello Alice!
|
|
```
|
|
|
|
## Configuration
|
|
|
|
All options are available via `config.yaml` or `DLC_*` environment variables.
|
|
|
|
| Env var | Default | Description |
|
|
|---------|---------|-------------|
|
|
| `DLC_SERVER_PORT` | `8080` | Listening port |
|
|
| `DLC_SERVER_HOST` | `0.0.0.0` | Bind address |
|
|
| `DLC_LOGGING_JSON` | `false` | JSON log format |
|
|
| `DLC_LOGGING_OUTPUT` | stderr | Log file path |
|
|
| `DLC_SHUTDOWN_TIMEOUT` | `30s` | Graceful shutdown window |
|
|
| `DLC_API_V2_ENABLED` | `false` | Enable `/api/v2` routes |
|
|
| `DLC_CONFIG_FILE` | `./config.yaml` | Override config path |
|
|
|
|
See `config.example.yaml` for a full template.
|
|
|
|
## API
|
|
|
|
| Method | Path | Description |
|
|
|--------|------|-------------|
|
|
| GET | `/api/health` | Liveness check |
|
|
| GET | `/api/ready` | Readiness check (503 during shutdown) |
|
|
| GET | `/api/version` | Version info (`?format=plain\|full\|json`) |
|
|
| GET | `/api/v1/greet/` | Default greeting |
|
|
| GET | `/api/v1/greet/{name}` | Named greeting |
|
|
| POST | `/api/v2/greet` | V2 greeting with validation |
|
|
| GET | `/swagger/` | Swagger UI |
|
|
|
|
## Testing
|
|
|
|
```bash
|
|
go test ./... # unit + integration tests
|
|
./scripts/test-graceful-shutdown.sh # lifecycle + JSON logging validation
|
|
./scripts/test-opentelemetry.sh # tracing end-to-end
|
|
```
|
|
|
|
## Gitea Client
|
|
|
|
AI agent helper script at `.vibe/skills/gitea-client/scripts/gitea-client.sh`.
|
|
|
|
Auth setup:
|
|
```bash
|
|
echo "your_token" > ~/.gitea_token
|
|
chmod 600 ~/.gitea_token
|
|
export GITEA_API_TOKEN_FILE="$HOME/.gitea_token"
|
|
```
|
|
|
|
Get a token at https://gitea.arcodange.lab → Profile → Settings → Applications.
|
|
|
|
## Architecture
|
|
|
|
Key decisions are documented in [adr/](adr/). See [AGENTS.md](AGENTS.md) for the full development reference (commands, config, ADR index, commit conventions).
|
|
|
|
## License
|
|
|
|
MIT
|