This is an automated email from the ASF dual-hosted git repository. wu-sheng pushed a commit to branch main in repository https://gitbox.apache.org/repos/asf/skywalking-horizon-ui.git
commit 1fd965986fc82b66a790cdc912a28e7c58c784b2 Author: Wu Sheng <[email protected]> AuthorDate: Mon May 18 21:07:57 2026 +0800 logging: treat local `node dist/server.js` as production (quiet); only `pnpm dev` is dev The previous logger default flipped on `NODE_ENV !== 'production'`, so `node dist/server.js` without an explicit env var fell into dev mode (verbose pretty logs). The published binary is a production target — it should be quiet by default and emit JSON for log aggregators. Inverted: dev mode requires `NODE_ENV=development` explicitly. Everything else (the local binary, the Docker image, CI) is production. - logger.ts: `isDev = NODE_ENV === 'development'`. Dev → debug+pretty, prod → error+JSON. Doc-comment spells out where each mode kicks in. - apps/bff dev script sets `NODE_ENV=development` explicitly so the contributor workflow (`pnpm --filter bff dev`) keeps the verbose + per-request access logs that make iteration fast. - container-image.md updated to reflect: any non-development entry point lands in the production log shape. - README Development section rewritten — replaced stale `npm install` recipe with the real pnpm-based loop, added the binary + image paths, and documented the two log modes + the LOG_LEVEL knob for triage. verified: tests 77/77, lint clean, license-eye clean. --- README.md | 39 +++++++++++++++++++++++++++++++-------- apps/bff/package.json | 2 +- apps/bff/src/logger.ts | 19 ++++++++++++++----- docs/setup/container-image.md | 4 ++-- 4 files changed, 48 insertions(+), 16 deletions(-) diff --git a/README.md b/README.md index 65fb970..b46184c 100644 --- a/README.md +++ b/README.md @@ -88,18 +88,41 @@ Horizon UI is built against the SkyWalking OAP GraphQL query-protocol (same sche ## Development -Requires Node.js 20+. +Requires Node.js 20+ and pnpm 10+ (pinned via Corepack in `package.json`). ```bash -npm install -npm run dev # vite dev server (proxies /graphql to http://127.0.0.1:12800) -npm run build # production build -npm run type-check -npm run lint -npm run test:unit -npm run license:check +pnpm install # one-time / after lockfile changes; auto-builds workspace packages via `prepare` + +# Dev loop (hot-reload, verbose pretty logs) +pnpm --filter bff dev # BFF on :8081 with NODE_ENV=development → debug level + per-request access logs +pnpm --filter ui dev # Vite dev server on :9091, proxies /api to the BFF + +# Static checks / tests +pnpm -r type-check +pnpm -r lint # read-only; `pnpm -r lint:fix` to mutate +pnpm -r test:unit +pnpm license:check # CI gate via skywalking-eyes + +# Self-contained "binary mode" — produces ./dist/ that boots with `node dist/server.js` +pnpm package +HORIZON_CONFIG=./horizon.yaml HORIZON_STATIC_DIR=./dist/static node dist/server.js + +# Container — Docker just copies in the pre-built dist (no compile in image) +docker build -t horizon-ui:local . +docker run --rm -p 8081:8081 -v "$PWD/horizon.yaml:/app/horizon.yaml:ro" horizon-ui:local ``` +### Logging + +The BFF uses [pino](https://github.com/pinojs/pino). Two modes, picked from `NODE_ENV`: + +| Mode | When | Format | Default level | +|---|---|---|---| +| **Dev** | `pnpm --filter bff dev` (sets `NODE_ENV=development`) | Pretty, colorized, via `pino-pretty` | `debug` + per-request access logs | +| **Prod** | Everything else — `node dist/server.js`, Docker container, CI | One JSON object per line on stdout | `error` — quiet by default | + +Adjust with `LOG_LEVEL`: `info` opens per-request access logs in prod, `debug` adds lifecycle chatter, `trace` is everything. Genuine request errors stay logged at `error` under any default that includes `error`. See [docs/setup/container-image.md → Logging](docs/setup/container-image.md#logging) for the three orthogonal channels (app logs, audit log, wire-debug log) and example `jq` recipes. + ## License Apache 2.0. See [LICENSE](LICENSE) and [NOTICE](NOTICE). diff --git a/apps/bff/package.json b/apps/bff/package.json index 9e50ba6..b7b50d4 100644 --- a/apps/bff/package.json +++ b/apps/bff/package.json @@ -8,7 +8,7 @@ "dist" ], "scripts": { - "dev": "tsx watch src/server.ts", + "dev": "NODE_ENV=development tsx watch src/server.ts", "build": "esbuild src/server.ts --bundle --platform=node --format=esm --target=node20 --outfile=dist/server.js --packages=external", "cli:hash": "tsx src/cli/hash.ts", "type-check": "tsc --noEmit", diff --git a/apps/bff/src/logger.ts b/apps/bff/src/logger.ts index bbeb0db..576d6b9 100644 --- a/apps/bff/src/logger.ts +++ b/apps/bff/src/logger.ts @@ -17,14 +17,23 @@ import pino, { type LoggerOptions } from 'pino'; -const isDev = process.env.NODE_ENV !== 'production'; +// Production unless explicitly opted into dev. Matters because the +// "production target" includes both `node dist/server.js` (local +// binary) and the Docker image — both should be quiet by default and +// emit machine-readable JSON for log aggregators. Only `pnpm dev` / +// `tsx watch` flips into dev mode (its `dev` script sets +// NODE_ENV=development). +const isDev = process.env.NODE_ENV === 'development'; /** * Default log level: - * - dev: `debug` (verbose, helpful while iterating) - * - prod: `error` (quiet by default — Fastify's per-request `info` - * access logs are suppressed; only warnings, errors, and fatals - * reach stdout) + * - dev (`NODE_ENV=development`, e.g. `pnpm --filter bff dev`): + * `debug` — verbose lifecycle + per-request access logs, pretty- + * printed via `pino-pretty` for human reading. + * - prod (anything else, incl. local `node dist/server.js` and the + * Docker image): `error` — quiet by default. Fastify's per-request + * `info` access logs are suppressed; only warnings, errors, and + * fatals reach stdout as JSON. * * Operators turn it up explicitly when triaging: `LOG_LEVEL=info` for * access logs, `LOG_LEVEL=debug` for the lifecycle chatter, `trace` diff --git a/docs/setup/container-image.md b/docs/setup/container-image.md index 2ce6ccd..3d31312 100644 --- a/docs/setup/container-image.md +++ b/docs/setup/container-image.md @@ -224,8 +224,8 @@ The BFF uses [pino](https://github.com/pinojs/pino) and writes **structured JSON | Mode | How to enter | Output | |---|---|---| -| Production | The image sets `NODE_ENV=production`. Local: `NODE_ENV=production node dist/server.js`. | One JSON object per line on stdout. **Default level `error`** — quiet by default; only warnings, errors, and fatals reach stdout. Fields: `level`, `time`, `pid`, `hostname`, plus per-event keys (`reqId`, `req`, `res`, `responseTime`, `msg`, …). | -| Development | The local binary defaults to dev (`NODE_ENV` unset). | Pretty-printed, colorized, with timestamps via `pino-pretty`. Default level `debug`. Same fields, human-readable. | +| Production | The image sets `NODE_ENV=production`. Anything that isn't explicitly `NODE_ENV=development` is treated as production — including the local binary `node dist/server.js`. | One JSON object per line on stdout. **Default level `error`** — quiet by default; only warnings, errors, and fatals reach stdout. Fields: `level`, `time`, `pid`, `hostname`, plus per-event keys (`reqId`, `req`, `res`, `responseTime`, `msg`, …). | +| Development | `pnpm --filter bff dev` (the `dev` script sets `NODE_ENV=development` explicitly). | Pretty-printed, colorized, with timestamps via `pino-pretty`. **Default level `debug`** — full lifecycle chatter + per-request access logs. Human-readable. | Adjust the floor with `LOG_LEVEL` when triaging:
