@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.
Files changed (167) hide show
  1. package/.env.example +21 -2
  2. package/README.md +1 -2
  3. package/dist/cjs/config/bootConfig.cjs +19 -14
  4. package/dist/cjs/config/config.cjs +112 -125
  5. package/dist/cjs/config/config.types.cjs +1 -4
  6. package/dist/cjs/docs/openapi.yaml +158 -4
  7. package/dist/cjs/index.cjs +27 -30
  8. package/dist/cjs/routesManager.cjs +62 -70
  9. package/dist/cjs/telemetry/custom-implementations/exporters/InMemoryDbLogExporter.cjs +202 -190
  10. package/dist/cjs/telemetry/custom-implementations/exporters/InMemoryDbMetricExporter.cjs +204 -99
  11. package/dist/cjs/telemetry/custom-implementations/exporters/InMemoryDbSpanExporter.cjs +152 -116
  12. package/dist/cjs/telemetry/custom-implementations/instrumentations/logsInstrumentation.cjs +92 -0
  13. package/dist/cjs/telemetry/custom-implementations/metrics/tsdb/Chunk.cjs +159 -0
  14. package/dist/cjs/telemetry/custom-implementations/metrics/tsdb/Series.cjs +168 -0
  15. package/dist/cjs/telemetry/custom-implementations/metrics/tsdb/SeriesRegistry.cjs +389 -0
  16. package/dist/cjs/telemetry/custom-implementations/metrics/tsdb/types.cjs +2 -0
  17. package/dist/cjs/telemetry/custom-implementations/metrics/tsdb/utils.cjs +77 -0
  18. package/dist/cjs/telemetry/custom-implementations/processors/dynamicMultiLogProcessor.cjs +65 -63
  19. package/dist/cjs/telemetry/custom-implementations/processors/dynamicMultiSpanProcessor.cjs +63 -62
  20. package/dist/cjs/telemetry/custom-implementations/utils/circular.cjs +47 -47
  21. package/dist/cjs/telemetry/custom-implementations/utils/storagePath.cjs +39 -0
  22. package/dist/cjs/telemetry/custom-implementations/wrappers.cjs +141 -138
  23. package/dist/cjs/telemetry/initializeTelemetry.cjs +35 -91
  24. package/dist/cjs/telemetry/telemetryConfigurator.cjs +70 -72
  25. package/dist/cjs/telemetry/telemetryRegistry.cjs +45 -31
  26. package/dist/cjs/tlm-ai/agent.cjs +49 -64
  27. package/dist/cjs/tlm-ai/aiController.cjs +54 -76
  28. package/dist/cjs/tlm-ai/aiRoutes.cjs +17 -20
  29. package/dist/cjs/tlm-ai/aiService.cjs +91 -95
  30. package/dist/cjs/tlm-ai/tools.cjs +177 -174
  31. package/dist/cjs/tlm-auth/authController.cjs +80 -123
  32. package/dist/cjs/tlm-auth/authMiddleware.cjs +25 -30
  33. package/dist/cjs/tlm-auth/authRoutes.cjs +11 -14
  34. package/dist/cjs/tlm-log/logController.cjs +171 -116
  35. package/dist/cjs/tlm-log/logRoutes.cjs +20 -20
  36. package/dist/cjs/tlm-metric/metricsController.cjs +211 -121
  37. package/dist/cjs/tlm-metric/metricsRoutes.cjs +23 -20
  38. package/dist/cjs/tlm-plugin/pluginController.cjs +128 -140
  39. package/dist/cjs/tlm-plugin/pluginProcess.cjs +89 -94
  40. package/dist/cjs/tlm-plugin/pluginRoutes.cjs +11 -14
  41. package/dist/cjs/tlm-plugin/pluginService.cjs +73 -74
  42. package/dist/cjs/tlm-trace/traceController.cjs +169 -117
  43. package/dist/cjs/tlm-trace/traceRoutes.cjs +20 -20
  44. package/dist/cjs/tlm-ui/uiRoutes.cjs +63 -32
  45. package/dist/cjs/tlm-util/utilController.cjs +68 -70
  46. package/dist/cjs/tlm-util/utilRoutes.cjs +51 -63
  47. package/dist/cjs/types/index.cjs +2 -5
  48. package/dist/cjs/utils/logger.cjs +38 -43
  49. package/dist/cjs/utils/regexUtils.cjs +22 -22
  50. package/dist/esm/config/bootConfig.js +6 -0
  51. package/dist/esm/config/config.js +1 -2
  52. package/dist/esm/docs/openapi.yaml +158 -4
  53. package/dist/esm/index.js +9 -8
  54. package/dist/esm/routesManager.js +6 -10
  55. package/dist/esm/telemetry/custom-implementations/exporters/InMemoryDbLogExporter.js +47 -8
  56. package/dist/esm/telemetry/custom-implementations/exporters/InMemoryDbMetricExporter.js +164 -48
  57. package/dist/esm/telemetry/custom-implementations/exporters/InMemoryDbSpanExporter.js +69 -29
  58. package/dist/esm/telemetry/custom-implementations/instrumentations/logsInstrumentation.js +85 -0
  59. package/dist/esm/telemetry/custom-implementations/metrics/tsdb/Chunk.js +155 -0
  60. package/dist/esm/telemetry/custom-implementations/metrics/tsdb/Series.js +164 -0
  61. package/dist/esm/telemetry/custom-implementations/metrics/tsdb/SeriesRegistry.js +382 -0
  62. package/dist/esm/telemetry/custom-implementations/metrics/tsdb/types.js +1 -0
  63. package/dist/esm/telemetry/custom-implementations/metrics/tsdb/utils.js +74 -0
  64. package/dist/esm/telemetry/custom-implementations/processors/dynamicMultiLogProcessor.js +2 -1
  65. package/dist/esm/telemetry/custom-implementations/processors/dynamicMultiSpanProcessor.js +1 -1
  66. package/dist/esm/telemetry/custom-implementations/utils/storagePath.js +33 -0
  67. package/dist/esm/telemetry/custom-implementations/wrappers.js +5 -2
  68. package/dist/esm/telemetry/initializeTelemetry.js +27 -69
  69. package/dist/esm/telemetry/telemetryConfigurator.js +42 -40
  70. package/dist/esm/telemetry/telemetryRegistry.js +12 -1
  71. package/dist/esm/tlm-ai/agent.js +5 -3
  72. package/dist/esm/tlm-ai/aiController.js +3 -3
  73. package/dist/esm/tlm-ai/aiService.js +6 -2
  74. package/dist/esm/tlm-ai/tools.js +5 -9
  75. package/dist/esm/tlm-auth/authController.js +3 -2
  76. package/dist/esm/tlm-log/logController.js +84 -4
  77. package/dist/esm/tlm-log/logRoutes.js +5 -2
  78. package/dist/esm/tlm-metric/metricsController.js +172 -49
  79. package/dist/esm/tlm-metric/metricsRoutes.js +10 -4
  80. package/dist/esm/tlm-plugin/pluginController.js +6 -11
  81. package/dist/esm/tlm-plugin/pluginService.js +2 -4
  82. package/dist/esm/tlm-trace/traceController.js +102 -16
  83. package/dist/esm/tlm-trace/traceRoutes.js +5 -2
  84. package/dist/esm/tlm-ui/uiRoutes.js +5 -5
  85. package/dist/esm/tlm-util/utilController.js +3 -9
  86. package/dist/esm/tlm-util/utilRoutes.js +2 -2
  87. package/dist/types/config/bootConfig.d.ts +4 -0
  88. package/dist/types/config/config.d.ts +36 -7
  89. package/dist/types/config/config.types.d.ts +6 -0
  90. package/dist/types/index.d.ts +2 -3
  91. package/dist/types/telemetry/custom-implementations/exporters/InMemoryDbLogExporter.d.ts +4 -1
  92. package/dist/types/telemetry/custom-implementations/exporters/InMemoryDbMetricExporter.d.ts +60 -15
  93. package/dist/types/telemetry/custom-implementations/exporters/InMemoryDbSpanExporter.d.ts +9 -4
  94. package/dist/types/telemetry/custom-implementations/instrumentations/logsInstrumentation.d.ts +23 -0
  95. package/dist/types/telemetry/custom-implementations/metrics/tsdb/Chunk.d.ts +49 -0
  96. package/dist/types/telemetry/custom-implementations/metrics/tsdb/Series.d.ts +67 -0
  97. package/dist/types/telemetry/custom-implementations/metrics/tsdb/SeriesRegistry.d.ts +69 -0
  98. package/dist/types/telemetry/custom-implementations/metrics/tsdb/types.d.ts +68 -0
  99. package/dist/types/telemetry/custom-implementations/metrics/tsdb/utils.d.ts +21 -0
  100. package/dist/types/telemetry/custom-implementations/processors/dynamicMultiLogProcessor.d.ts +2 -2
  101. package/dist/types/telemetry/custom-implementations/utils/storagePath.d.ts +12 -0
  102. package/dist/types/telemetry/custom-implementations/wrappers.d.ts +1 -1
  103. package/dist/types/telemetry/telemetryConfigurator.d.ts +1 -1
  104. package/dist/types/telemetry/telemetryRegistry.d.ts +8 -0
  105. package/dist/types/tlm-ai/agent.d.ts +1 -1
  106. package/dist/types/tlm-ai/aiService.d.ts +1 -1
  107. package/dist/types/tlm-log/logController.d.ts +2 -0
  108. package/dist/types/tlm-metric/metricsController.d.ts +16 -2
  109. package/dist/types/tlm-trace/traceController.d.ts +3 -1
  110. package/dist/types/types/index.d.ts +2 -2
  111. package/dist/ui/assets/{ApiDocsPage-C_VVPPHa.js → ApiDocsPage-BFUrXE5F.js} +2 -2
  112. package/dist/ui/assets/CollapsibleCard-STA1GVQO.js +1 -0
  113. package/dist/ui/assets/DevToolsPage-BRSfZqO_.js +1 -0
  114. package/dist/ui/assets/LandingPage-DzeDy7q7.js +6 -0
  115. package/dist/ui/assets/LogsPage-BeiFrV2X.js +1 -0
  116. package/dist/ui/assets/{NotFoundPage-B3quk3P1.js → NotFoundPage-fRNOatbM.js} +1 -1
  117. package/dist/ui/assets/PluginCreatePage-Ch_RXsdf.js +50 -0
  118. package/dist/ui/assets/PluginPage-Cl65ZZ_n.js +27 -0
  119. package/dist/ui/assets/TraceSpansPage-BoK4M5Hh.js +6 -0
  120. package/dist/ui/assets/VirtualizedListPanel-zcj0v7DL.js +16 -0
  121. package/dist/ui/assets/alert-BkNVKxJN.js +1133 -0
  122. package/dist/ui/assets/badge-CN7FeufU.js +1 -0
  123. package/dist/ui/assets/{chevron-down-CPsvsmqj.js → chevron-down-CG--ounh.js} +1 -1
  124. package/dist/ui/assets/{chevron-up-Df9jMo1X.js → chevron-up-B6tzMAOm.js} +1 -1
  125. package/dist/ui/assets/{circle-alert-DOPQPvU8.js → circle-alert-BDF8Tq9y.js} +1 -1
  126. package/dist/ui/assets/dialog-BrpWNk36.js +15 -0
  127. package/dist/ui/assets/index-6xOVKwKn.js +305 -0
  128. package/dist/ui/assets/index-D6f1KjWV.css +1 -0
  129. package/dist/ui/assets/index-D96rVSkR.js +1 -0
  130. package/dist/ui/assets/info-99kuqpbx.js +6 -0
  131. package/dist/ui/assets/{input-Dzvg_ZEZ.js → input-B-01QDg_.js} +1 -1
  132. package/dist/ui/assets/label-CQLeZjM1.js +1 -0
  133. package/dist/ui/assets/{loader-circle-CrvlRy5o.js → loader-circle-BoDGk-BO.js} +1 -1
  134. package/dist/ui/assets/{loginPage-qa4V-B70.js → loginPage-8F4EEd1B.js} +1 -1
  135. package/dist/ui/assets/metrics-page-D1GxaB_c.css +1 -0
  136. package/dist/ui/assets/metrics-page-DPtteXqY.js +31 -0
  137. package/dist/ui/assets/popover-DS_8DYYt.js +11 -0
  138. package/dist/ui/assets/select-DYjegiXi.js +6 -0
  139. package/dist/ui/assets/separator-DGsRxIrl.js +6 -0
  140. package/dist/ui/assets/severityOptions-DEOvJqC9.js +11 -0
  141. package/dist/ui/assets/square-pen-DPhgYz6O.js +6 -0
  142. package/dist/ui/assets/switch-Di9NJH2A.js +1 -0
  143. package/dist/ui/assets/trace-DJq1miYa.js +1 -0
  144. package/dist/ui/assets/upload-BiLTpCnX.js +11 -0
  145. package/dist/ui/assets/{utilService-DNyqzwj0.js → utilService-CNZOmadC.js} +1 -1
  146. package/dist/ui/assets/wand-sparkles-CPoBNFFg.js +6 -0
  147. package/dist/ui/index.html +2 -2
  148. package/package.json +44 -48
  149. package/dist/ui/assets/CollapsibleCard-B3KR_8mL.js +0 -1
  150. package/dist/ui/assets/DevToolsPage-OyZcDcmw.js +0 -1
  151. package/dist/ui/assets/LandingPage-CppFBA6K.js +0 -6
  152. package/dist/ui/assets/LogsPage-9Fq8GArS.js +0 -26
  153. package/dist/ui/assets/PluginCreatePage-X_aCH4t4.js +0 -50
  154. package/dist/ui/assets/PluginPage-DMDSihrZ.js +0 -27
  155. package/dist/ui/assets/alert-jQ9HCPIf.js +0 -1133
  156. package/dist/ui/assets/badge-CNq0-mH5.js +0 -1
  157. package/dist/ui/assets/card-DFAwwhN3.js +0 -1
  158. package/dist/ui/assets/index-BkD6DijD.js +0 -15
  159. package/dist/ui/assets/index-CERGVYZK.js +0 -292
  160. package/dist/ui/assets/index-CSIPf9qw.css +0 -1
  161. package/dist/ui/assets/label-DuVnkZ4q.js +0 -1
  162. package/dist/ui/assets/select-DhS8YUtJ.js +0 -1
  163. package/dist/ui/assets/separator-isK4chBP.js +0 -6
  164. package/dist/ui/assets/severityOptions-O38dSOfk.js +0 -11
  165. package/dist/ui/assets/switch-Z3mImG9n.js +0 -1
  166. package/dist/ui/assets/tabs-_77MUUQe.js +0 -16
  167. package/dist/ui/assets/upload-C1LT4Gkb.js +0 -16
