@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.
Files changed (194) hide show
  1. package/.env.example +17 -3
  2. package/README.md +1 -2
  3. package/dist/cjs/config/bootConfig.cjs +16 -14
  4. package/dist/cjs/config/config.cjs +120 -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/DiskLogExporter.cjs +121 -0
  10. package/dist/cjs/telemetry/custom-implementations/exporters/DiskMetricExporter.cjs +101 -0
  11. package/dist/cjs/telemetry/custom-implementations/exporters/DiskTraceExporter.cjs +103 -0
  12. package/dist/cjs/telemetry/custom-implementations/exporters/InMemoryDbLogExporter.cjs +194 -190
  13. package/dist/cjs/telemetry/custom-implementations/exporters/InMemoryDbMetricExporter.cjs +147 -99
  14. package/dist/cjs/telemetry/custom-implementations/exporters/InMemoryDbSpanExporter.cjs +143 -116
  15. package/dist/cjs/telemetry/custom-implementations/exporters/MultiMetricExporter.cjs +57 -0
  16. package/dist/cjs/telemetry/custom-implementations/instrumentations/logsInstrumentation.cjs +92 -0
  17. package/dist/cjs/telemetry/custom-implementations/metrics/tsdb/Chunk.cjs +159 -0
  18. package/dist/cjs/telemetry/custom-implementations/metrics/tsdb/Series.cjs +168 -0
  19. package/dist/cjs/telemetry/custom-implementations/metrics/tsdb/SeriesRegistry.cjs +392 -0
  20. package/dist/cjs/telemetry/custom-implementations/metrics/tsdb/types.cjs +2 -0
  21. package/dist/cjs/telemetry/custom-implementations/metrics/tsdb/utils.cjs +77 -0
  22. package/dist/cjs/telemetry/custom-implementations/processors/dynamicMultiLogProcessor.cjs +65 -63
  23. package/dist/cjs/telemetry/custom-implementations/processors/dynamicMultiSpanProcessor.cjs +63 -62
  24. package/dist/cjs/telemetry/custom-implementations/utils/circular.cjs +47 -47
  25. package/dist/cjs/telemetry/custom-implementations/wrappers.cjs +209 -138
  26. package/dist/cjs/telemetry/initializeTelemetry.cjs +35 -91
  27. package/dist/cjs/telemetry/persistence/DiskImporter.cjs +85 -0
  28. package/dist/cjs/telemetry/persistence/DiskUtils.cjs +61 -0
  29. package/dist/cjs/telemetry/persistence/DiskWriter.cjs +66 -0
  30. package/dist/cjs/telemetry/telemetryConfigurator.cjs +139 -72
  31. package/dist/cjs/telemetry/telemetryRegistry.cjs +45 -31
  32. package/dist/cjs/tlm-ai/agent.cjs +49 -64
  33. package/dist/cjs/tlm-ai/aiController.cjs +54 -76
  34. package/dist/cjs/tlm-ai/aiRoutes.cjs +17 -20
  35. package/dist/cjs/tlm-ai/aiService.cjs +91 -95
  36. package/dist/cjs/tlm-ai/tools.cjs +177 -174
  37. package/dist/cjs/tlm-auth/authController.cjs +80 -123
  38. package/dist/cjs/tlm-auth/authMiddleware.cjs +25 -30
  39. package/dist/cjs/tlm-auth/authRoutes.cjs +11 -14
  40. package/dist/cjs/tlm-log/logController.cjs +135 -116
  41. package/dist/cjs/tlm-log/logRoutes.cjs +19 -20
  42. package/dist/cjs/tlm-log/logService.cjs +29 -0
  43. package/dist/cjs/tlm-metric/metricsController.cjs +154 -122
  44. package/dist/cjs/tlm-metric/metricsRoutes.cjs +22 -20
  45. package/dist/cjs/tlm-metric/metricsService.cjs +26 -0
  46. package/dist/cjs/tlm-plugin/pluginController.cjs +128 -140
  47. package/dist/cjs/tlm-plugin/pluginProcess.cjs +89 -94
  48. package/dist/cjs/tlm-plugin/pluginRoutes.cjs +11 -14
  49. package/dist/cjs/tlm-plugin/pluginService.cjs +73 -74
  50. package/dist/cjs/tlm-trace/traceController.cjs +140 -123
  51. package/dist/cjs/tlm-trace/traceRoutes.cjs +19 -20
  52. package/dist/cjs/tlm-trace/traceService.cjs +29 -0
  53. package/dist/cjs/tlm-ui/uiRoutes.cjs +63 -32
  54. package/dist/cjs/tlm-util/utilController.cjs +68 -70
  55. package/dist/cjs/tlm-util/utilRoutes.cjs +51 -63
  56. package/dist/cjs/types/index.cjs +2 -5
  57. package/dist/cjs/utils/logger.cjs +38 -43
  58. package/dist/cjs/utils/regexUtils.cjs +22 -22
  59. package/dist/esm/config/bootConfig.js +5 -2
  60. package/dist/esm/config/config.js +9 -2
  61. package/dist/esm/docs/openapi.yaml +158 -4
  62. package/dist/esm/index.js +9 -8
  63. package/dist/esm/routesManager.js +6 -10
  64. package/dist/esm/telemetry/custom-implementations/exporters/DiskLogExporter.js +114 -0
  65. package/dist/esm/telemetry/custom-implementations/exporters/DiskMetricExporter.js +94 -0
  66. package/dist/esm/telemetry/custom-implementations/exporters/DiskTraceExporter.js +96 -0
  67. package/dist/esm/telemetry/custom-implementations/exporters/InMemoryDbLogExporter.js +38 -7
  68. package/dist/esm/telemetry/custom-implementations/exporters/InMemoryDbMetricExporter.js +107 -48
  69. package/dist/esm/telemetry/custom-implementations/exporters/InMemoryDbSpanExporter.js +60 -29
  70. package/dist/esm/telemetry/custom-implementations/exporters/MultiMetricExporter.js +53 -0
  71. package/dist/esm/telemetry/custom-implementations/instrumentations/logsInstrumentation.js +85 -0
  72. package/dist/esm/telemetry/custom-implementations/metrics/tsdb/Chunk.js +155 -0
  73. package/dist/esm/telemetry/custom-implementations/metrics/tsdb/Series.js +164 -0
  74. package/dist/esm/telemetry/custom-implementations/metrics/tsdb/SeriesRegistry.js +385 -0
  75. package/dist/esm/telemetry/custom-implementations/metrics/tsdb/types.js +1 -0
  76. package/dist/esm/telemetry/custom-implementations/metrics/tsdb/utils.js +74 -0
  77. package/dist/esm/telemetry/custom-implementations/processors/dynamicMultiLogProcessor.js +2 -1
  78. package/dist/esm/telemetry/custom-implementations/processors/dynamicMultiSpanProcessor.js +1 -1
  79. package/dist/esm/telemetry/custom-implementations/wrappers.js +77 -6
  80. package/dist/esm/telemetry/initializeTelemetry.js +27 -69
  81. package/dist/esm/telemetry/persistence/DiskImporter.js +78 -0
  82. package/dist/esm/telemetry/persistence/DiskUtils.js +51 -0
  83. package/dist/esm/telemetry/persistence/DiskWriter.js +59 -0
  84. package/dist/esm/telemetry/telemetryConfigurator.js +110 -39
  85. package/dist/esm/telemetry/telemetryRegistry.js +12 -1
  86. package/dist/esm/tlm-ai/agent.js +5 -3
  87. package/dist/esm/tlm-ai/aiController.js +3 -3
  88. package/dist/esm/tlm-ai/aiService.js +6 -2
  89. package/dist/esm/tlm-ai/tools.js +5 -9
  90. package/dist/esm/tlm-auth/authController.js +3 -2
  91. package/dist/esm/tlm-log/logController.js +62 -18
  92. package/dist/esm/tlm-log/logRoutes.js +3 -1
  93. package/dist/esm/tlm-log/logService.js +25 -0
  94. package/dist/esm/tlm-metric/metricsController.js +116 -50
  95. package/dist/esm/tlm-metric/metricsRoutes.js +8 -3
  96. package/dist/esm/tlm-metric/metricsService.js +22 -0
  97. package/dist/esm/tlm-plugin/pluginController.js +6 -11
  98. package/dist/esm/tlm-plugin/pluginService.js +2 -4
  99. package/dist/esm/tlm-trace/traceController.js +87 -36
  100. package/dist/esm/tlm-trace/traceRoutes.js +3 -1
  101. package/dist/esm/tlm-trace/traceService.js +25 -0
  102. package/dist/esm/tlm-ui/uiRoutes.js +5 -5
  103. package/dist/esm/tlm-util/utilController.js +3 -9
  104. package/dist/esm/tlm-util/utilRoutes.js +2 -2
  105. package/dist/types/config/bootConfig.d.ts +3 -0
  106. package/dist/types/config/config.d.ts +48 -7
  107. package/dist/types/config/config.types.d.ts +7 -0
  108. package/dist/types/index.d.ts +2 -3
  109. package/dist/types/telemetry/custom-implementations/exporters/DiskLogExporter.d.ts +24 -0
  110. package/dist/types/telemetry/custom-implementations/exporters/DiskMetricExporter.d.ts +23 -0
  111. package/dist/types/telemetry/custom-implementations/exporters/DiskTraceExporter.d.ts +23 -0
  112. package/dist/types/telemetry/custom-implementations/exporters/InMemoryDbLogExporter.d.ts +3 -1
  113. package/dist/types/telemetry/custom-implementations/exporters/InMemoryDbMetricExporter.d.ts +56 -15
  114. package/dist/types/telemetry/custom-implementations/exporters/InMemoryDbSpanExporter.d.ts +8 -4
  115. package/dist/types/telemetry/custom-implementations/exporters/MultiMetricExporter.d.ts +9 -0
  116. package/dist/types/telemetry/custom-implementations/instrumentations/logsInstrumentation.d.ts +23 -0
  117. package/dist/types/telemetry/custom-implementations/metrics/tsdb/Chunk.d.ts +49 -0
  118. package/dist/types/telemetry/custom-implementations/metrics/tsdb/Series.d.ts +67 -0
  119. package/dist/types/telemetry/custom-implementations/metrics/tsdb/SeriesRegistry.d.ts +69 -0
  120. package/dist/types/telemetry/custom-implementations/metrics/tsdb/types.d.ts +68 -0
  121. package/dist/types/telemetry/custom-implementations/metrics/tsdb/utils.d.ts +21 -0
  122. package/dist/types/telemetry/custom-implementations/processors/dynamicMultiLogProcessor.d.ts +2 -2
  123. package/dist/types/telemetry/custom-implementations/wrappers.d.ts +2 -1
  124. package/dist/types/telemetry/persistence/DiskImporter.d.ts +17 -0
  125. package/dist/types/telemetry/persistence/DiskUtils.d.ts +11 -0
  126. package/dist/types/telemetry/persistence/DiskWriter.d.ts +21 -0
  127. package/dist/types/telemetry/telemetryConfigurator.d.ts +1 -1
  128. package/dist/types/telemetry/telemetryRegistry.d.ts +8 -0
  129. package/dist/types/tlm-ai/agent.d.ts +1 -1
  130. package/dist/types/tlm-ai/aiService.d.ts +1 -1
  131. package/dist/types/tlm-log/logController.d.ts +2 -0
  132. package/dist/types/tlm-log/logService.d.ts +4 -0
  133. package/dist/types/tlm-metric/metricsController.d.ts +11 -2
  134. package/dist/types/tlm-metric/metricsService.d.ts +6 -0
  135. package/dist/types/tlm-trace/traceController.d.ts +9 -7
  136. package/dist/types/tlm-trace/traceService.d.ts +4 -0
  137. package/dist/types/types/index.d.ts +2 -2
  138. package/dist/ui/assets/{ApiDocsPage-C_VVPPHa.js → ApiDocsPage-DTCgVbW2.js} +2 -2
  139. package/dist/ui/assets/CollapsibleCard-lWgfsaAn.js +1 -0
  140. package/dist/ui/assets/DevToolsPage-DEhf8CBy.js +1 -0
  141. package/dist/ui/assets/LandingPage-CfEHCDxY.js +6 -0
  142. package/dist/ui/assets/LogsPage-DFDKRuGH.js +1 -0
  143. package/dist/ui/assets/{NotFoundPage-B3quk3P1.js → NotFoundPage-DCy0DcV7.js} +1 -1
  144. package/dist/ui/assets/PluginCreatePage-BawZ5_-h.js +50 -0
  145. package/dist/ui/assets/PluginPage-D3FmgU7d.js +27 -0
  146. package/dist/ui/assets/TraceSpansPage-D0_L45Rb.js +6 -0
  147. package/dist/ui/assets/VirtualizedListPanel-q605n9He.js +16 -0
  148. package/dist/ui/assets/alert-DBAFshSi.js +1133 -0
  149. package/dist/ui/assets/badge-DGNBtnxU.js +1 -0
  150. package/dist/ui/assets/{chevron-down-CPsvsmqj.js → chevron-down-CFEqYzGC.js} +1 -1
  151. package/dist/ui/assets/{chevron-up-Df9jMo1X.js → chevron-up-lDnFwAJq.js} +1 -1
  152. package/dist/ui/assets/{circle-alert-DOPQPvU8.js → circle-alert-BpYUuRs7.js} +1 -1
  153. package/dist/ui/assets/dialog-1dRyI6SC.js +15 -0
  154. package/dist/ui/assets/index-C7RfU6hR.js +1 -0
  155. package/dist/ui/assets/index-C9dDYIpd.js +305 -0
  156. package/dist/ui/assets/index-D6f1KjWV.css +1 -0
  157. package/dist/ui/assets/info-CuJQWoBU.js +6 -0
  158. package/dist/ui/assets/{input-Dzvg_ZEZ.js → input-BLXaar0X.js} +1 -1
  159. package/dist/ui/assets/label-DfAcltsl.js +1 -0
  160. package/dist/ui/assets/{loader-circle-CrvlRy5o.js → loader-circle-B7oLyPsi.js} +1 -1
  161. package/dist/ui/assets/{loginPage-qa4V-B70.js → loginPage-DswZvOJ-.js} +1 -1
  162. package/dist/ui/assets/metrics-page-BhtXrfUW.js +31 -0
  163. package/dist/ui/assets/metrics-page-D1GxaB_c.css +1 -0
  164. package/dist/ui/assets/popover-IDker85U.js +11 -0
  165. package/dist/ui/assets/select-B8y5IidE.js +6 -0
  166. package/dist/ui/assets/separator-B6EzrxYY.js +6 -0
  167. package/dist/ui/assets/severityOptions-DtCsaAZK.js +11 -0
  168. package/dist/ui/assets/square-pen-D_oecB1x.js +6 -0
  169. package/dist/ui/assets/switch-Dqo0XkRD.js +1 -0
  170. package/dist/ui/assets/trace-DJq1miYa.js +1 -0
  171. package/dist/ui/assets/upload-prIohEdY.js +11 -0
  172. package/dist/ui/assets/{utilService-DNyqzwj0.js → utilService-C8TJKLqs.js} +1 -1
  173. package/dist/ui/assets/wand-sparkles-OgXuzsSx.js +6 -0
  174. package/dist/ui/index.html +2 -2
  175. package/package.json +44 -49
  176. package/dist/ui/assets/CollapsibleCard-B3KR_8mL.js +0 -1
  177. package/dist/ui/assets/DevToolsPage-OyZcDcmw.js +0 -1
  178. package/dist/ui/assets/LandingPage-CppFBA6K.js +0 -6
  179. package/dist/ui/assets/LogsPage-9Fq8GArS.js +0 -26
  180. package/dist/ui/assets/PluginCreatePage-X_aCH4t4.js +0 -50
  181. package/dist/ui/assets/PluginPage-DMDSihrZ.js +0 -27
  182. package/dist/ui/assets/alert-jQ9HCPIf.js +0 -1133
  183. package/dist/ui/assets/badge-CNq0-mH5.js +0 -1
  184. package/dist/ui/assets/card-DFAwwhN3.js +0 -1
  185. package/dist/ui/assets/index-BkD6DijD.js +0 -15
  186. package/dist/ui/assets/index-CERGVYZK.js +0 -292
  187. package/dist/ui/assets/index-CSIPf9qw.css +0 -1
  188. package/dist/ui/assets/label-DuVnkZ4q.js +0 -1
  189. package/dist/ui/assets/select-DhS8YUtJ.js +0 -1
  190. package/dist/ui/assets/separator-isK4chBP.js +0 -6
  191. package/dist/ui/assets/severityOptions-O38dSOfk.js +0 -11
  192. package/dist/ui/assets/switch-Z3mImG9n.js +0 -1
  193. package/dist/ui/assets/tabs-_77MUUQe.js +0 -16
  194. package/dist/ui/assets/upload-C1LT4Gkb.js +0 -16
@@ -31,8 +31,8 @@ servers:
31
31
  port:
32
32
  default: "3000"
33
33
  basePath:
34
- default: telemetry
35
- description: Base path for all endpoints. Can be customized, e.g. "myCustomTelemetryPath"
34
+ default: oas-telemetry
35
+ description: Base path for all endpoints. Configured via OASTLM_BOOT_BASE_URL environment variable
36
36
 
37
37
  tags:
38
38
  - name: traces
@@ -326,6 +326,44 @@ paths:
326
326
  type: string
327
327
  example: Invalid retention time. Must be a positive number.
328
328
 
329
+ /traces/export:
330
+ get:
331
+ tags:
332
+ - traces
333
+ summary: Export collected traces
334
+ description: Export all collected traces in line-delimited JSON format
335
+ responses:
336
+ '200':
337
+ description: Traces exported successfully
338
+ content:
339
+ application/json:
340
+ schema:
341
+ type: string
342
+
343
+ /traces/import:
344
+ post:
345
+ tags:
346
+ - traces
347
+ summary: Import traces
348
+ description: Import traces from line-delimited JSON format
349
+ requestBody:
350
+ required: true
351
+ content:
352
+ application/json:
353
+ schema:
354
+ type: string
355
+ responses:
356
+ '200':
357
+ description: Traces imported successfully
358
+ content:
359
+ application/json:
360
+ schema:
361
+ type: object
362
+ properties:
363
+ message:
364
+ type: string
365
+ example: Traces imported successfully
366
+
329
367
  /metrics:
330
368
  get:
331
369
  summary: Get collected metrics
@@ -548,6 +586,69 @@ paths:
548
586
  type: string
549
587
  example: Invalid retention time. Must be a positive number.
550
588
 
589
+ /metrics/export:
590
+ get:
591
+ tags:
592
+ - metrics
593
+ summary: Export collected metrics
594
+ description: Export all collected metrics in line-delimited JSON format
595
+ responses:
596
+ '200':
597
+ description: Metrics exported successfully
598
+ content:
599
+ application/json:
600
+ schema:
601
+ type: string
602
+
603
+ /metrics/import:
604
+ post:
605
+ tags:
606
+ - metrics
607
+ summary: Import metrics
608
+ description: Import metrics from line-delimited JSON format
609
+ requestBody:
610
+ required: true
611
+ content:
612
+ application/json:
613
+ schema:
614
+ type: string
615
+ responses:
616
+ '200':
617
+ description: Metrics imported successfully
618
+ content:
619
+ application/json:
620
+ schema:
621
+ type: object
622
+ properties:
623
+ message:
624
+ type: string
625
+ example: Metrics imported successfully
626
+
627
+ /metrics/stats:
628
+ get:
629
+ tags:
630
+ - metrics
631
+ summary: Get metrics statistics
632
+ description: Get statistics about collected metrics
633
+ responses:
634
+ '200':
635
+ description: Metrics statistics retrieved successfully
636
+ content:
637
+ application/json:
638
+ schema:
639
+ type: object
640
+ properties:
641
+ totalMetrics:
642
+ type: number
643
+ example: 42
644
+ activeMetrics:
645
+ type: number
646
+ example: 35
647
+ retentionTime:
648
+ type: number
649
+ description: Retention time in seconds
650
+ example: 3600
651
+
551
652
  /logs:
552
653
  get:
553
654
  summary: Get collected logs
@@ -683,6 +784,44 @@ paths:
683
784
  type: string
684
785
  example: Invalid regex in query
685
786
 
787
+ /logs/export:
788
+ get:
789
+ tags:
790
+ - logs
791
+ summary: Export collected logs
792
+ description: Export all collected logs in line-delimited JSON format
793
+ responses:
794
+ '200':
795
+ description: Logs exported successfully
796
+ content:
797
+ application/json:
798
+ schema:
799
+ type: string
800
+
801
+ /logs/import:
802
+ post:
803
+ tags:
804
+ - logs
805
+ summary: Import logs
806
+ description: Import logs from line-delimited JSON format
807
+ requestBody:
808
+ required: true
809
+ content:
810
+ application/json:
811
+ schema:
812
+ type: string
813
+ responses:
814
+ '200':
815
+ description: Logs imported successfully
816
+ content:
817
+ application/json:
818
+ schema:
819
+ type: object
820
+ properties:
821
+ message:
822
+ type: string
823
+ example: Logs imported successfully
824
+
686
825
  /utils/spec:
687
826
  get:
688
827
  summary: Get OpenAPI spec in JSON
@@ -842,14 +981,14 @@ paths:
842
981
  type: string
843
982
  example: Started generating mock logs
844
983
 
845
- /utils/generate-wait/{seconds}:
984
+ /utils/generate-wait:
846
985
  get:
847
986
  summary: Wait for the specified seconds
848
987
  tags:
849
988
  - utils
850
989
  parameters:
851
990
  - name: seconds
852
- in: path
991
+ in: query
853
992
  required: false
854
993
  schema:
855
994
  type: integer
@@ -867,6 +1006,21 @@ paths:
867
1006
  type: number
868
1007
  example: 2
869
1008
 
1009
+ /utils/oas-telemetry-spec:
1010
+ get:
1011
+ summary: Get OAS-Telemetry specification
1012
+ tags:
1013
+ - utils
1014
+ description: Retrieve the OpenAPI specification for OAS-Telemetry
1015
+ responses:
1016
+ '200':
1017
+ description: OK
1018
+ content:
1019
+ application/json:
1020
+ schema:
1021
+ type: object
1022
+ description: OpenAPI specification
1023
+
870
1024
  /health:
871
1025
  get:
872
1026
  summary: Health check
package/dist/esm/index.js CHANGED
@@ -5,25 +5,26 @@ import { getConfig } from './config/config.js';
5
5
  import { Router } from 'express';
6
6
  import { configureRoutes } from './routesManager.js';
7
7
  import { configureTelemetry } from './telemetry/telemetryConfigurator.js';
8
+ import { isTelemetryConfigured, setTelemetryRouter, getTelemetryRouter } from './telemetry/telemetryRegistry.js';
8
9
  import { bootEnvVariables } from "./config/bootConfig.js";
9
- // WARN: If changed the API, also change in packages/lib/src/types/cjs-index.d.ts (used for CJS compilation)
10
10
  /**
11
11
  * Returns the OAS-Telemetry middleware.
12
12
  * All parameters are optional. However, either `spec` or `specFileName` must be provided to enable endpoint filtering.
13
13
  */
14
- export default function oasTelemetry(oasTlmInputConfig) {
14
+ function oasTelemetry(oasTlmInputConfig) {
15
+ if (isTelemetryConfigured()) {
16
+ return getTelemetryRouter();
17
+ }
15
18
  const router = Router();
16
- // This environment variable cannot be set via the config object,
17
- // as it is required to disable OpenTelemetry SDK initialization,
18
- // which occurs during the first import at the top of this file.
19
19
  if (bootEnvVariables.OASTLM_BOOT_MODULE_DISABLED) {
20
+ setTelemetryRouter(router);
20
21
  return router;
21
22
  }
22
23
  const oasTlmConfig = getConfig(oasTlmInputConfig);
23
- logger.info("BaseUrl: ", oasTlmConfig.general.baseUrl);
24
- if (!oasTlmConfig.general.spec && !oasTlmConfig.general.specFileName)
25
- logger.warn("No spec provided, endpoint filtering will not be available. Please provide either `spec` or `specFileName` in the configuration.");
24
+ logger.info("BaseUrl: ", bootEnvVariables.OASTLM_BOOT_BASE_URL);
26
25
  configureTelemetry(oasTlmConfig);
27
26
  configureRoutes(router, oasTlmConfig);
27
+ setTelemetryRouter(router);
28
28
  return router;
29
29
  }
30
+ export { oasTelemetry };
@@ -13,21 +13,17 @@ import { getAIRoutes } from "./tlm-ai/aiRoutes.js";
13
13
  import { bootEnvVariables } from "./config/bootConfig.js";
14
14
  import { getPluginRoutes } from "./tlm-plugin/pluginRoutes.js";
15
15
  export const configureRoutes = (router, oasTlmConfig) => {
16
+ if (!oasTlmConfig.general.spec && !oasTlmConfig.general.specFileName) {
17
+ logger.warn("No spec provided, endpoint filtering will not be available. Please provide either `spec` or `specFileName` in the configuration.");
18
+ }
16
19
  if (bootEnvVariables.OASTLM_BOOT_ENV === 'development') {
17
20
  logger.info("Running in development mode, enabling CORS for all origins");
18
21
  router.use(cors({
19
- origin: (origin, callback) => {
20
- if (!origin || /^http:\/\/localhost:\d+$/.test(origin)) {
21
- callback(null, true);
22
- }
23
- else {
24
- callback(new Error('Not allowed by CORS'));
25
- }
26
- },
22
+ origin: true,
27
23
  credentials: true
28
24
  }));
29
25
  }
30
- const telemetryBaseUrl = oasTlmConfig.general.baseUrl;
26
+ const telemetryBaseUrl = bootEnvVariables.OASTLM_BOOT_BASE_URL;
31
27
  // Sub-router for all telemetry endpoints
32
28
  const telemetryRouter = Router();
33
29
  // Body parser for JSON requests
@@ -35,7 +31,7 @@ export const configureRoutes = (router, oasTlmConfig) => {
35
31
  if (req.body !== undefined) {
36
32
  return next(); // Already parsed, no need to parse again.
37
33
  }
38
- return json({ limit: '10mb' })(req, res, next);
34
+ return json({ limit: '500mb' })(req, res, next);
39
35
  });
40
36
  telemetryRouter.get('/health', (_req, res) => {
41
37
  res.status(200).send({ status: 'OK' });
@@ -0,0 +1,114 @@
1
+ import { ExportResultCode, hrTimeToMicroseconds } from '@opentelemetry/core';
2
+ import { applyNesting, removeCircularRefs } from '../utils/circular.js';
3
+ import { Enabler } from '../wrappers.js';
4
+ import { DiskWriter } from '../../persistence/DiskWriter.js';
5
+ import logger from '../../../utils/logger.js';
6
+ export class DiskLogExporter extends Enabler {
7
+ writer;
8
+ flushIntervalMs;
9
+ batchSize;
10
+ queuedLogs = [];
11
+ flushTimer = null;
12
+ flushing = false;
13
+ constructor(options) {
14
+ super();
15
+ this.flushIntervalMs = options.flushIntervalMs || 1000;
16
+ this.batchSize = options.batchSize || 500;
17
+ this.writer = new DiskWriter({
18
+ directoryPath: options.directoryPath,
19
+ segmentPrefix: 'logs',
20
+ maxSegmentBytes: options.maxSegmentBytes,
21
+ });
22
+ }
23
+ export(logs, resultCallback) {
24
+ if (!this.isEnabled()) {
25
+ resultCallback({ code: ExportResultCode.SUCCESS });
26
+ return;
27
+ }
28
+ try {
29
+ const serializableLogs = logs
30
+ .map((logRecord) => this.formatLogRecord(logRecord))
31
+ .map((log) => removeCircularRefs(log))
32
+ .map((log) => applyNesting(log));
33
+ if (serializableLogs.length > 0) {
34
+ this.queuedLogs.push(...serializableLogs);
35
+ if (this.queuedLogs.length >= this.batchSize) {
36
+ void this.flushPending();
37
+ }
38
+ else {
39
+ this.scheduleFlush();
40
+ }
41
+ }
42
+ resultCallback({ code: ExportResultCode.SUCCESS });
43
+ }
44
+ catch (error) {
45
+ logger.error(`[DiskLogExporter] Failed to queue logs: ${error?.message || error}`);
46
+ resultCallback({
47
+ code: ExportResultCode.FAILED,
48
+ error: error instanceof Error ? error : new Error(String(error)),
49
+ });
50
+ }
51
+ }
52
+ async shutdown() {
53
+ this.disable();
54
+ if (this.flushTimer) {
55
+ clearTimeout(this.flushTimer);
56
+ this.flushTimer = null;
57
+ }
58
+ await this.flushPending(true);
59
+ await this.writer.flush();
60
+ }
61
+ async forceFlush() {
62
+ await this.flushPending(true);
63
+ await this.writer.flush();
64
+ }
65
+ scheduleFlush() {
66
+ if (this.flushTimer)
67
+ return;
68
+ this.flushTimer = setTimeout(() => {
69
+ this.flushTimer = null;
70
+ void this.flushPending(true);
71
+ }, this.flushIntervalMs);
72
+ }
73
+ async flushPending(forceAll = false) {
74
+ if (this.flushing)
75
+ return;
76
+ if (this.queuedLogs.length === 0)
77
+ return;
78
+ this.flushing = true;
79
+ try {
80
+ while (this.queuedLogs.length > 0) {
81
+ if (!forceAll && this.queuedLogs.length < this.batchSize) {
82
+ this.scheduleFlush();
83
+ break;
84
+ }
85
+ const size = forceAll ? this.queuedLogs.length : this.batchSize;
86
+ const batch = this.queuedLogs.splice(0, size);
87
+ await this.writer.appendRecords(batch);
88
+ }
89
+ }
90
+ catch (error) {
91
+ logger.error(`[DiskLogExporter] Failed writing logs to disk: ${error?.message || error}`);
92
+ }
93
+ finally {
94
+ this.flushing = false;
95
+ }
96
+ }
97
+ formatLogRecord(logRecord) {
98
+ return {
99
+ resource: {
100
+ attributes: logRecord.resource.attributes,
101
+ },
102
+ instrumentationScope: logRecord.instrumentationScope,
103
+ timestamp: hrTimeToMicroseconds(logRecord.hrTime) ?? Date.now(),
104
+ observedTimestamp: hrTimeToMicroseconds(logRecord.hrTimeObserved) ?? Date.now(),
105
+ traceId: logRecord.spanContext?.traceId,
106
+ spanId: logRecord.spanContext?.spanId,
107
+ traceFlags: logRecord.spanContext?.traceFlags,
108
+ severityText: logRecord.severityText,
109
+ severityNumber: logRecord.severityNumber,
110
+ body: logRecord.body,
111
+ attributes: logRecord.attributes,
112
+ };
113
+ }
114
+ }
@@ -0,0 +1,94 @@
1
+ import { ExportResultCode } from '@opentelemetry/core';
2
+ import { removeCircularRefs } from '../utils/circular.js';
3
+ import { Enabler } from '../wrappers.js';
4
+ import logger from '../../../utils/logger.js';
5
+ import { DiskWriter } from '../../persistence/DiskWriter.js';
6
+ export class DiskMetricExporter extends Enabler {
7
+ writer;
8
+ flushIntervalMs;
9
+ batchSize;
10
+ queuedScopeMetrics = [];
11
+ flushTimer = null;
12
+ flushing = false;
13
+ constructor(options) {
14
+ super();
15
+ this.flushIntervalMs = options.flushIntervalMs || 1000;
16
+ this.batchSize = options.batchSize || 500;
17
+ this.writer = new DiskWriter({
18
+ directoryPath: options.directoryPath,
19
+ segmentPrefix: 'metrics',
20
+ maxSegmentBytes: options.maxSegmentBytes,
21
+ });
22
+ }
23
+ export(resourceMetrics, resultCallback) {
24
+ if (!this.isEnabled()) {
25
+ resultCallback({ code: ExportResultCode.SUCCESS });
26
+ return;
27
+ }
28
+ try {
29
+ const scopeMetrics = removeCircularRefs(resourceMetrics.scopeMetrics || []);
30
+ if (Array.isArray(scopeMetrics) && scopeMetrics.length > 0) {
31
+ this.queuedScopeMetrics.push(...scopeMetrics);
32
+ if (this.queuedScopeMetrics.length >= this.batchSize) {
33
+ void this.flushPending();
34
+ }
35
+ else {
36
+ this.scheduleFlush();
37
+ }
38
+ }
39
+ resultCallback({ code: ExportResultCode.SUCCESS });
40
+ }
41
+ catch (error) {
42
+ logger.error(`[DiskMetricExporter] Failed to queue scope metrics: ${error?.message || error}`);
43
+ resultCallback({
44
+ code: ExportResultCode.FAILED,
45
+ error: error instanceof Error ? error : new Error(String(error)),
46
+ });
47
+ }
48
+ }
49
+ async shutdown() {
50
+ this.disable();
51
+ if (this.flushTimer) {
52
+ clearTimeout(this.flushTimer);
53
+ this.flushTimer = null;
54
+ }
55
+ await this.flushPending(true);
56
+ await this.writer.flush();
57
+ }
58
+ async forceFlush() {
59
+ await this.flushPending(true);
60
+ await this.writer.flush();
61
+ }
62
+ scheduleFlush() {
63
+ if (this.flushTimer)
64
+ return;
65
+ this.flushTimer = setTimeout(() => {
66
+ this.flushTimer = null;
67
+ void this.flushPending(true);
68
+ }, this.flushIntervalMs);
69
+ }
70
+ async flushPending(forceAll = false) {
71
+ if (this.flushing)
72
+ return;
73
+ if (this.queuedScopeMetrics.length === 0)
74
+ return;
75
+ this.flushing = true;
76
+ try {
77
+ while (this.queuedScopeMetrics.length > 0) {
78
+ if (!forceAll && this.queuedScopeMetrics.length < this.batchSize) {
79
+ this.scheduleFlush();
80
+ break;
81
+ }
82
+ const size = forceAll ? this.queuedScopeMetrics.length : this.batchSize;
83
+ const batch = this.queuedScopeMetrics.splice(0, size);
84
+ await this.writer.appendRecords(batch);
85
+ }
86
+ }
87
+ catch (error) {
88
+ logger.error(`[DiskMetricExporter] Failed writing metrics to disk: ${error?.message || error}`);
89
+ }
90
+ finally {
91
+ this.flushing = false;
92
+ }
93
+ }
94
+ }
@@ -0,0 +1,96 @@
1
+ import { ExportResultCode } from '@opentelemetry/core';
2
+ import logger from '../../../utils/logger.js';
3
+ import { applyNesting, removeCircularRefs } from '../utils/circular.js';
4
+ import { DiskWriter } from '../../persistence/DiskWriter.js';
5
+ import { Enabler } from '../wrappers.js';
6
+ export class DiskTraceExporter extends Enabler {
7
+ writer;
8
+ flushIntervalMs;
9
+ batchSize;
10
+ queuedSpans = [];
11
+ flushTimer = null;
12
+ flushing = false;
13
+ constructor(options) {
14
+ super();
15
+ this.flushIntervalMs = options.flushIntervalMs || 1000;
16
+ this.batchSize = options.batchSize || 500;
17
+ this.writer = new DiskWriter({
18
+ directoryPath: options.directoryPath,
19
+ segmentPrefix: 'traces',
20
+ maxSegmentBytes: options.maxSegmentBytes,
21
+ });
22
+ }
23
+ export(spans, resultCallback) {
24
+ if (!this.isEnabled()) {
25
+ resultCallback({ code: ExportResultCode.SUCCESS });
26
+ return;
27
+ }
28
+ try {
29
+ const serializableSpans = spans
30
+ .map((span) => removeCircularRefs(span))
31
+ .map((span) => applyNesting(span));
32
+ if (serializableSpans.length > 0) {
33
+ this.queuedSpans.push(...serializableSpans);
34
+ if (this.queuedSpans.length >= this.batchSize) {
35
+ void this.flushPending();
36
+ }
37
+ else {
38
+ this.scheduleFlush();
39
+ }
40
+ }
41
+ resultCallback({ code: ExportResultCode.SUCCESS });
42
+ }
43
+ catch (error) {
44
+ logger.error(`[DiskTraceExporter] Failed to queue spans: ${error?.message || error}`);
45
+ resultCallback({
46
+ code: ExportResultCode.FAILED,
47
+ error: error instanceof Error ? error : new Error(String(error)),
48
+ });
49
+ }
50
+ }
51
+ async shutdown() {
52
+ this.disable();
53
+ if (this.flushTimer) {
54
+ clearTimeout(this.flushTimer);
55
+ this.flushTimer = null;
56
+ }
57
+ await this.flushPending(true);
58
+ await this.writer.flush();
59
+ }
60
+ async forceFlush() {
61
+ await this.flushPending(true);
62
+ await this.writer.flush();
63
+ }
64
+ scheduleFlush() {
65
+ if (this.flushTimer)
66
+ return;
67
+ this.flushTimer = setTimeout(() => {
68
+ this.flushTimer = null;
69
+ void this.flushPending(true);
70
+ }, this.flushIntervalMs);
71
+ }
72
+ async flushPending(forceAll = false) {
73
+ if (this.flushing)
74
+ return;
75
+ if (this.queuedSpans.length === 0)
76
+ return;
77
+ this.flushing = true;
78
+ try {
79
+ while (this.queuedSpans.length > 0) {
80
+ if (!forceAll && this.queuedSpans.length < this.batchSize) {
81
+ this.scheduleFlush();
82
+ break;
83
+ }
84
+ const size = forceAll ? this.queuedSpans.length : this.batchSize;
85
+ const batch = this.queuedSpans.splice(0, size);
86
+ await this.writer.appendRecords(batch);
87
+ }
88
+ }
89
+ catch (error) {
90
+ logger.error(`[DiskTraceExporter] Failed writing spans to disk: ${error?.message || error}`);
91
+ }
92
+ finally {
93
+ this.flushing = false;
94
+ }
95
+ }
96
+ }