tpaga-logger 0.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md ADDED
@@ -0,0 +1,41 @@
1
+ # @tpaga/logger
2
+
3
+ Structured logging SDK for Tpaga Node.js microservices. Emits **wide-event JSON** (canonical log line) to stdout for **AWS CloudWatch Logs Insights**, following [loggingsucks.com](https://loggingsucks.com/).
4
+
5
+ ## Status
6
+
7
+ | Fase | Estado | Rama |
8
+ |------|--------|------|
9
+ | 1 — Contrato de logs (SERF-5797) | Completada | `scaffolding` |
10
+ | 2 — Scaffold build (tsup, vitest, CI) | En revisión | `scaffolding` |
11
+ | 3 — Implementación SDK (SERF-5915) | Pendiente | — |
12
+ | 4 — Piloto CloudWatch (SERF-5916) | Pendiente | — |
13
+
14
+ ## Documentación
15
+
16
+ - Contrato: [`.agents/docs/SERF-5797_LOG_STRUCTURE_CONTRACT.md`](.agents/docs/SERF-5797_LOG_STRUCTURE_CONTRACT.md)
17
+ - Plan: [`.agents/docs/SERF-5796_TPAGA_LOGGER_IMPLEMENTATION_PLAN.md`](.agents/docs/SERF-5796_TPAGA_LOGGER_IMPLEMENTATION_PLAN.md)
18
+
19
+ ## Desarrollo
20
+
21
+ ```bash
22
+ pnpm install
23
+ pnpm typecheck
24
+ pnpm lint
25
+ pnpm test
26
+ pnpm build
27
+ ```
28
+
29
+ **Fase 2:** `createLogger`, `withWideEvent`, y correlación son stubs que lanzan hasta Fase 3. `serializeError`, `safeStringify`, `write`, y `redact` (passthrough) están listos para tests.
30
+
31
+ ## Instalación (cuando se publique)
32
+
33
+ ```bash
34
+ pnpm add @tpaga/logger
35
+ ```
36
+
37
+ Ver [`.npmrc.example`](.npmrc.example) para registry interno (TBD).
38
+
39
+ ## Repo
40
+
41
+ https://bitbucket.org/tpaga/tpaga-logger/src/main/
package/dist/index.cjs ADDED
@@ -0,0 +1,91 @@
1
+ "use strict";
2
+ var __create = Object.create;
3
+ var __defProp = Object.defineProperty;
4
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
5
+ var __getOwnPropNames = Object.getOwnPropertyNames;
6
+ var __getProtoOf = Object.getPrototypeOf;
7
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
8
+ var __export = (target, all) => {
9
+ for (var name in all)
10
+ __defProp(target, name, { get: all[name], enumerable: true });
11
+ };
12
+ var __copyProps = (to, from, except, desc) => {
13
+ if (from && typeof from === "object" || typeof from === "function") {
14
+ for (let key of __getOwnPropNames(from))
15
+ if (!__hasOwnProp.call(to, key) && key !== except)
16
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
17
+ }
18
+ return to;
19
+ };
20
+ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
21
+ // If the importer is in node compatibility mode or this is not an ESM
22
+ // file that has been converted to a CommonJS file using a Babel-
23
+ // compatible transform (i.e. "__esModule" has not been set), then set
24
+ // "default" to the CommonJS "module.exports" for node compatibility.
25
+ isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
26
+ mod
27
+ ));
28
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
29
+
30
+ // src/index.ts
31
+ var index_exports = {};
32
+ __export(index_exports, {
33
+ LOG_LEVELS: () => LOG_LEVELS,
34
+ OUTCOMES: () => OUTCOMES,
35
+ createLogger: () => createLogger,
36
+ serializeError: () => serializeError
37
+ });
38
+ module.exports = __toCommonJS(index_exports);
39
+
40
+ // src/logger.ts
41
+ var import_pino = __toESM(require("pino"), 1);
42
+ var serializeError = (err) => err instanceof Error ? {
43
+ type: err.name,
44
+ message: err.message,
45
+ code: err.code,
46
+ stack: err.stack
47
+ } : { type: "UnknownError", message: String(err) };
48
+ var createWideEventBuilder = (base, log) => {
49
+ const ctx = { ...base };
50
+ return {
51
+ enrich: (fields) => Object.assign(ctx, fields),
52
+ emit: (level, message, terminal) => log[level]({ ...ctx, ...terminal }, message)
53
+ };
54
+ };
55
+ var createLogger = (config) => {
56
+ const log = (0, import_pino.default)({
57
+ level: process.env.LOG_LEVEL ?? "info",
58
+ base: { service: config.service, environment: config.environment },
59
+ formatters: {
60
+ level: (label) => ({ level: label })
61
+ },
62
+ timestamp: import_pino.default.stdTimeFunctions.isoTime,
63
+ redact: {
64
+ paths: config.redactKeys ?? [],
65
+ censor: "[REDACTED]"
66
+ }
67
+ });
68
+ return {
69
+ startOperation: (functionName, base = {}) => createWideEventBuilder({ function: functionName, ...base }, log)
70
+ };
71
+ };
72
+
73
+ // src/constants.ts
74
+ var LOG_LEVELS = ["info", "warn", "error", "debug"];
75
+ var OUTCOMES = [
76
+ "success",
77
+ "error",
78
+ "validation_failed",
79
+ "not_found",
80
+ "conflict",
81
+ "timeout",
82
+ "skipped"
83
+ ];
84
+ // Annotate the CommonJS export names for ESM import in node:
85
+ 0 && (module.exports = {
86
+ LOG_LEVELS,
87
+ OUTCOMES,
88
+ createLogger,
89
+ serializeError
90
+ });
91
+ //# sourceMappingURL=index.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/index.ts","../src/logger.ts","../src/constants.ts"],"sourcesContent":["export { createLogger, serializeError } from './logger.js';\nexport { LOG_LEVELS, OUTCOMES } from './constants.js';\nexport type {\n Logger,\n LoggerConfig,\n LogLevel,\n Outcome,\n SerializedError,\n TerminalFields,\n WideEventBuilder,\n} from './types.js';\n","import pino from 'pino';\nimport type { Logger, LoggerConfig, SerializedError, TerminalFields, WideEventBuilder } from './types.js';\n\nexport const serializeError = (err: unknown): SerializedError =>\n err instanceof Error\n ? {\n type: err.name,\n message: err.message,\n code: (err as { code?: string }).code,\n stack: err.stack,\n }\n : { type: 'UnknownError', message: String(err) };\n\nconst createWideEventBuilder = (\n base: Record<string, unknown>,\n log: pino.Logger,\n): WideEventBuilder => {\n const ctx = { ...base };\n return {\n enrich: (fields) => Object.assign(ctx, fields),\n emit: (level, message, terminal: TerminalFields) => log[level]({ ...ctx, ...terminal }, message),\n };\n};\n\nexport const createLogger = (config: LoggerConfig): Logger => {\n const log = pino({\n level: process.env.LOG_LEVEL ?? 'info',\n base: { service: config.service, environment: config.environment },\n formatters: {\n level: (label) => ({ level: label }),\n },\n timestamp: pino.stdTimeFunctions.isoTime,\n redact: {\n paths: (config.redactKeys as string[]) ?? [],\n censor: '[REDACTED]',\n },\n });\n\n return {\n startOperation: (functionName, base = {}) =>\n createWideEventBuilder({ function: functionName, ...base }, log),\n };\n};\n","export const LOG_LEVELS = ['info', 'warn', 'error', 'debug'] as const;\n\nexport const OUTCOMES = [\n 'success',\n 'error',\n 'validation_failed',\n 'not_found',\n 'conflict',\n 'timeout',\n 'skipped',\n] as const;\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;;ACAA,kBAAiB;AAGV,IAAM,iBAAiB,CAAC,QAC7B,eAAe,QACX;AAAA,EACE,MAAM,IAAI;AAAA,EACV,SAAS,IAAI;AAAA,EACb,MAAO,IAA0B;AAAA,EACjC,OAAO,IAAI;AACb,IACA,EAAE,MAAM,gBAAgB,SAAS,OAAO,GAAG,EAAE;AAEnD,IAAM,yBAAyB,CAC7B,MACA,QACqB;AACrB,QAAM,MAAM,EAAE,GAAG,KAAK;AACtB,SAAO;AAAA,IACL,QAAQ,CAAC,WAAW,OAAO,OAAO,KAAK,MAAM;AAAA,IAC7C,MAAM,CAAC,OAAO,SAAS,aAA6B,IAAI,KAAK,EAAE,EAAE,GAAG,KAAK,GAAG,SAAS,GAAG,OAAO;AAAA,EACjG;AACF;AAEO,IAAM,eAAe,CAAC,WAAiC;AAC5D,QAAM,UAAM,YAAAA,SAAK;AAAA,IACf,OAAO,QAAQ,IAAI,aAAa;AAAA,IAChC,MAAM,EAAE,SAAS,OAAO,SAAS,aAAa,OAAO,YAAY;AAAA,IACjE,YAAY;AAAA,MACV,OAAO,CAAC,WAAW,EAAE,OAAO,MAAM;AAAA,IACpC;AAAA,IACA,WAAW,YAAAA,QAAK,iBAAiB;AAAA,IACjC,QAAQ;AAAA,MACN,OAAQ,OAAO,cAA2B,CAAC;AAAA,MAC3C,QAAQ;AAAA,IACV;AAAA,EACF,CAAC;AAED,SAAO;AAAA,IACL,gBAAgB,CAAC,cAAc,OAAO,CAAC,MACrC,uBAAuB,EAAE,UAAU,cAAc,GAAG,KAAK,GAAG,GAAG;AAAA,EACnE;AACF;;;AC1CO,IAAM,aAAa,CAAC,QAAQ,QAAQ,SAAS,OAAO;AAEpD,IAAM,WAAW;AAAA,EACtB;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF;","names":["pino"]}
@@ -0,0 +1,34 @@
1
+ declare const LOG_LEVELS: readonly ["info", "warn", "error", "debug"];
2
+ declare const OUTCOMES: readonly ["success", "error", "validation_failed", "not_found", "conflict", "timeout", "skipped"];
3
+
4
+ type LogLevel = (typeof LOG_LEVELS)[number];
5
+ type Outcome = (typeof OUTCOMES)[number];
6
+ type LoggerConfig = {
7
+ service: string;
8
+ environment?: string;
9
+ redactKeys?: readonly string[];
10
+ };
11
+ type SerializedError = {
12
+ type: string;
13
+ message: string;
14
+ code?: string;
15
+ stack?: string;
16
+ };
17
+ type TerminalFields = {
18
+ outcome: Outcome | string;
19
+ durationMs: number;
20
+ statusCode?: number;
21
+ error?: SerializedError;
22
+ };
23
+ type WideEventBuilder = {
24
+ enrich: (fields: Record<string, unknown>) => void;
25
+ emit: (level: LogLevel, message: string, terminal: TerminalFields) => void;
26
+ };
27
+ type Logger = {
28
+ startOperation: (functionName: string, base?: Record<string, unknown>) => WideEventBuilder;
29
+ };
30
+
31
+ declare const serializeError: (err: unknown) => SerializedError;
32
+ declare const createLogger: (config: LoggerConfig) => Logger;
33
+
34
+ export { LOG_LEVELS, type LogLevel, type Logger, type LoggerConfig, OUTCOMES, type Outcome, type SerializedError, type TerminalFields, type WideEventBuilder, createLogger, serializeError };
@@ -0,0 +1,34 @@
1
+ declare const LOG_LEVELS: readonly ["info", "warn", "error", "debug"];
2
+ declare const OUTCOMES: readonly ["success", "error", "validation_failed", "not_found", "conflict", "timeout", "skipped"];
3
+
4
+ type LogLevel = (typeof LOG_LEVELS)[number];
5
+ type Outcome = (typeof OUTCOMES)[number];
6
+ type LoggerConfig = {
7
+ service: string;
8
+ environment?: string;
9
+ redactKeys?: readonly string[];
10
+ };
11
+ type SerializedError = {
12
+ type: string;
13
+ message: string;
14
+ code?: string;
15
+ stack?: string;
16
+ };
17
+ type TerminalFields = {
18
+ outcome: Outcome | string;
19
+ durationMs: number;
20
+ statusCode?: number;
21
+ error?: SerializedError;
22
+ };
23
+ type WideEventBuilder = {
24
+ enrich: (fields: Record<string, unknown>) => void;
25
+ emit: (level: LogLevel, message: string, terminal: TerminalFields) => void;
26
+ };
27
+ type Logger = {
28
+ startOperation: (functionName: string, base?: Record<string, unknown>) => WideEventBuilder;
29
+ };
30
+
31
+ declare const serializeError: (err: unknown) => SerializedError;
32
+ declare const createLogger: (config: LoggerConfig) => Logger;
33
+
34
+ export { LOG_LEVELS, type LogLevel, type Logger, type LoggerConfig, OUTCOMES, type Outcome, type SerializedError, type TerminalFields, type WideEventBuilder, createLogger, serializeError };
package/dist/index.js ADDED
@@ -0,0 +1,51 @@
1
+ // src/logger.ts
2
+ import pino from "pino";
3
+ var serializeError = (err) => err instanceof Error ? {
4
+ type: err.name,
5
+ message: err.message,
6
+ code: err.code,
7
+ stack: err.stack
8
+ } : { type: "UnknownError", message: String(err) };
9
+ var createWideEventBuilder = (base, log) => {
10
+ const ctx = { ...base };
11
+ return {
12
+ enrich: (fields) => Object.assign(ctx, fields),
13
+ emit: (level, message, terminal) => log[level]({ ...ctx, ...terminal }, message)
14
+ };
15
+ };
16
+ var createLogger = (config) => {
17
+ const log = pino({
18
+ level: process.env.LOG_LEVEL ?? "info",
19
+ base: { service: config.service, environment: config.environment },
20
+ formatters: {
21
+ level: (label) => ({ level: label })
22
+ },
23
+ timestamp: pino.stdTimeFunctions.isoTime,
24
+ redact: {
25
+ paths: config.redactKeys ?? [],
26
+ censor: "[REDACTED]"
27
+ }
28
+ });
29
+ return {
30
+ startOperation: (functionName, base = {}) => createWideEventBuilder({ function: functionName, ...base }, log)
31
+ };
32
+ };
33
+
34
+ // src/constants.ts
35
+ var LOG_LEVELS = ["info", "warn", "error", "debug"];
36
+ var OUTCOMES = [
37
+ "success",
38
+ "error",
39
+ "validation_failed",
40
+ "not_found",
41
+ "conflict",
42
+ "timeout",
43
+ "skipped"
44
+ ];
45
+ export {
46
+ LOG_LEVELS,
47
+ OUTCOMES,
48
+ createLogger,
49
+ serializeError
50
+ };
51
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/logger.ts","../src/constants.ts"],"sourcesContent":["import pino from 'pino';\nimport type { Logger, LoggerConfig, SerializedError, TerminalFields, WideEventBuilder } from './types.js';\n\nexport const serializeError = (err: unknown): SerializedError =>\n err instanceof Error\n ? {\n type: err.name,\n message: err.message,\n code: (err as { code?: string }).code,\n stack: err.stack,\n }\n : { type: 'UnknownError', message: String(err) };\n\nconst createWideEventBuilder = (\n base: Record<string, unknown>,\n log: pino.Logger,\n): WideEventBuilder => {\n const ctx = { ...base };\n return {\n enrich: (fields) => Object.assign(ctx, fields),\n emit: (level, message, terminal: TerminalFields) => log[level]({ ...ctx, ...terminal }, message),\n };\n};\n\nexport const createLogger = (config: LoggerConfig): Logger => {\n const log = pino({\n level: process.env.LOG_LEVEL ?? 'info',\n base: { service: config.service, environment: config.environment },\n formatters: {\n level: (label) => ({ level: label }),\n },\n timestamp: pino.stdTimeFunctions.isoTime,\n redact: {\n paths: (config.redactKeys as string[]) ?? [],\n censor: '[REDACTED]',\n },\n });\n\n return {\n startOperation: (functionName, base = {}) =>\n createWideEventBuilder({ function: functionName, ...base }, log),\n };\n};\n","export const LOG_LEVELS = ['info', 'warn', 'error', 'debug'] as const;\n\nexport const OUTCOMES = [\n 'success',\n 'error',\n 'validation_failed',\n 'not_found',\n 'conflict',\n 'timeout',\n 'skipped',\n] as const;\n"],"mappings":";AAAA,OAAO,UAAU;AAGV,IAAM,iBAAiB,CAAC,QAC7B,eAAe,QACX;AAAA,EACE,MAAM,IAAI;AAAA,EACV,SAAS,IAAI;AAAA,EACb,MAAO,IAA0B;AAAA,EACjC,OAAO,IAAI;AACb,IACA,EAAE,MAAM,gBAAgB,SAAS,OAAO,GAAG,EAAE;AAEnD,IAAM,yBAAyB,CAC7B,MACA,QACqB;AACrB,QAAM,MAAM,EAAE,GAAG,KAAK;AACtB,SAAO;AAAA,IACL,QAAQ,CAAC,WAAW,OAAO,OAAO,KAAK,MAAM;AAAA,IAC7C,MAAM,CAAC,OAAO,SAAS,aAA6B,IAAI,KAAK,EAAE,EAAE,GAAG,KAAK,GAAG,SAAS,GAAG,OAAO;AAAA,EACjG;AACF;AAEO,IAAM,eAAe,CAAC,WAAiC;AAC5D,QAAM,MAAM,KAAK;AAAA,IACf,OAAO,QAAQ,IAAI,aAAa;AAAA,IAChC,MAAM,EAAE,SAAS,OAAO,SAAS,aAAa,OAAO,YAAY;AAAA,IACjE,YAAY;AAAA,MACV,OAAO,CAAC,WAAW,EAAE,OAAO,MAAM;AAAA,IACpC;AAAA,IACA,WAAW,KAAK,iBAAiB;AAAA,IACjC,QAAQ;AAAA,MACN,OAAQ,OAAO,cAA2B,CAAC;AAAA,MAC3C,QAAQ;AAAA,IACV;AAAA,EACF,CAAC;AAED,SAAO;AAAA,IACL,gBAAgB,CAAC,cAAc,OAAO,CAAC,MACrC,uBAAuB,EAAE,UAAU,cAAc,GAAG,KAAK,GAAG,GAAG;AAAA,EACnE;AACF;;;AC1CO,IAAM,aAAa,CAAC,QAAQ,QAAQ,SAAS,OAAO;AAEpD,IAAM,WAAW;AAAA,EACtB;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF;","names":[]}
package/package.json ADDED
@@ -0,0 +1,44 @@
1
+ {
2
+ "name": "tpaga-logger",
3
+ "version": "0.0.1",
4
+ "description": "Structured logging SDK for Tpaga microservices (wide events → CloudWatch)",
5
+ "type": "module",
6
+ "publishConfig": {
7
+ "access": "public"
8
+ },
9
+ "main": "./dist/index.cjs",
10
+ "module": "./dist/index.js",
11
+ "types": "./dist/index.d.ts",
12
+ "exports": {
13
+ ".": {
14
+ "types": "./dist/index.d.ts",
15
+ "import": "./dist/index.js",
16
+ "require": "./dist/index.cjs"
17
+ }
18
+ },
19
+ "files": [
20
+ "dist"
21
+ ],
22
+ "engines": {
23
+ "node": ">=20"
24
+ },
25
+ "dependencies": {
26
+ "pino": "^10.3.1"
27
+ },
28
+ "devDependencies": {
29
+ "@eslint/js": "^9.28.0",
30
+ "@types/node": "^22.15.0",
31
+ "eslint": "^9.28.0",
32
+ "tsup": "^8.5.0",
33
+ "typescript": "^5.8.3",
34
+ "typescript-eslint": "^8.33.0",
35
+ "vitest": "^3.2.0"
36
+ },
37
+ "scripts": {
38
+ "build": "tsup",
39
+ "test": "vitest run",
40
+ "test:watch": "vitest",
41
+ "lint": "eslint src tests",
42
+ "typecheck": "tsc --noEmit"
43
+ }
44
+ }