@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,199 +1,203 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
});
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
6
|
exports.InMemoryDbLogExporter = void 0;
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
this._db = new _nedb.default({
|
|
25
|
-
timestampData: true
|
|
26
|
-
});
|
|
27
|
-
this._db.ensureIndex({
|
|
28
|
-
fieldName: 'createdAt'
|
|
29
|
-
});
|
|
30
|
-
this._miniSearch = new _minisearch.default({
|
|
31
|
-
fields: ['body'],
|
|
32
|
-
storeFields: ['_id'],
|
|
33
|
-
idField: '_id'
|
|
34
|
-
});
|
|
35
|
-
this._startCleanupJob();
|
|
36
|
-
}
|
|
37
|
-
/*
|
|
38
|
-
* SUPER WARNING:
|
|
39
|
-
* Do NOT use console.log, console.error, or any logger inside this class's export function.
|
|
40
|
-
* Doing so will cause an infinite loop.
|
|
41
|
-
* Only console.dir is allowed, as it is not tracked by our log export implementation.
|
|
42
|
-
*/
|
|
43
|
-
/**
|
|
44
|
-
* Export logs.
|
|
45
|
-
* @param logs
|
|
46
|
-
* @param resultCallback
|
|
47
|
-
*/
|
|
48
|
-
export(logs, resultCallback) {
|
|
49
|
-
const logsToInsert = logs.map(logRecord => {
|
|
50
|
-
// Remove circular references first, then apply nesting, then export info
|
|
51
|
-
const formattedLog = this._formatLogRecord(logRecord);
|
|
52
|
-
const cleanedLog = (0, _circular.removeCircularRefs)(formattedLog);
|
|
53
|
-
const nestedLog = (0, _circular.applyNesting)(cleanedLog);
|
|
54
|
-
return nestedLog;
|
|
55
|
-
});
|
|
56
|
-
logsToInsert.forEach(log => {
|
|
57
|
-
_pluginService.pluginService.broadcastLog(log);
|
|
58
|
-
});
|
|
59
|
-
// ENABLED only affect storage not plugin broadcasting
|
|
60
|
-
if (this.isEnabled()) {
|
|
61
|
-
this._insertLogs(logsToInsert, resultCallback);
|
|
7
|
+
const core_1 = require("@opentelemetry/core");
|
|
8
|
+
const core_2 = require("@opentelemetry/core");
|
|
9
|
+
const nedb_1 = __importDefault(require("@seald-io/nedb"));
|
|
10
|
+
const minisearch_1 = __importDefault(require("minisearch"));
|
|
11
|
+
const circular_js_1 = require("../utils/circular.cjs");
|
|
12
|
+
const wrappers_js_1 = require("../wrappers.cjs");
|
|
13
|
+
const logger_js_1 = __importDefault(require("../../../utils/logger.cjs"));
|
|
14
|
+
const pluginService_js_1 = require("../../../tlm-plugin/pluginService.cjs");
|
|
15
|
+
class InMemoryDbLogExporter extends wrappers_js_1.Enabler {
|
|
16
|
+
_db = null;
|
|
17
|
+
_miniSearch = null;
|
|
18
|
+
_retentionTimeInSeconds;
|
|
19
|
+
_initialized = false;
|
|
20
|
+
constructor(retentionTimeInSeconds = 3600) {
|
|
21
|
+
super();
|
|
22
|
+
this._retentionTimeInSeconds = retentionTimeInSeconds;
|
|
23
|
+
this._startCleanupJob();
|
|
62
24
|
}
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
});
|
|
66
|
-
}
|
|
67
|
-
reset() {
|
|
68
|
-
this._db = new _nedb.default();
|
|
69
|
-
this._miniSearch = new _minisearch.default({
|
|
70
|
-
fields: ['body'],
|
|
71
|
-
storeFields: ['_id'],
|
|
72
|
-
idField: '_id'
|
|
73
|
-
});
|
|
74
|
-
}
|
|
75
|
-
/**
|
|
76
|
-
* Shutdown the exporter.
|
|
77
|
-
*/
|
|
78
|
-
async shutdown() {
|
|
79
|
-
this._db = null;
|
|
80
|
-
this._miniSearch = null;
|
|
81
|
-
}
|
|
82
|
-
async find(findConfig) {
|
|
83
|
-
const {
|
|
84
|
-
query,
|
|
85
|
-
messageSearch,
|
|
86
|
-
limit,
|
|
87
|
-
sortOrder
|
|
88
|
-
} = findConfig;
|
|
89
|
-
const finalQuery = _objectSpread({}, query);
|
|
90
|
-
const effectiveSortOrder = sortOrder || {
|
|
91
|
-
timestamp: -1
|
|
92
|
-
};
|
|
93
|
-
if (messageSearch) {
|
|
94
|
-
const searchResults = this._miniSearch.search(messageSearch, {
|
|
95
|
-
prefix: true,
|
|
96
|
-
fuzzy: 0.2
|
|
97
|
-
});
|
|
98
|
-
const ids = searchResults.map(result => result._id);
|
|
99
|
-
_logger.default.debug(`MiniSearch found ${ids.length} results for search term "${messageSearch}"`, {
|
|
100
|
-
depth: 3
|
|
101
|
-
});
|
|
102
|
-
finalQuery._id = {
|
|
103
|
-
$in: ids
|
|
104
|
-
};
|
|
105
|
-
}
|
|
106
|
-
const docs = await new Promise((resolve, reject) => {
|
|
107
|
-
this._db.find(finalQuery).sort(effectiveSortOrder).limit(limit).exec((err, docs) => {
|
|
108
|
-
if (err) reject(err);else resolve(docs);
|
|
109
|
-
});
|
|
110
|
-
});
|
|
111
|
-
return docs;
|
|
112
|
-
}
|
|
113
|
-
insert(data, callback) {
|
|
114
|
-
this._insertLogs(data, result => {
|
|
115
|
-
if (result.code === _core.ExportResultCode.SUCCESS) {
|
|
116
|
-
this._db.find({}, (err, docs) => {
|
|
117
|
-
if (err) {
|
|
118
|
-
_logger.default.debug(err);
|
|
119
|
-
callback(err, []);
|
|
25
|
+
_ensureInitialized() {
|
|
26
|
+
if (this._initialized)
|
|
120
27
|
return;
|
|
121
|
-
|
|
122
|
-
|
|
28
|
+
this._initialized = true;
|
|
29
|
+
this._db = new nedb_1.default({ timestampData: true });
|
|
30
|
+
this._db.ensureIndex({ fieldName: 'createdAt' });
|
|
31
|
+
this._miniSearch = new minisearch_1.default({
|
|
32
|
+
fields: ['body'],
|
|
33
|
+
storeFields: ['_id'],
|
|
34
|
+
idField: '_id',
|
|
123
35
|
});
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
observedTimestamp: (0, _core.hrTimeToMicroseconds)(logRecord.hrTimeObserved) ?? Date.now(),
|
|
146
|
-
traceId: logRecord.spanContext?.traceId,
|
|
147
|
-
spanId: logRecord.spanContext?.spanId,
|
|
148
|
-
traceFlags: logRecord.spanContext?.traceFlags,
|
|
149
|
-
severityText: logRecord.severityText,
|
|
150
|
-
severityNumber: logRecord.severityNumber,
|
|
151
|
-
body: logRecord.body,
|
|
152
|
-
attributes: logRecord.attributes
|
|
153
|
-
};
|
|
154
|
-
}
|
|
155
|
-
set retentionTimeInSeconds(retentionTimeInSeconds) {
|
|
156
|
-
this._retentionTimeInSeconds = retentionTimeInSeconds;
|
|
157
|
-
_logger.default.info(`InMemoryDbLogExporter retention time set to ${this._retentionTimeInSeconds} seconds`);
|
|
158
|
-
}
|
|
159
|
-
get retentionTimeInSeconds() {
|
|
160
|
-
return this._retentionTimeInSeconds;
|
|
161
|
-
}
|
|
162
|
-
_insertLogs(logsToInsert, resultCallback) {
|
|
163
|
-
this._db.insert(logsToInsert, (err, newDocs) => {
|
|
164
|
-
if (err) {
|
|
165
|
-
console.dir(err);
|
|
166
|
-
resultCallback({
|
|
167
|
-
code: _core.ExportResultCode.FAILED
|
|
36
|
+
logger_js_1.default.info(`[LogExporter] In-memory storage created`);
|
|
37
|
+
}
|
|
38
|
+
/*
|
|
39
|
+
* SUPER WARNING:
|
|
40
|
+
* Do NOT use console.log, console.error, or any logger inside this class's export function.
|
|
41
|
+
* Doing so will cause an infinite loop.
|
|
42
|
+
* Only console.dir is allowed, as it is not tracked by our log export implementation.
|
|
43
|
+
*/
|
|
44
|
+
/**
|
|
45
|
+
* Export logs.
|
|
46
|
+
* @param logs
|
|
47
|
+
* @param resultCallback
|
|
48
|
+
*/
|
|
49
|
+
export(logs, resultCallback) {
|
|
50
|
+
this._ensureInitialized();
|
|
51
|
+
const logsToInsert = logs.map(logRecord => {
|
|
52
|
+
// Remove circular references first, then apply nesting, then export info
|
|
53
|
+
const formattedLog = this._formatLogRecord(logRecord);
|
|
54
|
+
const cleanedLog = (0, circular_js_1.removeCircularRefs)(formattedLog);
|
|
55
|
+
const nestedLog = (0, circular_js_1.applyNesting)(cleanedLog);
|
|
56
|
+
return nestedLog;
|
|
168
57
|
});
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
});
|
|
176
|
-
});
|
|
177
|
-
return;
|
|
178
|
-
}
|
|
179
|
-
_startCleanupJob() {
|
|
180
|
-
const interval = 1000;
|
|
181
|
-
setInterval(() => {
|
|
182
|
-
const expirationDate = new Date(Date.now() - this._retentionTimeInSeconds * 1000);
|
|
183
|
-
this._db.remove({
|
|
184
|
-
createdAt: {
|
|
185
|
-
$lt: expirationDate
|
|
58
|
+
logsToInsert.forEach(log => {
|
|
59
|
+
pluginService_js_1.pluginService.broadcastLog(log);
|
|
60
|
+
});
|
|
61
|
+
// ENABLED only affect storage not plugin broadcasting
|
|
62
|
+
if (this.isEnabled()) {
|
|
63
|
+
this._insertLogs(logsToInsert, resultCallback);
|
|
186
64
|
}
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
}
|
|
193
|
-
|
|
65
|
+
resultCallback({ code: core_2.ExportResultCode.SUCCESS });
|
|
66
|
+
}
|
|
67
|
+
reset() {
|
|
68
|
+
this._ensureInitialized();
|
|
69
|
+
// Remove all logs from the in-memory database.
|
|
70
|
+
this._db.remove({}, { multi: true }, (err) => {
|
|
71
|
+
if (err) {
|
|
72
|
+
logger_js_1.default.error(`[LogExporter] Error during reset: ${err.message}`);
|
|
73
|
+
}
|
|
74
|
+
else {
|
|
75
|
+
logger_js_1.default.info(`[LogExporter] Reset - all logs cleared`);
|
|
76
|
+
}
|
|
77
|
+
});
|
|
78
|
+
// Clear mini search index
|
|
79
|
+
this._miniSearch = new minisearch_1.default({
|
|
80
|
+
fields: ['body'],
|
|
81
|
+
storeFields: ['_id'],
|
|
82
|
+
idField: '_id',
|
|
83
|
+
});
|
|
84
|
+
}
|
|
85
|
+
/**
|
|
86
|
+
* Shutdown the exporter.
|
|
87
|
+
*/
|
|
88
|
+
async shutdown() {
|
|
89
|
+
this._db = null;
|
|
90
|
+
this._miniSearch = null;
|
|
91
|
+
this._initialized = false;
|
|
92
|
+
}
|
|
93
|
+
async find(findConfig) {
|
|
94
|
+
this._ensureInitialized();
|
|
95
|
+
const { query, messageSearch, limit, sortOrder } = findConfig;
|
|
96
|
+
const finalQuery = { ...query };
|
|
97
|
+
const effectiveSortOrder = sortOrder || { timestamp: -1 };
|
|
98
|
+
if (messageSearch) {
|
|
99
|
+
const searchResults = this._miniSearch.search(messageSearch, { prefix: true, fuzzy: 0.2 });
|
|
100
|
+
const ids = searchResults.map((result) => result._id);
|
|
101
|
+
logger_js_1.default.debug(`MiniSearch found ${ids.length} results for search term "${messageSearch}"`, { depth: 3 });
|
|
102
|
+
finalQuery._id = { $in: ids };
|
|
194
103
|
}
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
104
|
+
const docs = await new Promise((resolve, reject) => {
|
|
105
|
+
let query_exec = this._db.find(finalQuery)
|
|
106
|
+
.sort(effectiveSortOrder);
|
|
107
|
+
// Only apply limit if provided
|
|
108
|
+
if (limit !== undefined) {
|
|
109
|
+
query_exec = query_exec.limit(limit);
|
|
110
|
+
}
|
|
111
|
+
query_exec.exec((err, docs) => {
|
|
112
|
+
if (err)
|
|
113
|
+
reject(err);
|
|
114
|
+
else
|
|
115
|
+
resolve(docs);
|
|
116
|
+
});
|
|
117
|
+
});
|
|
118
|
+
return docs;
|
|
119
|
+
}
|
|
120
|
+
insert(data, callback) {
|
|
121
|
+
this._insertLogs(data, (result) => {
|
|
122
|
+
if (result.code === core_2.ExportResultCode.SUCCESS) {
|
|
123
|
+
this._db.find({}, (err, docs) => {
|
|
124
|
+
if (err) {
|
|
125
|
+
logger_js_1.default.debug(err);
|
|
126
|
+
callback(err, []);
|
|
127
|
+
return;
|
|
128
|
+
}
|
|
129
|
+
callback(null, docs);
|
|
130
|
+
});
|
|
131
|
+
}
|
|
132
|
+
else {
|
|
133
|
+
callback(new Error('Failed to insert logs'), []);
|
|
134
|
+
}
|
|
135
|
+
});
|
|
136
|
+
}
|
|
137
|
+
getFinishedLogs() {
|
|
138
|
+
this._ensureInitialized();
|
|
139
|
+
return this._db.getAllData();
|
|
140
|
+
}
|
|
141
|
+
/**
|
|
142
|
+
* @copyright The OpenTelemetry Authors
|
|
143
|
+
* @license Apache-2.0
|
|
144
|
+
* converts logRecord info into more readable format
|
|
145
|
+
* @param logRecord
|
|
146
|
+
*/
|
|
147
|
+
_formatLogRecord(logRecord) {
|
|
148
|
+
return {
|
|
149
|
+
resource: {
|
|
150
|
+
attributes: logRecord.resource.attributes,
|
|
151
|
+
},
|
|
152
|
+
instrumentationScope: logRecord.instrumentationScope,
|
|
153
|
+
timestamp: (0, core_1.hrTimeToMicroseconds)(logRecord.hrTime) ?? Date.now(),
|
|
154
|
+
observedTimestamp: (0, core_1.hrTimeToMicroseconds)(logRecord.hrTimeObserved) ?? Date.now(),
|
|
155
|
+
traceId: logRecord.spanContext?.traceId,
|
|
156
|
+
spanId: logRecord.spanContext?.spanId,
|
|
157
|
+
traceFlags: logRecord.spanContext?.traceFlags,
|
|
158
|
+
severityText: logRecord.severityText,
|
|
159
|
+
severityNumber: logRecord.severityNumber,
|
|
160
|
+
body: logRecord.body,
|
|
161
|
+
attributes: logRecord.attributes,
|
|
162
|
+
};
|
|
163
|
+
}
|
|
164
|
+
set retentionTimeInSeconds(retentionTimeInSeconds) {
|
|
165
|
+
this._retentionTimeInSeconds = retentionTimeInSeconds;
|
|
166
|
+
logger_js_1.default.info(`InMemoryDbLogExporter retention time set to ${this._retentionTimeInSeconds} seconds`);
|
|
167
|
+
}
|
|
168
|
+
get retentionTimeInSeconds() {
|
|
169
|
+
return this._retentionTimeInSeconds;
|
|
170
|
+
}
|
|
171
|
+
_insertLogs(logsToInsert, resultCallback) {
|
|
172
|
+
if (!this._db)
|
|
173
|
+
return resultCallback({ code: core_2.ExportResultCode.FAILED });
|
|
174
|
+
this._db.insert(logsToInsert, (err, newDocs) => {
|
|
175
|
+
if (err) {
|
|
176
|
+
console.dir(err);
|
|
177
|
+
resultCallback({ code: core_2.ExportResultCode.FAILED });
|
|
178
|
+
return;
|
|
179
|
+
}
|
|
180
|
+
// console.dir(newDocs, { depth: 3 });
|
|
181
|
+
newDocs.forEach((doc) => this._miniSearch?.add(doc));
|
|
182
|
+
resultCallback({ code: core_2.ExportResultCode.SUCCESS });
|
|
183
|
+
});
|
|
184
|
+
return;
|
|
185
|
+
}
|
|
186
|
+
_startCleanupJob() {
|
|
187
|
+
const interval = 1000;
|
|
188
|
+
setInterval(() => {
|
|
189
|
+
if (!this._db)
|
|
190
|
+
return; // Safety check
|
|
191
|
+
const expirationDate = new Date(Date.now() - this._retentionTimeInSeconds * 1000);
|
|
192
|
+
this._db.remove({ createdAt: { $lt: expirationDate } }, { multi: true }, (err, numRemoved) => {
|
|
193
|
+
if (err) {
|
|
194
|
+
logger_js_1.default.error('Error in TTL cleanup:', err);
|
|
195
|
+
}
|
|
196
|
+
else if (numRemoved > 0) {
|
|
197
|
+
logger_js_1.default.debug(`TTL cleanup: removed ${numRemoved} expired logs`);
|
|
198
|
+
}
|
|
199
|
+
});
|
|
200
|
+
}, interval);
|
|
201
|
+
}
|
|
198
202
|
}
|
|
199
|
-
exports.InMemoryDbLogExporter = InMemoryDbLogExporter;
|
|
203
|
+
exports.InMemoryDbLogExporter = InMemoryDbLogExporter;
|
|
@@ -1,105 +1,153 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
});
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
6
|
exports.InMemoryDbMetricExporter = void 0;
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
const cleanMetrics = (0, _circular.applyNesting)(scopeMetrics);
|
|
30
|
-
cleanMetrics.forEach(metric => {
|
|
31
|
-
_pluginService.pluginService.broadcastMetric(metric);
|
|
32
|
-
});
|
|
33
|
-
// Insert only if exporter is enabled
|
|
34
|
-
if (this.isEnabled()) {
|
|
35
|
-
this._metrics.insert(cleanMetrics, (err, _newDoc) => {
|
|
36
|
-
if (err) {
|
|
37
|
-
_logger.default.error('Insertion Error:', err);
|
|
7
|
+
const core_1 = require("@opentelemetry/core");
|
|
8
|
+
const wrappers_js_1 = require("../wrappers.cjs");
|
|
9
|
+
const logger_js_1 = __importDefault(require("../../../utils/logger.cjs"));
|
|
10
|
+
const pluginService_js_1 = require("../../../tlm-plugin/pluginService.cjs");
|
|
11
|
+
const utils_js_1 = require("../metrics/tsdb/utils.cjs");
|
|
12
|
+
const SeriesRegistry_js_1 = require("../metrics/tsdb/SeriesRegistry.cjs");
|
|
13
|
+
/**
|
|
14
|
+
* In-Memory TSDB Metric Exporter
|
|
15
|
+
* Series identified by: scope + metricName + attributes
|
|
16
|
+
*/
|
|
17
|
+
class InMemoryDbMetricExporter extends wrappers_js_1.Enabler {
|
|
18
|
+
static DEFAULT_CONFIG = {
|
|
19
|
+
retentionTimeInSeconds: 3600,
|
|
20
|
+
chunkSize: 120,
|
|
21
|
+
maxChunks: 60
|
|
22
|
+
};
|
|
23
|
+
registry;
|
|
24
|
+
config;
|
|
25
|
+
cachedResource = null;
|
|
26
|
+
_initialized = false;
|
|
27
|
+
_ensureInitialized() {
|
|
28
|
+
if (this._initialized)
|
|
38
29
|
return;
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
/**
|
|
71
|
-
* Inserts metrics into the in-memory database.
|
|
72
|
-
* @param metrics - The metrics to insert.
|
|
73
|
-
* @param callback - The callback to execute after insertion.
|
|
74
|
-
*/
|
|
75
|
-
insert(metrics, callback) {
|
|
76
|
-
this._metrics.insert(metrics, callback);
|
|
77
|
-
}
|
|
78
|
-
set retentionTimeInSeconds(retentionTimeInSeconds) {
|
|
79
|
-
this._retentionTimeInSeconds = retentionTimeInSeconds;
|
|
80
|
-
_logger.default.info(`InMemoryDbMetricExporter retention time set to ${this._retentionTimeInSeconds} seconds`);
|
|
81
|
-
}
|
|
82
|
-
get retentionTimeInSeconds() {
|
|
83
|
-
return this._retentionTimeInSeconds;
|
|
84
|
-
}
|
|
85
|
-
_startCleanupJob() {
|
|
86
|
-
const interval = 1000;
|
|
87
|
-
setInterval(() => {
|
|
88
|
-
const expirationDate = new Date(Date.now() - this._retentionTimeInSeconds * 1000);
|
|
89
|
-
this._metrics.remove({
|
|
90
|
-
createdAt: {
|
|
91
|
-
$lt: expirationDate
|
|
30
|
+
this._initialized = true;
|
|
31
|
+
logger_js_1.default.info(`[MetricExporter] In-memory storage created`);
|
|
32
|
+
}
|
|
33
|
+
get rawDataDB() {
|
|
34
|
+
// For debug/inspection only - metrics are stored in registry chunks
|
|
35
|
+
const stats = this.registry.getStats();
|
|
36
|
+
return stats.totalSamples > 0 ? [`[${stats.totalSamples} samples in registry]`] : [];
|
|
37
|
+
}
|
|
38
|
+
constructor(config) {
|
|
39
|
+
super();
|
|
40
|
+
this.config = { ...InMemoryDbMetricExporter.DEFAULT_CONFIG, ...config };
|
|
41
|
+
this.registry = new SeriesRegistry_js_1.SeriesRegistry(this.config.chunkSize, this.config.maxChunks);
|
|
42
|
+
this._startCleanupJob();
|
|
43
|
+
}
|
|
44
|
+
export(resourceMetrics, resultCallback) {
|
|
45
|
+
this._ensureInitialized();
|
|
46
|
+
try {
|
|
47
|
+
// Cache resource (unique per exporter instance)
|
|
48
|
+
if (!this.cachedResource) {
|
|
49
|
+
this.cachedResource = resourceMetrics.resource;
|
|
50
|
+
}
|
|
51
|
+
const scopeMetrics = resourceMetrics.scopeMetrics;
|
|
52
|
+
// Broadcast to plugins
|
|
53
|
+
scopeMetrics?.forEach((metric) => {
|
|
54
|
+
pluginService_js_1.pluginService.broadcastMetric(metric);
|
|
55
|
+
});
|
|
56
|
+
// Store if enabled - use new storeScopeMetrics method
|
|
57
|
+
if (this.isEnabled() && scopeMetrics) {
|
|
58
|
+
this.registry.storeScopeMetrics(scopeMetrics);
|
|
59
|
+
}
|
|
60
|
+
setTimeout(() => resultCallback({ code: core_1.ExportResultCode.SUCCESS }), 0);
|
|
92
61
|
}
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
_logger.default.debug(`TTL cleanup: removed ${numRemoved} expired metrics`);
|
|
62
|
+
catch (error) {
|
|
63
|
+
logger_js_1.default.error('Error exporting metrics\n' + error.message + '\n' + error.stack);
|
|
64
|
+
return resultCallback({
|
|
65
|
+
code: core_1.ExportResultCode.FAILED,
|
|
66
|
+
error: new Error('Error exporting metrics\n' + error.message + '\n' + error.stack),
|
|
67
|
+
});
|
|
100
68
|
}
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
69
|
+
}
|
|
70
|
+
shutdown() {
|
|
71
|
+
this._enabled = false;
|
|
72
|
+
this.registry.reset();
|
|
73
|
+
return this.forceFlush();
|
|
74
|
+
}
|
|
75
|
+
reset() {
|
|
76
|
+
this._ensureInitialized();
|
|
77
|
+
this.registry.reset();
|
|
78
|
+
logger_js_1.default.info(`[MetricExporter] Reset - all metrics cleared`);
|
|
79
|
+
}
|
|
80
|
+
forceFlush() {
|
|
81
|
+
return Promise.resolve();
|
|
82
|
+
}
|
|
83
|
+
getCachedResource() {
|
|
84
|
+
return this.cachedResource;
|
|
85
|
+
}
|
|
86
|
+
set retentionTimeInSeconds(value) {
|
|
87
|
+
this.config.retentionTimeInSeconds = value;
|
|
88
|
+
logger_js_1.default.info(`Retention time set to ${value} seconds`);
|
|
89
|
+
}
|
|
90
|
+
get retentionTimeInSeconds() {
|
|
91
|
+
return this.config.retentionTimeInSeconds;
|
|
92
|
+
}
|
|
93
|
+
getStats() {
|
|
94
|
+
this._ensureInitialized();
|
|
95
|
+
return this.registry.getStats();
|
|
96
|
+
}
|
|
97
|
+
_startCleanupJob() {
|
|
98
|
+
setInterval(() => {
|
|
99
|
+
const retentionTimeNs = this.config.retentionTimeInSeconds * 1_000_000_000;
|
|
100
|
+
const result = this.registry.evictOldData(retentionTimeNs);
|
|
101
|
+
if (result.evictedChunks > 0 || result.evictedSeries > 0) {
|
|
102
|
+
logger_js_1.default.debug(`Cleanup: evicted ${result.evictedChunks} chunks, ${result.evictedSeries} series`);
|
|
103
|
+
}
|
|
104
|
+
}, 5000);
|
|
105
|
+
}
|
|
106
|
+
/**
|
|
107
|
+
* Find metrics by scope+metric queries with filters
|
|
108
|
+
* Supports both raw and otel formats
|
|
109
|
+
*/
|
|
110
|
+
find(request) {
|
|
111
|
+
this._ensureInitialized();
|
|
112
|
+
const format = request.format || 'raw';
|
|
113
|
+
// Get raw results from registry using new unified query method
|
|
114
|
+
const rawResults = this.registry.query(request.scopeMetrics, request.from, request.to);
|
|
115
|
+
// Convert format if needed
|
|
116
|
+
if (format === 'otel') {
|
|
117
|
+
return { results: (0, utils_js_1.rawToOtel)(rawResults) };
|
|
118
|
+
}
|
|
119
|
+
return { results: rawResults };
|
|
120
|
+
}
|
|
121
|
+
/**
|
|
122
|
+
* Export all metrics as line-delimited JSON (one chunk per line)
|
|
123
|
+
*/
|
|
124
|
+
exportToLineDelimitedJson() {
|
|
125
|
+
return this.registry.serializeToLineDelimitedJson();
|
|
126
|
+
}
|
|
127
|
+
/**
|
|
128
|
+
* Import metrics from line-delimited JSON format
|
|
129
|
+
*/
|
|
130
|
+
importFromLineDelimitedJson(lineDelimitedJsonData) {
|
|
131
|
+
this.registry.deserializeFromLineDelimitedJson(lineDelimitedJsonData);
|
|
132
|
+
}
|
|
133
|
+
/**
|
|
134
|
+
* Insert metrics in OpenTelemetry (OTEL) format directly into the registry
|
|
135
|
+
* @param scopeMetrics Array of ScopeMetrics (OTEL format)
|
|
136
|
+
*/
|
|
137
|
+
insertOtel(scopeMetrics) {
|
|
138
|
+
this._ensureInitialized();
|
|
139
|
+
// Store only in registry (chunks) - no duplication
|
|
140
|
+
if (this.isEnabled()) {
|
|
141
|
+
this.registry.storeScopeMetrics(scopeMetrics);
|
|
142
|
+
}
|
|
143
|
+
}
|
|
144
|
+
/**
|
|
145
|
+
* Insert metrics in raw format (MetricQueryResult[]), converts to OTEL and delegates to insertOtel
|
|
146
|
+
* @param rawScopeMetrics Array of MetricQueryResult (raw format)
|
|
147
|
+
*/
|
|
148
|
+
insertRaw(rawScopeMetrics) {
|
|
149
|
+
const otelScopeMetrics = (0, utils_js_1.rawToOtel)(rawScopeMetrics);
|
|
150
|
+
this.insertOtel(otelScopeMetrics);
|
|
151
|
+
}
|
|
104
152
|
}
|
|
105
|
-
exports.InMemoryDbMetricExporter = InMemoryDbMetricExporter;
|
|
153
|
+
exports.InMemoryDbMetricExporter = InMemoryDbMetricExporter;
|