@oas-tools/oas-telemetry 0.7.1 → 0.8.0-alpha.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/.env.example +17 -3
- package/README.md +1 -2
- package/dist/cjs/config/bootConfig.cjs +16 -14
- package/dist/cjs/config/config.cjs +120 -125
- package/dist/cjs/config/config.types.cjs +1 -4
- package/dist/cjs/docs/openapi.yaml +158 -4
- package/dist/cjs/index.cjs +27 -30
- package/dist/cjs/routesManager.cjs +62 -70
- package/dist/cjs/telemetry/custom-implementations/exporters/DiskLogExporter.cjs +121 -0
- package/dist/cjs/telemetry/custom-implementations/exporters/DiskMetricExporter.cjs +101 -0
- package/dist/cjs/telemetry/custom-implementations/exporters/DiskTraceExporter.cjs +103 -0
- package/dist/cjs/telemetry/custom-implementations/exporters/InMemoryDbLogExporter.cjs +194 -190
- package/dist/cjs/telemetry/custom-implementations/exporters/InMemoryDbMetricExporter.cjs +147 -99
- package/dist/cjs/telemetry/custom-implementations/exporters/InMemoryDbSpanExporter.cjs +143 -116
- package/dist/cjs/telemetry/custom-implementations/exporters/MultiMetricExporter.cjs +57 -0
- package/dist/cjs/telemetry/custom-implementations/instrumentations/logsInstrumentation.cjs +92 -0
- package/dist/cjs/telemetry/custom-implementations/metrics/tsdb/Chunk.cjs +159 -0
- package/dist/cjs/telemetry/custom-implementations/metrics/tsdb/Series.cjs +168 -0
- package/dist/cjs/telemetry/custom-implementations/metrics/tsdb/SeriesRegistry.cjs +392 -0
- package/dist/cjs/telemetry/custom-implementations/metrics/tsdb/types.cjs +2 -0
- package/dist/cjs/telemetry/custom-implementations/metrics/tsdb/utils.cjs +77 -0
- package/dist/cjs/telemetry/custom-implementations/processors/dynamicMultiLogProcessor.cjs +65 -63
- package/dist/cjs/telemetry/custom-implementations/processors/dynamicMultiSpanProcessor.cjs +63 -62
- package/dist/cjs/telemetry/custom-implementations/utils/circular.cjs +47 -47
- package/dist/cjs/telemetry/custom-implementations/wrappers.cjs +209 -138
- package/dist/cjs/telemetry/initializeTelemetry.cjs +35 -91
- package/dist/cjs/telemetry/persistence/DiskImporter.cjs +85 -0
- package/dist/cjs/telemetry/persistence/DiskUtils.cjs +61 -0
- package/dist/cjs/telemetry/persistence/DiskWriter.cjs +66 -0
- package/dist/cjs/telemetry/telemetryConfigurator.cjs +139 -72
- package/dist/cjs/telemetry/telemetryRegistry.cjs +45 -31
- package/dist/cjs/tlm-ai/agent.cjs +49 -64
- package/dist/cjs/tlm-ai/aiController.cjs +54 -76
- package/dist/cjs/tlm-ai/aiRoutes.cjs +17 -20
- package/dist/cjs/tlm-ai/aiService.cjs +91 -95
- package/dist/cjs/tlm-ai/tools.cjs +177 -174
- package/dist/cjs/tlm-auth/authController.cjs +80 -123
- package/dist/cjs/tlm-auth/authMiddleware.cjs +25 -30
- package/dist/cjs/tlm-auth/authRoutes.cjs +11 -14
- package/dist/cjs/tlm-log/logController.cjs +135 -116
- package/dist/cjs/tlm-log/logRoutes.cjs +19 -20
- package/dist/cjs/tlm-log/logService.cjs +29 -0
- package/dist/cjs/tlm-metric/metricsController.cjs +154 -122
- package/dist/cjs/tlm-metric/metricsRoutes.cjs +22 -20
- package/dist/cjs/tlm-metric/metricsService.cjs +26 -0
- package/dist/cjs/tlm-plugin/pluginController.cjs +128 -140
- package/dist/cjs/tlm-plugin/pluginProcess.cjs +89 -94
- package/dist/cjs/tlm-plugin/pluginRoutes.cjs +11 -14
- package/dist/cjs/tlm-plugin/pluginService.cjs +73 -74
- package/dist/cjs/tlm-trace/traceController.cjs +140 -123
- package/dist/cjs/tlm-trace/traceRoutes.cjs +19 -20
- package/dist/cjs/tlm-trace/traceService.cjs +29 -0
- package/dist/cjs/tlm-ui/uiRoutes.cjs +63 -32
- package/dist/cjs/tlm-util/utilController.cjs +68 -70
- package/dist/cjs/tlm-util/utilRoutes.cjs +51 -63
- package/dist/cjs/types/index.cjs +2 -5
- package/dist/cjs/utils/logger.cjs +38 -43
- package/dist/cjs/utils/regexUtils.cjs +22 -22
- package/dist/esm/config/bootConfig.js +5 -2
- package/dist/esm/config/config.js +9 -2
- package/dist/esm/docs/openapi.yaml +158 -4
- package/dist/esm/index.js +9 -8
- package/dist/esm/routesManager.js +6 -10
- package/dist/esm/telemetry/custom-implementations/exporters/DiskLogExporter.js +114 -0
- package/dist/esm/telemetry/custom-implementations/exporters/DiskMetricExporter.js +94 -0
- package/dist/esm/telemetry/custom-implementations/exporters/DiskTraceExporter.js +96 -0
- package/dist/esm/telemetry/custom-implementations/exporters/InMemoryDbLogExporter.js +38 -7
- package/dist/esm/telemetry/custom-implementations/exporters/InMemoryDbMetricExporter.js +107 -48
- package/dist/esm/telemetry/custom-implementations/exporters/InMemoryDbSpanExporter.js +60 -29
- package/dist/esm/telemetry/custom-implementations/exporters/MultiMetricExporter.js +53 -0
- package/dist/esm/telemetry/custom-implementations/instrumentations/logsInstrumentation.js +85 -0
- package/dist/esm/telemetry/custom-implementations/metrics/tsdb/Chunk.js +155 -0
- package/dist/esm/telemetry/custom-implementations/metrics/tsdb/Series.js +164 -0
- package/dist/esm/telemetry/custom-implementations/metrics/tsdb/SeriesRegistry.js +385 -0
- package/dist/esm/telemetry/custom-implementations/metrics/tsdb/types.js +1 -0
- package/dist/esm/telemetry/custom-implementations/metrics/tsdb/utils.js +74 -0
- package/dist/esm/telemetry/custom-implementations/processors/dynamicMultiLogProcessor.js +2 -1
- package/dist/esm/telemetry/custom-implementations/processors/dynamicMultiSpanProcessor.js +1 -1
- package/dist/esm/telemetry/custom-implementations/wrappers.js +77 -6
- package/dist/esm/telemetry/initializeTelemetry.js +27 -69
- package/dist/esm/telemetry/persistence/DiskImporter.js +78 -0
- package/dist/esm/telemetry/persistence/DiskUtils.js +51 -0
- package/dist/esm/telemetry/persistence/DiskWriter.js +59 -0
- package/dist/esm/telemetry/telemetryConfigurator.js +110 -39
- package/dist/esm/telemetry/telemetryRegistry.js +12 -1
- package/dist/esm/tlm-ai/agent.js +5 -3
- package/dist/esm/tlm-ai/aiController.js +3 -3
- package/dist/esm/tlm-ai/aiService.js +6 -2
- package/dist/esm/tlm-ai/tools.js +5 -9
- package/dist/esm/tlm-auth/authController.js +3 -2
- package/dist/esm/tlm-log/logController.js +62 -18
- package/dist/esm/tlm-log/logRoutes.js +3 -1
- package/dist/esm/tlm-log/logService.js +25 -0
- package/dist/esm/tlm-metric/metricsController.js +116 -50
- package/dist/esm/tlm-metric/metricsRoutes.js +8 -3
- package/dist/esm/tlm-metric/metricsService.js +22 -0
- package/dist/esm/tlm-plugin/pluginController.js +6 -11
- package/dist/esm/tlm-plugin/pluginService.js +2 -4
- package/dist/esm/tlm-trace/traceController.js +87 -36
- package/dist/esm/tlm-trace/traceRoutes.js +3 -1
- package/dist/esm/tlm-trace/traceService.js +25 -0
- package/dist/esm/tlm-ui/uiRoutes.js +5 -5
- package/dist/esm/tlm-util/utilController.js +3 -9
- package/dist/esm/tlm-util/utilRoutes.js +2 -2
- package/dist/types/config/bootConfig.d.ts +3 -0
- package/dist/types/config/config.d.ts +48 -7
- package/dist/types/config/config.types.d.ts +7 -0
- package/dist/types/index.d.ts +2 -3
- package/dist/types/telemetry/custom-implementations/exporters/DiskLogExporter.d.ts +24 -0
- package/dist/types/telemetry/custom-implementations/exporters/DiskMetricExporter.d.ts +23 -0
- package/dist/types/telemetry/custom-implementations/exporters/DiskTraceExporter.d.ts +23 -0
- package/dist/types/telemetry/custom-implementations/exporters/InMemoryDbLogExporter.d.ts +3 -1
- package/dist/types/telemetry/custom-implementations/exporters/InMemoryDbMetricExporter.d.ts +56 -15
- package/dist/types/telemetry/custom-implementations/exporters/InMemoryDbSpanExporter.d.ts +8 -4
- package/dist/types/telemetry/custom-implementations/exporters/MultiMetricExporter.d.ts +9 -0
- package/dist/types/telemetry/custom-implementations/instrumentations/logsInstrumentation.d.ts +23 -0
- package/dist/types/telemetry/custom-implementations/metrics/tsdb/Chunk.d.ts +49 -0
- package/dist/types/telemetry/custom-implementations/metrics/tsdb/Series.d.ts +67 -0
- package/dist/types/telemetry/custom-implementations/metrics/tsdb/SeriesRegistry.d.ts +69 -0
- package/dist/types/telemetry/custom-implementations/metrics/tsdb/types.d.ts +68 -0
- package/dist/types/telemetry/custom-implementations/metrics/tsdb/utils.d.ts +21 -0
- package/dist/types/telemetry/custom-implementations/processors/dynamicMultiLogProcessor.d.ts +2 -2
- package/dist/types/telemetry/custom-implementations/wrappers.d.ts +2 -1
- package/dist/types/telemetry/persistence/DiskImporter.d.ts +17 -0
- package/dist/types/telemetry/persistence/DiskUtils.d.ts +11 -0
- package/dist/types/telemetry/persistence/DiskWriter.d.ts +21 -0
- package/dist/types/telemetry/telemetryConfigurator.d.ts +1 -1
- package/dist/types/telemetry/telemetryRegistry.d.ts +8 -0
- package/dist/types/tlm-ai/agent.d.ts +1 -1
- package/dist/types/tlm-ai/aiService.d.ts +1 -1
- package/dist/types/tlm-log/logController.d.ts +2 -0
- package/dist/types/tlm-log/logService.d.ts +4 -0
- package/dist/types/tlm-metric/metricsController.d.ts +11 -2
- package/dist/types/tlm-metric/metricsService.d.ts +6 -0
- package/dist/types/tlm-trace/traceController.d.ts +9 -7
- package/dist/types/tlm-trace/traceService.d.ts +4 -0
- package/dist/types/types/index.d.ts +2 -2
- package/dist/ui/assets/{ApiDocsPage-C_VVPPHa.js → ApiDocsPage-DTCgVbW2.js} +2 -2
- package/dist/ui/assets/CollapsibleCard-lWgfsaAn.js +1 -0
- package/dist/ui/assets/DevToolsPage-DEhf8CBy.js +1 -0
- package/dist/ui/assets/LandingPage-CfEHCDxY.js +6 -0
- package/dist/ui/assets/LogsPage-DFDKRuGH.js +1 -0
- package/dist/ui/assets/{NotFoundPage-B3quk3P1.js → NotFoundPage-DCy0DcV7.js} +1 -1
- package/dist/ui/assets/PluginCreatePage-BawZ5_-h.js +50 -0
- package/dist/ui/assets/PluginPage-D3FmgU7d.js +27 -0
- package/dist/ui/assets/TraceSpansPage-D0_L45Rb.js +6 -0
- package/dist/ui/assets/VirtualizedListPanel-q605n9He.js +16 -0
- package/dist/ui/assets/alert-DBAFshSi.js +1133 -0
- package/dist/ui/assets/badge-DGNBtnxU.js +1 -0
- package/dist/ui/assets/{chevron-down-CPsvsmqj.js → chevron-down-CFEqYzGC.js} +1 -1
- package/dist/ui/assets/{chevron-up-Df9jMo1X.js → chevron-up-lDnFwAJq.js} +1 -1
- package/dist/ui/assets/{circle-alert-DOPQPvU8.js → circle-alert-BpYUuRs7.js} +1 -1
- package/dist/ui/assets/dialog-1dRyI6SC.js +15 -0
- package/dist/ui/assets/index-C7RfU6hR.js +1 -0
- package/dist/ui/assets/index-C9dDYIpd.js +305 -0
- package/dist/ui/assets/index-D6f1KjWV.css +1 -0
- package/dist/ui/assets/info-CuJQWoBU.js +6 -0
- package/dist/ui/assets/{input-Dzvg_ZEZ.js → input-BLXaar0X.js} +1 -1
- package/dist/ui/assets/label-DfAcltsl.js +1 -0
- package/dist/ui/assets/{loader-circle-CrvlRy5o.js → loader-circle-B7oLyPsi.js} +1 -1
- package/dist/ui/assets/{loginPage-qa4V-B70.js → loginPage-DswZvOJ-.js} +1 -1
- package/dist/ui/assets/metrics-page-BhtXrfUW.js +31 -0
- package/dist/ui/assets/metrics-page-D1GxaB_c.css +1 -0
- package/dist/ui/assets/popover-IDker85U.js +11 -0
- package/dist/ui/assets/select-B8y5IidE.js +6 -0
- package/dist/ui/assets/separator-B6EzrxYY.js +6 -0
- package/dist/ui/assets/severityOptions-DtCsaAZK.js +11 -0
- package/dist/ui/assets/square-pen-D_oecB1x.js +6 -0
- package/dist/ui/assets/switch-Dqo0XkRD.js +1 -0
- package/dist/ui/assets/trace-DJq1miYa.js +1 -0
- package/dist/ui/assets/upload-prIohEdY.js +11 -0
- package/dist/ui/assets/{utilService-DNyqzwj0.js → utilService-C8TJKLqs.js} +1 -1
- package/dist/ui/assets/wand-sparkles-OgXuzsSx.js +6 -0
- package/dist/ui/index.html +2 -2
- package/package.json +44 -49
- package/dist/ui/assets/CollapsibleCard-B3KR_8mL.js +0 -1
- package/dist/ui/assets/DevToolsPage-OyZcDcmw.js +0 -1
- package/dist/ui/assets/LandingPage-CppFBA6K.js +0 -6
- package/dist/ui/assets/LogsPage-9Fq8GArS.js +0 -26
- package/dist/ui/assets/PluginCreatePage-X_aCH4t4.js +0 -50
- package/dist/ui/assets/PluginPage-DMDSihrZ.js +0 -27
- package/dist/ui/assets/alert-jQ9HCPIf.js +0 -1133
- package/dist/ui/assets/badge-CNq0-mH5.js +0 -1
- package/dist/ui/assets/card-DFAwwhN3.js +0 -1
- package/dist/ui/assets/index-BkD6DijD.js +0 -15
- package/dist/ui/assets/index-CERGVYZK.js +0 -292
- package/dist/ui/assets/index-CSIPf9qw.css +0 -1
- package/dist/ui/assets/label-DuVnkZ4q.js +0 -1
- package/dist/ui/assets/select-DhS8YUtJ.js +0 -1
- package/dist/ui/assets/separator-isK4chBP.js +0 -6
- package/dist/ui/assets/severityOptions-O38dSOfk.js +0 -11
- package/dist/ui/assets/switch-Z3mImG9n.js +0 -1
- package/dist/ui/assets/tabs-_77MUUQe.js +0 -16
- package/dist/ui/assets/upload-C1LT4Gkb.js +0 -16
|
@@ -1,37 +1,91 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import {
|
|
1
|
+
import { BatchLogRecordProcessor as LogBatchLogRecordProcessor, SimpleLogRecordProcessor as LogSimpleLogRecordProcessor } from '@opentelemetry/sdk-logs';
|
|
2
|
+
import { PeriodicExportingMetricReader } from '@opentelemetry/sdk-metrics';
|
|
3
|
+
import { BatchSpanProcessor as TraceBatchSpanProcessor, SimpleSpanProcessor as TraceSimpleSpanProcessor } from '@opentelemetry/sdk-trace-node';
|
|
3
4
|
import logger from '../utils/logger.js';
|
|
4
|
-
import {
|
|
5
|
-
import {
|
|
6
|
-
import { HostMetrics } from '@opentelemetry/host-metrics';
|
|
5
|
+
import { inMemoryDbLogExporter, inMemoryDbMetricExporter, inMemoryDbSpanExporter, instrumentations, multiLogExporter, multiSpanExporter, oasTelemetryResource } from './telemetryRegistry.js';
|
|
6
|
+
import { NodeSDK } from '@opentelemetry/sdk-node';
|
|
7
7
|
import { bootEnvVariables } from '../config/bootConfig.js';
|
|
8
8
|
import { pluginService } from '../tlm-plugin/pluginService.js';
|
|
9
|
-
|
|
9
|
+
import { DiskTraceExporter } from './custom-implementations/exporters/DiskTraceExporter.js';
|
|
10
|
+
import { DiskLogExporter } from './custom-implementations/exporters/DiskLogExporter.js';
|
|
11
|
+
import { DiskMetricExporter } from './custom-implementations/exporters/DiskMetricExporter.js';
|
|
12
|
+
import { MultiMetricExporter } from './custom-implementations/exporters/MultiMetricExporter.js';
|
|
13
|
+
import { DiskImporter } from './persistence/DiskImporter.js';
|
|
14
|
+
import { importTracesToMemory } from '../tlm-trace/traceService.js';
|
|
15
|
+
import { importLogsToMemory } from '../tlm-log/logService.js';
|
|
16
|
+
import { importMetricsToMemory } from '../tlm-metric/metricsService.js';
|
|
17
|
+
export function configureTelemetry(oasTlmConfig) {
|
|
18
|
+
logger.info("🚀 Configuring Telemetry...");
|
|
19
|
+
configureStorage(oasTlmConfig);
|
|
20
|
+
if (oasTlmConfig.instrumentations) {
|
|
21
|
+
instrumentations.push(...oasTlmConfig.instrumentations);
|
|
22
|
+
}
|
|
10
23
|
configurePlugins(oasTlmConfig);
|
|
11
|
-
configureTraces(oasTlmConfig);
|
|
12
|
-
configureMetrics(oasTlmConfig);
|
|
13
|
-
configureLogs(oasTlmConfig);
|
|
14
|
-
|
|
15
|
-
|
|
24
|
+
const mainTraceProcessor = configureTraces(oasTlmConfig);
|
|
25
|
+
const mainMetricReader = configureMetrics(oasTlmConfig);
|
|
26
|
+
const mainLogProcessor = configureLogs(oasTlmConfig);
|
|
27
|
+
const sdk = new NodeSDK({
|
|
28
|
+
instrumentations: instrumentations,
|
|
29
|
+
resource: oasTelemetryResource,
|
|
30
|
+
traceExporter: inMemoryDbSpanExporter,
|
|
31
|
+
spanProcessors: [mainTraceProcessor, ...oasTlmConfig.traces.extraProcessors || []],
|
|
32
|
+
metricReaders: [mainMetricReader, ...(oasTlmConfig.metrics.extraReaders || [])],
|
|
33
|
+
logRecordProcessors: [mainLogProcessor, ...oasTlmConfig.logs.extraProcessors || []],
|
|
34
|
+
});
|
|
35
|
+
sdk.start();
|
|
36
|
+
logger.info("✅ Node SDK started with telemetry configuration");
|
|
37
|
+
if (oasTlmConfig.storage.path && oasTlmConfig.storage.loadFromStart) {
|
|
38
|
+
scheduleStartupImports(oasTlmConfig.storage.path);
|
|
39
|
+
}
|
|
40
|
+
else if (oasTlmConfig.storage.path && !oasTlmConfig.storage.loadFromStart) {
|
|
41
|
+
logger.info(`[DiskImporter] Startup import skipped by storage.loadFromStart=false. Path: ${oasTlmConfig.storage.path}`);
|
|
42
|
+
}
|
|
43
|
+
return true;
|
|
44
|
+
}
|
|
45
|
+
function configureStorage(oasTlmConfig) {
|
|
46
|
+
const path = oasTlmConfig.storage.path;
|
|
47
|
+
oasTlmConfig.storage.path = typeof path === 'string' && path.trim().length > 0
|
|
48
|
+
? path.trim()
|
|
49
|
+
: null;
|
|
50
|
+
}
|
|
16
51
|
function configurePlugins(oasTlmConfig) {
|
|
17
52
|
pluginService.enabled = oasTlmConfig.plugins.enabled;
|
|
18
53
|
}
|
|
19
54
|
function configureTraces(oasTlmConfig) {
|
|
20
55
|
// TRACES CONFIGURATION
|
|
21
56
|
// [OT]Provider -> [OT]SpanProcessor(multiSpan) -> n Processors(eg mainProcessor, extra) -> 1 SpanExporter
|
|
22
|
-
inMemoryDbSpanExporter.baseUrl = oasTlmConfig.general.baseUrl; // TODO this will be done with filters
|
|
23
57
|
inMemoryDbSpanExporter.retentionTimeInSeconds = oasTlmConfig.traces.memoryExporter.retentionTimeSeconds;
|
|
24
58
|
inMemoryDbSpanExporter.setEnabledValue(oasTlmConfig.traces.memoryExporter.enabled);
|
|
25
59
|
const mainExporter = multiSpanExporter;
|
|
26
|
-
|
|
60
|
+
mainExporter.clearExporters();
|
|
61
|
+
let mainProcessor = new TraceBatchSpanProcessor(mainExporter);
|
|
27
62
|
if (bootEnvVariables.OASTLM_BOOT_ENV !== 'production') {
|
|
28
63
|
logger.info('Not in production, using SimpleSpanProcessor for traces');
|
|
29
|
-
mainProcessor = new
|
|
64
|
+
mainProcessor = new TraceSimpleSpanProcessor(mainExporter);
|
|
30
65
|
}
|
|
31
66
|
mainExporter.addExporters(inMemoryDbSpanExporter); // Main exporter have at least the in-memory exporter used by the traces controller
|
|
67
|
+
if (oasTlmConfig.storage.path) {
|
|
68
|
+
mainExporter.addExporters(new DiskTraceExporter({ directoryPath: oasTlmConfig.storage.path }));
|
|
69
|
+
logger.info(`[TraceDiskExporter] Enabled at: ${oasTlmConfig.storage.path}`);
|
|
70
|
+
}
|
|
32
71
|
mainExporter.addExporters(oasTlmConfig.traces.extraExporters);
|
|
33
|
-
|
|
34
|
-
|
|
72
|
+
return mainProcessor;
|
|
73
|
+
}
|
|
74
|
+
function configureMetrics(oasTlmConfig) {
|
|
75
|
+
// METRICS CONFIGURATION
|
|
76
|
+
inMemoryDbMetricExporter.setEnabledValue(oasTlmConfig.metrics.memoryExporter.enabled);
|
|
77
|
+
inMemoryDbMetricExporter.retentionTimeInSeconds = oasTlmConfig.metrics.memoryExporter.retentionTimeSeconds;
|
|
78
|
+
const metricExporters = [inMemoryDbMetricExporter];
|
|
79
|
+
if (oasTlmConfig.storage.path) {
|
|
80
|
+
metricExporters.push(new DiskMetricExporter({ directoryPath: oasTlmConfig.storage.path }));
|
|
81
|
+
logger.info(`[MetricDiskExporter] Enabled at: ${oasTlmConfig.storage.path}`);
|
|
82
|
+
}
|
|
83
|
+
const mainReader = new PeriodicExportingMetricReader({
|
|
84
|
+
exporter: new MultiMetricExporter(metricExporters),
|
|
85
|
+
exportIntervalMillis: oasTlmConfig.metrics.mainMetricReaderOptions.exportIntervalMillis,
|
|
86
|
+
metricProducers: oasTlmConfig.metrics.mainMetricReaderOptions.metricProducers
|
|
87
|
+
});
|
|
88
|
+
return mainReader;
|
|
35
89
|
}
|
|
36
90
|
function configureLogs(oasTlmConfig) {
|
|
37
91
|
// LOGS CONFIGURATION
|
|
@@ -39,33 +93,50 @@ function configureLogs(oasTlmConfig) {
|
|
|
39
93
|
inMemoryDbLogExporter.setEnabledValue(oasTlmConfig.logs.memoryExporter.enabled);
|
|
40
94
|
inMemoryDbLogExporter.retentionTimeInSeconds = oasTlmConfig.logs.memoryExporter.retentionTimeSeconds;
|
|
41
95
|
const mainExporter = multiLogExporter;
|
|
42
|
-
|
|
96
|
+
mainExporter.clearExporters();
|
|
97
|
+
let mainProcessor = new LogBatchLogRecordProcessor(mainExporter);
|
|
43
98
|
if (bootEnvVariables.OASTLM_BOOT_ENV !== 'production') {
|
|
44
99
|
logger.info('Not in production, using SimpleLogRecordProcessor for logs');
|
|
45
|
-
mainProcessor = new
|
|
100
|
+
mainProcessor = new LogSimpleLogRecordProcessor(mainExporter);
|
|
46
101
|
}
|
|
47
102
|
mainExporter.addExporters(inMemoryDbLogExporter); // Main exporter have at least the in-memory exporter used by the logs controller
|
|
103
|
+
if (oasTlmConfig.storage.path) {
|
|
104
|
+
mainExporter.addExporters(new DiskLogExporter({ directoryPath: oasTlmConfig.storage.path }));
|
|
105
|
+
logger.info(`[LogDiskExporter] Enabled at: ${oasTlmConfig.storage.path}`);
|
|
106
|
+
}
|
|
48
107
|
mainExporter.addExporters(oasTlmConfig.logs.extraExporters);
|
|
49
|
-
|
|
50
|
-
dynamicMultiLogProcessor.addProcessors(oasTlmConfig.logs.extraProcessors);
|
|
108
|
+
return mainProcessor;
|
|
51
109
|
}
|
|
52
|
-
function
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
110
|
+
function scheduleStartupImports(storagePath) {
|
|
111
|
+
setTimeout(async () => {
|
|
112
|
+
try {
|
|
113
|
+
await runTimedImport('TraceDiskImport', storagePath, new DiskImporter({ directoryPath: storagePath }), async (spans) => {
|
|
114
|
+
await importTracesToMemory(spans);
|
|
115
|
+
});
|
|
116
|
+
await runTimedImport('LogDiskImport', storagePath, new DiskImporter({ directoryPath: storagePath, segmentPrefix: 'logs' }), async (logs) => {
|
|
117
|
+
await importLogsToMemory(logs);
|
|
118
|
+
});
|
|
119
|
+
await runTimedImport('MetricDiskImport', storagePath, new DiskImporter({ directoryPath: storagePath, segmentPrefix: 'metrics' }), async (scopeMetrics) => {
|
|
120
|
+
importMetricsToMemory(scopeMetrics, { format: 'otel' });
|
|
121
|
+
});
|
|
122
|
+
}
|
|
123
|
+
catch (error) {
|
|
124
|
+
logger.error(`[DiskImporter] Startup import sequence failed: ${error?.message || error}`);
|
|
125
|
+
}
|
|
126
|
+
}, 0);
|
|
127
|
+
}
|
|
128
|
+
async function runTimedImport(label, storagePath, importer, onBatch) {
|
|
129
|
+
const startedAt = Date.now();
|
|
130
|
+
logger.info(`[${label}] Startup import started. Path: ${storagePath}`);
|
|
131
|
+
try {
|
|
132
|
+
const result = await importer.import(onBatch);
|
|
133
|
+
logger.info(`[${label}] Startup import completed. Files: ${result.segmentFilesRead}, imported records: ${result.importedRecords}, failed frames: ${result.failedFrames}`);
|
|
134
|
+
}
|
|
135
|
+
catch (error) {
|
|
136
|
+
logger.error(`[${label}] Startup import failed: ${error?.message || error}`);
|
|
137
|
+
}
|
|
138
|
+
finally {
|
|
139
|
+
const elapsedMs = Date.now() - startedAt;
|
|
140
|
+
logger.info(`[${label}] Startup import finished in ${elapsedMs}ms`);
|
|
141
|
+
}
|
|
71
142
|
}
|
|
@@ -8,6 +8,15 @@ import { ATTR_SERVICE_NAME } from "@opentelemetry/semantic-conventions";
|
|
|
8
8
|
import { resourceFromAttributes } from "@opentelemetry/resources";
|
|
9
9
|
import { bootEnvVariables } from "../config/bootConfig.js";
|
|
10
10
|
// GLOBAL REGISTRY of telemetry components, used by SDKs and controllers.
|
|
11
|
+
let _bootInitialized = false;
|
|
12
|
+
let _telemetryConfigured = false;
|
|
13
|
+
let _router = undefined;
|
|
14
|
+
export function isBootInitialized() { return _bootInitialized; }
|
|
15
|
+
export function setBootInitialized(v) { _bootInitialized = v; }
|
|
16
|
+
export function isTelemetryConfigured() { return _telemetryConfigured; }
|
|
17
|
+
export function setTelemetryConfigured(v) { _telemetryConfigured = v; }
|
|
18
|
+
export function setTelemetryRouter(router) { _router = router; }
|
|
19
|
+
export function getTelemetryRouter() { return _router; }
|
|
11
20
|
export const oasTelemetryResource = resourceFromAttributes({
|
|
12
21
|
[ATTR_SERVICE_NAME]: bootEnvVariables.OASTLM_BOOT_SERVICE_NAME
|
|
13
22
|
});
|
|
@@ -22,7 +31,7 @@ export const dynamicMultiSpanProcessor = new DynamicMultiSpanProcessor();
|
|
|
22
31
|
export const inMemoryDbLogExporter = new InMemoryDbLogExporter();
|
|
23
32
|
export const multiLogExporter = new EnablerMultiLogExporter();
|
|
24
33
|
export const dynamicMultiLogProcessor = new DynamicMultiLogRecordProcessor();
|
|
25
|
-
//
|
|
34
|
+
// For custom log instrumentation, and lib logging
|
|
26
35
|
export const originalConsoleMethods = {
|
|
27
36
|
log: console.log,
|
|
28
37
|
warn: console.warn,
|
|
@@ -35,3 +44,5 @@ export const originalConsoleMethods = {
|
|
|
35
44
|
export const inMemoryDbMetricExporter = new InMemoryDbMetricExporter();
|
|
36
45
|
// Readers and their exporters cannot be grouped together in a MultiReader or similar construct
|
|
37
46
|
// due to differences in aggregation temporality and aggregation selection.
|
|
47
|
+
// INSTRUMENTATIONS -----------------------------------------------------------------------
|
|
48
|
+
export const instrumentations = [];
|
package/dist/esm/tlm-ai/agent.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { tools, availableTools } from './tools.js';
|
|
2
2
|
import logger from '../utils/logger.js';
|
|
3
|
-
export async function agent(openai, messages, model = "gpt-3.5-turbo"
|
|
3
|
+
export async function agent(openai, messages, model = "gpt-3.5-turbo") {
|
|
4
4
|
for (let i = 0; i < 5; i++) {
|
|
5
5
|
const modelResponse = await openai.chat.completions.create({
|
|
6
6
|
model,
|
|
@@ -12,11 +12,13 @@ export async function agent(openai, messages, model = "gpt-3.5-turbo", extraProm
|
|
|
12
12
|
logger.debug("Tool calls detected:", message.tool_calls);
|
|
13
13
|
const results = [];
|
|
14
14
|
for (const toolCall of message.tool_calls) {
|
|
15
|
+
// Type guard for tool_calls
|
|
16
|
+
if (toolCall.type !== 'function' || !toolCall.function)
|
|
17
|
+
continue;
|
|
15
18
|
const functionName = toolCall.function.name;
|
|
16
19
|
const functionToCall = availableTools[functionName];
|
|
17
20
|
const functionArgs = JSON.parse(toolCall.function.arguments);
|
|
18
21
|
const functionArgsArr = Object.values(functionArgs);
|
|
19
|
-
// @ts-expect-error yes
|
|
20
22
|
// eslint-disable-next-line prefer-spread
|
|
21
23
|
const functionResponse = await functionToCall.apply(null, functionArgsArr);
|
|
22
24
|
results.push({
|
|
@@ -26,7 +28,7 @@ export async function agent(openai, messages, model = "gpt-3.5-turbo", extraProm
|
|
|
26
28
|
}
|
|
27
29
|
const resultMessage = results.map(({ name, response }, idx) => {
|
|
28
30
|
const toolCall = message.tool_calls?.[idx];
|
|
29
|
-
const params = toolCall ? JSON.parse(toolCall.function.arguments) : {};
|
|
31
|
+
const params = toolCall && toolCall.type === 'function' && toolCall.function ? JSON.parse(toolCall.function.arguments) : {};
|
|
30
32
|
return `Tool "${name}" called with parameters:\n${JSON.stringify(params, null, 2)}\nResult:\n${JSON.stringify(response, null, 2)}`;
|
|
31
33
|
}).join("\n\n");
|
|
32
34
|
messages.push({
|
|
@@ -20,7 +20,7 @@ export async function listConversations(req, res) {
|
|
|
20
20
|
}
|
|
21
21
|
export async function getConversationHistory(req, res) {
|
|
22
22
|
try {
|
|
23
|
-
const
|
|
23
|
+
const conversationId = req.params.conversationId;
|
|
24
24
|
const conversation = getAiService().getConversation(conversationId);
|
|
25
25
|
if (!conversation) {
|
|
26
26
|
res.status(404).json({ error: 'Not found' });
|
|
@@ -34,7 +34,7 @@ export async function getConversationHistory(req, res) {
|
|
|
34
34
|
}
|
|
35
35
|
export async function deleteConversation(req, res) {
|
|
36
36
|
try {
|
|
37
|
-
const
|
|
37
|
+
const conversationId = req.params.conversationId;
|
|
38
38
|
const deleted = getAiService().deleteConversation(conversationId);
|
|
39
39
|
if (!deleted) {
|
|
40
40
|
res.status(404).json({ error: 'Not found' });
|
|
@@ -48,7 +48,7 @@ export async function deleteConversation(req, res) {
|
|
|
48
48
|
}
|
|
49
49
|
export async function sendMessage(req, res) {
|
|
50
50
|
try {
|
|
51
|
-
const
|
|
51
|
+
const conversationId = req.params.conversationId;
|
|
52
52
|
const { content } = req.body;
|
|
53
53
|
if (!content) {
|
|
54
54
|
res.status(400).json({ error: 'Missing content' });
|
|
@@ -1,9 +1,13 @@
|
|
|
1
1
|
import OpenAI from 'openai';
|
|
2
2
|
import { agent } from './agent.js';
|
|
3
3
|
class AIService {
|
|
4
|
+
config;
|
|
5
|
+
conversations = new Map();
|
|
6
|
+
openai;
|
|
7
|
+
model;
|
|
8
|
+
extraPrompts;
|
|
4
9
|
constructor(config) {
|
|
5
10
|
this.config = config;
|
|
6
|
-
this.conversations = new Map();
|
|
7
11
|
this.openai = new OpenAI({
|
|
8
12
|
apiKey: this.config.apiKey,
|
|
9
13
|
});
|
|
@@ -47,7 +51,7 @@ class AIService {
|
|
|
47
51
|
// Use the agent function with tools
|
|
48
52
|
// Internaly pushes new messages to conversation.messages
|
|
49
53
|
const currentMessagesCount = conversation.messages.length;
|
|
50
|
-
await agent(this.openai, conversation.messages, model || this.model
|
|
54
|
+
await agent(this.openai, conversation.messages, model || this.model);
|
|
51
55
|
// Return the last assistant message (the one just added by agent)
|
|
52
56
|
const generatedMessages = conversation.messages.slice(currentMessagesCount);
|
|
53
57
|
return generatedMessages;
|
package/dist/esm/tlm-ai/tools.js
CHANGED
|
@@ -3,14 +3,10 @@ import { inMemoryDbLogExporter, inMemoryDbMetricExporter, inMemoryDbSpanExporter
|
|
|
3
3
|
const getTraces = async (searchInput) => {
|
|
4
4
|
logger.debug("getTraces called with searchInput:", searchInput);
|
|
5
5
|
try {
|
|
6
|
-
const search = searchInput
|
|
7
|
-
const traces = await
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
reject(err);
|
|
11
|
-
else
|
|
12
|
-
resolve(docs);
|
|
13
|
-
});
|
|
6
|
+
const search = searchInput ? JSON.parse(searchInput) : {};
|
|
7
|
+
const traces = await inMemoryDbSpanExporter.find({
|
|
8
|
+
query: search,
|
|
9
|
+
limit: 1000
|
|
14
10
|
});
|
|
15
11
|
const simplifiedTraces = getSimplifiedTraces(traces);
|
|
16
12
|
logger.debug(`Searching for traces with searchInput: ${JSON.stringify(search)}`);
|
|
@@ -38,7 +34,7 @@ const getLogs = async (startDate, endDate) => {
|
|
|
38
34
|
const logs = (await inMemoryDbLogExporter.find({
|
|
39
35
|
query: nedbQuery,
|
|
40
36
|
messageSearch: null,
|
|
41
|
-
limit:
|
|
37
|
+
limit: 1000 // or any appropriate limit
|
|
42
38
|
})) || [];
|
|
43
39
|
logger.debug(`Found ${logs.length} logs in the specified range.`);
|
|
44
40
|
const simplifiedLogs = getSimplifiedLogs(logs);
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import jwt from 'jsonwebtoken';
|
|
2
2
|
import logger from '../utils/logger.js';
|
|
3
|
+
import { bootEnvVariables } from '../config/bootConfig.js';
|
|
3
4
|
function generateAccessToken(secret, expiresIn) {
|
|
4
5
|
return jwt.sign({ type: "access" }, secret, { expiresIn: Math.floor(expiresIn / 1000) });
|
|
5
6
|
}
|
|
@@ -28,7 +29,7 @@ export const getLogin = (oasTlmConfig) => (req, res) => {
|
|
|
28
29
|
httpOnly: true,
|
|
29
30
|
secure: process.env.NODE_ENV === "production",
|
|
30
31
|
sameSite: "lax",
|
|
31
|
-
path:
|
|
32
|
+
path: bootEnvVariables.OASTLM_BOOT_BASE_URL + "/auth/refresh"
|
|
32
33
|
});
|
|
33
34
|
res.status(200).json({ valid: true, message: "Login successful" });
|
|
34
35
|
return;
|
|
@@ -46,7 +47,7 @@ export const getLogout = (oasTlmConfig) => (req, res) => {
|
|
|
46
47
|
return;
|
|
47
48
|
}
|
|
48
49
|
res.clearCookie('oas-tlm-access-token', { path: '/' });
|
|
49
|
-
res.clearCookie('oas-tlm-refresh-token', { path:
|
|
50
|
+
res.clearCookie('oas-tlm-refresh-token', { path: bootEnvVariables.OASTLM_BOOT_BASE_URL + '/auth/refresh' });
|
|
50
51
|
res.status(200).json({ valid: true, message: "Logged out" });
|
|
51
52
|
};
|
|
52
53
|
export const getRefresh = (oasTlmConfig) => (req, res) => {
|
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
import { inMemoryDbLogExporter } from '../telemetry/telemetryRegistry.js';
|
|
2
2
|
import logger from '../utils/logger.js';
|
|
3
3
|
import { convertRegexRecursively } from '../utils/regexUtils.js';
|
|
4
|
+
import { importLogsToMemory, sanitizeLogRecords } from './logService.js';
|
|
5
|
+
import { gzipSync } from 'zlib';
|
|
4
6
|
export const findLogs = async (req, res) => {
|
|
5
7
|
const body = req.body || {};
|
|
6
8
|
const messageSearch = body.textSearch || null;
|
|
@@ -27,7 +29,8 @@ export const findLogs = async (req, res) => {
|
|
|
27
29
|
};
|
|
28
30
|
const docs = await inMemoryDbLogExporter.find(findConfig);
|
|
29
31
|
res.send({
|
|
30
|
-
|
|
32
|
+
logsCount: docs.length,
|
|
33
|
+
logs: docs,
|
|
31
34
|
});
|
|
32
35
|
}
|
|
33
36
|
catch (err) {
|
|
@@ -40,32 +43,19 @@ export const resetLogs = (req, res) => {
|
|
|
40
43
|
res.send('Logs reset');
|
|
41
44
|
};
|
|
42
45
|
export const insertLogsToDb = async (req, res) => {
|
|
43
|
-
const jsonContent = req.body.logs;
|
|
46
|
+
const jsonContent = (req.body || {}).logs;
|
|
44
47
|
const resetData = req.query.reset === 'true';
|
|
45
48
|
if (!Array.isArray(jsonContent)) {
|
|
46
49
|
res.status(400).send({ error: 'Invalid data format.' });
|
|
47
50
|
return;
|
|
48
51
|
}
|
|
49
|
-
const cleanedLogs = jsonContent
|
|
50
|
-
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
51
|
-
const { _id, ...rest } = log; // Remove _id if it exists
|
|
52
|
-
return rest; // Return the cleaned log object
|
|
53
|
-
});
|
|
52
|
+
const cleanedLogs = sanitizeLogRecords(jsonContent);
|
|
54
53
|
try {
|
|
55
54
|
let message = '';
|
|
55
|
+
await importLogsToMemory(cleanedLogs, { reset: resetData });
|
|
56
56
|
if (resetData) {
|
|
57
|
-
inMemoryDbLogExporter.reset();
|
|
58
57
|
message += 'Logs Database reset. ';
|
|
59
58
|
}
|
|
60
|
-
await new Promise((resolve, reject) => {
|
|
61
|
-
inMemoryDbLogExporter.insert(cleanedLogs, (err, newDocs) => {
|
|
62
|
-
if (err) {
|
|
63
|
-
logger.error('Error inserting logs:', err);
|
|
64
|
-
return reject(err);
|
|
65
|
-
}
|
|
66
|
-
resolve(newDocs);
|
|
67
|
-
});
|
|
68
|
-
});
|
|
69
59
|
message += `Inserted ${cleanedLogs.length} logs.`;
|
|
70
60
|
res.send({ message, InsertedLogsCount: cleanedLogs.length });
|
|
71
61
|
}
|
|
@@ -74,6 +64,29 @@ export const insertLogsToDb = async (req, res) => {
|
|
|
74
64
|
res.status(500).send({ error: 'Failed to reset and insert data', details: err.message });
|
|
75
65
|
}
|
|
76
66
|
};
|
|
67
|
+
export const importLogs = async (req, res) => {
|
|
68
|
+
const resetData = req.query.reset === 'true';
|
|
69
|
+
const body = req.body || {};
|
|
70
|
+
const importedLogs = Array.isArray(body) ? body : body.logs;
|
|
71
|
+
try {
|
|
72
|
+
if (!Array.isArray(importedLogs)) {
|
|
73
|
+
res.status(400).send({ error: 'Invalid data format. Expected an array in request body or body.logs.' });
|
|
74
|
+
return;
|
|
75
|
+
}
|
|
76
|
+
const cleanedLogs = sanitizeLogRecords(importedLogs);
|
|
77
|
+
let message = '';
|
|
78
|
+
await importLogsToMemory(cleanedLogs, { reset: resetData });
|
|
79
|
+
if (resetData) {
|
|
80
|
+
message += 'Logs Database reset. ';
|
|
81
|
+
}
|
|
82
|
+
message += `Imported ${cleanedLogs.length} logs.`;
|
|
83
|
+
res.send({ message, ImportedLogsCount: cleanedLogs.length });
|
|
84
|
+
}
|
|
85
|
+
catch (err) {
|
|
86
|
+
logger.error('Import failed:', err);
|
|
87
|
+
res.status(400).send({ error: 'Failed to import logs', details: err.message });
|
|
88
|
+
}
|
|
89
|
+
};
|
|
77
90
|
export const startLogs = (req, res) => {
|
|
78
91
|
inMemoryDbLogExporter.enable();
|
|
79
92
|
res.send('Log collection started');
|
|
@@ -87,7 +100,7 @@ export const statusLogs = (req, res) => {
|
|
|
87
100
|
res.send({ active: isRunning });
|
|
88
101
|
};
|
|
89
102
|
export const setLogRetentionTime = (req, res) => {
|
|
90
|
-
const retentionTimeInSeconds = req.body.retentionTimeInSeconds;
|
|
103
|
+
const retentionTimeInSeconds = (req.body || {}).retentionTimeInSeconds;
|
|
91
104
|
if (typeof retentionTimeInSeconds !== 'number' || retentionTimeInSeconds <= 0) {
|
|
92
105
|
res.status(400).send({ error: 'Invalid retention time. Must be a positive number.' });
|
|
93
106
|
return;
|
|
@@ -99,3 +112,34 @@ export const getLogRetentionTime = (req, res) => {
|
|
|
99
112
|
const retentionTimeInSeconds = inMemoryDbLogExporter.retentionTimeInSeconds || 0;
|
|
100
113
|
res.send({ retentionTimeInSeconds: retentionTimeInSeconds });
|
|
101
114
|
};
|
|
115
|
+
export const exportLogs = async (req, res) => {
|
|
116
|
+
try {
|
|
117
|
+
const findConfig = {
|
|
118
|
+
query: {},
|
|
119
|
+
messageSearch: null,
|
|
120
|
+
sortOrder: { timestamp: -1 }
|
|
121
|
+
};
|
|
122
|
+
const docs = await inMemoryDbLogExporter.find(findConfig);
|
|
123
|
+
const responseBody = { logsCount: docs.length, logs: docs };
|
|
124
|
+
const payload = JSON.stringify(responseBody);
|
|
125
|
+
const payloadSize = Buffer.byteLength(payload, 'utf-8');
|
|
126
|
+
const acceptsGzip = String(req.headers['accept-encoding'] || '').includes('gzip');
|
|
127
|
+
const timestamp = new Date().toISOString().slice(0, 19).replace(/[-T:]/g, '');
|
|
128
|
+
res.setHeader('Content-Type', 'application/json');
|
|
129
|
+
res.setHeader('Content-Disposition', `attachment; filename="logs-${timestamp}.json"`);
|
|
130
|
+
res.setHeader('Vary', 'Accept-Encoding');
|
|
131
|
+
if (acceptsGzip && payloadSize > 64 * 1024) {
|
|
132
|
+
const compressed = gzipSync(payload);
|
|
133
|
+
res.setHeader('Content-Encoding', 'gzip');
|
|
134
|
+
res.setHeader('Content-Length', compressed.length.toString());
|
|
135
|
+
res.end(compressed);
|
|
136
|
+
return;
|
|
137
|
+
}
|
|
138
|
+
res.setHeader('Content-Length', payloadSize.toString());
|
|
139
|
+
res.end(payload);
|
|
140
|
+
}
|
|
141
|
+
catch (err) {
|
|
142
|
+
logger.error('Failed to export logs:', err);
|
|
143
|
+
res.status(500).send({ error: 'Failed to export logs', details: err.message });
|
|
144
|
+
}
|
|
145
|
+
};
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { Router } from 'express';
|
|
2
|
-
import { startLogs, stopLogs, statusLogs, resetLogs, findLogs, insertLogsToDb, setLogRetentionTime, getLogRetentionTime } from './logController.js';
|
|
2
|
+
import { startLogs, stopLogs, statusLogs, resetLogs, findLogs, insertLogsToDb, importLogs, setLogRetentionTime, getLogRetentionTime, exportLogs } from './logController.js';
|
|
3
3
|
export const getLogRoutes = () => {
|
|
4
4
|
const router = Router();
|
|
5
5
|
// Logs Control
|
|
@@ -9,6 +9,8 @@ export const getLogRoutes = () => {
|
|
|
9
9
|
router.post('/reset', resetLogs);
|
|
10
10
|
router.post('/retention-time', setLogRetentionTime);
|
|
11
11
|
router.get('/retention-time', getLogRetentionTime);
|
|
12
|
+
router.get('/export', exportLogs);
|
|
13
|
+
router.post('/import', importLogs);
|
|
12
14
|
router.get('/', findLogs);
|
|
13
15
|
router.post('/', insertLogsToDb);
|
|
14
16
|
router.post('/find', findLogs);
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import { inMemoryDbLogExporter } from '../telemetry/telemetryRegistry.js';
|
|
2
|
+
export function sanitizeLogRecords(records) {
|
|
3
|
+
return records.map((record) => {
|
|
4
|
+
const { _id, ...rest } = record;
|
|
5
|
+
return rest;
|
|
6
|
+
});
|
|
7
|
+
}
|
|
8
|
+
export async function importLogsToMemory(records, options) {
|
|
9
|
+
if (options?.reset) {
|
|
10
|
+
inMemoryDbLogExporter.reset();
|
|
11
|
+
}
|
|
12
|
+
if (!records.length) {
|
|
13
|
+
return 0;
|
|
14
|
+
}
|
|
15
|
+
await new Promise((resolve, reject) => {
|
|
16
|
+
inMemoryDbLogExporter.insert(records, (err) => {
|
|
17
|
+
if (err) {
|
|
18
|
+
reject(err);
|
|
19
|
+
return;
|
|
20
|
+
}
|
|
21
|
+
resolve();
|
|
22
|
+
});
|
|
23
|
+
});
|
|
24
|
+
return records.length;
|
|
25
|
+
}
|