@noctcore/eslint-plugin-observability
Structured logging discipline: context objects, no sensitive fields, no lost error detail, declared PII in audit payloads.
What it solves
Section titled “What it solves”Logs are an interface that nobody type-checks. An interpolated message string cannot be queried, a log call that includes password or token is an incident, and a catch block that logs only e.message throws away the stack and cause you needed.
What it will yell at you about
Section titled “What it will yell at you about”It will yell at you about how you call your logger: a static message plus a context object, never a template literal with values in it. The sensitive-field and PII rules match on names, so they catch user.password but not a secret hiding in a field called data. The rules recognise <logger>.info/warn/error/debug(...) calls on logger names you configure through loggers. It is a bad fit if you log through console by design, or your logger has no way to carry a context object, because the fix every rule asks for is to move values out of the message and into one.
Install and configure
Section titled “Install and configure”npm install --save-dev @noctcore/eslint-plugin-observability @typescript-eslint/parser# or: bun add -D / pnpm add -D @noctcore/eslint-plugin-observability @typescript-eslint/parser// eslint.config.jsimport tsParser from '@typescript-eslint/parser';import observability from '@noctcore/eslint-plugin-observability';
export default [ { ...observability.configs.recommended, files: ['**/*.{ts,tsx}'], languageOptions: { parser: tsParser }, },];The recommended preset enables 4 of 4 rules.
Each rule links to its page, with the options it takes and Incorrect and Correct examples. A good first
read is structured-log-arguments.
| Rule | What it reports | Preset | Fix | Types |
|---|---|---|---|---|
audit-pii-declared | A PII-shaped key written into an audit payload must be declared, either registered for scrubbing on purge or declared non-PII. | error | ||
no-error-detail-loss | A catch block that reports a failure must not reduce the error to only e.message / String(e) / ${e} — log the error itself so its stack and cause survive. | error | ||
no-sensitive-fields-in-logs | A logger call must not reference an identifier, property, or object key whose name matches a sensitive-field denylist (password, token, secret, ...). Redact it before logging. | error | ||
structured-log-arguments | A logger call must not interpolate dynamic values into the message string (a template literal with expressions). Pass a static message and a structured context object instead. | error |
Preset: severity in configs.recommended; off means the preset registers the rule switched off, not listed means it leaves the rule out; both are opt-in, so you turn the rule on yourself. Fix: whether the rule ships an autofix or an editor suggestion. Types: whether the rule needs a type-checked program (parserOptions.projectService).