@ngn-net/nestjs-telescope 0.2.15 → 0.3.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/README.md +168 -20
- package/dist/index.js +0 -2
- package/dist/storage/entities/telescope-entry.entity.d.ts +12 -1
- package/dist/storage/entities/telescope-entry.entity.js +11 -42
- package/dist/storage/telescope-repository.service.d.ts +5 -5
- package/dist/storage/telescope-repository.service.js +36 -43
- package/dist/telescope.module.js +10 -30
- package/dist/telescope.service.js +1 -1
- package/dist/ui/manifest.json +2 -2
- package/dist/watchers/command.watcher.d.ts +1 -5
- package/dist/watchers/command.watcher.js +19 -18
- package/dist/watchers/gate.watcher.d.ts +4 -9
- package/dist/watchers/gate.watcher.js +39 -22
- package/dist/watchers/http-client.watcher.d.ts +1 -0
- package/dist/watchers/http-client.watcher.js +58 -16
- package/dist/watchers/model.subscriber.d.ts +0 -4
- package/dist/watchers/model.subscriber.js +1 -8
- package/dist/watchers/model.watcher.d.ts +1 -4
- package/dist/watchers/model.watcher.js +45 -17
- package/dist/watchers/notification.watcher.d.ts +1 -5
- package/dist/watchers/notification.watcher.js +35 -18
- package/dist/watchers/schedule.watcher.d.ts +3 -4
- package/dist/watchers/schedule.watcher.js +79 -60
- package/package.json +4 -2
|
@@ -1,13 +1,9 @@
|
|
|
1
1
|
import { OnModuleInit } from '@nestjs/common';
|
|
2
2
|
import { TelescopeService } from '../telescope.service';
|
|
3
|
-
/**
|
|
4
|
-
* Placeholder watcher for notification events.
|
|
5
|
-
* In a full implementation you would hook into NestJS's EventEmitter2 or any
|
|
6
|
-
* custom notification system and log the payload.
|
|
7
|
-
*/
|
|
8
3
|
export declare class NotificationWatcher implements OnModuleInit {
|
|
9
4
|
private readonly telescope;
|
|
10
5
|
private readonly logger;
|
|
11
6
|
constructor(telescope: TelescopeService);
|
|
12
7
|
onModuleInit(): void;
|
|
8
|
+
private tryHookEventEmitter;
|
|
13
9
|
}
|
|
@@ -11,15 +11,9 @@ var __metadata = (this && this.__metadata) || function (k, v) {
|
|
|
11
11
|
var NotificationWatcher_1;
|
|
12
12
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
13
13
|
exports.NotificationWatcher = void 0;
|
|
14
|
-
// src/watchers/notification.watcher.ts
|
|
15
14
|
const common_1 = require("@nestjs/common");
|
|
16
15
|
const telescope_service_1 = require("../telescope.service");
|
|
17
16
|
const entry_type_enum_1 = require("../enums/entry-type.enum");
|
|
18
|
-
/**
|
|
19
|
-
* Placeholder watcher for notification events.
|
|
20
|
-
* In a full implementation you would hook into NestJS's EventEmitter2 or any
|
|
21
|
-
* custom notification system and log the payload.
|
|
22
|
-
*/
|
|
23
17
|
let NotificationWatcher = NotificationWatcher_1 = class NotificationWatcher {
|
|
24
18
|
telescope;
|
|
25
19
|
logger = new common_1.Logger(NotificationWatcher_1.name);
|
|
@@ -27,18 +21,41 @@ let NotificationWatcher = NotificationWatcher_1 = class NotificationWatcher {
|
|
|
27
21
|
this.telescope = telescope;
|
|
28
22
|
}
|
|
29
23
|
onModuleInit() {
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
24
|
+
this.tryHookEventEmitter();
|
|
25
|
+
}
|
|
26
|
+
tryHookEventEmitter() {
|
|
27
|
+
try {
|
|
28
|
+
const { EventEmitter2 } = require('@nestjs/event-emitter');
|
|
29
|
+
if (!EventEmitter2)
|
|
30
|
+
return;
|
|
31
|
+
const originalEmit = EventEmitter2.prototype.emit;
|
|
32
|
+
const self = this;
|
|
33
|
+
EventEmitter2.prototype.emit = function (event, ...args) {
|
|
34
|
+
const eventName = Array.isArray(event) ? event.join('.') : event;
|
|
35
|
+
if (eventName.startsWith('telescope.') || eventName === 'notifications.send') {
|
|
36
|
+
return originalEmit.apply(this, [event, ...args]);
|
|
37
|
+
}
|
|
38
|
+
const isNotification = eventName.includes('notification') ||
|
|
39
|
+
eventName.includes('mail') ||
|
|
40
|
+
eventName.includes('sms') ||
|
|
41
|
+
eventName.includes('push');
|
|
42
|
+
if (isNotification) {
|
|
43
|
+
const payload = args[0] || {};
|
|
44
|
+
self.telescope.record({
|
|
45
|
+
type: entry_type_enum_1.EntryType.NOTIFICATION,
|
|
46
|
+
content: {
|
|
47
|
+
notification: eventName,
|
|
48
|
+
channel: payload.channel || eventName.split('.')[0],
|
|
49
|
+
recipient: payload.to || payload.recipient || null,
|
|
50
|
+
payload,
|
|
51
|
+
timestamp: new Date().toISOString(),
|
|
52
|
+
},
|
|
53
|
+
}).catch(() => { });
|
|
54
|
+
}
|
|
55
|
+
return originalEmit.apply(this, [event, ...args]);
|
|
56
|
+
};
|
|
57
|
+
}
|
|
58
|
+
catch { }
|
|
42
59
|
}
|
|
43
60
|
};
|
|
44
61
|
exports.NotificationWatcher = NotificationWatcher;
|
|
@@ -5,10 +5,9 @@ export declare class ScheduleWatcher implements OnApplicationBootstrap {
|
|
|
5
5
|
private schedulerRegistry;
|
|
6
6
|
constructor(telescope: TelescopeService);
|
|
7
7
|
onApplicationBootstrap(): void;
|
|
8
|
-
/**
|
|
9
|
-
* Set the scheduler registry reference. Called from the module setup
|
|
10
|
-
* when @nestjs/schedule is available.
|
|
11
|
-
*/
|
|
12
8
|
setSchedulerRegistry(registry: any): void;
|
|
9
|
+
private tryAutoDetectCronJobs;
|
|
10
|
+
private hookCronJobsMap;
|
|
13
11
|
private hookIntoCronJobs;
|
|
12
|
+
private hookCronJob;
|
|
14
13
|
}
|
|
@@ -10,7 +10,6 @@ var __metadata = (this && this.__metadata) || function (k, v) {
|
|
|
10
10
|
};
|
|
11
11
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
12
12
|
exports.ScheduleWatcher = void 0;
|
|
13
|
-
// src/watchers/schedule.watcher.ts
|
|
14
13
|
const common_1 = require("@nestjs/common");
|
|
15
14
|
const telescope_service_1 = require("../telescope.service");
|
|
16
15
|
const entry_type_enum_1 = require("../enums/entry-type.enum");
|
|
@@ -21,82 +20,102 @@ let ScheduleWatcher = class ScheduleWatcher {
|
|
|
21
20
|
this.telescope = telescope;
|
|
22
21
|
}
|
|
23
22
|
onApplicationBootstrap() {
|
|
24
|
-
// Dynamically resolve SchedulerRegistry to avoid hard dependency
|
|
25
23
|
try {
|
|
26
24
|
const schedule = require('@nestjs/schedule');
|
|
27
|
-
// SchedulerRegistry is a provider, we can't inject it here
|
|
28
|
-
// This watcher works when setSchedulerRegistry() is called from the module
|
|
29
|
-
}
|
|
30
|
-
catch {
|
|
31
|
-
// @nestjs/schedule not installed
|
|
32
25
|
}
|
|
26
|
+
catch { }
|
|
33
27
|
if (this.schedulerRegistry) {
|
|
34
28
|
this.hookIntoCronJobs();
|
|
35
29
|
}
|
|
30
|
+
else {
|
|
31
|
+
this.tryAutoDetectCronJobs();
|
|
32
|
+
}
|
|
36
33
|
}
|
|
37
|
-
/**
|
|
38
|
-
* Set the scheduler registry reference. Called from the module setup
|
|
39
|
-
* when @nestjs/schedule is available.
|
|
40
|
-
*/
|
|
41
34
|
setSchedulerRegistry(registry) {
|
|
42
35
|
this.schedulerRegistry = registry;
|
|
43
36
|
this.hookIntoCronJobs();
|
|
44
37
|
}
|
|
38
|
+
tryAutoDetectCronJobs() {
|
|
39
|
+
try {
|
|
40
|
+
const { SchedulerRegistry } = require('@nestjs/schedule');
|
|
41
|
+
if (!SchedulerRegistry)
|
|
42
|
+
return;
|
|
43
|
+
const self = this;
|
|
44
|
+
const originalGetCronJobs = SchedulerRegistry.prototype.getCronJobs;
|
|
45
|
+
if (originalGetCronJobs) {
|
|
46
|
+
SchedulerRegistry.prototype.getCronJobs = function () {
|
|
47
|
+
const jobs = originalGetCronJobs.call(this);
|
|
48
|
+
self.hookCronJobsMap(jobs);
|
|
49
|
+
return jobs;
|
|
50
|
+
};
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
catch { }
|
|
54
|
+
}
|
|
55
|
+
hookCronJobsMap(cronJobs) {
|
|
56
|
+
if (!cronJobs || typeof cronJobs.forEach !== 'function')
|
|
57
|
+
return;
|
|
58
|
+
cronJobs.forEach((job, name) => {
|
|
59
|
+
this.hookCronJob(job, name);
|
|
60
|
+
});
|
|
61
|
+
}
|
|
45
62
|
hookIntoCronJobs() {
|
|
46
63
|
if (!this.schedulerRegistry)
|
|
47
64
|
return;
|
|
48
65
|
try {
|
|
49
66
|
const cronJobs = this.schedulerRegistry.getCronJobs();
|
|
50
|
-
|
|
51
|
-
const originalCallbacks = job.callbacks || [];
|
|
52
|
-
if (originalCallbacks.length > 0) {
|
|
53
|
-
job.callbacks = originalCallbacks.map((cb) => {
|
|
54
|
-
return async (...args) => {
|
|
55
|
-
const start = Date.now();
|
|
56
|
-
this.telescope.record({
|
|
57
|
-
type: entry_type_enum_1.EntryType.SCHEDULED_TASK,
|
|
58
|
-
content: {
|
|
59
|
-
name,
|
|
60
|
-
status: 'running',
|
|
61
|
-
cronTime: job.cronTime?.toString(),
|
|
62
|
-
},
|
|
63
|
-
});
|
|
64
|
-
try {
|
|
65
|
-
const res = await cb(...args);
|
|
66
|
-
const duration = Date.now() - start;
|
|
67
|
-
this.telescope.record({
|
|
68
|
-
type: entry_type_enum_1.EntryType.SCHEDULED_TASK,
|
|
69
|
-
content: {
|
|
70
|
-
name,
|
|
71
|
-
status: 'completed',
|
|
72
|
-
duration,
|
|
73
|
-
cronTime: job.cronTime?.toString(),
|
|
74
|
-
},
|
|
75
|
-
});
|
|
76
|
-
return res;
|
|
77
|
-
}
|
|
78
|
-
catch (err) {
|
|
79
|
-
const duration = Date.now() - start;
|
|
80
|
-
this.telescope.record({
|
|
81
|
-
type: entry_type_enum_1.EntryType.SCHEDULED_TASK,
|
|
82
|
-
content: {
|
|
83
|
-
name,
|
|
84
|
-
status: 'failed',
|
|
85
|
-
duration,
|
|
86
|
-
error: err.message || String(err),
|
|
87
|
-
cronTime: job.cronTime?.toString(),
|
|
88
|
-
},
|
|
89
|
-
});
|
|
90
|
-
throw err;
|
|
91
|
-
}
|
|
92
|
-
};
|
|
93
|
-
});
|
|
94
|
-
}
|
|
95
|
-
});
|
|
96
|
-
}
|
|
97
|
-
catch {
|
|
98
|
-
// Ignore if schedule registry lookup fails
|
|
67
|
+
this.hookCronJobsMap(cronJobs);
|
|
99
68
|
}
|
|
69
|
+
catch { }
|
|
70
|
+
}
|
|
71
|
+
hookCronJob(job, name) {
|
|
72
|
+
if (!job || job.__telescopeHooked)
|
|
73
|
+
return;
|
|
74
|
+
job.__telescopeHooked = true;
|
|
75
|
+
const originalCallback = job.callback;
|
|
76
|
+
if (!originalCallback)
|
|
77
|
+
return;
|
|
78
|
+
const self = this;
|
|
79
|
+
job.callback = async (...args) => {
|
|
80
|
+
const start = Date.now();
|
|
81
|
+
self.telescope.record({
|
|
82
|
+
type: entry_type_enum_1.EntryType.SCHEDULED_TASK,
|
|
83
|
+
content: {
|
|
84
|
+
name,
|
|
85
|
+
status: 'running',
|
|
86
|
+
cronTime: job.cronTime?.toString(),
|
|
87
|
+
startedAt: new Date().toISOString(),
|
|
88
|
+
},
|
|
89
|
+
});
|
|
90
|
+
try {
|
|
91
|
+
const res = await originalCallback(...args);
|
|
92
|
+
const duration = Date.now() - start;
|
|
93
|
+
self.telescope.record({
|
|
94
|
+
type: entry_type_enum_1.EntryType.SCHEDULED_TASK,
|
|
95
|
+
content: {
|
|
96
|
+
name,
|
|
97
|
+
status: 'completed',
|
|
98
|
+
duration,
|
|
99
|
+
cronTime: job.cronTime?.toString(),
|
|
100
|
+
},
|
|
101
|
+
});
|
|
102
|
+
return res;
|
|
103
|
+
}
|
|
104
|
+
catch (err) {
|
|
105
|
+
const duration = Date.now() - start;
|
|
106
|
+
self.telescope.record({
|
|
107
|
+
type: entry_type_enum_1.EntryType.SCHEDULED_TASK,
|
|
108
|
+
content: {
|
|
109
|
+
name,
|
|
110
|
+
status: 'failed',
|
|
111
|
+
duration,
|
|
112
|
+
error: err.message || String(err),
|
|
113
|
+
cronTime: job.cronTime?.toString(),
|
|
114
|
+
},
|
|
115
|
+
});
|
|
116
|
+
throw err;
|
|
117
|
+
}
|
|
118
|
+
};
|
|
100
119
|
}
|
|
101
120
|
};
|
|
102
121
|
exports.ScheduleWatcher = ScheduleWatcher;
|
package/package.json
CHANGED
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@ngn-net/nestjs-telescope",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.3.0",
|
|
4
4
|
"publishConfig": {
|
|
5
5
|
"access": "public"
|
|
6
6
|
},
|
|
7
|
-
"description": "Full
|
|
7
|
+
"description": "Full-featured monitoring package for NestJS (inspired by Laravel Telescope) — uses MongoDB for zero-impact storage",
|
|
8
8
|
"author": "Generated by Antigravity",
|
|
9
9
|
"license": "MIT",
|
|
10
10
|
"main": "dist/index.js",
|
|
@@ -21,9 +21,11 @@
|
|
|
21
21
|
"prepare": "npm run build"
|
|
22
22
|
},
|
|
23
23
|
"dependencies": {
|
|
24
|
+
"@nestjs/mongoose": "^11",
|
|
24
25
|
"@nestjs/serve-static": "^5.0.5",
|
|
25
26
|
"class-transformer": "^0.5",
|
|
26
27
|
"class-validator": "^0.14",
|
|
28
|
+
"mongoose": "^8",
|
|
27
29
|
"passport-jwt": "^4",
|
|
28
30
|
"reflect-metadata": "^0.2"
|
|
29
31
|
},
|