@oas-tools/oas-telemetry 0.7.1 → 0.8.0-alpha.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.env.example +21 -2
- package/README.md +1 -2
- package/dist/cjs/config/bootConfig.cjs +19 -14
- package/dist/cjs/config/config.cjs +112 -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/InMemoryDbLogExporter.cjs +202 -190
- package/dist/cjs/telemetry/custom-implementations/exporters/InMemoryDbMetricExporter.cjs +204 -99
- package/dist/cjs/telemetry/custom-implementations/exporters/InMemoryDbSpanExporter.cjs +152 -116
- 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 +389 -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/utils/storagePath.cjs +39 -0
- package/dist/cjs/telemetry/custom-implementations/wrappers.cjs +141 -138
- package/dist/cjs/telemetry/initializeTelemetry.cjs +35 -91
- package/dist/cjs/telemetry/telemetryConfigurator.cjs +70 -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 +171 -116
- package/dist/cjs/tlm-log/logRoutes.cjs +20 -20
- package/dist/cjs/tlm-metric/metricsController.cjs +211 -121
- package/dist/cjs/tlm-metric/metricsRoutes.cjs +23 -20
- 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 +169 -117
- package/dist/cjs/tlm-trace/traceRoutes.cjs +20 -20
- 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 +6 -0
- package/dist/esm/config/config.js +1 -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/InMemoryDbLogExporter.js +47 -8
- package/dist/esm/telemetry/custom-implementations/exporters/InMemoryDbMetricExporter.js +164 -48
- package/dist/esm/telemetry/custom-implementations/exporters/InMemoryDbSpanExporter.js +69 -29
- 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 +382 -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/utils/storagePath.js +33 -0
- package/dist/esm/telemetry/custom-implementations/wrappers.js +5 -2
- package/dist/esm/telemetry/initializeTelemetry.js +27 -69
- package/dist/esm/telemetry/telemetryConfigurator.js +42 -40
- 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 +84 -4
- package/dist/esm/tlm-log/logRoutes.js +5 -2
- package/dist/esm/tlm-metric/metricsController.js +172 -49
- package/dist/esm/tlm-metric/metricsRoutes.js +10 -4
- 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 +102 -16
- package/dist/esm/tlm-trace/traceRoutes.js +5 -2
- 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 +4 -0
- package/dist/types/config/config.d.ts +36 -7
- package/dist/types/config/config.types.d.ts +6 -0
- package/dist/types/index.d.ts +2 -3
- package/dist/types/telemetry/custom-implementations/exporters/InMemoryDbLogExporter.d.ts +4 -1
- package/dist/types/telemetry/custom-implementations/exporters/InMemoryDbMetricExporter.d.ts +60 -15
- package/dist/types/telemetry/custom-implementations/exporters/InMemoryDbSpanExporter.d.ts +9 -4
- 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/utils/storagePath.d.ts +12 -0
- package/dist/types/telemetry/custom-implementations/wrappers.d.ts +1 -1
- 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-metric/metricsController.d.ts +16 -2
- package/dist/types/tlm-trace/traceController.d.ts +3 -1
- package/dist/types/types/index.d.ts +2 -2
- package/dist/ui/assets/{ApiDocsPage-C_VVPPHa.js → ApiDocsPage-BFUrXE5F.js} +2 -2
- package/dist/ui/assets/CollapsibleCard-STA1GVQO.js +1 -0
- package/dist/ui/assets/DevToolsPage-BRSfZqO_.js +1 -0
- package/dist/ui/assets/LandingPage-DzeDy7q7.js +6 -0
- package/dist/ui/assets/LogsPage-BeiFrV2X.js +1 -0
- package/dist/ui/assets/{NotFoundPage-B3quk3P1.js → NotFoundPage-fRNOatbM.js} +1 -1
- package/dist/ui/assets/PluginCreatePage-Ch_RXsdf.js +50 -0
- package/dist/ui/assets/PluginPage-Cl65ZZ_n.js +27 -0
- package/dist/ui/assets/TraceSpansPage-BoK4M5Hh.js +6 -0
- package/dist/ui/assets/VirtualizedListPanel-zcj0v7DL.js +16 -0
- package/dist/ui/assets/alert-BkNVKxJN.js +1133 -0
- package/dist/ui/assets/badge-CN7FeufU.js +1 -0
- package/dist/ui/assets/{chevron-down-CPsvsmqj.js → chevron-down-CG--ounh.js} +1 -1
- package/dist/ui/assets/{chevron-up-Df9jMo1X.js → chevron-up-B6tzMAOm.js} +1 -1
- package/dist/ui/assets/{circle-alert-DOPQPvU8.js → circle-alert-BDF8Tq9y.js} +1 -1
- package/dist/ui/assets/dialog-BrpWNk36.js +15 -0
- package/dist/ui/assets/index-6xOVKwKn.js +305 -0
- package/dist/ui/assets/index-D6f1KjWV.css +1 -0
- package/dist/ui/assets/index-D96rVSkR.js +1 -0
- package/dist/ui/assets/info-99kuqpbx.js +6 -0
- package/dist/ui/assets/{input-Dzvg_ZEZ.js → input-B-01QDg_.js} +1 -1
- package/dist/ui/assets/label-CQLeZjM1.js +1 -0
- package/dist/ui/assets/{loader-circle-CrvlRy5o.js → loader-circle-BoDGk-BO.js} +1 -1
- package/dist/ui/assets/{loginPage-qa4V-B70.js → loginPage-8F4EEd1B.js} +1 -1
- package/dist/ui/assets/metrics-page-D1GxaB_c.css +1 -0
- package/dist/ui/assets/metrics-page-DPtteXqY.js +31 -0
- package/dist/ui/assets/popover-DS_8DYYt.js +11 -0
- package/dist/ui/assets/select-DYjegiXi.js +6 -0
- package/dist/ui/assets/separator-DGsRxIrl.js +6 -0
- package/dist/ui/assets/severityOptions-DEOvJqC9.js +11 -0
- package/dist/ui/assets/square-pen-DPhgYz6O.js +6 -0
- package/dist/ui/assets/switch-Di9NJH2A.js +1 -0
- package/dist/ui/assets/trace-DJq1miYa.js +1 -0
- package/dist/ui/assets/upload-BiLTpCnX.js +11 -0
- package/dist/ui/assets/{utilService-DNyqzwj0.js → utilService-CNZOmadC.js} +1 -1
- package/dist/ui/assets/wand-sparkles-CPoBNFFg.js +6 -0
- package/dist/ui/index.html +2 -2
- package/package.json +44 -48
- 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,76 +1,68 @@
|
|
|
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.configureRoutes = void 0;
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e }; }
|
|
7
|
+
const express_1 = require("express");
|
|
8
|
+
const logger_js_1 = __importDefault(require("./utils/logger.cjs"));
|
|
9
|
+
const cors_1 = __importDefault(require("cors"));
|
|
10
|
+
const traceRoutes_js_1 = require("./tlm-trace/traceRoutes.cjs");
|
|
11
|
+
const metricsRoutes_js_1 = require("./tlm-metric/metricsRoutes.cjs");
|
|
12
|
+
const logRoutes_js_1 = require("./tlm-log/logRoutes.cjs");
|
|
13
|
+
const cookie_parser_1 = __importDefault(require("cookie-parser"));
|
|
14
|
+
const authRoutes_js_1 = require("./tlm-auth/authRoutes.cjs");
|
|
15
|
+
const uiRoutes_js_1 = require("./tlm-ui/uiRoutes.cjs");
|
|
16
|
+
const authMiddleware_js_1 = require("./tlm-auth/authMiddleware.cjs");
|
|
17
|
+
const utilRoutes_js_1 = require("./tlm-util/utilRoutes.cjs");
|
|
18
|
+
const aiRoutes_js_1 = require("./tlm-ai/aiRoutes.cjs");
|
|
19
|
+
const bootConfig_js_1 = require("./config/bootConfig.cjs");
|
|
20
|
+
const pluginRoutes_js_1 = require("./tlm-plugin/pluginRoutes.cjs");
|
|
22
21
|
const configureRoutes = (router, oasTlmConfig) => {
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
router.use((0, _cors.default)({
|
|
26
|
-
origin: (origin, callback) => {
|
|
27
|
-
if (!origin || /^http:\/\/localhost:\d+$/.test(origin)) {
|
|
28
|
-
callback(null, true);
|
|
29
|
-
} else {
|
|
30
|
-
callback(new Error('Not allowed by CORS'));
|
|
31
|
-
}
|
|
32
|
-
},
|
|
33
|
-
credentials: true
|
|
34
|
-
}));
|
|
35
|
-
}
|
|
36
|
-
const telemetryBaseUrl = oasTlmConfig.general.baseUrl;
|
|
37
|
-
// Sub-router for all telemetry endpoints
|
|
38
|
-
const telemetryRouter = (0, _express.Router)();
|
|
39
|
-
// Body parser for JSON requests
|
|
40
|
-
telemetryRouter.use((req, res, next) => {
|
|
41
|
-
if (req.body !== undefined) {
|
|
42
|
-
return next(); // Already parsed, no need to parse again.
|
|
22
|
+
if (!oasTlmConfig.general.spec && !oasTlmConfig.general.specFileName) {
|
|
23
|
+
logger_js_1.default.warn("No spec provided, endpoint filtering will not be available. Please provide either `spec` or `specFileName` in the configuration.");
|
|
43
24
|
}
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
25
|
+
if (bootConfig_js_1.bootEnvVariables.OASTLM_BOOT_ENV === 'development') {
|
|
26
|
+
logger_js_1.default.info("Running in development mode, enabling CORS for all origins");
|
|
27
|
+
router.use((0, cors_1.default)({
|
|
28
|
+
origin: true,
|
|
29
|
+
credentials: true
|
|
30
|
+
}));
|
|
31
|
+
}
|
|
32
|
+
const telemetryBaseUrl = bootConfig_js_1.bootEnvVariables.OASTLM_BOOT_BASE_URL;
|
|
33
|
+
// Sub-router for all telemetry endpoints
|
|
34
|
+
const telemetryRouter = (0, express_1.Router)();
|
|
35
|
+
// Body parser for JSON requests
|
|
36
|
+
telemetryRouter.use((req, res, next) => {
|
|
37
|
+
if (req.body !== undefined) {
|
|
38
|
+
return next(); // Already parsed, no need to parse again.
|
|
39
|
+
}
|
|
40
|
+
return (0, express_1.json)({ limit: '500mb' })(req, res, next);
|
|
51
41
|
});
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
telemetryRouter.use("/
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
42
|
+
telemetryRouter.get('/health', (_req, res) => {
|
|
43
|
+
res.status(200).send({ status: 'OK' });
|
|
44
|
+
});
|
|
45
|
+
// Redirect to the UI when accessing the base URL
|
|
46
|
+
telemetryRouter.get('/', (req, res) => {
|
|
47
|
+
res.redirect(`${telemetryBaseUrl}/oas-telemetry-ui/`);
|
|
48
|
+
});
|
|
49
|
+
// WARNING: This path must be the same as the one used in the UI package App.tsx "oas-telemetry-ui"
|
|
50
|
+
telemetryRouter.use("/oas-telemetry-ui", (0, uiRoutes_js_1.getUIRoutes)());
|
|
51
|
+
telemetryRouter.use("/utils", (0, utilRoutes_js_1.getUtilsRoutes)(oasTlmConfig));
|
|
52
|
+
// Auth routes must be registered. If authentication is not enabled, all requests will be allowed.
|
|
53
|
+
// Frontend will use these endpoints;
|
|
54
|
+
telemetryRouter.use((0, cookie_parser_1.default)());
|
|
55
|
+
// Refresh token uses /auth/refresh path, careful if you change it
|
|
56
|
+
telemetryRouter.use('/auth', (0, authRoutes_js_1.getAuthRoutes)(oasTlmConfig));
|
|
57
|
+
telemetryRouter.use((0, authMiddleware_js_1.getAuthMiddleware)(oasTlmConfig));
|
|
58
|
+
telemetryRouter.use("/traces", (0, traceRoutes_js_1.getTraceRoutes)());
|
|
59
|
+
telemetryRouter.use("/metrics", (0, metricsRoutes_js_1.getMetricsRoutes)());
|
|
60
|
+
telemetryRouter.use("/logs", (0, logRoutes_js_1.getLogRoutes)());
|
|
61
|
+
if (oasTlmConfig.ai.openAIKey) {
|
|
62
|
+
telemetryRouter.use("/ai", (0, aiRoutes_js_1.getAIRoutes)(oasTlmConfig));
|
|
63
|
+
}
|
|
64
|
+
telemetryRouter.use("/plugins", (0, pluginRoutes_js_1.getPluginRoutes)());
|
|
65
|
+
// Mount the telemetryRouter under telemetryBaseUrl
|
|
66
|
+
router.use(telemetryBaseUrl, telemetryRouter);
|
|
75
67
|
};
|
|
76
|
-
exports.configureRoutes = configureRoutes;
|
|
68
|
+
exports.configureRoutes = configureRoutes;
|
|
@@ -1,199 +1,211 @@
|
|
|
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
|
-
|
|
25
|
-
|
|
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
|
+
const storagePath_js_1 = require("../utils/storagePath.cjs");
|
|
16
|
+
class InMemoryDbLogExporter extends wrappers_js_1.Enabler {
|
|
17
|
+
_db = null;
|
|
18
|
+
_miniSearch = null;
|
|
19
|
+
_retentionTimeInSeconds;
|
|
20
|
+
_storagePath = null;
|
|
21
|
+
_initialized = false;
|
|
22
|
+
constructor(retentionTimeInSeconds = 3600) {
|
|
23
|
+
super();
|
|
24
|
+
this._retentionTimeInSeconds = retentionTimeInSeconds;
|
|
25
|
+
this._storagePath = (0, storagePath_js_1.getStoragePath)('logs');
|
|
26
|
+
this._startCleanupJob();
|
|
62
27
|
}
|
|
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, []);
|
|
28
|
+
_ensureInitialized() {
|
|
29
|
+
if (this._initialized)
|
|
120
30
|
return;
|
|
121
|
-
|
|
122
|
-
|
|
31
|
+
this._initialized = true;
|
|
32
|
+
this._db = new nedb_1.default(this._storagePath ? { filename: this._storagePath, timestampData: true, autoload: true } : { timestampData: true });
|
|
33
|
+
this._db.ensureIndex({ fieldName: 'createdAt' });
|
|
34
|
+
this._miniSearch = new minisearch_1.default({
|
|
35
|
+
fields: ['body'],
|
|
36
|
+
storeFields: ['_id'],
|
|
37
|
+
idField: '_id',
|
|
38
|
+
});
|
|
39
|
+
if (this._storagePath) {
|
|
40
|
+
logger_js_1.default.info(`[LogExporter] Disk storage enabled at: ${this._storagePath}`);
|
|
41
|
+
}
|
|
42
|
+
else {
|
|
43
|
+
logger_js_1.default.info(`[LogExporter] Using in-memory storage`);
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
/*
|
|
47
|
+
* SUPER WARNING:
|
|
48
|
+
* Do NOT use console.log, console.error, or any logger inside this class's export function.
|
|
49
|
+
* Doing so will cause an infinite loop.
|
|
50
|
+
* Only console.dir is allowed, as it is not tracked by our log export implementation.
|
|
51
|
+
*/
|
|
52
|
+
/**
|
|
53
|
+
* Export logs.
|
|
54
|
+
* @param logs
|
|
55
|
+
* @param resultCallback
|
|
56
|
+
*/
|
|
57
|
+
export(logs, resultCallback) {
|
|
58
|
+
this._ensureInitialized();
|
|
59
|
+
const logsToInsert = logs.map(logRecord => {
|
|
60
|
+
// Remove circular references first, then apply nesting, then export info
|
|
61
|
+
const formattedLog = this._formatLogRecord(logRecord);
|
|
62
|
+
const cleanedLog = (0, circular_js_1.removeCircularRefs)(formattedLog);
|
|
63
|
+
const nestedLog = (0, circular_js_1.applyNesting)(cleanedLog);
|
|
64
|
+
return nestedLog;
|
|
123
65
|
});
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
}
|
|
127
|
-
});
|
|
128
|
-
}
|
|
129
|
-
getFinishedLogs() {
|
|
130
|
-
return this._db.getAllData();
|
|
131
|
-
}
|
|
132
|
-
/**
|
|
133
|
-
* @copyright The OpenTelemetry Authors
|
|
134
|
-
* @license Apache-2.0
|
|
135
|
-
* converts logRecord info into more readable format
|
|
136
|
-
* @param logRecord
|
|
137
|
-
*/
|
|
138
|
-
_formatLogRecord(logRecord) {
|
|
139
|
-
return {
|
|
140
|
-
resource: {
|
|
141
|
-
attributes: logRecord.resource.attributes
|
|
142
|
-
},
|
|
143
|
-
instrumentationScope: logRecord.instrumentationScope,
|
|
144
|
-
timestamp: (0, _core.hrTimeToMicroseconds)(logRecord.hrTime) ?? Date.now(),
|
|
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
|
|
66
|
+
logsToInsert.forEach(log => {
|
|
67
|
+
pluginService_js_1.pluginService.broadcastLog(log);
|
|
168
68
|
});
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
newDocs.forEach(doc => this._miniSearch.add(doc));
|
|
173
|
-
resultCallback({
|
|
174
|
-
code: _core.ExportResultCode.SUCCESS
|
|
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
|
|
69
|
+
// ENABLED only affect storage not plugin broadcasting
|
|
70
|
+
if (this.isEnabled()) {
|
|
71
|
+
this._insertLogs(logsToInsert, resultCallback);
|
|
186
72
|
}
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
}
|
|
193
|
-
|
|
73
|
+
resultCallback({ code: core_2.ExportResultCode.SUCCESS });
|
|
74
|
+
}
|
|
75
|
+
reset() {
|
|
76
|
+
this._ensureInitialized();
|
|
77
|
+
// Remove all logs from database but keep persistence enabled
|
|
78
|
+
this._db.remove({}, { multi: true }, (err) => {
|
|
79
|
+
if (err) {
|
|
80
|
+
logger_js_1.default.error(`[LogExporter] Error during reset: ${err.message}`);
|
|
81
|
+
}
|
|
82
|
+
else {
|
|
83
|
+
logger_js_1.default.info(`[LogExporter] Reset - all logs cleared`);
|
|
84
|
+
}
|
|
85
|
+
});
|
|
86
|
+
// Clear mini search index
|
|
87
|
+
this._miniSearch = new minisearch_1.default({
|
|
88
|
+
fields: ['body'],
|
|
89
|
+
storeFields: ['_id'],
|
|
90
|
+
idField: '_id',
|
|
91
|
+
});
|
|
92
|
+
}
|
|
93
|
+
/**
|
|
94
|
+
* Shutdown the exporter.
|
|
95
|
+
*/
|
|
96
|
+
async shutdown() {
|
|
97
|
+
this._db = null;
|
|
98
|
+
this._miniSearch = null;
|
|
99
|
+
this._initialized = false;
|
|
100
|
+
}
|
|
101
|
+
async find(findConfig) {
|
|
102
|
+
this._ensureInitialized();
|
|
103
|
+
const { query, messageSearch, limit, sortOrder } = findConfig;
|
|
104
|
+
const finalQuery = { ...query };
|
|
105
|
+
const effectiveSortOrder = sortOrder || { timestamp: -1 };
|
|
106
|
+
if (messageSearch) {
|
|
107
|
+
const searchResults = this._miniSearch.search(messageSearch, { prefix: true, fuzzy: 0.2 });
|
|
108
|
+
const ids = searchResults.map((result) => result._id);
|
|
109
|
+
logger_js_1.default.debug(`MiniSearch found ${ids.length} results for search term "${messageSearch}"`, { depth: 3 });
|
|
110
|
+
finalQuery._id = { $in: ids };
|
|
194
111
|
}
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
112
|
+
const docs = await new Promise((resolve, reject) => {
|
|
113
|
+
let query_exec = this._db.find(finalQuery)
|
|
114
|
+
.sort(effectiveSortOrder);
|
|
115
|
+
// Only apply limit if provided
|
|
116
|
+
if (limit !== undefined) {
|
|
117
|
+
query_exec = query_exec.limit(limit);
|
|
118
|
+
}
|
|
119
|
+
query_exec.exec((err, docs) => {
|
|
120
|
+
if (err)
|
|
121
|
+
reject(err);
|
|
122
|
+
else
|
|
123
|
+
resolve(docs);
|
|
124
|
+
});
|
|
125
|
+
});
|
|
126
|
+
return docs;
|
|
127
|
+
}
|
|
128
|
+
insert(data, callback) {
|
|
129
|
+
this._insertLogs(data, (result) => {
|
|
130
|
+
if (result.code === core_2.ExportResultCode.SUCCESS) {
|
|
131
|
+
this._db.find({}, (err, docs) => {
|
|
132
|
+
if (err) {
|
|
133
|
+
logger_js_1.default.debug(err);
|
|
134
|
+
callback(err, []);
|
|
135
|
+
return;
|
|
136
|
+
}
|
|
137
|
+
callback(null, docs);
|
|
138
|
+
});
|
|
139
|
+
}
|
|
140
|
+
else {
|
|
141
|
+
callback(new Error('Failed to insert logs'), []);
|
|
142
|
+
}
|
|
143
|
+
});
|
|
144
|
+
}
|
|
145
|
+
getFinishedLogs() {
|
|
146
|
+
this._ensureInitialized();
|
|
147
|
+
return this._db.getAllData();
|
|
148
|
+
}
|
|
149
|
+
/**
|
|
150
|
+
* @copyright The OpenTelemetry Authors
|
|
151
|
+
* @license Apache-2.0
|
|
152
|
+
* converts logRecord info into more readable format
|
|
153
|
+
* @param logRecord
|
|
154
|
+
*/
|
|
155
|
+
_formatLogRecord(logRecord) {
|
|
156
|
+
return {
|
|
157
|
+
resource: {
|
|
158
|
+
attributes: logRecord.resource.attributes,
|
|
159
|
+
},
|
|
160
|
+
instrumentationScope: logRecord.instrumentationScope,
|
|
161
|
+
timestamp: (0, core_1.hrTimeToMicroseconds)(logRecord.hrTime) ?? Date.now(),
|
|
162
|
+
observedTimestamp: (0, core_1.hrTimeToMicroseconds)(logRecord.hrTimeObserved) ?? Date.now(),
|
|
163
|
+
traceId: logRecord.spanContext?.traceId,
|
|
164
|
+
spanId: logRecord.spanContext?.spanId,
|
|
165
|
+
traceFlags: logRecord.spanContext?.traceFlags,
|
|
166
|
+
severityText: logRecord.severityText,
|
|
167
|
+
severityNumber: logRecord.severityNumber,
|
|
168
|
+
body: logRecord.body,
|
|
169
|
+
attributes: logRecord.attributes,
|
|
170
|
+
};
|
|
171
|
+
}
|
|
172
|
+
set retentionTimeInSeconds(retentionTimeInSeconds) {
|
|
173
|
+
this._retentionTimeInSeconds = retentionTimeInSeconds;
|
|
174
|
+
logger_js_1.default.info(`InMemoryDbLogExporter retention time set to ${this._retentionTimeInSeconds} seconds`);
|
|
175
|
+
}
|
|
176
|
+
get retentionTimeInSeconds() {
|
|
177
|
+
return this._retentionTimeInSeconds;
|
|
178
|
+
}
|
|
179
|
+
_insertLogs(logsToInsert, resultCallback) {
|
|
180
|
+
if (!this._db)
|
|
181
|
+
return resultCallback({ code: core_2.ExportResultCode.FAILED });
|
|
182
|
+
this._db.insert(logsToInsert, (err, newDocs) => {
|
|
183
|
+
if (err) {
|
|
184
|
+
console.dir(err);
|
|
185
|
+
resultCallback({ code: core_2.ExportResultCode.FAILED });
|
|
186
|
+
return;
|
|
187
|
+
}
|
|
188
|
+
// console.dir(newDocs, { depth: 3 });
|
|
189
|
+
newDocs.forEach((doc) => this._miniSearch?.add(doc));
|
|
190
|
+
resultCallback({ code: core_2.ExportResultCode.SUCCESS });
|
|
191
|
+
});
|
|
192
|
+
return;
|
|
193
|
+
}
|
|
194
|
+
_startCleanupJob() {
|
|
195
|
+
const interval = 1000;
|
|
196
|
+
setInterval(() => {
|
|
197
|
+
if (!this._db)
|
|
198
|
+
return; // Safety check
|
|
199
|
+
const expirationDate = new Date(Date.now() - this._retentionTimeInSeconds * 1000);
|
|
200
|
+
this._db.remove({ createdAt: { $lt: expirationDate } }, { multi: true }, (err, numRemoved) => {
|
|
201
|
+
if (err) {
|
|
202
|
+
logger_js_1.default.error('Error in TTL cleanup:', err);
|
|
203
|
+
}
|
|
204
|
+
else if (numRemoved > 0) {
|
|
205
|
+
logger_js_1.default.debug(`TTL cleanup: removed ${numRemoved} expired logs`);
|
|
206
|
+
}
|
|
207
|
+
});
|
|
208
|
+
}, interval);
|
|
209
|
+
}
|
|
198
210
|
}
|
|
199
|
-
exports.InMemoryDbLogExporter = InMemoryDbLogExporter;
|
|
211
|
+
exports.InMemoryDbLogExporter = InMemoryDbLogExporter;
|