@@ -1,105 +1,210 @@
1
1
  "use strict";
2
-
3
- Object.defineProperty(exports, "__esModule", {
4
- value: true
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
- var _core = require("@opentelemetry/core");
8
- var _nedb = _interopRequireDefault(require("@seald-io/nedb"));
9
- var _circular = require("../utils/circular.cjs");
10
- var _wrappers = require("../wrappers.cjs");
11
- var _logger = _interopRequireDefault(require("../../../utils/logger.cjs"));
12
- var _pluginService = require("../../../tlm-plugin/pluginService.cjs");
13
- function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e }; }
14
- class InMemoryDbMetricExporter extends _wrappers.Enabler {
15
- constructor(retentionTimeInSeconds = 3600) {
16
- super();
17
- this._retentionTimeInSeconds = retentionTimeInSeconds;
18
- this._metrics = new _nedb.default({
19
- timestampData: true
20
- });
21
- this._metrics.ensureIndex({
22
- fieldName: 'createdAt'
23
- });
24
- this._startCleanupJob();
25
- }
26
- export(metrics, resultCallback) {
27
- try {
28
- const scopeMetrics = metrics?.scopeMetrics;
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
+ const storagePath_js_1 = require("../utils/storagePath.cjs");
14
+ const fs_1 = __importDefault(require("fs"));
15
+ /**
16
+ * In-Memory TSDB Metric Exporter
17
+ * Series identified by: scope + metricName + attributes
18
+ */
19
+ class InMemoryDbMetricExporter extends wrappers_js_1.Enabler {
20
+ static DEFAULT_CONFIG = {
21
+ retentionTimeInSeconds: 3600,
22
+ chunkSize: 120,
23
+ maxChunks: 60
24
+ };
25
+ registry;
26
+ config;
27
+ cachedResource = null;
28
+ _storageFilePath = null;
29
+ _autoSaveInterval = null;
30
+ _storageLogged = false; // Track if we've logged storage info
31
+ get rawDataDB() {
32
+ // For debug/inspection only - metrics are stored in registry chunks
33
+ const stats = this.registry.getStats();
34
+ return stats.totalSamples > 0 ? [`[${stats.totalSamples} samples in registry]`] : [];
35
+ }
36
+ constructor(config) {
37
+ super();
38
+ this.config = { ...InMemoryDbMetricExporter.DEFAULT_CONFIG, ...config };
39
+ this.registry = new SeriesRegistry_js_1.SeriesRegistry(this.config.chunkSize, this.config.maxChunks);
40
+ // Load persisted metrics if disk storage is enabled
41
+ this._storageFilePath = (0, storagePath_js_1.getStoragePath)('metrics');
42
+ if (this._storageFilePath) {
43
+ this._loadMetricsFromDisk();
44
+ this._startAutoSave();
45
+ }
46
+ this._startCleanupJob();
47
+ }
48
+ _loadMetricsFromDisk() {
49
+ if (!this._storageFilePath)
50
+ return;
51
+ try {
52
+ if (fs_1.default.existsSync(this._storageFilePath)) {
53
+ const ndjsonData = fs_1.default.readFileSync(this._storageFilePath, 'utf-8');
54
+ this.registry.deserializeFromNDJSON(ndjsonData);
55
+ }
56
+ }
57
+ catch {
58
+ // Silently fail during boot
59
+ }
60
+ }
61
+ _startAutoSave() {
62
+ if (!this._storageFilePath)
63
+ return;
64
+ // Save every 30 seconds
65
+ this._autoSaveInterval = setInterval(() => {
66
+ this._saveMetricsToDisk();
67
+ }, 30000);
68
+ }
69
+ _saveMetricsToDisk() {
70
+ if (!this._storageFilePath)
38
71
  return;
39
- }
40
- });
41
- }
42
- setTimeout(() => resultCallback({
43
- code: _core.ExportResultCode.SUCCESS
44
- }), 0);
45
- } catch (error) {
46
- _logger.default.error('Error exporting metrics\n' + error.message + '\n' + error.stack);
47
- return resultCallback({
48
- code: _core.ExportResultCode.FAILED,
49
- error: new Error('Error exporting metrics\n' + error.message + '\n' + error.stack)
50
- });
51
- }
52
- }
53
- shutdown() {
54
- this._enabled = false;
55
- this._metrics = new _nedb.default();
56
- return this.forceFlush();
57
- }
58
- forceFlush() {
59
- return Promise.resolve();
60
- }
61
- find(search, callback) {
62
- this._metrics.find(search, callback);
63
- }
64
- reset() {
65
- this._metrics = new _nedb.default();
66
- }
67
- getFinishedMetrics() {
68
- return this._metrics.getAllData();
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
72
+ try {
73
+ const ndjsonData = this.registry.serializeToNDJSON();
74
+ fs_1.default.writeFileSync(this._storageFilePath, ndjsonData);
92
75
  }
93
- }, {
94
- multi: true
95
- }, (err, numRemoved) => {
96
- if (err) {
97
- _logger.default.error('Error in TTL cleanup:', err);
98
- } else if (numRemoved > 0) {
99
- _logger.default.debug(`TTL cleanup: removed ${numRemoved} expired metrics`);
76
+ catch {
77
+ // Silently fail to avoid logging issues
100
78
  }
101
- });
102
- }, interval);
103
- }
79
+ }
80
+ export(resourceMetrics, resultCallback) {
81
+ // Log storage info on first export (when logger is ready)
82
+ if (!this._storageLogged) {
83
+ this._storageLogged = true;
84
+ if (this._storageFilePath) {
85
+ logger_js_1.default.info(`[MetricExporter] Disk storage enabled at: ${this._storageFilePath} (auto-save every 30s)`);
86
+ }
87
+ else {
88
+ logger_js_1.default.info(`[MetricExporter] Using in-memory storage`);
89
+ }
90
+ }
91
+ try {
92
+ // Cache resource (unique per exporter instance)
93
+ if (!this.cachedResource) {
94
+ this.cachedResource = resourceMetrics.resource;
95
+ }
96
+ const scopeMetrics = resourceMetrics.scopeMetrics;
97
+ // Broadcast to plugins
98
+ scopeMetrics?.forEach((metric) => {
99
+ pluginService_js_1.pluginService.broadcastMetric(metric);
100
+ });
101
+ // Store if enabled - use new storeScopeMetrics method
102
+ if (this.isEnabled() && scopeMetrics) {
103
+ this.registry.storeScopeMetrics(scopeMetrics);
104
+ }
105
+ setTimeout(() => resultCallback({ code: core_1.ExportResultCode.SUCCESS }), 0);
106
+ }
107
+ catch (error) {
108
+ logger_js_1.default.error('Error exporting metrics\n' + error.message + '\n' + error.stack);
109
+ return resultCallback({
110
+ code: core_1.ExportResultCode.FAILED,
111
+ error: new Error('Error exporting metrics\n' + error.message + '\n' + error.stack),
112
+ });
113
+ }
114
+ }
115
+ shutdown() {
116
+ this._enabled = false;
117
+ // Stop auto-save and save one final time
118
+ if (this._autoSaveInterval) {
119
+ clearInterval(this._autoSaveInterval);
120
+ this._autoSaveInterval = null;
121
+ }
122
+ if (this._storageFilePath) {
123
+ this._saveMetricsToDisk();
124
+ logger_js_1.default.info(`[MetricExporter] Metrics saved to disk at shutdown`);
125
+ }
126
+ this.registry.reset();
127
+ return this.forceFlush();
128
+ }
129
+ reset() {
130
+ // Clear metrics but save empty state to disk
131
+ this.registry.reset();
132
+ if (this._storageFilePath) {
133
+ this._saveMetricsToDisk();
134
+ logger_js_1.default.info(`[MetricExporter] Reset - all metrics cleared and saved to disk`);
135
+ }
136
+ else {
137
+ logger_js_1.default.info(`[MetricExporter] Reset - all metrics cleared`);
138
+ }
139
+ }
140
+ forceFlush() {
141
+ return Promise.resolve();
142
+ }
143
+ getCachedResource() {
144
+ return this.cachedResource;
145
+ }
146
+ set retentionTimeInSeconds(value) {
147
+ this.config.retentionTimeInSeconds = value;
148
+ logger_js_1.default.info(`Retention time set to ${value} seconds`);
149
+ }
150
+ get retentionTimeInSeconds() {
151
+ return this.config.retentionTimeInSeconds;
152
+ }
153
+ getStats() {
154
+ return this.registry.getStats();
155
+ }
156
+ _startCleanupJob() {
157
+ setInterval(() => {
158
+ const retentionTimeNs = this.config.retentionTimeInSeconds * 1_000_000_000;
159
+ const result = this.registry.evictOldData(retentionTimeNs);
160
+ if (result.evictedChunks > 0 || result.evictedSeries > 0) {
161
+ logger_js_1.default.debug(`Cleanup: evicted ${result.evictedChunks} chunks, ${result.evictedSeries} series`);
162
+ }
163
+ }, 5000);
164
+ }
165
+ /**
166
+ * Find metrics by scope+metric queries with filters
167
+ * Supports both raw and otel formats
168
+ */
169
+ find(request) {
170
+ const format = request.format || 'raw';
171
+ // Get raw results from registry using new unified query method
172
+ const rawResults = this.registry.query(request.scopeMetrics, request.from, request.to);
173
+ // Convert format if needed
174
+ if (format === 'otel') {
175
+ return { results: (0, utils_js_1.rawToOtel)(rawResults) };
176
+ }
177
+ return { results: rawResults };
178
+ }
179
+ /**
180
+ * Export all metrics to NDJSON format (one chunk per line)
181
+ */
182
+ exportToNDJSON() {
183
+ return this.registry.serializeToNDJSON();
184
+ }
185
+ /**
186
+ * Import metrics from NDJSON format
187
+ */
188
+ importFromNDJSON(ndjsonData) {
189
+ this.registry.deserializeFromNDJSON(ndjsonData);
190
+ }
191
+ /**
192
+ * Insert metrics in OpenTelemetry (OTEL) format directly into the registry
193
+ * @param scopeMetrics Array of ScopeMetrics (OTEL format)
194
+ */
195
+ insertOtel(scopeMetrics) {
196
+ // Store only in registry (chunks) - no duplication
197
+ if (this.isEnabled()) {
198
+ this.registry.storeScopeMetrics(scopeMetrics);
199
+ }
200
+ }
201
+ /**
202
+ * Insert metrics in raw format (MetricQueryResult[]), converts to OTEL and delegates to insertOtel
203
+ * @param rawScopeMetrics Array of MetricQueryResult (raw format)
204
+ */
205
+ insertRaw(rawScopeMetrics) {
206
+ const otelScopeMetrics = (0, utils_js_1.rawToOtel)(rawScopeMetrics);
207
+ this.insertOtel(otelScopeMetrics);
208
+ }
104
209
  }
