feat(logging): add structured server diagnostics
CI / validate (push) Successful in 4m55s
Release / release (push) Successful in 9m46s

This commit is contained in:
dmg
2026-08-01 17:37:52 -04:00
parent 5e693e2cdd
commit 86c87153b4
19 changed files with 331 additions and 13 deletions
+19
View File
@@ -0,0 +1,19 @@
{
"name": "@minecraft-account-manager/logging",
"version": "0.1.0",
"private": true,
"type": "module",
"exports": { ".": "./src/index.ts" },
"scripts": {
"test": "vitest run",
"typecheck": "tsc --noEmit"
},
"dependencies": {
"pino": "^10.3.1"
},
"devDependencies": {
"@types/node": "^25.0.3",
"typescript": "^5.9.3",
"vitest": "^4.1.0"
}
}
+35
View File
@@ -0,0 +1,35 @@
import pino, { type DestinationStream, type Logger } from "pino";
const redactedPaths = [
"apiKey",
"authorization",
"password",
"token",
"*.apiKey",
"*.authorization",
"*.password",
"*.token",
"headers.authorization",
"req.headers.authorization",
];
export function createLogger(
service: string,
options: { destination?: DestinationStream } = {},
): Logger {
return pino(
{
level: process.env.LOG_LEVEL?.trim() || "info",
base: {
service,
environment: process.env.NODE_ENV ?? "development",
version: process.env.APP_VERSION ?? "development",
},
redact: {
paths: redactedPaths,
censor: "[Redacted]",
},
},
options.destination,
);
}
+31
View File
@@ -0,0 +1,31 @@
import { Writable } from "node:stream";
import { describe, expect, it } from "vitest";
import { createLogger } from "../src/index";
function captureLog() {
let output = "";
const destination = new Writable({
write(chunk, _encoding, callback) {
output += chunk.toString();
callback();
},
});
return { destination, read: () => JSON.parse(output.trim()) as Record<string, unknown> };
}
describe("structured application logging", () => {
it("emits service metadata and redacts credential fields", () => {
const capture = captureLog();
const logger = createLogger("account-manager-test", { destination: capture.destination });
logger.info({ token: "secret-token", apiKey: "secret-key", operation: "test" }, "Test event");
expect(capture.read()).toMatchObject({
service: "account-manager-test",
token: "[Redacted]",
apiKey: "[Redacted]",
operation: "test",
msg: "Test event",
});
});
});
+5
View File
@@ -0,0 +1,5 @@
{
"extends": "../../tsconfig.base.json",
"compilerOptions": { "types": ["node", "vitest/globals"] },
"include": ["src/**/*.ts", "test/**/*.ts"]
}