@gravito/spectrum 3.0.0 → 3.0.2
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 +100 -48
- package/README.zh-TW.md +163 -0
- package/dist/index.cjs +320 -20
- package/dist/index.d.cts +343 -2
- package/dist/index.d.ts +343 -2
- package/dist/index.js +320 -20
- package/package.json +12 -10
package/dist/index.d.cts
CHANGED
|
@@ -3,41 +3,98 @@ import { GravitoContext, GravitoOrbit, PlanetCore } from '@gravito/core';
|
|
|
3
3
|
/**
|
|
4
4
|
* @gravito/spectrum - Types
|
|
5
5
|
*/
|
|
6
|
+
/**
|
|
7
|
+
* Represents a detailed snapshot of an HTTP request processed by the application.
|
|
8
|
+
*
|
|
9
|
+
* @public
|
|
10
|
+
* @since 3.0.0
|
|
11
|
+
*/
|
|
6
12
|
interface CapturedRequest {
|
|
13
|
+
/** Unique execution ID. */
|
|
7
14
|
id: string;
|
|
15
|
+
/** HTTP Method (GET, POST, etc.). */
|
|
8
16
|
method: string;
|
|
17
|
+
/** URL Path. */
|
|
9
18
|
path: string;
|
|
19
|
+
/** Full URL. */
|
|
10
20
|
url: string;
|
|
21
|
+
/** HTTP response status code. */
|
|
11
22
|
status: number;
|
|
23
|
+
/** Processing duration in milliseconds. */
|
|
12
24
|
duration: number;
|
|
25
|
+
/** Epoch timestamp of when the request started. */
|
|
13
26
|
startTime: number;
|
|
27
|
+
/** Client IP address. */
|
|
14
28
|
ip: string;
|
|
29
|
+
/** Client user agent string. */
|
|
15
30
|
userAgent?: string;
|
|
31
|
+
/** Incoming request headers. */
|
|
16
32
|
requestHeaders: Record<string, string>;
|
|
33
|
+
/** Outgoing response headers. */
|
|
17
34
|
responseHeaders: Record<string, string>;
|
|
35
|
+
/** Parsed request body (if captured). */
|
|
18
36
|
requestBody?: any;
|
|
37
|
+
/** Parsed response body (if captured). */
|
|
19
38
|
responseBody?: any;
|
|
39
|
+
/** Request ID for correlation with logs and queries. */
|
|
40
|
+
requestId?: string;
|
|
20
41
|
}
|
|
42
|
+
/**
|
|
43
|
+
* Represents a log entry captured during application execution.
|
|
44
|
+
*
|
|
45
|
+
* @public
|
|
46
|
+
* @since 3.0.0
|
|
47
|
+
*/
|
|
21
48
|
interface CapturedLog {
|
|
49
|
+
/** Unique log entry ID. */
|
|
22
50
|
id: string;
|
|
51
|
+
/** Log severity level. */
|
|
23
52
|
level: 'debug' | 'info' | 'warn' | 'error';
|
|
53
|
+
/** The primary log message text. */
|
|
24
54
|
message: string;
|
|
55
|
+
/** Additional arguments passed to the logger. */
|
|
25
56
|
args: any[];
|
|
57
|
+
/** Epoch timestamp when the log was generated. */
|
|
26
58
|
timestamp: number;
|
|
59
|
+
/** Request ID for correlation with the originating request. */
|
|
60
|
+
requestId?: string;
|
|
27
61
|
}
|
|
62
|
+
/**
|
|
63
|
+
* Represents a database query captured during application execution.
|
|
64
|
+
*
|
|
65
|
+
* @public
|
|
66
|
+
* @since 3.0.0
|
|
67
|
+
*/
|
|
28
68
|
interface CapturedQuery {
|
|
69
|
+
/** Unique query execution ID. */
|
|
29
70
|
id: string;
|
|
71
|
+
/** The name of the database connection used. */
|
|
30
72
|
connection: string;
|
|
73
|
+
/** The raw or prepared SQL statement. */
|
|
31
74
|
sql: string;
|
|
75
|
+
/** Prepared statement bindings/parameters. */
|
|
32
76
|
bindings: any[];
|
|
77
|
+
/** Query execution duration in milliseconds. */
|
|
33
78
|
duration: number;
|
|
79
|
+
/** Epoch timestamp when the query was executed. */
|
|
34
80
|
timestamp: number;
|
|
81
|
+
/** Request ID for correlation with the originating request. */
|
|
82
|
+
requestId?: string;
|
|
35
83
|
}
|
|
36
84
|
|
|
37
85
|
/**
|
|
38
86
|
* @gravito/spectrum - Storage Contract
|
|
39
87
|
*/
|
|
40
88
|
|
|
89
|
+
/**
|
|
90
|
+
* Interface for Spectrum storage backends.
|
|
91
|
+
*
|
|
92
|
+
* Implement this interface to provide custom storage for captured telemetry
|
|
93
|
+
* data (requests, logs, queries).
|
|
94
|
+
*
|
|
95
|
+
* @public
|
|
96
|
+
* @since 3.0.0
|
|
97
|
+
*/
|
|
41
98
|
interface SpectrumStorage {
|
|
42
99
|
/**
|
|
43
100
|
* Initialize storage driver
|
|
@@ -85,17 +142,30 @@ interface SpectrumStorage {
|
|
|
85
142
|
* @gravito/spectrum - SpectrumOrbit
|
|
86
143
|
*/
|
|
87
144
|
|
|
145
|
+
/**
|
|
146
|
+
* Configuration options for the Spectrum observability orbit.
|
|
147
|
+
*
|
|
148
|
+
* @public
|
|
149
|
+
* @since 3.0.0
|
|
150
|
+
*/
|
|
88
151
|
interface SpectrumConfig {
|
|
152
|
+
/** The URL path where the dashboard UI will be served. @default '/gravito/spectrum' */
|
|
89
153
|
path?: string;
|
|
154
|
+
/** Maximum number of records to keep in memory/disk per category. @default 100 */
|
|
90
155
|
maxItems?: number;
|
|
156
|
+
/** Whether the spectrum capture is enabled. @default true */
|
|
91
157
|
enabled?: boolean;
|
|
158
|
+
/** Custom storage backend for captured data. Defaults to MemoryStorage. */
|
|
92
159
|
storage?: SpectrumStorage;
|
|
93
160
|
/**
|
|
94
|
-
* Authorization gate
|
|
161
|
+
* Authorization gate for accessing the dashboard and its API.
|
|
162
|
+
* Return true to allow access, false to block.
|
|
95
163
|
*/
|
|
96
164
|
gate?: (c: GravitoContext) => boolean | Promise<boolean>;
|
|
97
165
|
/**
|
|
98
|
-
*
|
|
166
|
+
* Probability sample rate (0.0 to 1.0).
|
|
167
|
+
* 1.0 captures everything, 0.0 captures nothing.
|
|
168
|
+
* @default 1.0
|
|
99
169
|
*/
|
|
100
170
|
sampleRate?: number;
|
|
101
171
|
}
|
|
@@ -111,21 +181,112 @@ interface SpectrumOrbitDeps {
|
|
|
111
181
|
};
|
|
112
182
|
} | null>;
|
|
113
183
|
}
|
|
184
|
+
/**
|
|
185
|
+
* SpectrumOrbit is the official observability and debug dashboard for Gravito.
|
|
186
|
+
*
|
|
187
|
+
* It automatically captures HTTP requests, application logs, and database queries,
|
|
188
|
+
* providing a real-time view of your application's internals. It includes a
|
|
189
|
+
* built-in web dashboard for exploring and replaying captured data.
|
|
190
|
+
*
|
|
191
|
+
* @example
|
|
192
|
+
* ```typescript
|
|
193
|
+
* import { SpectrumOrbit } from '@gravito/spectrum';
|
|
194
|
+
*
|
|
195
|
+
* const spectrum = new SpectrumOrbit({
|
|
196
|
+
* gate: (ctx) => ctx.get('auth')?.user?.isAdmin
|
|
197
|
+
* });
|
|
198
|
+
* core.addOrbit(spectrum);
|
|
199
|
+
* ```
|
|
200
|
+
*
|
|
201
|
+
* @public
|
|
202
|
+
* @since 3.0.0
|
|
203
|
+
*/
|
|
114
204
|
declare class SpectrumOrbit implements GravitoOrbit {
|
|
205
|
+
/**
|
|
206
|
+
* Global instance of SpectrumOrbit.
|
|
207
|
+
*
|
|
208
|
+
* Used for internal access and singleton patterns within the framework.
|
|
209
|
+
*/
|
|
115
210
|
static instance: SpectrumOrbit | undefined;
|
|
116
211
|
readonly name = "spectrum";
|
|
117
212
|
private config;
|
|
118
213
|
private listeners;
|
|
214
|
+
private currentRequestId;
|
|
119
215
|
private warnedSecurity;
|
|
120
216
|
private deps;
|
|
217
|
+
/**
|
|
218
|
+
* Initializes a new instance of SpectrumOrbit.
|
|
219
|
+
*
|
|
220
|
+
* @param config - Configuration options for behavior and storage
|
|
221
|
+
* @param deps - Internal dependencies for integration with other orbits
|
|
222
|
+
*
|
|
223
|
+
* @example
|
|
224
|
+
* ```typescript
|
|
225
|
+
* const spectrum = new SpectrumOrbit({ path: '/debug' });
|
|
226
|
+
* ```
|
|
227
|
+
*/
|
|
121
228
|
constructor(config?: SpectrumConfig, deps?: SpectrumOrbitDeps);
|
|
229
|
+
/**
|
|
230
|
+
* Checks if the current operation should be captured based on sample rate.
|
|
231
|
+
*
|
|
232
|
+
* @returns True if capture is allowed
|
|
233
|
+
*/
|
|
122
234
|
private shouldCapture;
|
|
235
|
+
/**
|
|
236
|
+
* Broadcasts telemetry data to all connected SSE clients.
|
|
237
|
+
*
|
|
238
|
+
* @param type - The category of the data
|
|
239
|
+
* @param data - The telemetry payload
|
|
240
|
+
*/
|
|
123
241
|
private broadcast;
|
|
242
|
+
/**
|
|
243
|
+
* Installs the Spectrum orbit into the Gravito core.
|
|
244
|
+
*
|
|
245
|
+
* Sets up collection listeners, initializes storage, and registers API/UI routes.
|
|
246
|
+
*
|
|
247
|
+
* @param core - The planet core instance
|
|
248
|
+
* @returns Resolves when installation is complete
|
|
249
|
+
* @throws {Error} If storage initialization fails
|
|
250
|
+
*
|
|
251
|
+
* @example
|
|
252
|
+
* ```typescript
|
|
253
|
+
* await spectrum.install(core);
|
|
254
|
+
* ```
|
|
255
|
+
*/
|
|
124
256
|
install(core: PlanetCore): Promise<void>;
|
|
257
|
+
/**
|
|
258
|
+
* Configures collection of database queries from Atlas orbit.
|
|
259
|
+
*
|
|
260
|
+
* @param core - The planet core instance
|
|
261
|
+
*/
|
|
125
262
|
private setupDatabaseCollection;
|
|
263
|
+
/**
|
|
264
|
+
* Configures interception of HTTP requests and responses.
|
|
265
|
+
*
|
|
266
|
+
* @param core - The planet core instance
|
|
267
|
+
*/
|
|
126
268
|
private setupHttpCollection;
|
|
269
|
+
/**
|
|
270
|
+
* Configures interception of application logs.
|
|
271
|
+
*
|
|
272
|
+
* Wraps the core logger to capture all log calls.
|
|
273
|
+
*
|
|
274
|
+
* @param core - The planet core instance
|
|
275
|
+
*/
|
|
127
276
|
private setupLogCollection;
|
|
277
|
+
/**
|
|
278
|
+
* Processes and stores a captured log entry.
|
|
279
|
+
*
|
|
280
|
+
* @param level - Log severity level
|
|
281
|
+
* @param message - Primary message string
|
|
282
|
+
* @param args - Additional log arguments
|
|
283
|
+
*/
|
|
128
284
|
private captureLog;
|
|
285
|
+
/**
|
|
286
|
+
* Registers all API and UI routes for the Spectrum dashboard.
|
|
287
|
+
*
|
|
288
|
+
* @param core - The planet core instance
|
|
289
|
+
*/
|
|
129
290
|
private registerRoutes;
|
|
130
291
|
}
|
|
131
292
|
|
|
@@ -135,28 +296,129 @@ declare class SpectrumOrbit implements GravitoOrbit {
|
|
|
135
296
|
* Persistent storage using JSONL files.
|
|
136
297
|
*/
|
|
137
298
|
|
|
299
|
+
/**
|
|
300
|
+
* Configuration for the `FileStorage` backend.
|
|
301
|
+
*
|
|
302
|
+
* @public
|
|
303
|
+
* @since 3.0.0
|
|
304
|
+
*/
|
|
138
305
|
interface FileStorageConfig {
|
|
306
|
+
/** The directory where captured telemetry data will be stored as JSONL files. */
|
|
139
307
|
directory: string;
|
|
140
308
|
}
|
|
309
|
+
/**
|
|
310
|
+
* FileStorage persists Spectrum telemetry data to the local file system.
|
|
311
|
+
*
|
|
312
|
+
* It uses newline-delimited JSON (JSONL) files for efficient appends and
|
|
313
|
+
* maintains an in-memory cache for fast dashboard retrieval.
|
|
314
|
+
*
|
|
315
|
+
* @public
|
|
316
|
+
* @since 3.0.0
|
|
317
|
+
*/
|
|
141
318
|
declare class FileStorage implements SpectrumStorage {
|
|
142
319
|
private config;
|
|
143
320
|
private requestsPath;
|
|
144
321
|
private logsPath;
|
|
145
322
|
private queriesPath;
|
|
146
323
|
private cache;
|
|
324
|
+
/**
|
|
325
|
+
* Initializes a new instance of FileStorage.
|
|
326
|
+
*
|
|
327
|
+
* @param config - Configuration including the target directory for JSONL files
|
|
328
|
+
*
|
|
329
|
+
* @example
|
|
330
|
+
* ```typescript
|
|
331
|
+
* const storage = new FileStorage({ directory: './storage' });
|
|
332
|
+
* ```
|
|
333
|
+
*/
|
|
147
334
|
constructor(config: FileStorageConfig);
|
|
335
|
+
/**
|
|
336
|
+
* Initializes the storage by creating the directory and loading existing files into memory.
|
|
337
|
+
*
|
|
338
|
+
* @returns Resolves when initialization is complete
|
|
339
|
+
* @throws {Error} If directory creation fails
|
|
340
|
+
*/
|
|
148
341
|
init(): Promise<void>;
|
|
342
|
+
/**
|
|
343
|
+
* Loads newline-delimited JSON data from a file into a target array.
|
|
344
|
+
*
|
|
345
|
+
* @param path - The absolute path to the JSONL file
|
|
346
|
+
* @param target - The array to populate with parsed objects
|
|
347
|
+
*/
|
|
149
348
|
private loadCache;
|
|
349
|
+
/**
|
|
350
|
+
* Internal helper to append data to both the in-memory cache and the JSONL file.
|
|
351
|
+
*
|
|
352
|
+
* @param path - File path to append to
|
|
353
|
+
* @param data - The telemetry object
|
|
354
|
+
* @param list - The cache array
|
|
355
|
+
*/
|
|
150
356
|
private append;
|
|
357
|
+
/**
|
|
358
|
+
* Persists a captured HTTP request.
|
|
359
|
+
*
|
|
360
|
+
* @param req - The request snapshot
|
|
361
|
+
*/
|
|
151
362
|
storeRequest(req: CapturedRequest): Promise<void>;
|
|
363
|
+
/**
|
|
364
|
+
* Persists a captured log entry.
|
|
365
|
+
*
|
|
366
|
+
* @param log - The log snapshot
|
|
367
|
+
*/
|
|
152
368
|
storeLog(log: CapturedLog): Promise<void>;
|
|
369
|
+
/**
|
|
370
|
+
* Persists a captured database query.
|
|
371
|
+
*
|
|
372
|
+
* @param query - The query snapshot
|
|
373
|
+
*/
|
|
153
374
|
storeQuery(query: CapturedQuery): Promise<void>;
|
|
375
|
+
/**
|
|
376
|
+
* Retrieves recent HTTP requests from storage.
|
|
377
|
+
*
|
|
378
|
+
* @param limit - Maximum number of items to return
|
|
379
|
+
* @param offset - Pagination offset
|
|
380
|
+
* @returns Array of requests
|
|
381
|
+
*/
|
|
154
382
|
getRequests(limit?: number, offset?: number): Promise<CapturedRequest[]>;
|
|
383
|
+
/**
|
|
384
|
+
* Retrieves a specific HTTP request by its unique ID.
|
|
385
|
+
*
|
|
386
|
+
* @param id - The snapshot ID
|
|
387
|
+
* @returns The request or null if not found
|
|
388
|
+
*/
|
|
155
389
|
getRequest(id: string): Promise<CapturedRequest | null>;
|
|
390
|
+
/**
|
|
391
|
+
* Retrieves recent logs from storage.
|
|
392
|
+
*
|
|
393
|
+
* @param limit - Maximum number of items to return
|
|
394
|
+
* @param offset - Pagination offset
|
|
395
|
+
* @returns Array of logs
|
|
396
|
+
*/
|
|
156
397
|
getLogs(limit?: number, offset?: number): Promise<CapturedLog[]>;
|
|
398
|
+
/**
|
|
399
|
+
* Retrieves recent database queries from storage.
|
|
400
|
+
*
|
|
401
|
+
* @param limit - Maximum number of items to return
|
|
402
|
+
* @param offset - Pagination offset
|
|
403
|
+
* @returns Array of queries
|
|
404
|
+
*/
|
|
157
405
|
getQueries(limit?: number, offset?: number): Promise<CapturedQuery[]>;
|
|
406
|
+
/**
|
|
407
|
+
* Wipes all data from both cache and files.
|
|
408
|
+
*/
|
|
158
409
|
clear(): Promise<void>;
|
|
410
|
+
/**
|
|
411
|
+
* Truncates the storage to stay within the specified limit.
|
|
412
|
+
*
|
|
413
|
+
* @param maxItems - The maximum allowed records per category
|
|
414
|
+
*/
|
|
159
415
|
prune(maxItems: number): Promise<void>;
|
|
416
|
+
/**
|
|
417
|
+
* Overwrites the file content with the current in-memory data.
|
|
418
|
+
*
|
|
419
|
+
* @param path - File path to overwrite
|
|
420
|
+
* @param data - The array of data objects
|
|
421
|
+
*/
|
|
160
422
|
private rewrite;
|
|
161
423
|
}
|
|
162
424
|
|
|
@@ -166,21 +428,100 @@ declare class FileStorage implements SpectrumStorage {
|
|
|
166
428
|
* Non-persistent storage for development.
|
|
167
429
|
*/
|
|
168
430
|
|
|
431
|
+
/**
|
|
432
|
+
* MemoryStorage provides a fast, non-persistent storage backend for Spectrum telemetry.
|
|
433
|
+
*
|
|
434
|
+
* This implementation is ideal for local development environments where data persistence
|
|
435
|
+
* across server restarts is not required. It maintains all captured data in memory
|
|
436
|
+
* and automatically prunes old records based on the configured limits.
|
|
437
|
+
*
|
|
438
|
+
* @public
|
|
439
|
+
* @since 3.0.0
|
|
440
|
+
*
|
|
441
|
+
* @example
|
|
442
|
+
* ```typescript
|
|
443
|
+
* const storage = new MemoryStorage();
|
|
444
|
+
* ```
|
|
445
|
+
*/
|
|
169
446
|
declare class MemoryStorage implements SpectrumStorage {
|
|
170
447
|
private requests;
|
|
171
448
|
private logs;
|
|
172
449
|
private queries;
|
|
173
450
|
private maxItems;
|
|
451
|
+
/**
|
|
452
|
+
* Initializes the memory storage.
|
|
453
|
+
*
|
|
454
|
+
* As memory storage does not require external resources, this is a no-op.
|
|
455
|
+
*
|
|
456
|
+
* @returns Resolves immediately
|
|
457
|
+
*/
|
|
174
458
|
init(): Promise<void>;
|
|
459
|
+
/**
|
|
460
|
+
* Temporarily stores a captured HTTP request in memory.
|
|
461
|
+
*
|
|
462
|
+
* @param req - The request snapshot to store
|
|
463
|
+
*/
|
|
175
464
|
storeRequest(req: CapturedRequest): Promise<void>;
|
|
465
|
+
/**
|
|
466
|
+
* Temporarily stores a captured log entry in memory.
|
|
467
|
+
*
|
|
468
|
+
* @param log - The log entry to store
|
|
469
|
+
*/
|
|
176
470
|
storeLog(log: CapturedLog): Promise<void>;
|
|
471
|
+
/**
|
|
472
|
+
* Temporarily stores a captured database query in memory.
|
|
473
|
+
*
|
|
474
|
+
* @param query - The query information to store
|
|
475
|
+
*/
|
|
177
476
|
storeQuery(query: CapturedQuery): Promise<void>;
|
|
477
|
+
/**
|
|
478
|
+
* Retrieves a list of recent HTTP requests from memory.
|
|
479
|
+
*
|
|
480
|
+
* @param limit - Maximum number of requests to return
|
|
481
|
+
* @param offset - Number of requests to skip for pagination
|
|
482
|
+
* @returns A promise resolving to an array of captured requests
|
|
483
|
+
*/
|
|
178
484
|
getRequests(limit?: number, offset?: number): Promise<CapturedRequest[]>;
|
|
485
|
+
/**
|
|
486
|
+
* Finds a specific HTTP request by its unique identifier.
|
|
487
|
+
*
|
|
488
|
+
* @param id - The unique ID of the request to find
|
|
489
|
+
* @returns The found request or null if not present
|
|
490
|
+
*/
|
|
179
491
|
getRequest(id: string): Promise<CapturedRequest | null>;
|
|
492
|
+
/**
|
|
493
|
+
* Retrieves a list of recent application logs from memory.
|
|
494
|
+
*
|
|
495
|
+
* @param limit - Maximum number of logs to return
|
|
496
|
+
* @param offset - Number of logs to skip for pagination
|
|
497
|
+
* @returns A promise resolving to an array of captured logs
|
|
498
|
+
*/
|
|
180
499
|
getLogs(limit?: number, offset?: number): Promise<CapturedLog[]>;
|
|
500
|
+
/**
|
|
501
|
+
* Retrieves a list of recent database queries from memory.
|
|
502
|
+
*
|
|
503
|
+
* @param limit - Maximum number of queries to return
|
|
504
|
+
* @param offset - Number of queries to skip for pagination
|
|
505
|
+
* @returns A promise resolving to an array of captured queries
|
|
506
|
+
*/
|
|
181
507
|
getQueries(limit?: number, offset?: number): Promise<CapturedQuery[]>;
|
|
508
|
+
/**
|
|
509
|
+
* Wipes all captured telemetry data from memory.
|
|
510
|
+
*
|
|
511
|
+
* @returns Resolves when all collections are emptied
|
|
512
|
+
*/
|
|
182
513
|
clear(): Promise<void>;
|
|
514
|
+
/**
|
|
515
|
+
* Sets a new capacity limit and prunes existing data to fit.
|
|
516
|
+
*
|
|
517
|
+
* @param maxItems - The new maximum number of items to retain per category
|
|
518
|
+
*/
|
|
183
519
|
prune(maxItems: number): Promise<void>;
|
|
520
|
+
/**
|
|
521
|
+
* Truncates an array to ensure it does not exceed the maximum allowed capacity.
|
|
522
|
+
*
|
|
523
|
+
* @param arr - The target array to truncate
|
|
524
|
+
*/
|
|
184
525
|
private trim;
|
|
185
526
|
}
|
|
186
527
|
|