105
- exports.InMemoryDbMetricExporter = InMemoryDbMetricExporter;
210
+ exports.InMemoryDbMetricExporter = InMemoryDbMetricExporter;
@@ -1,123 +1,159 @@
1
1
  "use strict";
2
-
3
- Object.defineProperty(exports, "__esModule", {
4
- value: true
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.InMemoryDbSpanExporter = void 0;
7
- var _core = require("@opentelemetry/core");
8
- var _nedb = _interopRequireDefault(require("@seald-io/nedb"));
9
- var _logger = _interopRequireDefault(require("../../../utils/logger.cjs"));
10
- var _circular = require("../utils/circular.cjs");
11
- var _wrappers = require("../wrappers.cjs");
12
- var _pluginService = require("../../../tlm-plugin/pluginService.cjs");
13
- function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e }; }
14
- class InMemoryDbSpanExporter extends _wrappers.Enabler {
15
- constructor(retentionTimeInSeconds = 3600) {
16
- super();
17
- this._baseUrl = '/telemetry'; // Default base URL, can be overridden by the config
18
- this._retentionTimeInSeconds = retentionTimeInSeconds;
19
- this._spans = new _nedb.default({
20
- timestampData: true
21
- });
22
- this._spans.ensureIndex({
23
- fieldName: 'createdAt'
24
- });
25
- this._startCleanupJob();
26
- }
27
- set baseUrl(baseUrl) {
28
- this._baseUrl = baseUrl;
29
- }
30
- set retentionTimeInSeconds(retentionTimeInSeconds) {
31
- this._retentionTimeInSeconds = retentionTimeInSeconds;
32
- _logger.default.info(`InMemoryDbSpanExporter retention time set to ${this._retentionTimeInSeconds} seconds`);
33
- }
34
- get retentionTimeInSeconds() {
35
- return this._retentionTimeInSeconds;
36
- }
37
- export(readableSpans, resultCallback) {
38
- _logger.default.debug('InMemoryDbSpanExporter.export called with spans: ', readableSpans.length);
39
- try {
40
- // Prepare spans to be inserted into the in-memory database (remove circular references and convert to nested objects)
41
- const cleanSpans = readableSpans.map(nestedSpan => (0, _circular.removeCircularRefs)(nestedSpan)) // to avoid JSON parsing error
42
- .map(span => (0, _circular.applyNesting)(span)) // to avoid dot notation in keys (neDB does not support dot notation in keys)
43
- .filter(span => {
44
- const target = span?.attributes?.http?.target;
45
- // Exclude spans where target includes 'telemetry' but NOT 'telemetry/utils/generate-log' or 'telemetry/utils/generate-wait'
46
- if (target && target.includes(this._baseUrl)) {
47
- return target.includes("generate");
48
- }
49
- return true;
50
- });
51
- cleanSpans.forEach(span => {
52
- _pluginService.pluginService.broadcastTrace(span);
53
- });
54
- //
55
- if (this.isEnabled()) {
56
- // Insert spans into the in-memory database
57
- this._spans.insert(cleanSpans, (err, _newDoc) => {
58
- if (err) {
59
- _logger.default.error(err);
7
+ const core_1 = require("@opentelemetry/core");
8
+ const nedb_1 = __importDefault(require("@seald-io/nedb"));
9
+ const logger_js_1 = __importDefault(require("../../../utils/logger.cjs"));
10
+ const circular_js_1 = require("../utils/circular.cjs");
11
+ const wrappers_js_1 = require("../wrappers.cjs");
12
+ const pluginService_js_1 = require("../../../tlm-plugin/pluginService.cjs");
13
+ const storagePath_js_1 = require("../utils/storagePath.cjs");
14
+ class InMemoryDbSpanExporter extends wrappers_js_1.Enabler {
15
+ _spans = null;
16
+ _retentionTimeInSeconds;
17
+ _storagePath = null;
18
+ _initialized = false;
19
+ constructor(retentionTimeInSeconds = 3600) {
20
+ super();
21
+ this._retentionTimeInSeconds = retentionTimeInSeconds;
22
+ this._storagePath = (0, storagePath_js_1.getStoragePath)('traces');
23
+ this._startCleanupJob();
24
+ }
25
+ ;
26
+ _ensureInitialized() {
27
+ if (this._initialized)
60
28
  return;
61
- }
62
- });
63
- }
64
- return resultCallback({
65
- code: _core.ExportResultCode.SUCCESS
66
- });
67
- } catch (error) {
68
- _logger.default.error('Error exporting spans\n' + error.message + '\n' + error.stack);
69
- return resultCallback({
70
- code: _core.ExportResultCode.FAILED,
71
- error: new Error('Error exporting spans\n' + error.message + '\n' + error.stack)
72
- });
29
+ this._initialized = true;
30
+ this._spans = new nedb_1.default(this._storagePath ? { filename: this._storagePath, timestampData: true, autoload: true } : { timestampData: true });
31
+ this._spans.ensureIndex({ fieldName: 'createdAt' });
32
+ if (this._storagePath) {
33
+ logger_js_1.default.info(`[SpanExporter] Disk storage enabled at: ${this._storagePath}`);
34
+ }
35
+ else {
36
+ logger_js_1.default.info(`[SpanExporter] Using in-memory storage`);
37
+ }
73
38
  }
74
- }
75
- shutdown() {
76
- this._spans = new _nedb.default();
77
- return this.forceFlush();
78
- }
79
- /**
80
- * Exports any pending spans in the exporter
81
- */
82
- forceFlush() {
83
- return Promise.resolve();
84
- }
85
- //err,docs
86
- find(search, callback) {
87
- this._spans.find(search, callback);
88
- }
89
- reset() {
90
- this._spans = new _nedb.default();
91
- }
92
- getFinishedSpans() {
93
- return this._spans.getAllData();
94
- }
95
- /**
96
- * Inserts spans into the in-memory database.
97
- * @param spans - The spans to insert.
98
- * @param callback - The callback to execute after insertion.
99
- */
100
- insert(spans, callback) {
101
- this._spans.insert(spans, callback);
102
- }
103
- _startCleanupJob() {
104
- const interval = 1000;
105
- setInterval(() => {
106
- const expirationDate = new Date(Date.now() - this._retentionTimeInSeconds * 1000);
107
- this._spans.remove({
108
- createdAt: {
109
- $lt: expirationDate
39
+ set retentionTimeInSeconds(retentionTimeInSeconds) {
40
+ this._retentionTimeInSeconds = retentionTimeInSeconds;
41
+ logger_js_1.default.info(`InMemoryDbSpanExporter retention time set to ${this._retentionTimeInSeconds} seconds`);
42
+ }
43
+ get retentionTimeInSeconds() {
44
+ return this._retentionTimeInSeconds;
45
+ }
46
+ export(readableSpans, resultCallback) {
47
+ this._ensureInitialized();
48
+ logger_js_1.default.debug('InMemoryDbSpanExporter.export called with spans: ', readableSpans.length);
49
+ try {
50
+ // Prepare spans to be inserted into the in-memory database (remove circular references and convert to nested objects)
51
+ const cleanSpans = readableSpans
52
+ .map(nestedSpan => (0, circular_js_1.removeCircularRefs)(nestedSpan)) // to avoid JSON parsing error
53
+ .map(span => (0, circular_js_1.applyNesting)(span)); // to avoid dot notation in keys (neDB does not support dot notation in keys)
54
+ cleanSpans.forEach(span => {
55
+ pluginService_js_1.pluginService.broadcastTrace(span);
56
+ });
57
+ if (this.isEnabled()) {
58
+ // Insert spans into the in-memory database
59
+ if (this._spans) {
60
+ this._spans.insert(cleanSpans, (err, _newDoc) => {
61
+ if (err) {
62
+ logger_js_1.default.error(err);
63
+ return;
64
+ }
65
+ });
66
+ }
67
+ }
68
+ return resultCallback({ code: core_1.ExportResultCode.SUCCESS });
110
69
  }
111
- }, {
112
- multi: true
113
- }, (err, numRemoved) => {
114
- if (err) {
115
- _logger.default.error('Error in TTL cleanup:', err);
116
- } else if (numRemoved > 0) {
117
- _logger.default.debug(`TTL cleanup: removed ${numRemoved} expired spans`);
70
+ catch (error) {
71
+ logger_js_1.default.error('Error exporting spans\n' + error.message + '\n' + error.stack);
72
+ return resultCallback({
73
+ code: core_1.ExportResultCode.FAILED,
74
+ error: new Error('Error exporting spans\n' + error.message + '\n' + error.stack),
75
+ });
76
+ }
77
+ }
78
+ ;
79
+ shutdown() {
80
+ this._spans = null;
81
+ return this.forceFlush();
82
+ }
83
+ ;
84
+ reset() {
85
+ this._ensureInitialized();
86
+ // Remove all spans from database but keep persistence enabled
87
+ this._spans.remove({}, { multi: true }, (err) => {
88
+ if (err) {
89
+ logger_js_1.default.error(`[SpanExporter] Error during reset: ${err.message}`);
90
+ }
91
+ else {
92
+ logger_js_1.default.info(`[SpanExporter] Reset - all spans cleared`);
93
+ }
94
+ });
95
+ }
96
+ /**
97
+ * Exports any pending spans in the exporter
98
+ */
99
+ forceFlush() {
100
+ return Promise.resolve();
101
+ }
102
+ ;
103
+ async find(findConfig) {
104
+ this._ensureInitialized();
105
+ const { query, limit, sortOrder } = findConfig;
106
+ const effectiveSortOrder = sortOrder || { timestamp: -1 };
107
+ const docs = await new Promise((resolve, reject) => {
108
+ let query_exec = this._spans.find(query)
109
+ .sort(effectiveSortOrder);
110
+ // Only apply limit if provided
111
+ if (limit !== undefined) {
112
+ query_exec = query_exec.limit(limit);
113
+ }
114
+ query_exec.exec((err, docs) => {
115
+ if (err)
116
+ reject(err);
117
+ else
118
+ resolve(docs);
119
+ });
120
+ });
121
+ return docs;
122
+ }
123
+ getFinishedSpans() {
124
+ this._ensureInitialized();
125
+ if (!this._spans)
126
+ return [];
127
+ return this._spans.getAllData();
128
+ }
129
+ ;
130
+ /**
131
+ * Inserts spans into the in-memory database.
132
+ * @param spans - The spans to insert.
133
+ * @param callback - The callback to execute after insertion.
134
+ */
135
+ insert(spans, callback) {
136
+ this._ensureInitialized();
137
+ if (!this._spans) {
138
+ return callback(new Error('Spans database not initialized'), []);
118
139
  }
119
- });
120
- }, interval);
121
- }
140
+ this._spans.insert(spans, callback);
141
+ }
142
+ _startCleanupJob() {
143
+ const interval = 1000;
144
+ setInterval(() => {
145
+ if (!this._spans)
146
+ return; // Safety check - not initialized yet
147
+ const expirationDate = new Date(Date.now() - this._retentionTimeInSeconds * 1000);
148
+ this._spans.remove({ createdAt: { $lt: expirationDate } }, { multi: true }, (err, numRemoved) => {
149
+ if (err) {
150
+ logger_js_1.default.error('Error in TTL cleanup:', err);
151
+ }
152
+ else if (numRemoved > 0) {
153
+ logger_js_1.default.debug(`TTL cleanup: removed ${numRemoved} expired spans`);
154
+ }
155
+ });
156
+ }, interval);
157
+ }
122
158
  }
123
- exports.InMemoryDbSpanExporter = InMemoryDbSpanExporter;
159
+ exports.InMemoryDbSpanExporter = InMemoryDbSpanExporter;
@@ -0,0 +1,92 @@
1
+ "use strict";
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
+ exports.LogsInstrumentation = void 0;
7
+ const instrumentation_1 = require("@opentelemetry/instrumentation");
8
+ const api_logs_1 = require("@opentelemetry/api-logs");
9
+ const util_1 = __importDefault(require("util"));
10
+ const telemetryRegistry_js_1 = require("../../telemetryRegistry.cjs");
11
+ class LogsInstrumentation extends instrumentation_1.InstrumentationBase {
12
+ _loggerProvider;
13
+ _otelLogger;
14
+ constructor(config = {}) {
15
+ super('@oas-telemetry/logs-instrumentation', '1.0.0', config);
16
+ }
17
+ /**
18
+ * No-op: this instrumentation does not patch modules loaded via require().
19
+ */
20
+ init() {
21
+ return [];
22
+ }
23
+ /**
24
+ * Called by the SDK when the LoggerProvider is available.
25
+ * This is the correct way for an instrumentation to receive a logger provider.
26
+ */
27
+ setLoggerProvider(provider) {
28
+ this._loggerProvider = provider;
29
+ this._otelLogger = provider.getLogger(this.instrumentationName);
30
+ // If already enabled, re-apply patches with the new logger provider.
31
+ if (this.isEnabled()) {
32
+ this._unpatchConsole();
33
+ this._patchConsole();
34
+ }
35
+ }
36
+ /**
37
+ * Called by the SDK after all providers have been registered.
38
+ */
39
+ enable() {
40
+ super.enable();
41
+ // Fallback: if no logger provider has been set yet, we do nothing.
42
+ if (!this._loggerProvider) {
43
+ return;
44
+ }
45
+ this._patchConsole();
46
+ }
47
+ disable() {
48
+ super.disable();
49
+ this._unpatchConsole();
50
+ }
51
+ _patchConsole() {
52
+ if (!this._otelLogger)
53
+ return;
54
+ Object.keys(telemetryRegistry_js_1.originalConsoleMethods).forEach((method) => {
55
+ const original = telemetryRegistry_js_1.originalConsoleMethods[method];
56
+ console[method] = (...args) => {
57
+ const { number, text } = getSeverityForMethod(method);
58
+ this._otelLogger.emit({
59
+ severityNumber: number,
60
+ severityText: text,
61
+ body: util_1.default.format(...args),
62
+ attributes: {
63
+ source: `console.${method}`,
64
+ library: this.instrumentationName,
65
+ },
66
+ });
67
+ original(...args);
68
+ };
69
+ });
70
+ }
71
+ _unpatchConsole() {
72
+ Object.keys(telemetryRegistry_js_1.originalConsoleMethods).forEach((method) => {
73
+ console[method] = telemetryRegistry_js_1.originalConsoleMethods[method];
74
+ });
75
+ }
76
+ }
77
+ exports.LogsInstrumentation = LogsInstrumentation;
78
+ function getSeverityForMethod(method) {
79
+ switch (method) {
80
+ case "log":
81
+ case "info":
82
+ return { number: api_logs_1.SeverityNumber.INFO, text: "INFO" };
83
+ case "debug":
84
+ return { number: api_logs_1.SeverityNumber.DEBUG, text: "DEBUG" };
85
+ case "warn":
86
+ return { number: api_logs_1.SeverityNumber.WARN, text: "WARN" };
87
+ case "error":
88
+ return { number: api_logs_1.SeverityNumber.ERROR, text: "ERROR" };
89
+ default:
90
+ return { number: api_logs_1.SeverityNumber.INFO, text: "INFO" };
91
+ }
92
+ }