Rules Hub
Coding Rules Library
← Back to all rules
Rule priority, scope & exceptions
Use this to align rules with the senior-level structure (P0/P1/P2, scope, exceptions/tradeoffs).
backend ruleP1universalStack: node
loggingobservabilityops
Treat logs as event streams (stdout/stderr)
Apps should not manage log files—write structured logs to stdout/stderr and let the platform route them.
Created: Feb 10, 2026
Bad example
Old codets
| 1 | // logger.ts |
| 2 | import fs from "node:fs"; |
| 3 |
|
| 4 | export function log(message: string) { |
| 5 | fs.appendFileSync("./app.log", `${new Date().toISOString()} ${message}\n`); |
| 6 | } |
Explanation (EN)
Managing log files inside the app complicates deployments and breaks common production logging pipelines.
Objašnjenje (HR)
Upravljanje log datotekama unutar aplikacije komplicira deploy i ruši standardne production logging tokove.
Good example
New codets
| 1 | // logger.ts |
| 2 | type LogLevel = "debug" | "info" | "warn" | "error"; |
| 3 |
|
| 4 | export function log(level: LogLevel, message: string, meta?: Record<string, unknown>) { |
| 5 | const entry = { |
| 6 | ts: new Date().toISOString(), |
| 7 | level, |
| 8 | message, |
| 9 | ...(meta ? { meta } : {}) |
| 10 | }; |
| 11 | // stdout/stderr are handled by the platform (Docker/K8s/systemd/log router) |
| 12 | const line = JSON.stringify(entry); |
| 13 | if (level === "error") { |
| 14 | // eslint-disable-next-line no-console |
| 15 | console.error(line); |
| 16 | } else { |
| 17 | // eslint-disable-next-line no-console |
| 18 | console.log(line); |
| 19 | } |
| 20 | } |
Explanation (EN)
Structured logs to stdout/stderr work well with containers, log routers, and centralized monitoring.
Objašnjenje (HR)
Strukturirani logovi na stdout/stderr dobro rade s containerima, log routerima i centraliziranim nadzorom.