@ngn-net/nestjs-telescope 0.2.8 → 0.2.10
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/dist/ui/manifest.json
CHANGED
|
@@ -22,6 +22,10 @@ let ExceptionWatcher = class ExceptionWatcher {
|
|
|
22
22
|
this.telescope = telescope;
|
|
23
23
|
}
|
|
24
24
|
intercept(context, next) {
|
|
25
|
+
// Skip non-HTTP execution contexts (e.g. RPC/RabbitMQ or WebSockets)
|
|
26
|
+
if (context.getType() !== 'http') {
|
|
27
|
+
return next.handle();
|
|
28
|
+
}
|
|
25
29
|
const request = context.switchToHttp().getRequest();
|
|
26
30
|
return next.handle().pipe((0, operators_1.catchError)((err) => {
|
|
27
31
|
this.telescope.record({
|
|
@@ -38,7 +42,7 @@ let ExceptionWatcher = class ExceptionWatcher {
|
|
|
38
42
|
ip: request?.ip,
|
|
39
43
|
},
|
|
40
44
|
},
|
|
41
|
-
});
|
|
45
|
+
}).catch(() => { });
|
|
42
46
|
return (0, rxjs_1.throwError)(() => err);
|
|
43
47
|
}));
|
|
44
48
|
}
|
|
@@ -27,6 +27,10 @@ let HttpRequestWatcher = class HttpRequestWatcher {
|
|
|
27
27
|
this.options = options;
|
|
28
28
|
}
|
|
29
29
|
intercept(context, next) {
|
|
30
|
+
// Skip non-HTTP execution contexts (e.g. RPC/RabbitMQ or WebSockets)
|
|
31
|
+
if (context.getType() !== 'http') {
|
|
32
|
+
return next.handle();
|
|
33
|
+
}
|
|
30
34
|
const request = context.switchToHttp().getRequest();
|
|
31
35
|
const response = context.switchToHttp().getResponse();
|
|
32
36
|
const url = request.originalUrl || request.url || '/';
|
|
@@ -43,20 +47,40 @@ let HttpRequestWatcher = class HttpRequestWatcher {
|
|
|
43
47
|
query: request.query,
|
|
44
48
|
ip: request.ip,
|
|
45
49
|
};
|
|
46
|
-
return next.handle().pipe((0, operators_1.tap)(
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
50
|
+
return next.handle().pipe((0, operators_1.tap)({
|
|
51
|
+
next: (responseBody) => {
|
|
52
|
+
const duration = Date.now() - start;
|
|
53
|
+
const statusCode = response.statusCode || 200;
|
|
54
|
+
this.telescope.record({
|
|
55
|
+
type: entry_type_enum_1.EntryType.REQUEST,
|
|
56
|
+
content: {
|
|
57
|
+
request: requestData,
|
|
58
|
+
response: {
|
|
59
|
+
statusCode,
|
|
60
|
+
body: responseBody,
|
|
61
|
+
},
|
|
62
|
+
duration,
|
|
63
|
+
},
|
|
64
|
+
}).catch(() => { });
|
|
65
|
+
},
|
|
66
|
+
error: (error) => {
|
|
67
|
+
const duration = Date.now() - start;
|
|
68
|
+
const statusCode = error.status || error.statusCode || 500;
|
|
69
|
+
this.telescope.record({
|
|
70
|
+
type: entry_type_enum_1.EntryType.REQUEST,
|
|
71
|
+
content: {
|
|
72
|
+
request: requestData,
|
|
73
|
+
response: {
|
|
74
|
+
statusCode,
|
|
75
|
+
body: {
|
|
76
|
+
message: error.message || String(error),
|
|
77
|
+
error: error.name || 'Error',
|
|
78
|
+
},
|
|
79
|
+
},
|
|
80
|
+
duration,
|
|
56
81
|
},
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
});
|
|
82
|
+
}).catch(() => { });
|
|
83
|
+
},
|
|
60
84
|
}));
|
|
61
85
|
}
|
|
62
86
|
};
|
|
@@ -14,6 +14,44 @@ exports.LogWatcher = void 0;
|
|
|
14
14
|
const common_1 = require("@nestjs/common");
|
|
15
15
|
const telescope_service_1 = require("../telescope.service");
|
|
16
16
|
const entry_type_enum_1 = require("../enums/entry-type.enum");
|
|
17
|
+
class TelescopeLoggerWrapper {
|
|
18
|
+
original;
|
|
19
|
+
recordLog;
|
|
20
|
+
constructor(original, recordLog) {
|
|
21
|
+
this.original = original;
|
|
22
|
+
this.recordLog = recordLog;
|
|
23
|
+
}
|
|
24
|
+
log(message, ...optionalParams) {
|
|
25
|
+
this.recordLog('log', message, ...optionalParams);
|
|
26
|
+
this.original.log(message, ...optionalParams);
|
|
27
|
+
}
|
|
28
|
+
error(message, ...optionalParams) {
|
|
29
|
+
this.recordLog('error', message, ...optionalParams);
|
|
30
|
+
this.original.error(message, ...optionalParams);
|
|
31
|
+
}
|
|
32
|
+
warn(message, ...optionalParams) {
|
|
33
|
+
this.recordLog('warn', message, ...optionalParams);
|
|
34
|
+
this.original.warn(message, ...optionalParams);
|
|
35
|
+
}
|
|
36
|
+
debug(message, ...optionalParams) {
|
|
37
|
+
this.recordLog('debug', message, ...optionalParams);
|
|
38
|
+
if (this.original.debug) {
|
|
39
|
+
this.original.debug(message, ...optionalParams);
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
verbose(message, ...optionalParams) {
|
|
43
|
+
this.recordLog('verbose', message, ...optionalParams);
|
|
44
|
+
if (this.original.verbose) {
|
|
45
|
+
this.original.verbose(message, ...optionalParams);
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
fatal(message, ...optionalParams) {
|
|
49
|
+
this.recordLog('fatal', message, ...optionalParams);
|
|
50
|
+
if (this.original.fatal) {
|
|
51
|
+
this.original.fatal(message, ...optionalParams);
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
}
|
|
17
55
|
let LogWatcher = class LogWatcher {
|
|
18
56
|
telescope;
|
|
19
57
|
isRecording = false; // Guard against infinite recursion
|
|
@@ -27,38 +65,76 @@ let LogWatcher = class LogWatcher {
|
|
|
27
65
|
const originalDebug = console.debug.bind(console);
|
|
28
66
|
const self = this;
|
|
29
67
|
const formatArgs = (args) => args.map((a) => (typeof a === 'object' ? JSON.stringify(a) : String(a))).join(' ');
|
|
30
|
-
const
|
|
31
|
-
// Guard: if we're already recording, skip to prevent infinite recursion
|
|
32
|
-
// (recording a log → save to DB → TypeORM logs → recording again → ...)
|
|
68
|
+
const recordConsoleLog = (level, args) => {
|
|
33
69
|
if (self.isRecording)
|
|
34
70
|
return;
|
|
71
|
+
const message = formatArgs(args);
|
|
72
|
+
// Skip telescope queries, logs, or dashboard routes to prevent recursion
|
|
73
|
+
if (message.includes('telescope_entries') || message.includes('TelescopeModule')) {
|
|
74
|
+
return;
|
|
75
|
+
}
|
|
35
76
|
self.isRecording = true;
|
|
36
77
|
try {
|
|
37
78
|
self.telescope.record({
|
|
38
79
|
type: entry_type_enum_1.EntryType.LOG,
|
|
39
|
-
content: { level, message
|
|
40
|
-
});
|
|
80
|
+
content: { level, message },
|
|
81
|
+
}).catch(() => { });
|
|
41
82
|
}
|
|
42
83
|
finally {
|
|
43
84
|
self.isRecording = false;
|
|
44
85
|
}
|
|
45
86
|
};
|
|
87
|
+
// 1. Intercept raw console logs
|
|
46
88
|
console.log = function (...args) {
|
|
47
|
-
|
|
89
|
+
recordConsoleLog('log', args);
|
|
48
90
|
return originalLog(...args);
|
|
49
91
|
};
|
|
50
92
|
console.error = function (...args) {
|
|
51
|
-
|
|
93
|
+
recordConsoleLog('error', args);
|
|
52
94
|
return originalError(...args);
|
|
53
95
|
};
|
|
54
96
|
console.warn = function (...args) {
|
|
55
|
-
|
|
97
|
+
recordConsoleLog('warn', args);
|
|
56
98
|
return originalWarn(...args);
|
|
57
99
|
};
|
|
58
100
|
console.debug = function (...args) {
|
|
59
|
-
|
|
101
|
+
recordConsoleLog('debug', args);
|
|
60
102
|
return originalDebug(...args);
|
|
61
103
|
};
|
|
104
|
+
// 2. Intercept NestJS Logger Service logs
|
|
105
|
+
try {
|
|
106
|
+
const activeLogger = common_1.Logger.logger;
|
|
107
|
+
if (activeLogger && !(activeLogger instanceof TelescopeLoggerWrapper)) {
|
|
108
|
+
const wrapper = new TelescopeLoggerWrapper(activeLogger, (level, message, ...optionalParams) => {
|
|
109
|
+
if (self.isRecording)
|
|
110
|
+
return;
|
|
111
|
+
let formattedMessage = typeof message === 'object' ? JSON.stringify(message) : String(message);
|
|
112
|
+
if (optionalParams.length > 0) {
|
|
113
|
+
// Get context (usually the last parameter, e.g. [PurchaseService])
|
|
114
|
+
const context = optionalParams[optionalParams.length - 1];
|
|
115
|
+
const contextStr = typeof context === 'string' ? `[${context}] ` : '';
|
|
116
|
+
formattedMessage = contextStr + formattedMessage;
|
|
117
|
+
}
|
|
118
|
+
if (formattedMessage.includes('telescope_entries') || formattedMessage.includes('TelescopeModule')) {
|
|
119
|
+
return;
|
|
120
|
+
}
|
|
121
|
+
self.isRecording = true;
|
|
122
|
+
try {
|
|
123
|
+
self.telescope.record({
|
|
124
|
+
type: entry_type_enum_1.EntryType.LOG,
|
|
125
|
+
content: { level, message: formattedMessage },
|
|
126
|
+
}).catch(() => { });
|
|
127
|
+
}
|
|
128
|
+
finally {
|
|
129
|
+
self.isRecording = false;
|
|
130
|
+
}
|
|
131
|
+
});
|
|
132
|
+
common_1.Logger.overrideLogger(wrapper);
|
|
133
|
+
}
|
|
134
|
+
}
|
|
135
|
+
catch {
|
|
136
|
+
// Ignore errors if overrideLogger doesn't exist or fails
|
|
137
|
+
}
|
|
62
138
|
}
|
|
63
139
|
};
|
|
64
140
|
exports.LogWatcher = LogWatcher;
|