@x12i/logxer 4.0.0
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/LICENSE +21 -0
- package/README.md +1255 -0
- package/dist/app-info.d.ts +25 -0
- package/dist/app-info.d.ts.map +1 -0
- package/dist/app-info.js +179 -0
- package/dist/app-info.js.map +1 -0
- package/dist/formatters/table-formatter.d.ts +23 -0
- package/dist/formatters/table-formatter.d.ts.map +1 -0
- package/dist/formatters/table-formatter.js +218 -0
- package/dist/formatters/table-formatter.js.map +1 -0
- package/dist/formatters/yaml-formatter.d.ts +14 -0
- package/dist/formatters/yaml-formatter.d.ts.map +1 -0
- package/dist/formatters/yaml-formatter.js +164 -0
- package/dist/formatters/yaml-formatter.js.map +1 -0
- package/dist/index.d.ts +44 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +219 -0
- package/dist/index.js.map +1 -0
- package/dist/logxer.d.ts +145 -0
- package/dist/logxer.d.ts.map +1 -0
- package/dist/logxer.js +811 -0
- package/dist/logxer.js.map +1 -0
- package/dist/outputs/shadow-sink.d.ts +83 -0
- package/dist/outputs/shadow-sink.d.ts.map +1 -0
- package/dist/outputs/shadow-sink.js +380 -0
- package/dist/outputs/shadow-sink.js.map +1 -0
- package/dist/outputs/unified-logger-output.d.ts +30 -0
- package/dist/outputs/unified-logger-output.d.ts.map +1 -0
- package/dist/outputs/unified-logger-output.js +125 -0
- package/dist/outputs/unified-logger-output.js.map +1 -0
- package/dist/sanitizer.d.ts +69 -0
- package/dist/sanitizer.d.ts.map +1 -0
- package/dist/sanitizer.js +507 -0
- package/dist/sanitizer.js.map +1 -0
- package/dist/trails/headers.d.ts +21 -0
- package/dist/trails/headers.d.ts.map +1 -0
- package/dist/trails/headers.js +121 -0
- package/dist/trails/headers.js.map +1 -0
- package/dist/trails/index.d.ts +59 -0
- package/dist/trails/index.d.ts.map +1 -0
- package/dist/trails/index.js +197 -0
- package/dist/trails/index.js.map +1 -0
- package/dist/types.d.ts +411 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +8 -0
- package/dist/types.js.map +1 -0
- package/dist/utils/debug-config.d.ts +19 -0
- package/dist/utils/debug-config.d.ts.map +1 -0
- package/dist/utils/debug-config.js +172 -0
- package/dist/utils/debug-config.js.map +1 -0
- package/dist/utils/package-logs-level.d.ts +40 -0
- package/dist/utils/package-logs-level.d.ts.map +1 -0
- package/dist/utils/package-logs-level.js +79 -0
- package/dist/utils/package-logs-level.js.map +1 -0
- package/docs/package-usage.md +155 -0
- package/docs/package.md +48 -0
- package/docs/upgrade-for-package-authors.md +85 -0
- package/package.json +98 -0
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Automatic detection of consuming application's package name and version
|
|
3
|
+
*
|
|
4
|
+
* This module automatically reads the consuming project's package.json
|
|
5
|
+
* to include app name and version in log entries for better traceability.
|
|
6
|
+
*/
|
|
7
|
+
export interface AppInfo {
|
|
8
|
+
name?: string;
|
|
9
|
+
version?: string;
|
|
10
|
+
}
|
|
11
|
+
/**
|
|
12
|
+
* Automatically detect the consuming application's package name and version
|
|
13
|
+
* by searching up the directory tree for the nearest package.json file
|
|
14
|
+
* that is not in node_modules.
|
|
15
|
+
*
|
|
16
|
+
* This is cached after first call for performance.
|
|
17
|
+
*
|
|
18
|
+
* @returns Object with name and version, or empty object if not found
|
|
19
|
+
*/
|
|
20
|
+
export declare function detectAppInfo(): AppInfo;
|
|
21
|
+
/**
|
|
22
|
+
* Reset the cached app info (useful for testing)
|
|
23
|
+
*/
|
|
24
|
+
export declare function resetAppInfoCache(): void;
|
|
25
|
+
//# sourceMappingURL=app-info.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"app-info.d.ts","sourceRoot":"","sources":["../src/app-info.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAKH,MAAM,WAAW,OAAO;IACtB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB;AAID;;;;;;;;GAQG;AACH,wBAAgB,aAAa,IAAI,OAAO,CA4HvC;AAED;;GAEG;AACH,wBAAgB,iBAAiB,IAAI,IAAI,CAExC"}
|
package/dist/app-info.js
ADDED
|
@@ -0,0 +1,179 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Automatic detection of consuming application's package name and version
|
|
4
|
+
*
|
|
5
|
+
* This module automatically reads the consuming project's package.json
|
|
6
|
+
* to include app name and version in log entries for better traceability.
|
|
7
|
+
*/
|
|
8
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
9
|
+
if (k2 === undefined) k2 = k;
|
|
10
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
11
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
12
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
13
|
+
}
|
|
14
|
+
Object.defineProperty(o, k2, desc);
|
|
15
|
+
}) : (function(o, m, k, k2) {
|
|
16
|
+
if (k2 === undefined) k2 = k;
|
|
17
|
+
o[k2] = m[k];
|
|
18
|
+
}));
|
|
19
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
20
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
21
|
+
}) : function(o, v) {
|
|
22
|
+
o["default"] = v;
|
|
23
|
+
});
|
|
24
|
+
var __importStar = (this && this.__importStar) || (function () {
|
|
25
|
+
var ownKeys = function(o) {
|
|
26
|
+
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
27
|
+
var ar = [];
|
|
28
|
+
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
29
|
+
return ar;
|
|
30
|
+
};
|
|
31
|
+
return ownKeys(o);
|
|
32
|
+
};
|
|
33
|
+
return function (mod) {
|
|
34
|
+
if (mod && mod.__esModule) return mod;
|
|
35
|
+
var result = {};
|
|
36
|
+
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
37
|
+
__setModuleDefault(result, mod);
|
|
38
|
+
return result;
|
|
39
|
+
};
|
|
40
|
+
})();
|
|
41
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
42
|
+
exports.detectAppInfo = detectAppInfo;
|
|
43
|
+
exports.resetAppInfoCache = resetAppInfoCache;
|
|
44
|
+
const fs = __importStar(require("fs"));
|
|
45
|
+
const path = __importStar(require("path"));
|
|
46
|
+
let cachedAppInfo = null;
|
|
47
|
+
/**
|
|
48
|
+
* Automatically detect the consuming application's package name and version
|
|
49
|
+
* by searching up the directory tree for the nearest package.json file
|
|
50
|
+
* that is not in node_modules.
|
|
51
|
+
*
|
|
52
|
+
* This is cached after first call for performance.
|
|
53
|
+
*
|
|
54
|
+
* @returns Object with name and version, or empty object if not found
|
|
55
|
+
*/
|
|
56
|
+
function detectAppInfo() {
|
|
57
|
+
// Return cached result if available
|
|
58
|
+
if (cachedAppInfo !== null) {
|
|
59
|
+
return cachedAppInfo;
|
|
60
|
+
}
|
|
61
|
+
try {
|
|
62
|
+
// Determine logs-gateway's own package.json location
|
|
63
|
+
// __dirname in compiled code will be dist/app-info.js, so we go up to find logs-gateway root
|
|
64
|
+
let logsGatewayPackageJsonPath = null;
|
|
65
|
+
let logsGatewayRootDir = null;
|
|
66
|
+
// Search up from __dirname to find logs-gateway's own package.json
|
|
67
|
+
const rootPath = path.parse(__dirname).root;
|
|
68
|
+
let searchDir = __dirname;
|
|
69
|
+
while (searchDir !== rootPath) {
|
|
70
|
+
const packageJsonPath = path.join(searchDir, 'package.json');
|
|
71
|
+
if (fs.existsSync(packageJsonPath) && !searchDir.includes('node_modules')) {
|
|
72
|
+
try {
|
|
73
|
+
const packageJsonContent = fs.readFileSync(packageJsonPath, 'utf8');
|
|
74
|
+
const packageJson = JSON.parse(packageJsonContent);
|
|
75
|
+
// Check if this is logs-gateway's own package.json
|
|
76
|
+
if (packageJson.name === 'logs-gateway') {
|
|
77
|
+
logsGatewayPackageJsonPath = path.resolve(packageJsonPath);
|
|
78
|
+
logsGatewayRootDir = path.resolve(searchDir);
|
|
79
|
+
break;
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
catch (parseError) {
|
|
83
|
+
// Invalid JSON, continue searching
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
const parentDir = path.dirname(searchDir);
|
|
87
|
+
if (parentDir === searchDir) {
|
|
88
|
+
break;
|
|
89
|
+
}
|
|
90
|
+
searchDir = parentDir;
|
|
91
|
+
}
|
|
92
|
+
// Strategy: Start from process.cwd() (the working directory where the app is running)
|
|
93
|
+
// and search up until we find a package.json that's not in node_modules
|
|
94
|
+
// If we find logs-gateway's own package.json, check if we're running from within logs-gateway
|
|
95
|
+
// (i.e., logs-gateway IS the app). If so, use it. Otherwise, skip it and continue searching.
|
|
96
|
+
let currentDir = process.cwd();
|
|
97
|
+
const cwdRootPath = path.parse(currentDir).root;
|
|
98
|
+
while (currentDir !== cwdRootPath) {
|
|
99
|
+
const packageJsonPath = path.join(currentDir, 'package.json');
|
|
100
|
+
// Check if package.json exists and is not in node_modules
|
|
101
|
+
if (fs.existsSync(packageJsonPath) && !currentDir.includes('node_modules')) {
|
|
102
|
+
try {
|
|
103
|
+
const packageJsonContent = fs.readFileSync(packageJsonPath, 'utf8');
|
|
104
|
+
const packageJson = JSON.parse(packageJsonContent);
|
|
105
|
+
const resolvedPackageJsonPath = path.resolve(packageJsonPath);
|
|
106
|
+
// If this is logs-gateway's own package.json
|
|
107
|
+
if (packageJson.name === 'logs-gateway') {
|
|
108
|
+
// Check if we're running from within logs-gateway's directory
|
|
109
|
+
// (i.e., logs-gateway IS the app, not a dependency)
|
|
110
|
+
// We check if the current working directory is within logs-gateway's root
|
|
111
|
+
const resolvedCwd = path.resolve(process.cwd());
|
|
112
|
+
const isWithinLogsGateway = logsGatewayRootDir && (resolvedCwd === logsGatewayRootDir ||
|
|
113
|
+
resolvedCwd.startsWith(logsGatewayRootDir + path.sep));
|
|
114
|
+
if (isWithinLogsGateway &&
|
|
115
|
+
resolvedPackageJsonPath === logsGatewayPackageJsonPath) {
|
|
116
|
+
// We're running from logs-gateway itself, use its package.json
|
|
117
|
+
const appInfo = {};
|
|
118
|
+
if (packageJson.name) {
|
|
119
|
+
appInfo.name = packageJson.name;
|
|
120
|
+
}
|
|
121
|
+
if (packageJson.version) {
|
|
122
|
+
appInfo.version = packageJson.version;
|
|
123
|
+
}
|
|
124
|
+
cachedAppInfo = appInfo;
|
|
125
|
+
return appInfo;
|
|
126
|
+
}
|
|
127
|
+
else {
|
|
128
|
+
// This is logs-gateway's package.json but we're using it as a dependency
|
|
129
|
+
// Skip it and continue searching for the consuming app's package.json
|
|
130
|
+
const parentDir = path.dirname(currentDir);
|
|
131
|
+
if (parentDir === currentDir) {
|
|
132
|
+
break;
|
|
133
|
+
}
|
|
134
|
+
currentDir = parentDir;
|
|
135
|
+
continue;
|
|
136
|
+
}
|
|
137
|
+
}
|
|
138
|
+
// Found a valid package.json that's not logs-gateway - extract name and version
|
|
139
|
+
const appInfo = {};
|
|
140
|
+
if (packageJson.name) {
|
|
141
|
+
appInfo.name = packageJson.name;
|
|
142
|
+
}
|
|
143
|
+
if (packageJson.version) {
|
|
144
|
+
appInfo.version = packageJson.version;
|
|
145
|
+
}
|
|
146
|
+
// Cache the result
|
|
147
|
+
cachedAppInfo = appInfo;
|
|
148
|
+
return appInfo;
|
|
149
|
+
}
|
|
150
|
+
catch (parseError) {
|
|
151
|
+
// Invalid JSON, continue searching
|
|
152
|
+
}
|
|
153
|
+
}
|
|
154
|
+
// Move up one directory
|
|
155
|
+
const parentDir = path.dirname(currentDir);
|
|
156
|
+
if (parentDir === currentDir) {
|
|
157
|
+
// Reached root, stop searching
|
|
158
|
+
break;
|
|
159
|
+
}
|
|
160
|
+
currentDir = parentDir;
|
|
161
|
+
}
|
|
162
|
+
// If we reach here, no package.json was found
|
|
163
|
+
// Cache empty result to avoid repeated searches
|
|
164
|
+
cachedAppInfo = {};
|
|
165
|
+
return {};
|
|
166
|
+
}
|
|
167
|
+
catch (error) {
|
|
168
|
+
// If any error occurs, return empty and cache it
|
|
169
|
+
cachedAppInfo = {};
|
|
170
|
+
return {};
|
|
171
|
+
}
|
|
172
|
+
}
|
|
173
|
+
/**
|
|
174
|
+
* Reset the cached app info (useful for testing)
|
|
175
|
+
*/
|
|
176
|
+
function resetAppInfoCache() {
|
|
177
|
+
cachedAppInfo = null;
|
|
178
|
+
}
|
|
179
|
+
//# sourceMappingURL=app-info.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"app-info.js","sourceRoot":"","sources":["../src/app-info.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* logs-gateway - Table Formatter
|
|
3
|
+
*
|
|
4
|
+
* This file contains the table formatting logic for console log entries.
|
|
5
|
+
*/
|
|
6
|
+
import type { LogEnvelope } from '../types';
|
|
7
|
+
/**
|
|
8
|
+
* Format a log entry as a table row for console output
|
|
9
|
+
*
|
|
10
|
+
* @param envelope - The log envelope to format
|
|
11
|
+
* @returns Formatted table row object
|
|
12
|
+
*/
|
|
13
|
+
export declare function formatLogEntryAsTable(envelope: LogEnvelope): Record<string, any>;
|
|
14
|
+
/**
|
|
15
|
+
* Output log entry as a simple text line (conceptual table format)
|
|
16
|
+
* Each log entry is displayed as a single line with key fields.
|
|
17
|
+
* No truncation - full message is shown. Terminal will handle wrapping if configured.
|
|
18
|
+
*
|
|
19
|
+
* @param envelope - The log envelope to format
|
|
20
|
+
* @param showFullTimestamp - If true, show full ISO timestamp; if false, show short time format (default: false)
|
|
21
|
+
*/
|
|
22
|
+
export declare function outputLogAsTable(envelope: LogEnvelope, showFullTimestamp?: boolean): void;
|
|
23
|
+
//# sourceMappingURL=table-formatter.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"table-formatter.d.ts","sourceRoot":"","sources":["../../src/formatters/table-formatter.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,UAAU,CAAC;AAE5C;;;;;GAKG;AACH,wBAAgB,qBAAqB,CAAC,QAAQ,EAAE,WAAW,GAAG,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CAqEhF;AAgED;;;;;;;GAOG;AACH,wBAAgB,gBAAgB,CAAC,QAAQ,EAAE,WAAW,EAAE,iBAAiB,GAAE,OAAe,GAAG,IAAI,CAoFhG"}
|
|
@@ -0,0 +1,218 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* logs-gateway - Table Formatter
|
|
4
|
+
*
|
|
5
|
+
* This file contains the table formatting logic for console log entries.
|
|
6
|
+
*/
|
|
7
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
8
|
+
exports.formatLogEntryAsTable = formatLogEntryAsTable;
|
|
9
|
+
exports.outputLogAsTable = outputLogAsTable;
|
|
10
|
+
/**
|
|
11
|
+
* Format a log entry as a table row for console output
|
|
12
|
+
*
|
|
13
|
+
* @param envelope - The log envelope to format
|
|
14
|
+
* @returns Formatted table row object
|
|
15
|
+
*/
|
|
16
|
+
function formatLogEntryAsTable(envelope) {
|
|
17
|
+
const row = {
|
|
18
|
+
Time: formatTimestamp(envelope.timestamp),
|
|
19
|
+
Level: formatLevel(envelope.level),
|
|
20
|
+
Package: envelope.package,
|
|
21
|
+
Message: envelope.message,
|
|
22
|
+
};
|
|
23
|
+
// Add source if present
|
|
24
|
+
if (envelope.source && envelope.source !== 'application') {
|
|
25
|
+
row.Source = envelope.source;
|
|
26
|
+
}
|
|
27
|
+
// Add app name/version if present
|
|
28
|
+
if (envelope.appName) {
|
|
29
|
+
row.App = envelope.appName;
|
|
30
|
+
}
|
|
31
|
+
if (envelope.appVersion) {
|
|
32
|
+
row.Version = envelope.appVersion;
|
|
33
|
+
}
|
|
34
|
+
// Add correlation ID if present
|
|
35
|
+
if (envelope.correlationId) {
|
|
36
|
+
row.Correlation = envelope.correlationId;
|
|
37
|
+
}
|
|
38
|
+
// Add job/run/session IDs if present
|
|
39
|
+
if (envelope.jobId) {
|
|
40
|
+
row.Job = envelope.jobId;
|
|
41
|
+
}
|
|
42
|
+
if (envelope.runId) {
|
|
43
|
+
row.Run = envelope.runId;
|
|
44
|
+
}
|
|
45
|
+
if (envelope.sessionId) {
|
|
46
|
+
row.Session = envelope.sessionId;
|
|
47
|
+
}
|
|
48
|
+
// Add operation info if present
|
|
49
|
+
if (envelope.operationName) {
|
|
50
|
+
row.Operation = envelope.operationName;
|
|
51
|
+
}
|
|
52
|
+
// Add thread info if present
|
|
53
|
+
if (envelope.threadId) {
|
|
54
|
+
row.Thread = envelope.threadId;
|
|
55
|
+
}
|
|
56
|
+
// Add trace/span if present
|
|
57
|
+
if (envelope.traceId) {
|
|
58
|
+
row.Trace = envelope.traceId.substring(0, 8); // Short trace ID
|
|
59
|
+
}
|
|
60
|
+
if (envelope.spanId) {
|
|
61
|
+
row.Span = envelope.spanId.substring(0, 8); // Short span ID
|
|
62
|
+
}
|
|
63
|
+
// Add data summary if present
|
|
64
|
+
if (envelope.data) {
|
|
65
|
+
const dataStr = formatDataSummary(envelope.data);
|
|
66
|
+
if (dataStr) {
|
|
67
|
+
row.Data = dataStr;
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
// Add tags if present
|
|
71
|
+
if (envelope.tags && envelope.tags.length > 0) {
|
|
72
|
+
row.Tags = envelope.tags.join(', ');
|
|
73
|
+
}
|
|
74
|
+
return row;
|
|
75
|
+
}
|
|
76
|
+
/**
|
|
77
|
+
* Format timestamp to a shorter, more readable format
|
|
78
|
+
*/
|
|
79
|
+
function formatTimestamp(timestamp) {
|
|
80
|
+
try {
|
|
81
|
+
const date = new Date(timestamp);
|
|
82
|
+
const hours = String(date.getHours()).padStart(2, '0');
|
|
83
|
+
const minutes = String(date.getMinutes()).padStart(2, '0');
|
|
84
|
+
const seconds = String(date.getSeconds()).padStart(2, '0');
|
|
85
|
+
const ms = String(date.getMilliseconds()).padStart(3, '0');
|
|
86
|
+
return `${hours}:${minutes}:${seconds}.${ms}`;
|
|
87
|
+
}
|
|
88
|
+
catch {
|
|
89
|
+
return timestamp;
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
/**
|
|
93
|
+
* Format log level with color indicators (for display)
|
|
94
|
+
*/
|
|
95
|
+
function formatLevel(level) {
|
|
96
|
+
const levelUpper = level.toUpperCase();
|
|
97
|
+
// Return level with emoji indicators for better visibility
|
|
98
|
+
const indicators = {
|
|
99
|
+
'VERBOSE': '🔍',
|
|
100
|
+
'DEBUG': '🐛',
|
|
101
|
+
'INFO': 'ℹ️',
|
|
102
|
+
'WARN': '⚠️',
|
|
103
|
+
'ERROR': '❌'
|
|
104
|
+
};
|
|
105
|
+
return `${indicators[levelUpper] || ''} ${levelUpper}`;
|
|
106
|
+
}
|
|
107
|
+
/**
|
|
108
|
+
* Format data object to a compact string summary
|
|
109
|
+
*/
|
|
110
|
+
function formatDataSummary(data) {
|
|
111
|
+
if (!data || typeof data !== 'object') {
|
|
112
|
+
return String(data);
|
|
113
|
+
}
|
|
114
|
+
try {
|
|
115
|
+
// Remove internal/routing fields from summary
|
|
116
|
+
const { _routing, _sanitization, _shadow, source, ...rest } = data;
|
|
117
|
+
// If no meaningful data left, return empty
|
|
118
|
+
if (Object.keys(rest).length === 0) {
|
|
119
|
+
return '';
|
|
120
|
+
}
|
|
121
|
+
// Create a compact summary
|
|
122
|
+
const entries = Object.entries(rest).slice(0, 3); // Limit to first 3 fields
|
|
123
|
+
const summary = entries.map(([key, value]) => {
|
|
124
|
+
const valStr = typeof value === 'object' ? JSON.stringify(value).substring(0, 30) : String(value);
|
|
125
|
+
return `${key}:${valStr.length > 30 ? valStr.substring(0, 30) + '...' : valStr}`;
|
|
126
|
+
}).join(', ');
|
|
127
|
+
return summary.length > 80 ? summary.substring(0, 80) + '...' : summary;
|
|
128
|
+
}
|
|
129
|
+
catch {
|
|
130
|
+
return '[object]';
|
|
131
|
+
}
|
|
132
|
+
}
|
|
133
|
+
/**
|
|
134
|
+
* Output log entry as a simple text line (conceptual table format)
|
|
135
|
+
* Each log entry is displayed as a single line with key fields.
|
|
136
|
+
* No truncation - full message is shown. Terminal will handle wrapping if configured.
|
|
137
|
+
*
|
|
138
|
+
* @param envelope - The log envelope to format
|
|
139
|
+
* @param showFullTimestamp - If true, show full ISO timestamp; if false, show short time format (default: false)
|
|
140
|
+
*/
|
|
141
|
+
function outputLogAsTable(envelope, showFullTimestamp = false) {
|
|
142
|
+
const parts = [];
|
|
143
|
+
// Time format - full ISO timestamp or short format
|
|
144
|
+
const time = showFullTimestamp ? envelope.timestamp : formatTimestamp(envelope.timestamp);
|
|
145
|
+
parts.push(`[${time}]`);
|
|
146
|
+
// Level with indicator - fixed width for alignment
|
|
147
|
+
const level = formatLevel(envelope.level);
|
|
148
|
+
// Pad level to consistent width (accounting for emoji + space)
|
|
149
|
+
const levelPadded = level.padEnd(8);
|
|
150
|
+
parts.push(levelPadded);
|
|
151
|
+
// Package - fixed width bracket format
|
|
152
|
+
parts.push(`[${envelope.package}]`);
|
|
153
|
+
// Message - FULL LENGTH, no truncation
|
|
154
|
+
// User can scroll horizontally if needed, or scroll down if not interested
|
|
155
|
+
parts.push(envelope.message);
|
|
156
|
+
// Optional metadata fields (compact format, separated by pipe)
|
|
157
|
+
const metadataParts = [];
|
|
158
|
+
if (envelope.appName) {
|
|
159
|
+
metadataParts.push(`app:${envelope.appName}`);
|
|
160
|
+
}
|
|
161
|
+
if (envelope.appVersion) {
|
|
162
|
+
metadataParts.push(`v:${envelope.appVersion}`);
|
|
163
|
+
}
|
|
164
|
+
if (envelope.source && envelope.source !== 'application') {
|
|
165
|
+
metadataParts.push(`src:${envelope.source}`);
|
|
166
|
+
}
|
|
167
|
+
if (envelope.correlationId) {
|
|
168
|
+
metadataParts.push(`corr:${envelope.correlationId}`);
|
|
169
|
+
}
|
|
170
|
+
if (envelope.jobId) {
|
|
171
|
+
metadataParts.push(`job:${envelope.jobId}`);
|
|
172
|
+
}
|
|
173
|
+
if (envelope.runId) {
|
|
174
|
+
metadataParts.push(`run:${envelope.runId}`);
|
|
175
|
+
}
|
|
176
|
+
if (envelope.sessionId) {
|
|
177
|
+
metadataParts.push(`session:${envelope.sessionId}`);
|
|
178
|
+
}
|
|
179
|
+
if (envelope.operationName) {
|
|
180
|
+
metadataParts.push(`op:${envelope.operationName}`);
|
|
181
|
+
}
|
|
182
|
+
if (envelope.threadId) {
|
|
183
|
+
metadataParts.push(`thread:${envelope.threadId}`);
|
|
184
|
+
}
|
|
185
|
+
if (envelope.traceId) {
|
|
186
|
+
metadataParts.push(`trace:${envelope.traceId}`);
|
|
187
|
+
}
|
|
188
|
+
if (envelope.spanId) {
|
|
189
|
+
metadataParts.push(`span:${envelope.spanId}`);
|
|
190
|
+
}
|
|
191
|
+
if (envelope.tags && envelope.tags.length > 0) {
|
|
192
|
+
metadataParts.push(`tags:${envelope.tags.join(',')}`);
|
|
193
|
+
}
|
|
194
|
+
if (envelope.identity) {
|
|
195
|
+
metadataParts.push(`identity:${envelope.identity}`);
|
|
196
|
+
}
|
|
197
|
+
// Add metadata section if present (separated by pipe for visual clarity)
|
|
198
|
+
if (metadataParts.length > 0) {
|
|
199
|
+
parts.push(`| ${metadataParts.join(' ')}`);
|
|
200
|
+
}
|
|
201
|
+
// Data section (if present) - FULL data, no truncation
|
|
202
|
+
// Separated by double pipe for visual distinction
|
|
203
|
+
if (envelope.data) {
|
|
204
|
+
try {
|
|
205
|
+
// Format data as compact JSON (single line, no pretty printing)
|
|
206
|
+
const dataJson = JSON.stringify(envelope.data);
|
|
207
|
+
parts.push(`|| ${dataJson}`);
|
|
208
|
+
}
|
|
209
|
+
catch {
|
|
210
|
+
// If JSON.stringify fails, use string representation
|
|
211
|
+
parts.push(`|| ${String(envelope.data)}`);
|
|
212
|
+
}
|
|
213
|
+
}
|
|
214
|
+
// Output as single line - terminal will handle wrapping naturally
|
|
215
|
+
// No forced wrapping - user controls via terminal settings or horizontal scrolling
|
|
216
|
+
console.log(parts.join(' '));
|
|
217
|
+
}
|
|
218
|
+
//# sourceMappingURL=table-formatter.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"table-formatter.js","sourceRoot":"","sources":["../../src/formatters/table-formatter.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* logs-gateway - YAML Formatter
|
|
3
|
+
*
|
|
4
|
+
* This file contains the YAML formatting logic for log entries.
|
|
5
|
+
*/
|
|
6
|
+
import type { LogEnvelope } from '../types';
|
|
7
|
+
/**
|
|
8
|
+
* Format a log envelope as YAML
|
|
9
|
+
*
|
|
10
|
+
* @param envelope - The log envelope to format
|
|
11
|
+
* @returns Formatted YAML string with document separator
|
|
12
|
+
*/
|
|
13
|
+
export declare function formatLogEntryAsYaml(envelope: LogEnvelope): string;
|
|
14
|
+
//# sourceMappingURL=yaml-formatter.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"yaml-formatter.d.ts","sourceRoot":"","sources":["../../src/formatters/yaml-formatter.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAGH,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,UAAU,CAAC;AAuC5C;;;;;GAKG;AACH,wBAAgB,oBAAoB,CAAC,QAAQ,EAAE,WAAW,GAAG,MAAM,CA8BlE"}
|
|
@@ -0,0 +1,164 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* logs-gateway - YAML Formatter
|
|
4
|
+
*
|
|
5
|
+
* This file contains the YAML formatting logic for log entries.
|
|
6
|
+
*/
|
|
7
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
8
|
+
if (k2 === undefined) k2 = k;
|
|
9
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
10
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
11
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
12
|
+
}
|
|
13
|
+
Object.defineProperty(o, k2, desc);
|
|
14
|
+
}) : (function(o, m, k, k2) {
|
|
15
|
+
if (k2 === undefined) k2 = k;
|
|
16
|
+
o[k2] = m[k];
|
|
17
|
+
}));
|
|
18
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
19
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
20
|
+
}) : function(o, v) {
|
|
21
|
+
o["default"] = v;
|
|
22
|
+
});
|
|
23
|
+
var __importStar = (this && this.__importStar) || (function () {
|
|
24
|
+
var ownKeys = function(o) {
|
|
25
|
+
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
26
|
+
var ar = [];
|
|
27
|
+
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
28
|
+
return ar;
|
|
29
|
+
};
|
|
30
|
+
return ownKeys(o);
|
|
31
|
+
};
|
|
32
|
+
return function (mod) {
|
|
33
|
+
if (mod && mod.__esModule) return mod;
|
|
34
|
+
var result = {};
|
|
35
|
+
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
36
|
+
__setModuleDefault(result, mod);
|
|
37
|
+
return result;
|
|
38
|
+
};
|
|
39
|
+
})();
|
|
40
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
41
|
+
exports.formatLogEntryAsYaml = formatLogEntryAsYaml;
|
|
42
|
+
const yaml = __importStar(require("js-yaml"));
|
|
43
|
+
/**
|
|
44
|
+
* Replace circular references with a placeholder so YAML/JSON can serialize.
|
|
45
|
+
*/
|
|
46
|
+
function breakCircularRefs(obj, seen = new WeakSet()) {
|
|
47
|
+
if (obj === null || typeof obj !== 'object') {
|
|
48
|
+
return obj;
|
|
49
|
+
}
|
|
50
|
+
if (obj instanceof Date) {
|
|
51
|
+
return obj.toISOString();
|
|
52
|
+
}
|
|
53
|
+
if (seen.has(obj)) {
|
|
54
|
+
return '[Circular]';
|
|
55
|
+
}
|
|
56
|
+
seen.add(obj);
|
|
57
|
+
if (Array.isArray(obj)) {
|
|
58
|
+
return obj.map((item) => breakCircularRefs(item, seen));
|
|
59
|
+
}
|
|
60
|
+
const out = {};
|
|
61
|
+
for (const [k, v] of Object.entries(obj)) {
|
|
62
|
+
out[k] = breakCircularRefs(v, seen);
|
|
63
|
+
}
|
|
64
|
+
return out;
|
|
65
|
+
}
|
|
66
|
+
function safeJsonStringify(value) {
|
|
67
|
+
const seen = new WeakSet();
|
|
68
|
+
return JSON.stringify(value, (_key, v) => {
|
|
69
|
+
if (typeof v === 'object' && v !== null) {
|
|
70
|
+
if (seen.has(v)) {
|
|
71
|
+
return '[Circular]';
|
|
72
|
+
}
|
|
73
|
+
seen.add(v);
|
|
74
|
+
}
|
|
75
|
+
return v;
|
|
76
|
+
});
|
|
77
|
+
}
|
|
78
|
+
/**
|
|
79
|
+
* Format a log envelope as YAML
|
|
80
|
+
*
|
|
81
|
+
* @param envelope - The log envelope to format
|
|
82
|
+
* @returns Formatted YAML string with document separator
|
|
83
|
+
*/
|
|
84
|
+
function formatLogEntryAsYaml(envelope) {
|
|
85
|
+
try {
|
|
86
|
+
// Coerce Date / non-string IDs first so breakCircularRefs does not treat Date as an empty object
|
|
87
|
+
const safeEnvelope = breakCircularRefs(ensureStringTypes(envelope));
|
|
88
|
+
const yamlContent = yaml.dump(safeEnvelope, {
|
|
89
|
+
noRefs: true, // No references/anchors for readability & ingest safety
|
|
90
|
+
skipInvalid: true, // Skip invalid values
|
|
91
|
+
indent: 2, // 2-space indentation
|
|
92
|
+
lineWidth: 120, // Line width limit
|
|
93
|
+
noCompatMode: true, // Use modern YAML features
|
|
94
|
+
quotingType: '"', // Use double quotes for strings
|
|
95
|
+
forceQuotes: false // Only quote when necessary
|
|
96
|
+
});
|
|
97
|
+
return `---\n${yamlContent}`;
|
|
98
|
+
}
|
|
99
|
+
catch {
|
|
100
|
+
const fallbackEnvelope = {
|
|
101
|
+
...envelope,
|
|
102
|
+
data: {
|
|
103
|
+
...envelope.data,
|
|
104
|
+
__meta: {
|
|
105
|
+
...envelope.data?.__meta,
|
|
106
|
+
formatFallback: 'yaml→json'
|
|
107
|
+
}
|
|
108
|
+
}
|
|
109
|
+
};
|
|
110
|
+
return safeJsonStringify(fallbackEnvelope);
|
|
111
|
+
}
|
|
112
|
+
}
|
|
113
|
+
/**
|
|
114
|
+
* Ensure timestamps and IDs are strings to avoid YAML implicit typing issues
|
|
115
|
+
*/
|
|
116
|
+
function ensureStringTypes(envelope) {
|
|
117
|
+
const safe = { ...envelope };
|
|
118
|
+
// Ensure timestamp is string (should already be ISO string)
|
|
119
|
+
if (safe.timestamp && typeof safe.timestamp !== 'string') {
|
|
120
|
+
safe.timestamp = new Date(safe.timestamp).toISOString();
|
|
121
|
+
}
|
|
122
|
+
// Ensure trace/span IDs are strings
|
|
123
|
+
if (safe.traceId && typeof safe.traceId !== 'string') {
|
|
124
|
+
safe.traceId = String(safe.traceId);
|
|
125
|
+
}
|
|
126
|
+
if (safe.spanId && typeof safe.spanId !== 'string') {
|
|
127
|
+
safe.spanId = String(safe.spanId);
|
|
128
|
+
}
|
|
129
|
+
// Ensure operation/thread IDs are strings
|
|
130
|
+
if (safe.operationId && typeof safe.operationId !== 'string') {
|
|
131
|
+
safe.operationId = String(safe.operationId);
|
|
132
|
+
}
|
|
133
|
+
if (safe.threadId && typeof safe.threadId !== 'string') {
|
|
134
|
+
safe.threadId = String(safe.threadId);
|
|
135
|
+
}
|
|
136
|
+
if (safe.eventId && typeof safe.eventId !== 'string') {
|
|
137
|
+
safe.eventId = String(safe.eventId);
|
|
138
|
+
}
|
|
139
|
+
// Ensure correlation/job/session IDs are strings
|
|
140
|
+
if (safe.correlationId && typeof safe.correlationId !== 'string') {
|
|
141
|
+
safe.correlationId = String(safe.correlationId);
|
|
142
|
+
}
|
|
143
|
+
if (safe.jobId && typeof safe.jobId !== 'string') {
|
|
144
|
+
safe.jobId = String(safe.jobId);
|
|
145
|
+
}
|
|
146
|
+
if (safe.runId && typeof safe.runId !== 'string') {
|
|
147
|
+
safe.runId = String(safe.runId);
|
|
148
|
+
}
|
|
149
|
+
if (safe.sessionId && typeof safe.sessionId !== 'string') {
|
|
150
|
+
safe.sessionId = String(safe.sessionId);
|
|
151
|
+
}
|
|
152
|
+
// Ensure sequence numbers are numbers (not strings)
|
|
153
|
+
if (safe.sequenceNo && typeof safe.sequenceNo === 'string') {
|
|
154
|
+
safe.sequenceNo = parseInt(safe.sequenceNo, 10);
|
|
155
|
+
}
|
|
156
|
+
if (safe.operationStep && typeof safe.operationStep === 'string') {
|
|
157
|
+
safe.operationStep = parseInt(safe.operationStep, 10);
|
|
158
|
+
}
|
|
159
|
+
if (safe.attempt && typeof safe.attempt === 'string') {
|
|
160
|
+
safe.attempt = parseInt(safe.attempt, 10);
|
|
161
|
+
}
|
|
162
|
+
return safe;
|
|
163
|
+
}
|
|
164
|
+
//# sourceMappingURL=yaml-formatter.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"yaml-formatter.js","sourceRoot":"","sources":["../../src/formatters/yaml-formatter.ts"],"names":[],"mappings":"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"}
|