generated from nholtware/service-template-react
feat: JSON access log in the platform logging contract
This commit is contained in:
parent
fc7ebd5798
commit
444044b99a
5 changed files with 46 additions and 1 deletions
|
|
@ -5,5 +5,6 @@
|
||||||
- Routes: table in `src/routes.tsx`, one component per file in `src/routes/`, loaders exported next to their component.
|
- Routes: table in `src/routes.tsx`, one component per file in `src/routes/`, loaders exported next to their component.
|
||||||
- Runtime config: read only via `getConfig()` (`src/lib/config.ts`). A new browser-visible env var must be added to `VARS` in `docker-entrypoint.d/10-config.sh`, `AppConfig`, and the gitops Deployment. No secrets: config.js is public.
|
- Runtime config: read only via `getConfig()` (`src/lib/config.ts`). A new browser-visible env var must be added to `VARS` in `docker-entrypoint.d/10-config.sh`, `AppConfig`, and the gitops Deployment. No secrets: config.js is public.
|
||||||
- Backend calls: `apiGet()` in `src/lib/api.ts`, relative to `API_BASE_URL` (`/api` same-host ingress path, stripped before the backend). No CORS.
|
- Backend calls: `apiGet()` in `src/lib/api.ts`, relative to `API_BASE_URL` (`/api` same-host ingress path, stripped before the backend). No CORS.
|
||||||
|
- Logging: nginx access log is JSON in the platform logging contract (`log_format contract` in `nginx/default.conf`; `$app_name`/`$git_sha` from `conf.d/service-vars.conf` written by `10-config.sh`). Keep field names identical to the backend template's pino-http lines.
|
||||||
- Serving contract: port 8080, `/healthz` 200, SPA fallback, immutable `/assets/`, no-cache `index.html`/`config.js` (`nginx/default.conf`).
|
- Serving contract: port 8080, `/healthz` 200, SPA fallback, immutable `/assets/`, no-cache `index.html`/`config.js` (`nginx/default.conf`).
|
||||||
- Deploy: push to `main` -> Forgejo CI -> image -> gitops bump -> ArgoCD. Never `kubectl apply` by hand.
|
- Deploy: push to `main` -> Forgejo CI -> image -> gitops bump -> ArgoCD. Never `kubectl apply` by hand.
|
||||||
|
|
|
||||||
|
|
@ -15,4 +15,7 @@ COPY nginx/default.conf /etc/nginx/conf.d/default.conf
|
||||||
COPY --chmod=0755 docker-entrypoint.d/10-config.sh /docker-entrypoint.d/10-config.sh
|
COPY --chmod=0755 docker-entrypoint.d/10-config.sh /docker-entrypoint.d/10-config.sh
|
||||||
# html dir owned by nginx so 10-config.sh can write config.js at start.
|
# html dir owned by nginx so 10-config.sh can write config.js at start.
|
||||||
COPY --from=build --chown=101:101 /app/dist /usr/share/nginx/html
|
COPY --from=build --chown=101:101 /app/dist /usr/share/nginx/html
|
||||||
|
# Logged as "version" in every access-log line.
|
||||||
|
ARG GIT_SHA=dev
|
||||||
|
ENV GIT_SHA=${GIT_SHA}
|
||||||
EXPOSE 8080
|
EXPOSE 8080
|
||||||
|
|
|
||||||
|
|
@ -34,6 +34,13 @@ Everything in `config.js` is public. Never put secrets there.
|
||||||
- nginx listens on 8080: `/healthz` returns 200, unknown paths fall back to
|
- nginx listens on 8080: `/healthz` returns 200, unknown paths fall back to
|
||||||
`index.html`, `/assets/*` are cached as immutable, and `index.html` and
|
`index.html`, `/assets/*` are cached as immutable, and `index.html` and
|
||||||
`config.js` are not cached.
|
`config.js` are not cached.
|
||||||
|
- Access log: one JSON line per request in the platform logging contract
|
||||||
|
(`level`, `time`, `service` = `APP_NAME`, `version` = `GIT_SHA`, `req.id`
|
||||||
|
(echoes `X-Request-Id`), `req.method`, `req.url`, `res.statusCode`,
|
||||||
|
`responseTime` in ms, `msg: "request completed"`), the same shape as the backend
|
||||||
|
template. In Kibana (http://kibana.192.168.1.83.nip.io, data view `kube-*`):
|
||||||
|
`service:"hello-web" and res.statusCode >= 400`. `/healthz` isn't logged.
|
||||||
|
nginx's own startup/error lines stay plain text (field `log`).
|
||||||
|
|
||||||
## Deploy
|
## Deploy
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -23,4 +23,12 @@ for name in $VARS; do
|
||||||
done
|
done
|
||||||
|
|
||||||
printf 'window.__APP_CONFIG__ = {%s};\n' "$body" > "$OUT"
|
printf 'window.__APP_CONFIG__ = {%s};\n' "$body" > "$OUT"
|
||||||
echo "10-config.sh: wrote $OUT"
|
|
||||||
|
# nginx variables for the JSON access log (nginx/default.conf). Restricted
|
||||||
|
# charset: these land inside nginx string literals.
|
||||||
|
safe() { printf '%s' "$1" | tr -cd 'A-Za-z0-9._-'; }
|
||||||
|
cat > /etc/nginx/conf.d/service-vars.conf <<NGINX
|
||||||
|
map \$host \$app_name { default "$(safe "$APP_NAME")"; }
|
||||||
|
map \$host \$git_sha { default "$(safe "${GIT_SHA:-dev}")"; }
|
||||||
|
NGINX
|
||||||
|
echo "10-config.sh: wrote $OUT and service-vars.conf"
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,33 @@
|
||||||
|
# Access log in the platform logging contract (same shape as the backend
|
||||||
|
# template's pino-http lines), so Fluent Bit turns every key into a Kibana
|
||||||
|
# field. $app_name / $git_sha come from conf.d/service-vars.conf, written at
|
||||||
|
# container start by docker-entrypoint.d/10-config.sh.
|
||||||
|
map $status $log_level {
|
||||||
|
~^5 error;
|
||||||
|
default info;
|
||||||
|
}
|
||||||
|
# Echo X-Request-Id if the caller sent one, else nginx's own id.
|
||||||
|
map $http_x_request_id $req_id {
|
||||||
|
"" $request_id;
|
||||||
|
default $http_x_request_id;
|
||||||
|
}
|
||||||
|
# $request_time is seconds ("0.002"); the contract's responseTime is integer ms.
|
||||||
|
map $request_time $response_ms {
|
||||||
|
"~^0\.0*(?<ms>\d+)$" $ms;
|
||||||
|
"~^(?<s>[1-9]\d*)\.(?<ms>\d{3})$" $s$ms;
|
||||||
|
default 0;
|
||||||
|
}
|
||||||
|
log_format contract escape=json
|
||||||
|
'{"level":"$log_level","time":"$time_iso8601","service":"$app_name",'
|
||||||
|
'"version":"$git_sha","req":{"id":"$req_id","method":"$request_method",'
|
||||||
|
'"url":"$request_uri"},"res":{"statusCode":$status},'
|
||||||
|
'"responseTime":$response_ms,"msg":"request completed"}';
|
||||||
|
|
||||||
server {
|
server {
|
||||||
listen 8080;
|
listen 8080;
|
||||||
server_name _;
|
server_name _;
|
||||||
root /usr/share/nginx/html;
|
root /usr/share/nginx/html;
|
||||||
|
access_log /dev/stdout contract;
|
||||||
|
|
||||||
# Liveness/readiness for k8s probes.
|
# Liveness/readiness for k8s probes.
|
||||||
location = /healthz {
|
location = /healthz {
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue