@oas-tools/oas-telemetry 0.6.2 → 0.7.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 (125) hide show
  1. package/README.md +442 -442
  2. package/dist/{config.cjs → cjs/config.cjs} +6 -7
  3. package/dist/{exporters → cjs/exporters}/InMemoryDBMetricsExporter.cjs +5 -40
  4. package/dist/cjs/exporters/InMemoryDbExporter.cjs +87 -0
  5. package/dist/cjs/exporters/InMemoryLogRecordExporter.cjs +110 -0
  6. package/dist/{exporters → cjs/exporters}/consoleExporter.cjs +2 -7
  7. package/dist/{exporters → cjs/exporters}/dynamicExporter.cjs +12 -19
  8. package/dist/cjs/index.cjs +43 -0
  9. package/dist/cjs/instrumentation/index.cjs +28 -0
  10. package/dist/cjs/instrumentation/logs.cjs +46 -0
  11. package/dist/cjs/instrumentation/metrics.cjs +27 -0
  12. package/dist/cjs/instrumentation/traces.cjs +19 -0
  13. package/dist/cjs/tlm-ai/agent.cjs +79 -0
  14. package/dist/cjs/tlm-ai/aiController.cjs +69 -0
  15. package/dist/cjs/tlm-ai/aiRoutes.cjs +13 -0
  16. package/dist/cjs/tlm-ai/knownMicroservices.cjs +13 -0
  17. package/dist/cjs/tlm-ai/tools.cjs +504 -0
  18. package/dist/{routes/authRoutes.cjs → cjs/tlm-auth/authController.cjs} +21 -28
  19. package/dist/{middleware → cjs/tlm-auth}/authMiddleware.cjs +1 -1
  20. package/dist/cjs/tlm-auth/authRoutes.cjs +14 -0
  21. package/dist/cjs/tlm-log/logController.cjs +55 -0
  22. package/dist/cjs/tlm-log/logRoutes.cjs +13 -0
  23. package/dist/{routes → cjs/tlm-metric}/metricsRoutes.cjs +1 -2
  24. package/dist/{controllers → cjs/tlm-plugin}/pluginController.cjs +31 -41
  25. package/dist/cjs/tlm-plugin/pluginRoutes.cjs +13 -0
  26. package/dist/{controllers/telemetryController.cjs → cjs/tlm-trace/traceController.cjs} +8 -19
  27. package/dist/cjs/tlm-trace/traceRoutes.cjs +17 -0
  28. package/dist/cjs/tlm-ui/uiRoutes.cjs +31 -0
  29. package/dist/cjs/tlm-util/utilController.cjs +63 -0
  30. package/dist/cjs/tlm-util/utilRoutes.cjs +12 -0
  31. package/dist/cjs/tlmRoutes.cjs +79 -0
  32. package/dist/cjs/types/index.cjs +8 -0
  33. package/dist/cjs/utils/circular.cjs +90 -0
  34. package/dist/cjs/utils/logger.cjs +28 -0
  35. package/{src → dist/esm}/config.js +20 -23
  36. package/{src → dist/esm}/exporters/InMemoryDBMetricsExporter.js +57 -111
  37. package/dist/esm/exporters/InMemoryDbExporter.js +87 -0
  38. package/dist/esm/exporters/InMemoryLogRecordExporter.js +95 -0
  39. package/{src → dist/esm}/exporters/consoleExporter.js +38 -47
  40. package/{src → dist/esm}/exporters/dynamicExporter.js +50 -62
  41. package/dist/esm/index.js +39 -0
  42. package/dist/esm/instrumentation/index.js +26 -0
  43. package/dist/esm/instrumentation/logs.js +34 -0
  44. package/dist/esm/instrumentation/metrics.js +18 -0
  45. package/dist/esm/instrumentation/traces.js +12 -0
  46. package/dist/esm/tlm-ai/agent.js +68 -0
  47. package/dist/esm/tlm-ai/aiController.js +45 -0
  48. package/dist/esm/tlm-ai/aiRoutes.js +7 -0
  49. package/dist/esm/tlm-ai/knownMicroservices.js +5 -0
  50. package/dist/esm/tlm-ai/tools.js +490 -0
  51. package/dist/esm/tlm-auth/authController.js +41 -0
  52. package/{src/middleware → dist/esm/tlm-auth}/authMiddleware.js +12 -14
  53. package/dist/esm/tlm-auth/authRoutes.js +7 -0
  54. package/dist/esm/tlm-log/logController.js +36 -0
  55. package/dist/esm/tlm-log/logRoutes.js +7 -0
  56. package/{src/controllers → dist/esm/tlm-metric}/metricsController.js +28 -30
  57. package/{src/routes → dist/esm/tlm-metric}/metricsRoutes.js +8 -15
  58. package/{src/controllers → dist/esm/tlm-plugin}/pluginController.js +103 -115
  59. package/dist/esm/tlm-plugin/pluginRoutes.js +7 -0
  60. package/dist/esm/tlm-trace/traceController.js +54 -0
  61. package/dist/esm/tlm-trace/traceRoutes.js +11 -0
  62. package/dist/esm/tlm-ui/uiRoutes.js +23 -0
  63. package/dist/esm/tlm-util/utilController.js +57 -0
  64. package/dist/esm/tlm-util/utilRoutes.js +6 -0
  65. package/dist/esm/tlmRoutes.js +72 -0
  66. package/dist/esm/types/index.js +4 -0
  67. package/dist/esm/utils/circular.js +84 -0
  68. package/dist/esm/utils/logger.js +19 -0
  69. package/dist/types/config.d.ts +6 -0
  70. package/dist/types/exporters/InMemoryDBMetricsExporter.d.ts +15 -0
  71. package/dist/types/exporters/InMemoryDbExporter.d.ts +24 -0
  72. package/dist/types/exporters/InMemoryLogRecordExporter.d.ts +27 -0
  73. package/dist/types/exporters/consoleExporter.d.ts +13 -0
  74. package/dist/types/exporters/dynamicExporter.d.ts +25 -0
  75. package/dist/types/index.d.ts +8 -0
  76. package/dist/types/instrumentation/index.d.ts +1 -0
  77. package/dist/types/instrumentation/logs.d.ts +1 -0
  78. package/dist/types/instrumentation/metrics.d.ts +1 -0
  79. package/dist/types/instrumentation/traces.d.ts +1 -0
  80. package/dist/types/tlm-ai/agent.d.ts +1 -0
  81. package/dist/types/tlm-ai/aiController.d.ts +4 -0
  82. package/dist/types/tlm-ai/aiRoutes.d.ts +2 -0
  83. package/dist/types/tlm-ai/knownMicroservices.d.ts +6 -0
  84. package/dist/types/tlm-ai/tools.d.ts +45 -0
  85. package/dist/types/tlm-auth/authController.d.ts +4 -0
  86. package/dist/types/tlm-auth/authMiddleware.d.ts +2 -0
  87. package/dist/types/tlm-auth/authRoutes.d.ts +2 -0
  88. package/dist/types/tlm-log/logController.d.ts +4 -0
  89. package/dist/types/tlm-log/logRoutes.d.ts +2 -0
  90. package/dist/types/tlm-metric/metricsController.d.ts +4 -0
  91. package/dist/types/tlm-metric/metricsRoutes.d.ts +2 -0
  92. package/dist/types/tlm-plugin/pluginController.d.ts +3 -0
  93. package/dist/types/tlm-plugin/pluginRoutes.d.ts +2 -0
  94. package/dist/types/tlm-trace/traceController.d.ts +7 -0
  95. package/dist/types/tlm-trace/traceRoutes.d.ts +2 -0
  96. package/dist/types/tlm-ui/uiRoutes.d.ts +2 -0
  97. package/dist/types/tlm-util/utilController.d.ts +3 -0
  98. package/dist/types/tlm-util/utilRoutes.d.ts +2 -0
  99. package/dist/types/tlmRoutes.d.ts +2 -0
  100. package/dist/types/types/index.d.ts +56 -0
  101. package/dist/types/utils/circular.d.ts +31 -0
  102. package/dist/types/utils/logger.d.ts +9 -0
  103. package/dist/ui/assets/index-BNhZBPi2.css +1 -0
  104. package/dist/ui/assets/index-DxGAMrAl.js +401 -0
  105. package/dist/ui/index.html +14 -0
  106. package/dist/ui/vite.svg +1 -0
  107. package/package.json +80 -77
  108. package/dist/controllers/uiController.cjs +0 -78
  109. package/dist/exporters/InMemoryDbExporter.cjs +0 -178
  110. package/dist/index.cjs +0 -110
  111. package/dist/openTelemetry.cjs +0 -58
  112. package/dist/routes/telemetryRoutes.cjs +0 -31
  113. package/dist/services/uiService.cjs +0 -1520
  114. package/dist/systemMetrics.cjs +0 -97
  115. package/src/controllers/telemetryController.js +0 -69
  116. package/src/controllers/uiController.js +0 -69
  117. package/src/dev/ui/login.html +0 -32
  118. package/src/exporters/InMemoryDbExporter.js +0 -181
  119. package/src/index.js +0 -121
  120. package/src/openTelemetry.js +0 -58
  121. package/src/routes/authRoutes.js +0 -53
  122. package/src/routes/telemetryRoutes.js +0 -38
  123. package/src/services/uiService.js +0 -1520
  124. package/src/systemMetrics.js +0 -102
  125. /package/dist/{controllers → cjs/tlm-metric}/metricsController.cjs +0 -0
@@ -4,18 +4,18 @@ Object.defineProperty(exports, "__esModule", {
4
4
  value: true
5
5
  });
6
6
  exports.globalOasTlmConfig = exports.default = void 0;
7
- var _api = require("@opentelemetry/api");
8
7
  var _dynamicExporter = _interopRequireDefault(require("./exporters/dynamicExporter.cjs"));
9
8
  var _InMemoryDBMetricsExporter = require("./exporters/InMemoryDBMetricsExporter.cjs");
10
- function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
9
+ var _InMemoryLogRecordExporter = require("./exporters/InMemoryLogRecordExporter.cjs");
10
+ function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e }; }
11
11
  //Environment variables
12
12
  //OASTLM_MODULE_DISABLED = 'true' //Disables the module (empty middleware and no tracing)
13
-
14
13
  const globalOasTlmConfig = exports.globalOasTlmConfig = {
15
- dynamicExporter: new _dynamicExporter.default(),
14
+ dynamicSpanExporter: new _dynamicExporter.default(),
16
15
  metricsExporter: new _InMemoryDBMetricsExporter.InMemoryDBMetricsExporter(),
17
- systemMetricsInterval: 1000 * 5,
18
- // 5 seconds
16
+ logExporter: new _InMemoryLogRecordExporter.InMemoryLogRecordExporter(),
17
+ metricsExporterInterval: 1000 * 30,
18
+ // milliseconds
19
19
  baseURL: "/telemetry",
20
20
  spec: null,
21
21
  specFileName: "",
@@ -26,7 +26,6 @@ const globalOasTlmConfig = exports.globalOasTlmConfig = {
26
26
  password: "oas-telemetry-password",
27
27
  jwtSecret: "oas-telemetry-secret"
28
28
  };
29
- //5 name alternatives. one for globals
30
29
  var _default = exports.default = {
31
30
  globalOasTlmConfig
32
31
  };
@@ -6,7 +6,8 @@ Object.defineProperty(exports, "__esModule", {
6
6
  exports.InMemoryDBMetricsExporter = void 0;
7
7
  var _core = require("@opentelemetry/core");
8
8
  var _nedb = _interopRequireDefault(require("@seald-io/nedb"));
9
- function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
9
+ var _circular = require("../utils/circular.cjs");
10
+ function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e }; }
10
11
  class InMemoryDBMetricsExporter {
11
12
  constructor() {
12
13
  this._metrics = new _nedb.default();
@@ -16,8 +17,8 @@ class InMemoryDBMetricsExporter {
16
17
  try {
17
18
  if (!this._stopped) {
18
19
  // metrics = metrics?.scopeMetrics;
19
- // const cleanMetrics = metrics.map(metric => applyNesting(metric));
20
- this._metrics.insert(metrics, (err, newDoc) => {
20
+ const cleanMetrics = (0, _circular.applyNesting)(metrics);
21
+ this._metrics.insert(cleanMetrics, (err, _newDoc) => {
21
22
  if (err) {
22
23
  console.error('Insertion Error:', err);
23
24
  return;
@@ -62,40 +63,4 @@ class InMemoryDBMetricsExporter {
62
63
  return this._metrics.getAllData();
63
64
  }
64
65
  }
65
- exports.InMemoryDBMetricsExporter = InMemoryDBMetricsExporter;
66
- function convertToNestedObject(obj) {
67
- const result = {};
68
- for (const key in obj) {
69
- const keys = key.split('.');
70
- let temp = result;
71
- for (let i = 0; i < keys.length; i++) {
72
- const currentKey = keys[i];
73
- if (i === keys.length - 1) {
74
- // Last key, set the value
75
- temp[currentKey] = obj[key];
76
- } else {
77
- // Intermediate key, ensure the object exists
78
- if (!temp[currentKey]) {
79
- temp[currentKey] = {};
80
- }
81
- temp = temp[currentKey];
82
- }
83
- }
84
- }
85
- return result;
86
- }
87
-
88
- /**
89
- * Applies nesting to all dot-separated keys within an object.
90
- *
91
- * @param {Object} obj - The object to apply nesting to.
92
- * @returns {Object} - The transformed object with nested structures.
93
- */
94
- function applyNesting(obj) {
95
- for (const key in obj) {
96
- if (typeof obj[key] === 'object' && obj[key] !== null) {
97
- obj[key] = applyNesting(obj[key]);
98
- }
99
- }
100
- return obj;
101
- }
66
+ exports.InMemoryDBMetricsExporter = InMemoryDBMetricsExporter;
@@ -0,0 +1,87 @@
1
+ "use strict";
2
+
3
+ Object.defineProperty(exports, "__esModule", {
4
+ value: true
5
+ });
6
+ exports.InMemoryExporter = 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
+ function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e }; }
12
+ //import in memory database
13
+
14
+ class InMemoryExporter {
15
+ constructor() {
16
+ // Overrided by dynamic exporter
17
+ this.plugins = [];
18
+ this._spans = new _nedb.default();
19
+ this._stopped = true;
20
+ }
21
+ export(readableSpans, resultCallback) {
22
+ try {
23
+ if (!this._stopped) {
24
+ // Prepare spans to be inserted into the in-memory database (remove circular references and convert to nested objects)
25
+ const cleanSpans = readableSpans.map(nestedSpan => (0, _circular.removeCircularRefs)(nestedSpan)) // to avoid JSON parsing error
26
+ .map(span => (0, _circular.applyNesting)(span)) // to avoid dot notation in keys (neDB does not support dot notation in keys)
27
+ .filter(span => !span?.attributes?.http?.target?.includes("/telemetry")); // to avoid telemetry spans
28
+ // Insert spans into the in-memory database
29
+ this._spans.insert(cleanSpans, (err, _newDoc) => {
30
+ // p = {name, plugin
31
+ this.plugins.forEach((pluginResource, i) => {
32
+ cleanSpans.forEach(span => {
33
+ _logger.default.debug(`Sending span <${span._id}> to plugin (Plugin #${i}) <${pluginResource.name}>`);
34
+ _logger.default.debug(`Span: \n<${JSON.stringify(span, null, 2)}`);
35
+ //TODO: This should be called newSpan instead of newTrace
36
+ pluginResource.plugin.newTrace(span);
37
+ });
38
+ });
39
+ if (err) {
40
+ console.error(err);
41
+ return;
42
+ }
43
+ });
44
+ }
45
+ setTimeout(() => resultCallback({
46
+ code: _core.ExportResultCode.SUCCESS
47
+ }), 0);
48
+ } catch (error) {
49
+ console.error('Error exporting spans\n' + error.message + '\n' + error.stack);
50
+ return resultCallback({
51
+ code: _core.ExportResultCode.FAILED,
52
+ error: new Error('Error exporting spans\n' + error.message + '\n' + error.stack)
53
+ });
54
+ }
55
+ }
56
+ start() {
57
+ this._stopped = false;
58
+ }
59
+ stop() {
60
+ this._stopped = true;
61
+ }
62
+ isRunning() {
63
+ return !this._stopped;
64
+ }
65
+ shutdown() {
66
+ this._stopped = true;
67
+ this._spans = new _nedb.default();
68
+ return this.forceFlush();
69
+ }
70
+ /**
71
+ * Exports any pending spans in the exporter
72
+ */
73
+ forceFlush() {
74
+ return Promise.resolve();
75
+ }
76
+ //err,docs
77
+ find(search, callback) {
78
+ this._spans.find(search, callback);
79
+ }
80
+ reset() {
81
+ this._spans = new _nedb.default();
82
+ }
83
+ getFinishedSpans() {
84
+ return this._spans.getAllData();
85
+ }
86
+ }
87
+ exports.InMemoryExporter = InMemoryExporter;
@@ -0,0 +1,110 @@
1
+ "use strict";
2
+
3
+ Object.defineProperty(exports, "__esModule", {
4
+ value: true
5
+ });
6
+ exports.InMemoryLogRecordExporter = void 0;
7
+ var _core = require("@opentelemetry/core");
8
+ var _circular = require("../utils/circular.cjs");
9
+ var _nedb = _interopRequireDefault(require("@seald-io/nedb"));
10
+ var _minisearch = _interopRequireDefault(require("minisearch"));
11
+ function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e }; }
12
+ class InMemoryLogRecordExporter {
13
+ constructor() {
14
+ this._db = new _nedb.default();
15
+ this._miniSearch = new _minisearch.default({
16
+ fields: ['body'],
17
+ storeFields: ['_id'],
18
+ idField: '_id'
19
+ });
20
+ }
21
+ /*
22
+ * SUPER WARNING:
23
+ * Do NOT use console.log, console.error, or any logger inside this class's export function.
24
+ * Doing so will cause an infinite loop.
25
+ * Only console.dir is allowed, as it is not tracked by our log export implementation.
26
+ */
27
+ /**
28
+ * Export logs.
29
+ * @param logs
30
+ * @param resultCallback
31
+ */
32
+ export(logs, resultCallback) {
33
+ const logsToInsert = logs.map(logRecord => {
34
+ // Remove circular references first, then apply nesting, then export info
35
+ const formattedLog = this._formatLogRecord(logRecord);
36
+ const cleanedLog = (0, _circular.removeCircularRefs)(formattedLog);
37
+ const nestedLog = (0, _circular.applyNesting)(cleanedLog);
38
+ return nestedLog;
39
+ });
40
+ this._db.insert(logsToInsert, (err, newDocs) => {
41
+ if (err) {
42
+ console.dir(err);
43
+ resultCallback({
44
+ code: _core.ExportResultCode.FAILED
45
+ });
46
+ return;
47
+ }
48
+ // console.dir(newDocs, { depth: 3 });
49
+ newDocs.forEach(doc => this._miniSearch.add(doc));
50
+ resultCallback({
51
+ code: _core.ExportResultCode.SUCCESS
52
+ });
53
+ });
54
+ }
55
+ reset() {
56
+ this._db = new _nedb.default();
57
+ this._miniSearch = new _minisearch.default({
58
+ fields: ['body'],
59
+ storeFields: ['_id'],
60
+ idField: '_id'
61
+ });
62
+ }
63
+ /**
64
+ * Shutdown the exporter.
65
+ */
66
+ async shutdown() {
67
+ this._db = null;
68
+ this._miniSearch = null;
69
+ }
70
+ find(query, messageSearch, callback) {
71
+ if (messageSearch) {
72
+ const searchResults = this._miniSearch.search(messageSearch);
73
+ const ids = searchResults.map(result => result._id);
74
+ console.dir(`MiniSearch found ${ids.length} results for search term "${messageSearch}"`, {
75
+ depth: 3
76
+ });
77
+ // Add MiniSearch results to the query
78
+ query._id = {
79
+ $in: ids
80
+ };
81
+ }
82
+ this._db.find(query, callback);
83
+ }
84
+ getFinishedSpans() {
85
+ return this._db.getAllData();
86
+ }
87
+ /**
88
+ * @copyright The OpenTelemetry Authors
89
+ * @license Apache-2.0
90
+ * converts logRecord info into more readable format
91
+ * @param logRecord
92
+ */
93
+ _formatLogRecord(logRecord) {
94
+ return {
95
+ resource: {
96
+ attributes: logRecord.resource.attributes
97
+ },
98
+ instrumentationScope: logRecord.instrumentationScope,
99
+ timestamp: (0, _core.hrTimeToMicroseconds)(logRecord.hrTime) || Date.now(),
100
+ traceId: logRecord.spanContext?.traceId,
101
+ spanId: logRecord.spanContext?.spanId,
102
+ traceFlags: logRecord.spanContext?.traceFlags,
103
+ severityText: logRecord.severityText,
104
+ severityNumber: logRecord.severityNumber,
105
+ body: logRecord.body,
106
+ attributes: logRecord.attributes
107
+ };
108
+ }
109
+ }
110
+ exports.InMemoryLogRecordExporter = InMemoryLogRecordExporter;
@@ -4,13 +4,10 @@ Object.defineProperty(exports, "__esModule", {
4
4
  value: true
5
5
  });
6
6
  exports.ConsoleExporter = void 0;
7
- function _defineProperty(obj, key, value) { key = _toPropertyKey(key); if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; }
8
- function _toPropertyKey(t) { var i = _toPrimitive(t, "string"); return "symbol" == typeof i ? i : i + ""; }
9
- function _toPrimitive(t, r) { if ("object" != typeof t || !t) return t; var e = t[Symbol.toPrimitive]; if (void 0 !== e) { var i = e.call(t, r || "default"); if ("object" != typeof i) return i; throw new TypeError("@@toPrimitive must return a primitive value."); } return ("string" === r ? String : Number)(t); }
10
7
  class ConsoleExporter {
11
8
  constructor() {
12
9
  // PLUGIN SYSTEM -----------------------------------------------------------
13
- _defineProperty(this, "plugins", []);
10
+ this.plugins = [];
14
11
  }
15
12
  // OPEN TELEMETRY EXPORTER INTERFACE ---------------------------------------
16
13
  export(readableSpans, resultCallback) {
@@ -25,9 +22,7 @@ class ConsoleExporter {
25
22
  forceFlush() {
26
23
  return Promise.resolve();
27
24
  }
28
-
29
25
  // OAS-TOOLS OAS-TELEMETRY EXPORTER INTERFACE ---------------------------------------
30
-
31
26
  start() {
32
27
  console.log("Exporter started");
33
28
  }
@@ -45,7 +40,7 @@ class ConsoleExporter {
45
40
  callback(null, []);
46
41
  return [];
47
42
  }
48
- async getFinishedSpans() {
43
+ getFinishedSpans() {
49
44
  return [];
50
45
  }
51
46
  }
@@ -5,26 +5,20 @@ Object.defineProperty(exports, "__esModule", {
5
5
  });
6
6
  exports.default = exports.DynamicExporter = void 0;
7
7
  var _consoleExporter = require("./consoleExporter.cjs");
8
- function _defineProperty(obj, key, value) { key = _toPropertyKey(key); if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; }
9
- function _toPropertyKey(t) { var i = _toPrimitive(t, "string"); return "symbol" == typeof i ? i : i + ""; }
10
- function _toPrimitive(t, r) { if ("object" != typeof t || !t) return t; var e = t[Symbol.toPrimitive]; if (void 0 !== e) { var i = e.call(t, r || "default"); if ("object" != typeof i) return i; throw new TypeError("@@toPrimitive must return a primitive value."); } return ("string" === r ? String : Number)(t); }
11
- /**
12
- * DynamicExporter is a class that can be used to dynamically change the exporter used by OpenTelemetry.
13
- * This is useful when you want to change the exporter at runtime.
14
- * Links start, stop and export methods to the Real exporter.
8
+ /**
9
+ * DynamicExporter is a class that can be used to dynamically change the exporter used by OpenTelemetry.
10
+ * This is useful when you want to change the exporter at runtime.
11
+ * Links start, stop and export methods to the Real exporter.
15
12
  */
16
13
  class DynamicExporter {
17
- /**
18
- * @returns {Array<PluginResource>} Returns the list of plugins registered in the exporter
14
+ /**
15
+ * Returns the list of plugins registered in the exporter
19
16
  */
20
17
  getPlugins() {
21
18
  return this.exporter.plugins;
22
19
  }
23
-
24
- /**
25
- * Registers a plugin in the exporter
26
- * @param {PluginResource} pluginResource The plugin to be registered
27
- * @returns {void}
20
+ /**
21
+ * Registers a plugin in the exporter
28
22
  */
29
23
  pushPlugin(pluginResource) {
30
24
  if (!this.exporter.plugins) {
@@ -33,7 +27,7 @@ class DynamicExporter {
33
27
  this.exporter.plugins.push(pluginResource);
34
28
  }
35
29
  activatePlugin(pluginId) {
36
- let plugins = this.exporter.plugins;
30
+ const plugins = this.exporter.plugins;
37
31
  if (plugins) {
38
32
  // plugin.active = true;
39
33
  plugins.forEach(plugin => {
@@ -44,8 +38,7 @@ class DynamicExporter {
44
38
  }
45
39
  }
46
40
  constructor() {
47
- _defineProperty(this, "exporter", void 0);
48
- let defaultExporter = new _consoleExporter.ConsoleExporter();
41
+ const defaultExporter = new _consoleExporter.ConsoleExporter();
49
42
  this.exporter = defaultExporter;
50
43
  this.export = (readableSpans, resultCallback) => defaultExporter.export(readableSpans, resultCallback);
51
44
  this.shutdown = () => defaultExporter.shutdown();
@@ -54,10 +47,10 @@ class DynamicExporter {
54
47
  changeExporter(newExporter) {
55
48
  this.exporter = newExporter;
56
49
  // OpenTelemetry methods
57
- this.export = (readableSpans, resultCallback) => newExporter.export(readableSpans, resultCallback);
50
+ this.export = (readableSpan, resultCallback) => newExporter.export(readableSpan, resultCallback);
58
51
  this.shutdown = () => newExporter.shutdown();
59
52
  this.forceFlush = () => newExporter.forceFlush();
60
- // Other methods should be called directly from the exporter: globalOasTlmConfig.dynamicExporter.exporter.method()
53
+ // Other methods should be called directly from the exporter: globalOasTlmConfig.dynamicSpanExporter.exporter.method()
61
54
  }
62
55
  }
63
56
  exports.DynamicExporter = DynamicExporter;
@@ -0,0 +1,43 @@
1
+ "use strict";
2
+
3
+ Object.defineProperty(exports, "__esModule", {
4
+ value: true
5
+ });
6
+ exports.default = oasTelemetry;
7
+ require("./instrumentation/index.cjs");
8
+ var _config = require("./config.cjs");
9
+ var _express = require("express");
10
+ var _InMemoryDbExporter = require("./exporters/InMemoryDbExporter.cjs");
11
+ var _logger = _interopRequireDefault(require("./utils/logger.cjs"));
12
+ var _tlmRoutes = require("./tlmRoutes.cjs");
13
+ function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e }; }
14
+ /**
15
+ * Returns the Oas Telemetry middleware. The parameters are the same as `globalOasTlmConfig`.
16
+ * All parameters are optional. However, either `spec` or `specFileName` must be provided to enable endpoint filtering.
17
+ */
18
+ function oasTelemetry(oasTlmInputConfig) {
19
+ const router = (0, _express.Router)();
20
+ if (process.env.OASTLM_MODULE_DISABLED === 'true') {
21
+ return router;
22
+ }
23
+ if (oasTlmInputConfig) {
24
+ _logger.default.info("User provided config");
25
+ // Override global config with user provided config
26
+ for (const key in _config.globalOasTlmConfig) {
27
+ _config.globalOasTlmConfig[key] = oasTlmInputConfig[key] ?? _config.globalOasTlmConfig[key];
28
+ }
29
+ }
30
+ _logger.default.info("BaseURL: ", _config.globalOasTlmConfig.baseURL);
31
+ _config.globalOasTlmConfig.dynamicSpanExporter.changeExporter(_config.globalOasTlmConfig.exporter ?? new _InMemoryDbExporter.InMemoryExporter());
32
+ if (_config.globalOasTlmConfig.spec) _logger.default.info(`Spec content provided`);else {
33
+ if (_config.globalOasTlmConfig.specFileName != "") _logger.default.info(`Spec file used for telemetry: ${_config.globalOasTlmConfig.specFileName}`);else {
34
+ console.error("No spec available !");
35
+ }
36
+ }
37
+ if (_config.globalOasTlmConfig.autoActivate) {
38
+ _config.globalOasTlmConfig.dynamicSpanExporter.exporter?.start();
39
+ }
40
+ (0, _tlmRoutes.configureRoutes)(router);
41
+ return router;
42
+ }
43
+ module.exports = exports.default;
@@ -0,0 +1,28 @@
1
+ "use strict";
2
+
3
+ var _resources = require("@opentelemetry/resources");
4
+ var _instrumentationHttp = require("@opentelemetry/instrumentation-http");
5
+ var _semanticConventions = require("@opentelemetry/semantic-conventions");
6
+ var _logger = _interopRequireDefault(require("../utils/logger.cjs"));
7
+ var _logs = require("./logs.cjs");
8
+ var _traces = require("./traces.cjs");
9
+ var _instrumentation = require("@opentelemetry/instrumentation");
10
+ var _metrics = require("./metrics.cjs");
11
+ function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e }; }
12
+ // import { NodeSDK } from '@opentelemetry/sdk-node';
13
+
14
+ const oasTelemetryResource = (0, _resources.resourceFromAttributes)({
15
+ [_semanticConventions.ATTR_SERVICE_NAME]: 'oas-telemetry-service'
16
+ });
17
+ if (process.env.OASTLM_MODULE_DISABLED !== 'true') {
18
+ (0, _traces.initializeTraces)(oasTelemetryResource);
19
+ (0, _metrics.initializeMetrics)(oasTelemetryResource);
20
+ (0, _logs.initializeLogs)(oasTelemetryResource);
21
+ (0, _instrumentation.registerInstrumentations)({
22
+ instrumentations: [new _instrumentationHttp.HttpInstrumentation()
23
+ // new ExpressInstrumentation(),
24
+ ]
25
+ });
26
+ } else {
27
+ _logger.default.info('🚫 OASTLM module is disabled, SDKs not initialized.');
28
+ }
@@ -0,0 +1,46 @@
1
+ "use strict";
2
+
3
+ Object.defineProperty(exports, "__esModule", {
4
+ value: true
5
+ });
6
+ exports.initializeLogs = initializeLogs;
7
+ var _sdkLogs = require("@opentelemetry/sdk-logs");
8
+ var _apiLogs = require("@opentelemetry/api-logs");
9
+ var _config = require("../config.cjs");
10
+ var _logger = _interopRequireDefault(require("../utils/logger.cjs"));
11
+ function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e }; }
12
+ function initializeLogs(resource) {
13
+ // Create and configure LoggerProvider
14
+ const logExporter = _config.globalOasTlmConfig.logExporter;
15
+ const logRecordProcessor = new _sdkLogs.SimpleLogRecordProcessor(logExporter);
16
+ const loggerProvider = new _sdkLogs.LoggerProvider({
17
+ resource: resource,
18
+ processors: [logRecordProcessor]
19
+ });
20
+ // Get a logger instance
21
+ const loggerInstance = loggerProvider.getLogger('oas-telemetry'); // Use loggerProvider to get the logger
22
+ // Override console methods to emit logs via OpenTelemetry
23
+ const originalConsoleMethods = {
24
+ log: console.log,
25
+ warn: console.warn,
26
+ error: console.error,
27
+ info: console.info,
28
+ debug: console.debug
29
+ };
30
+ Object.keys(originalConsoleMethods).forEach(method => {
31
+ // @ts-expect-error yes
32
+ console[method] = (...args) => {
33
+ loggerInstance.emit({
34
+ severityNumber: _apiLogs.SeverityNumber[method.toUpperCase()] || _apiLogs.SeverityNumber.INFO,
35
+ severityText: method.toUpperCase(),
36
+ body: args.join(' '),
37
+ attributes: {
38
+ 'source.source': `console.${method}`
39
+ }
40
+ });
41
+ // @ts-expect-error yes
42
+ originalConsoleMethods[method](...args);
43
+ };
44
+ });
45
+ _logger.default.info('✅ OpenTelemetry Logs initialized.');
46
+ }
@@ -0,0 +1,27 @@
1
+ "use strict";
2
+
3
+ Object.defineProperty(exports, "__esModule", {
4
+ value: true
5
+ });
6
+ exports.initializeMetrics = initializeMetrics;
7
+ var _sdkMetrics = require("@opentelemetry/sdk-metrics");
8
+ var _logger = _interopRequireDefault(require("../utils/logger.cjs"));
9
+ var _config = require("../config.cjs");
10
+ var _hostMetrics = require("@opentelemetry/host-metrics");
11
+ function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e }; }
12
+ function initializeMetrics(resource) {
13
+ const metricReader = new _sdkMetrics.PeriodicExportingMetricReader({
14
+ // exporter: new ConsoleMetricExporter(),
15
+ exporter: _config.globalOasTlmConfig.metricsExporter,
16
+ exportIntervalMillis: _config.globalOasTlmConfig.metricsExporterInterval
17
+ });
18
+ const meterProvider = new _sdkMetrics.MeterProvider({
19
+ resource: resource,
20
+ readers: [metricReader]
21
+ });
22
+ const hostMetrics = new _hostMetrics.HostMetrics({
23
+ meterProvider
24
+ });
25
+ hostMetrics.start();
26
+ _logger.default.info('✅ OpenTelemetry Metrics initialized.');
27
+ }
@@ -0,0 +1,19 @@
1
+ "use strict";
2
+
3
+ Object.defineProperty(exports, "__esModule", {
4
+ value: true
5
+ });
6
+ exports.initializeTraces = initializeTraces;
7
+ var _logger = _interopRequireDefault(require("../utils/logger.cjs"));
8
+ var _sdkTraceNode = require("@opentelemetry/sdk-trace-node");
9
+ var _config = require("../config.cjs");
10
+ function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e }; }
11
+ function initializeTraces(resource) {
12
+ const tracerProvider = new _sdkTraceNode.NodeTracerProvider({
13
+ resource: resource,
14
+ spanProcessors: [new _sdkTraceNode.BatchSpanProcessor(_config.globalOasTlmConfig.dynamicSpanExporter)]
15
+ });
16
+ // tracerProvider.addSpanProcessor();
17
+ tracerProvider.register();
18
+ _logger.default.info('✅ OpenTelemetry Traces initialized.');
19
+ }
@@ -0,0 +1,79 @@
1
+ "use strict";
2
+
3
+ Object.defineProperty(exports, "__esModule", {
4
+ value: true
5
+ });
6
+ exports.getAgentResponse = getAgentResponse;
7
+ var _openai = _interopRequireDefault(require("openai"));
8
+ var _dotenv = _interopRequireDefault(require("dotenv"));
9
+ var _tools = require("./tools.cjs");
10
+ var _logger = _interopRequireDefault(require("../utils/logger.cjs"));
11
+ function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e }; }
12
+ _dotenv.default.config();
13
+ let openai;
14
+ try {
15
+ openai = new _openai.default({
16
+ apiKey: process.env.OASTLM_AI_OPENAI_API_KEY,
17
+ dangerouslyAllowBrowser: true
18
+ });
19
+ } catch {
20
+ openai = null;
21
+ }
22
+ const messages = [{
23
+ role: "assistant",
24
+ content: "You are a helpful telemetry assistant. Only use the functions you have been provided with. If the question is not related to the functions, respond with 'I cannot help with that.'. If you need to call to other agents, do so using the tools provided."
25
+ }];
26
+ async function agent(userInput) {
27
+ messages.push({
28
+ role: "user",
29
+ content: userInput
30
+ });
31
+ for (let i = 0; i < 5; i++) {
32
+ const response = await openai?.chat?.completions?.create?.({
33
+ model: process.env.OASTLM_AI_OPENAI_MODEL_NAME || "gpt-4o-mini",
34
+ messages: messages,
35
+ tools: _tools.tools
36
+ });
37
+ const {
38
+ finish_reason,
39
+ message
40
+ } = response.choices[0];
41
+ if (finish_reason === "tool_calls" && message.tool_calls) {
42
+ _logger.default.debug("Tool calls detected:", message.tool_calls);
43
+ const results = [];
44
+ for (const toolCall of message.tool_calls) {
45
+ const functionName = toolCall.function.name;
46
+ const functionToCall = _tools.availableTools[functionName];
47
+ const functionArgs = JSON.parse(toolCall.function.arguments);
48
+ const functionArgsArr = Object.values(functionArgs);
49
+ // @ts-expect-error yes
50
+ // eslint-disable-next-line prefer-spread
51
+ const functionResponse = await functionToCall.apply(null, functionArgsArr);
52
+ results.push({
53
+ name: functionName,
54
+ response: functionResponse
55
+ });
56
+ }
57
+ const resultMessage = results.map(({
58
+ name,
59
+ response
60
+ }) => `Result from "${name}":\n${JSON.stringify(response, null, 2)}`).join("\n\n");
61
+ messages.push({
62
+ role: "function",
63
+ name: "multiple_tool_calls",
64
+ content: resultMessage
65
+ });
66
+ } else if (finish_reason === "stop") {
67
+ messages.push(message);
68
+ return message;
69
+ }
70
+ }
71
+ return {
72
+ content: "Se alcanzó el número máximo de iteraciones sin una respuesta adecuada. Intenta con una consulta más específica."
73
+ };
74
+ }
75
+ async function getAgentResponse(question) {
76
+ const response = await agent(question);
77
+ _logger.default.debug("Response from agent:", response);
78
+ return response.content;
79
+ }