@oas-tools/oas-telemetry 0.7.0-alpha.4 → 0.7.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 (112) hide show
  1. package/.env.example +6 -2
  2. package/README.md +35 -17
  3. package/dist/cjs/config/bootConfig.cjs +3 -1
  4. package/dist/cjs/config/config.cjs +7 -5
  5. package/dist/cjs/docs/openapi.yaml +1399 -0
  6. package/dist/cjs/routesManager.cjs +36 -48
  7. package/dist/cjs/telemetry/custom-implementations/exporters/InMemoryDbLogExporter.cjs +43 -13
  8. package/dist/cjs/telemetry/custom-implementations/exporters/InMemoryDbMetricExporter.cjs +10 -2
  9. package/dist/cjs/telemetry/custom-implementations/exporters/InMemoryDbSpanExporter.cjs +21 -16
  10. package/dist/cjs/telemetry/initializeTelemetry.cjs +39 -15
  11. package/dist/cjs/telemetry/telemetryConfigurator.cjs +6 -9
  12. package/dist/cjs/telemetry/telemetryRegistry.cjs +11 -8
  13. package/dist/cjs/tlm-ai/agent.cjs +54 -84
  14. package/dist/cjs/tlm-ai/aiController.cjs +69 -47
  15. package/dist/cjs/tlm-ai/aiRoutes.cjs +10 -3
  16. package/dist/cjs/tlm-ai/aiService.cjs +109 -0
  17. package/dist/cjs/tlm-ai/tools.cjs +30 -268
  18. package/dist/cjs/tlm-auth/authController.cjs +91 -26
  19. package/dist/cjs/tlm-auth/authMiddleware.cjs +20 -7
  20. package/dist/cjs/tlm-auth/authRoutes.cjs +3 -2
  21. package/dist/cjs/tlm-log/logController.cjs +30 -36
  22. package/dist/cjs/tlm-log/logRoutes.cjs +3 -2
  23. package/dist/cjs/tlm-metric/metricsController.cjs +15 -8
  24. package/dist/cjs/tlm-metric/metricsRoutes.cjs +2 -1
  25. package/dist/cjs/tlm-plugin/pluginController.cjs +11 -1
  26. package/dist/cjs/tlm-plugin/pluginProcess.cjs +4 -2
  27. package/dist/cjs/tlm-plugin/pluginService.cjs +3 -0
  28. package/dist/cjs/tlm-trace/traceController.cjs +16 -9
  29. package/dist/cjs/tlm-trace/traceRoutes.cjs +2 -1
  30. package/dist/cjs/tlm-util/utilController.cjs +23 -2
  31. package/dist/cjs/tlm-util/utilRoutes.cjs +44 -5
  32. package/dist/cjs/utils/logger.cjs +35 -13
  33. package/dist/esm/config/bootConfig.js +2 -0
  34. package/dist/esm/config/config.js +4 -2
  35. package/dist/esm/docs/openapi.yaml +1399 -0
  36. package/dist/esm/routesManager.js +37 -49
  37. package/dist/esm/telemetry/custom-implementations/exporters/InMemoryDbLogExporter.js +32 -11
  38. package/dist/esm/telemetry/custom-implementations/exporters/InMemoryDbMetricExporter.js +10 -2
  39. package/dist/esm/telemetry/custom-implementations/exporters/InMemoryDbSpanExporter.js +20 -13
  40. package/dist/esm/telemetry/initializeTelemetry.js +22 -14
  41. package/dist/esm/telemetry/telemetryConfigurator.js +7 -10
  42. package/dist/esm/telemetry/telemetryRegistry.js +10 -7
  43. package/dist/esm/tlm-ai/agent.js +37 -78
  44. package/dist/esm/tlm-ai/aiController.js +56 -39
  45. package/dist/esm/tlm-ai/aiRoutes.js +11 -4
  46. package/dist/esm/tlm-ai/aiService.js +94 -0
  47. package/dist/esm/tlm-ai/tools.js +29 -255
  48. package/dist/esm/tlm-auth/authController.js +62 -20
  49. package/dist/esm/tlm-auth/authMiddleware.js +18 -9
  50. package/dist/esm/tlm-auth/authRoutes.js +4 -3
  51. package/dist/esm/tlm-log/logController.js +26 -28
  52. package/dist/esm/tlm-log/logRoutes.js +4 -3
  53. package/dist/esm/tlm-metric/metricsController.js +10 -6
  54. package/dist/esm/tlm-metric/metricsRoutes.js +3 -2
  55. package/dist/esm/tlm-plugin/pluginController.js +2 -1
  56. package/dist/esm/tlm-plugin/pluginProcess.js +4 -2
  57. package/dist/esm/tlm-plugin/pluginService.js +4 -0
  58. package/dist/esm/tlm-trace/traceController.js +11 -7
  59. package/dist/esm/tlm-trace/traceRoutes.js +3 -2
  60. package/dist/esm/tlm-util/utilController.js +22 -0
  61. package/dist/esm/tlm-util/utilRoutes.js +40 -5
  62. package/dist/esm/utils/logger.js +35 -12
  63. package/dist/types/config/bootConfig.d.ts +1 -0
  64. package/dist/types/config/config.d.ts +6 -3
  65. package/dist/types/telemetry/custom-implementations/exporters/InMemoryDbLogExporter.d.ts +7 -1
  66. package/dist/types/telemetry/custom-implementations/exporters/InMemoryDbMetricExporter.d.ts +1 -0
  67. package/dist/types/telemetry/custom-implementations/exporters/InMemoryDbSpanExporter.d.ts +1 -0
  68. package/dist/types/telemetry/telemetryRegistry.d.ts +22 -6
  69. package/dist/types/tlm-ai/agent.d.ts +2 -2
  70. package/dist/types/tlm-ai/aiController.d.ts +5 -4
  71. package/dist/types/tlm-ai/aiRoutes.d.ts +1 -1
  72. package/dist/types/tlm-ai/aiService.d.ts +38 -0
  73. package/dist/types/tlm-ai/tools.d.ts +5 -14
  74. package/dist/types/tlm-auth/authController.d.ts +2 -1
  75. package/dist/types/tlm-log/logController.d.ts +2 -2
  76. package/dist/types/tlm-metric/metricsController.d.ts +2 -1
  77. package/dist/types/tlm-plugin/pluginService.d.ts +2 -0
  78. package/dist/types/tlm-trace/traceController.d.ts +2 -1
  79. package/dist/types/tlm-util/utilController.d.ts +1 -0
  80. package/dist/types/utils/logger.d.ts +5 -5
  81. package/dist/ui/assets/ApiDocsPage-C_VVPPHa.js +16 -0
  82. package/dist/ui/assets/CollapsibleCard-B3KR_8mL.js +1 -0
  83. package/dist/ui/assets/DevToolsPage-OyZcDcmw.js +1 -0
  84. package/dist/ui/assets/LandingPage-CppFBA6K.js +6 -0
  85. package/dist/ui/assets/LogsPage-9Fq8GArS.js +26 -0
  86. package/dist/ui/assets/NotFoundPage-B3quk3P1.js +1 -0
  87. package/dist/ui/assets/PluginCreatePage-X_aCH4t4.js +50 -0
  88. package/dist/ui/assets/PluginPage-DMDSihrZ.js +27 -0
  89. package/dist/ui/assets/alert-jQ9HCPIf.js +1133 -0
  90. package/dist/ui/assets/badge-CNq0-mH5.js +1 -0
  91. package/dist/ui/assets/card-DFAwwhN3.js +1 -0
  92. package/dist/ui/assets/chevron-down-CPsvsmqj.js +6 -0
  93. package/dist/ui/assets/chevron-up-Df9jMo1X.js +6 -0
  94. package/dist/ui/assets/circle-alert-DOPQPvU8.js +6 -0
  95. package/dist/ui/assets/index-BkD6DijD.js +15 -0
  96. package/dist/ui/assets/index-CERGVYZK.js +292 -0
  97. package/dist/ui/assets/index-CSIPf9qw.css +1 -0
  98. package/dist/ui/assets/input-Dzvg_ZEZ.js +1 -0
  99. package/dist/ui/assets/label-DuVnkZ4q.js +1 -0
  100. package/dist/ui/assets/loader-circle-CrvlRy5o.js +6 -0
  101. package/dist/ui/assets/loginPage-qa4V-B70.js +6 -0
  102. package/dist/ui/assets/select-DhS8YUtJ.js +1 -0
  103. package/dist/ui/assets/separator-isK4chBP.js +6 -0
  104. package/dist/ui/assets/severityOptions-O38dSOfk.js +11 -0
  105. package/dist/ui/assets/switch-Z3mImG9n.js +1 -0
  106. package/dist/ui/assets/tabs-_77MUUQe.js +16 -0
  107. package/dist/ui/assets/upload-C1LT4Gkb.js +16 -0
  108. package/dist/ui/assets/utilService-DNyqzwj0.js +1 -0
  109. package/dist/ui/index.html +2 -2
  110. package/package.json +18 -7
  111. package/dist/ui/assets/index-BzIdRox6.js +0 -1733
  112. package/dist/ui/assets/index-CkoHzrrt.css +0 -1
@@ -23,13 +23,21 @@ const configureRoutes = (router, oasTlmConfig) => {
23
23
  if (_bootConfig.bootEnvVariables.OASTLM_BOOT_ENV === 'development') {
24
24
  _logger.default.info("Running in development mode, enabling CORS for all origins");
25
25
  router.use((0, _cors.default)({
26
- origin: '*',
27
- // Permitir todas las solicitudes en desarrollo
28
- methods: ['GET', 'POST', 'PUT', 'DELETE'],
29
- allowedHeaders: ['Content-Type', 'Authorization']
26
+ origin: (origin, callback) => {
27
+ if (!origin || /^http:\/\/localhost:\d+$/.test(origin)) {
28
+ callback(null, true);
29
+ } else {
30
+ callback(new Error('Not allowed by CORS'));
31
+ }
32
+ },
33
+ credentials: true
30
34
  }));
31
35
  }
32
- router.use((req, res, next) => {
36
+ const telemetryBaseUrl = oasTlmConfig.general.baseUrl;
37
+ // Sub-router for all telemetry endpoints
38
+ const telemetryRouter = (0, _express.Router)();
39
+ // Body parser for JSON requests
40
+ telemetryRouter.use((req, res, next) => {
33
41
  if (req.body !== undefined) {
34
42
  return next(); // Already parsed, no need to parse again.
35
43
  }
@@ -37,52 +45,32 @@ const configureRoutes = (router, oasTlmConfig) => {
37
45
  limit: '10mb'
38
46
  })(req, res, next);
39
47
  });
40
- const allAuthMiddlewares = getWrappedMiddlewares(() => oasTlmConfig.auth.enabled, [(0, _cookieParser.default)(), (0, _authRoutes.getAuthRoutes)(oasTlmConfig), (0, _authMiddleware.getAuthMiddleware)(oasTlmConfig)]);
41
- const baseUrl = oasTlmConfig.general.baseUrl;
42
- router.use(baseUrl, allAuthMiddlewares);
43
- router.use(baseUrl + "/traces", (0, _traceRoutes.getTraceRoutes)());
44
- router.use(baseUrl + "/metrics", (0, _metricsRoutes.getMetricsRoutes)());
45
- router.use(baseUrl + "/logs", (0, _logRoutes.getLogRoutes)());
46
- router.use(baseUrl + "/ai", getWrappedMiddlewares(() => oasTlmConfig.ai.openAIKey !== null, [(0, _aiRoutes.getAIRoutes)(oasTlmConfig)]));
47
- // WARNING: This path must be the same as the one used in the UI package App.tsx "oas-telemetry-ui"
48
- router.use(baseUrl + "/oas-telemetry-ui", (0, _uiRoutes.getUIRoutes)());
49
- router.use(baseUrl + "/utils", (0, _utilRoutes.getUtilsRoutes)(oasTlmConfig));
50
- router.use(baseUrl + "/plugins", (0, _pluginRoutes.getPluginRoutes)());
51
- router.get(baseUrl + '/health', (_req, res) => {
48
+ telemetryRouter.get('/health', (_req, res) => {
52
49
  res.status(200).send({
53
50
  status: 'OK'
54
51
  });
55
52
  });
56
- //redirect to the UI when accessing the base URL
57
- router.get(baseUrl, (req, res) => {
58
- res.redirect(baseUrl + "/oas-telemetry-ui");
53
+ // Redirect to the UI when accessing the base URL
54
+ telemetryRouter.get('/', (req, res) => {
55
+ res.redirect(`${telemetryBaseUrl}/oas-telemetry-ui/`);
59
56
  });
57
+ // WARNING: This path must be the same as the one used in the UI package App.tsx "oas-telemetry-ui"
58
+ telemetryRouter.use("/oas-telemetry-ui", (0, _uiRoutes.getUIRoutes)());
59
+ telemetryRouter.use("/utils", (0, _utilRoutes.getUtilsRoutes)(oasTlmConfig));
60
+ // Auth routes must be registered. If authentication is not enabled, all requests will be allowed.
61
+ // Frontend will use these endpoints;
62
+ telemetryRouter.use((0, _cookieParser.default)());
63
+ // Refresh token uses /auth/refresh path, careful if you change it
64
+ telemetryRouter.use('/auth', (0, _authRoutes.getAuthRoutes)(oasTlmConfig));
65
+ telemetryRouter.use((0, _authMiddleware.getAuthMiddleware)(oasTlmConfig));
66
+ telemetryRouter.use("/traces", (0, _traceRoutes.getTraceRoutes)());
67
+ telemetryRouter.use("/metrics", (0, _metricsRoutes.getMetricsRoutes)());
68
+ telemetryRouter.use("/logs", (0, _logRoutes.getLogRoutes)());
69
+ if (oasTlmConfig.ai.openAIKey) {
70
+ telemetryRouter.use("/ai", (0, _aiRoutes.getAIRoutes)(oasTlmConfig));
71
+ }
72
+ telemetryRouter.use("/plugins", (0, _pluginRoutes.getPluginRoutes)());
73
+ // Mount the telemetryRouter under telemetryBaseUrl
74
+ router.use(telemetryBaseUrl, telemetryRouter);
60
75
  };
61
- /**
62
- * This function wraps the provided middleware functions with a condition callback.
63
- * If the condition callback returns true, the middleware/router will be executed.
64
- * If the condition callback returns false, the middleware/router will be skipped.
65
- *
66
- * @callback {function} conditionCallback A callback function that returns a boolean to determine if the middleware should be used.
67
- * @param {Array} middlewares An array of middleware or routers to be wrapped.
68
- * @returns {Array} An array of wrapped middleware functions.
69
- */
70
- exports.configureRoutes = configureRoutes;
71
- function getWrappedMiddlewares(conditionCallback, middlewares) {
72
- return middlewares.map(middleware => {
73
- return function (req, res, next) {
74
- if (conditionCallback()) {
75
- if (typeof middleware === 'function') {
76
- // look for handle property, if it exists, it's a router. If not call middleware
77
- if (middleware.handle) {
78
- middleware.handle(req, res, next);
79
- } else {
80
- middleware(req, res, next);
81
- }
82
- }
83
- } else {
84
- next();
85
- }
86
- };
87
- });
88
- }
76
+ exports.configureRoutes = configureRoutes;
@@ -10,7 +10,13 @@ var _minisearch = _interopRequireDefault(require("minisearch"));
10
10
  var _circular = require("../utils/circular.cjs");
11
11
  var _wrappers = require("../wrappers.cjs");
12
12
  var _logger = _interopRequireDefault(require("../../../utils/logger.cjs"));
13
+ var _pluginService = require("../../../tlm-plugin/pluginService.cjs");
13
14
  function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e }; }
15
+ function ownKeys(e, r) { var t = Object.keys(e); if (Object.getOwnPropertySymbols) { var o = Object.getOwnPropertySymbols(e); r && (o = o.filter(function (r) { return Object.getOwnPropertyDescriptor(e, r).enumerable; })), t.push.apply(t, o); } return t; }
16
+ function _objectSpread(e) { for (var r = 1; r < arguments.length; r++) { var t = null != arguments[r] ? arguments[r] : {}; r % 2 ? ownKeys(Object(t), !0).forEach(function (r) { _defineProperty(e, r, t[r]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(e, Object.getOwnPropertyDescriptors(t)) : ownKeys(Object(t)).forEach(function (r) { Object.defineProperty(e, r, Object.getOwnPropertyDescriptor(t, r)); }); } return e; }
17
+ function _defineProperty(e, r, t) { return (r = _toPropertyKey(r)) in e ? Object.defineProperty(e, r, { value: t, enumerable: !0, configurable: !0, writable: !0 }) : e[r] = t, e; }
18
+ function _toPropertyKey(t) { var i = _toPrimitive(t, "string"); return "symbol" == typeof i ? i : i + ""; }
19
+ 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); }
14
20
  class InMemoryDbLogExporter extends _wrappers.Enabler {
15
21
  constructor(retentionTimeInSeconds = 3600) {
16
22
  super();
@@ -40,12 +46,6 @@ class InMemoryDbLogExporter extends _wrappers.Enabler {
40
46
  * @param resultCallback
41
47
  */
42
48
  export(logs, resultCallback) {
43
- if (!this.isEnabled()) {
44
- resultCallback({
45
- code: _core.ExportResultCode.SUCCESS
46
- });
47
- return;
48
- }
49
49
  const logsToInsert = logs.map(logRecord => {
50
50
  // Remove circular references first, then apply nesting, then export info
51
51
  const formattedLog = this._formatLogRecord(logRecord);
@@ -53,7 +53,16 @@ class InMemoryDbLogExporter extends _wrappers.Enabler {
53
53
  const nestedLog = (0, _circular.applyNesting)(cleanedLog);
54
54
  return nestedLog;
55
55
  });
56
- this._insertLogs(logsToInsert, resultCallback);
56
+ logsToInsert.forEach(log => {
57
+ _pluginService.pluginService.broadcastLog(log);
58
+ });
59
+ // ENABLED only affect storage not plugin broadcasting
60
+ if (this.isEnabled()) {
61
+ this._insertLogs(logsToInsert, resultCallback);
62
+ }
63
+ resultCallback({
64
+ code: _core.ExportResultCode.SUCCESS
65
+ });
57
66
  }
58
67
  reset() {
59
68
  this._db = new _nedb.default();
@@ -70,19 +79,36 @@ class InMemoryDbLogExporter extends _wrappers.Enabler {
70
79
  this._db = null;
71
80
  this._miniSearch = null;
72
81
  }
73
- find(query, messageSearch, callback) {
82
+ async find(findConfig) {
83
+ const {
84
+ query,
85
+ messageSearch,
86
+ limit,
87
+ sortOrder
88
+ } = findConfig;
89
+ const finalQuery = _objectSpread({}, query);
90
+ const effectiveSortOrder = sortOrder || {
91
+ timestamp: -1
92
+ };
74
93
  if (messageSearch) {
75
- const searchResults = this._miniSearch.search(messageSearch);
94
+ const searchResults = this._miniSearch.search(messageSearch, {
95
+ prefix: true,
96
+ fuzzy: 0.2
97
+ });
76
98
  const ids = searchResults.map(result => result._id);
77
99
  _logger.default.debug(`MiniSearch found ${ids.length} results for search term "${messageSearch}"`, {
78
100
  depth: 3
79
101
  });
80
- // Add MiniSearch results to the query
81
- query._id = {
102
+ finalQuery._id = {
82
103
  $in: ids
83
104
  };
84
105
  }
85
- this._db.find(query, callback);
106
+ const docs = await new Promise((resolve, reject) => {
107
+ this._db.find(finalQuery).sort(effectiveSortOrder).limit(limit).exec((err, docs) => {
108
+ if (err) reject(err);else resolve(docs);
109
+ });
110
+ });
111
+ return docs;
86
112
  }
87
113
  insert(data, callback) {
88
114
  this._insertLogs(data, result => {
@@ -115,7 +141,8 @@ class InMemoryDbLogExporter extends _wrappers.Enabler {
115
141
  attributes: logRecord.resource.attributes
116
142
  },
117
143
  instrumentationScope: logRecord.instrumentationScope,
118
- timestamp: (0, _core.hrTimeToMicroseconds)(logRecord.hrTime) || Date.now(),
144
+ timestamp: (0, _core.hrTimeToMicroseconds)(logRecord.hrTime) ?? Date.now(),
145
+ observedTimestamp: (0, _core.hrTimeToMicroseconds)(logRecord.hrTimeObserved) ?? Date.now(),
119
146
  traceId: logRecord.spanContext?.traceId,
120
147
  spanId: logRecord.spanContext?.spanId,
121
148
  traceFlags: logRecord.spanContext?.traceFlags,
@@ -129,6 +156,9 @@ class InMemoryDbLogExporter extends _wrappers.Enabler {
129
156
  this._retentionTimeInSeconds = retentionTimeInSeconds;
130
157
  _logger.default.info(`InMemoryDbLogExporter retention time set to ${this._retentionTimeInSeconds} seconds`);
131
158
  }
159
+ get retentionTimeInSeconds() {
160
+ return this._retentionTimeInSeconds;
161
+ }
132
162
  _insertLogs(logsToInsert, resultCallback) {
133
163
  this._db.insert(logsToInsert, (err, newDocs) => {
134
164
  if (err) {
@@ -9,6 +9,7 @@ var _nedb = _interopRequireDefault(require("@seald-io/nedb"));
9
9
  var _circular = require("../utils/circular.cjs");
10
10
  var _wrappers = require("../wrappers.cjs");
11
11
  var _logger = _interopRequireDefault(require("../../../utils/logger.cjs"));
12
+ var _pluginService = require("../../../tlm-plugin/pluginService.cjs");
12
13
  function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e }; }
13
14
  class InMemoryDbMetricExporter extends _wrappers.Enabler {
14
15
  constructor(retentionTimeInSeconds = 3600) {
@@ -24,9 +25,13 @@ class InMemoryDbMetricExporter extends _wrappers.Enabler {
24
25
  }
25
26
  export(metrics, resultCallback) {
26
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
27
34
  if (this.isEnabled()) {
28
- const scopeMetrics = metrics?.scopeMetrics;
29
- const cleanMetrics = (0, _circular.applyNesting)(scopeMetrics);
30
35
  this._metrics.insert(cleanMetrics, (err, _newDoc) => {
31
36
  if (err) {
32
37
  _logger.default.error('Insertion Error:', err);
@@ -74,6 +79,9 @@ class InMemoryDbMetricExporter extends _wrappers.Enabler {
74
79
  this._retentionTimeInSeconds = retentionTimeInSeconds;
75
80
  _logger.default.info(`InMemoryDbMetricExporter retention time set to ${this._retentionTimeInSeconds} seconds`);
76
81
  }
82
+ get retentionTimeInSeconds() {
83
+ return this._retentionTimeInSeconds;
84
+ }
77
85
  _startCleanupJob() {
78
86
  const interval = 1000;
79
87
  setInterval(() => {
@@ -9,6 +9,7 @@ var _nedb = _interopRequireDefault(require("@seald-io/nedb"));
9
9
  var _logger = _interopRequireDefault(require("../../../utils/logger.cjs"));
10
10
  var _circular = require("../utils/circular.cjs");
11
11
  var _wrappers = require("../wrappers.cjs");
12
+ var _pluginService = require("../../../tlm-plugin/pluginService.cjs");
12
13
  function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e }; }
13
14
  class InMemoryDbSpanExporter extends _wrappers.Enabler {
14
15
  constructor(retentionTimeInSeconds = 3600) {
@@ -30,35 +31,39 @@ class InMemoryDbSpanExporter extends _wrappers.Enabler {
30
31
  this._retentionTimeInSeconds = retentionTimeInSeconds;
31
32
  _logger.default.info(`InMemoryDbSpanExporter retention time set to ${this._retentionTimeInSeconds} seconds`);
32
33
  }
34
+ get retentionTimeInSeconds() {
35
+ return this._retentionTimeInSeconds;
36
+ }
33
37
  export(readableSpans, resultCallback) {
34
38
  _logger.default.debug('InMemoryDbSpanExporter.export called with spans: ', readableSpans.length);
35
39
  try {
36
- if (!this.isEnabled()) {
37
- _logger.default.debug('InMemoryDbSpanExporter is not enabled. Skipping export.');
38
- return resultCallback({
39
- code: _core.ExportResultCode.SUCCESS
40
- });
41
- }
42
40
  // Prepare spans to be inserted into the in-memory database (remove circular references and convert to nested objects)
43
41
  const cleanSpans = readableSpans.map(nestedSpan => (0, _circular.removeCircularRefs)(nestedSpan)) // to avoid JSON parsing error
44
42
  .map(span => (0, _circular.applyNesting)(span)) // to avoid dot notation in keys (neDB does not support dot notation in keys)
45
43
  .filter(span => {
46
- const target = span?.attributes?.http?.target; // Exclude spans where target includes 'telemetry' but NOT 'telemetry/utils'
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'
47
46
  if (target && target.includes(this._baseUrl)) {
48
- return target.includes(this._baseUrl + '/utils');
47
+ return target.includes("generate");
49
48
  }
50
49
  return true;
51
50
  });
52
- // Insert spans into the in-memory database
53
- this._spans.insert(cleanSpans, (err, _newDoc) => {
54
- if (err) {
55
- _logger.default.error(err);
56
- return;
57
- }
51
+ cleanSpans.forEach(span => {
52
+ _pluginService.pluginService.broadcastTrace(span);
58
53
  });
59
- setTimeout(() => resultCallback({
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);
60
+ return;
61
+ }
62
+ });
63
+ }
64
+ return resultCallback({
60
65
  code: _core.ExportResultCode.SUCCESS
61
- }), 0);
66
+ });
62
67
  } catch (error) {
63
68
  _logger.default.error('Error exporting spans\n' + error.message + '\n' + error.stack);
64
69
  return resultCallback({
@@ -8,6 +8,7 @@ var _sdkTraceNode = require("@opentelemetry/sdk-trace-node");
8
8
  var _apiLogs = require("@opentelemetry/api-logs");
9
9
  var _sdkLogs = require("@opentelemetry/sdk-logs");
10
10
  var _bootConfig = require("../config/bootConfig.cjs");
11
+ var _util = _interopRequireDefault(require("util"));
11
12
  function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e }; }
12
13
  // THIS INSTRUMENTATIONS NEED TO BE LOADED BEFORE ANYTHING ELSE
13
14
  // They use monkey-patching to instrument the HTTP server and client.
@@ -42,33 +43,56 @@ function initializeLogs() {
42
43
  });
43
44
  // Get a logger instance
44
45
  const loggerInstance = loggerProvider.getLogger('oas-telemetry'); // Use loggerProvider to get the logger
45
- // Override console methods to emit logs via OpenTelemetry, like an instrumentation
46
- const originalConsoleMethods = {
47
- log: console.log,
48
- warn: console.warn,
49
- error: console.error,
50
- info: console.info,
51
- debug: console.debug
52
- };
53
- Object.keys(originalConsoleMethods).forEach(method => {
46
+ Object.keys(_telemetryRegistry.originalConsoleMethods).forEach(method => {
54
47
  // @ts-expect-error yes
55
48
  console[method] = (...args) => {
49
+ const severity = getSeverityForMethod(method);
56
50
  loggerInstance.emit({
57
- severityNumber: _apiLogs.SeverityNumber[method.toUpperCase()] || _apiLogs.SeverityNumber.INFO,
58
- severityText: method.toUpperCase(),
59
- body: args.join(' '),
51
+ severityNumber: severity.number,
52
+ severityText: severity.text,
53
+ body: _util.default.format(...args),
60
54
  attributes: {
61
- 'source.source': `console.${method}`
55
+ 'source': `console.${method}`,
56
+ "library": "oas-telemetry"
62
57
  }
63
58
  });
64
59
  // @ts-expect-error yes
65
- originalConsoleMethods[method](...args);
60
+ _telemetryRegistry.originalConsoleMethods[method](...args);
66
61
  };
67
62
  });
68
63
  }
69
64
  function initializeMetrics() {
70
65
  _logger.default.info('📈 Initializing MeterProvider');
71
- // WARN: This is a custom provider that allows adding readers dynamically at runtime.
72
66
  // WARN: Default PeriodicExportingMetricReader is added post initialization (see telemetryConfigurator.ts)
73
67
  // The in memory exporter is added by default to that reader. More readers are allowed to be added dynamically
68
+ }
69
+ function getSeverityForMethod(method) {
70
+ switch (method) {
71
+ case "log":
72
+ case "info":
73
+ return {
74
+ number: _apiLogs.SeverityNumber.INFO,
75
+ text: "INFO"
76
+ };
77
+ case "debug":
78
+ return {
79
+ number: _apiLogs.SeverityNumber.DEBUG,
80
+ text: "DEBUG"
81
+ };
82
+ case "warn":
83
+ return {
84
+ number: _apiLogs.SeverityNumber.WARN,
85
+ text: "WARN"
86
+ };
87
+ case "error":
88
+ return {
89
+ number: _apiLogs.SeverityNumber.ERROR,
90
+ text: "ERROR"
91
+ };
92
+ default:
93
+ return {
94
+ number: _apiLogs.SeverityNumber.INFO,
95
+ text: "INFO"
96
+ };
97
+ }
74
98
  }
@@ -11,21 +11,25 @@ var _sdkLogs = require("@opentelemetry/sdk-logs");
11
11
  var _sdkMetrics = require("@opentelemetry/sdk-metrics");
12
12
  var _hostMetrics = require("@opentelemetry/host-metrics");
13
13
  var _bootConfig = require("../config/bootConfig.cjs");
14
+ var _pluginService = require("../tlm-plugin/pluginService.cjs");
14
15
  function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e }; }
15
16
  const configureTelemetry = oasTlmConfig => {
17
+ configurePlugins(oasTlmConfig);
16
18
  configureTraces(oasTlmConfig);
17
19
  configureMetrics(oasTlmConfig);
18
20
  configureLogs(oasTlmConfig);
19
21
  _logger.default.info("✅ Telemetry configured successfully. All exporters are ready");
20
22
  };
21
23
  exports.configureTelemetry = configureTelemetry;
24
+ function configurePlugins(oasTlmConfig) {
25
+ _pluginService.pluginService.enabled = oasTlmConfig.plugins.enabled;
26
+ }
22
27
  function configureTraces(oasTlmConfig) {
23
28
  // TRACES CONFIGURATION
24
29
  // [OT]Provider -> [OT]SpanProcessor(multiSpan) -> n Processors(eg mainProcessor, extra) -> 1 SpanExporter
25
30
  _telemetryRegistry.inMemoryDbSpanExporter.baseUrl = oasTlmConfig.general.baseUrl; // TODO this will be done with filters
26
31
  _telemetryRegistry.inMemoryDbSpanExporter.retentionTimeInSeconds = oasTlmConfig.traces.memoryExporter.retentionTimeSeconds;
27
32
  _telemetryRegistry.inMemoryDbSpanExporter.setEnabledValue(oasTlmConfig.traces.memoryExporter.enabled);
28
- _telemetryRegistry.pluginSpanExporter.setEnabledValue(oasTlmConfig.plugins.enabled);
29
33
  const mainExporter = _telemetryRegistry.multiSpanExporter;
30
34
  let mainProcessor = new _sdkTraceNode.BatchSpanProcessor(mainExporter);
31
35
  if (_bootConfig.bootEnvVariables.OASTLM_BOOT_ENV !== 'production') {
@@ -33,7 +37,6 @@ function configureTraces(oasTlmConfig) {
33
37
  mainProcessor = new _sdkTraceNode.SimpleSpanProcessor(mainExporter);
34
38
  }
35
39
  mainExporter.addExporters(_telemetryRegistry.inMemoryDbSpanExporter); // Main exporter have at least the in-memory exporter used by the traces controller
36
- mainExporter.addExporters(_telemetryRegistry.pluginSpanExporter);
37
40
  mainExporter.addExporters(oasTlmConfig.traces.extraExporters);
38
41
  _telemetryRegistry.dynamicMultiSpanProcessor.addProcessors(mainProcessor);
39
42
  _telemetryRegistry.dynamicMultiSpanProcessor.addProcessors(oasTlmConfig.traces.extraProcessors);
@@ -51,7 +54,6 @@ function configureLogs(oasTlmConfig) {
51
54
  }
52
55
  mainExporter.addExporters(_telemetryRegistry.inMemoryDbLogExporter); // Main exporter have at least the in-memory exporter used by the logs controller
53
56
  mainExporter.addExporters(oasTlmConfig.logs.extraExporters);
54
- mainExporter.addExporters(_telemetryRegistry.pluginLogExporter); // Allow logs to be sent to plugins too
55
57
  _telemetryRegistry.dynamicMultiLogProcessor.addProcessors(mainProcessor);
56
58
  _telemetryRegistry.dynamicMultiLogProcessor.addProcessors(oasTlmConfig.logs.extraProcessors);
57
59
  }
@@ -65,14 +67,9 @@ function configureMetrics(oasTlmConfig) {
65
67
  exportIntervalMillis: oasTlmConfig.metrics.mainMetricReaderOptions.exportIntervalMillis,
66
68
  metricProducers: oasTlmConfig.metrics.mainMetricReaderOptions.metricProducers
67
69
  });
68
- const pluginReader = new _sdkMetrics.PeriodicExportingMetricReader({
69
- exporter: _telemetryRegistry.pluginMetricExporter,
70
- exportIntervalMillis: oasTlmConfig.metrics.mainMetricReaderOptions.exportIntervalMillis,
71
- metricProducers: oasTlmConfig.metrics.mainMetricReaderOptions.metricProducers
72
- });
73
70
  const meterProvider = new _sdkMetrics.MeterProvider({
74
71
  resource: _telemetryRegistry.oasTelemetryResource,
75
- readers: [mainReader, pluginReader, ...oasTlmConfig.metrics.extraReaders],
72
+ readers: [mainReader, ...oasTlmConfig.metrics.extraReaders],
76
73
  views: oasTlmConfig.metrics.extraViews || []
77
74
  });
78
75
  // TODO maybe hostMetrics are too much, consider using only a subset of them.
@@ -3,7 +3,7 @@
3
3
  Object.defineProperty(exports, "__esModule", {
4
4
  value: true
5
5
  });
6
- exports.pluginSpanExporter = exports.pluginMetricExporter = exports.pluginLogExporter = exports.oasTelemetryResource = exports.multiSpanExporter = exports.multiLogExporter = exports.inMemoryDbSpanExporter = exports.inMemoryDbMetricExporter = exports.inMemoryDbLogExporter = exports.dynamicMultiSpanProcessor = exports.dynamicMultiLogProcessor = void 0;
6
+ exports.originalConsoleMethods = exports.oasTelemetryResource = exports.multiSpanExporter = exports.multiLogExporter = exports.inMemoryDbSpanExporter = exports.inMemoryDbMetricExporter = exports.inMemoryDbLogExporter = exports.dynamicMultiSpanProcessor = exports.dynamicMultiLogProcessor = void 0;
7
7
  var _InMemoryDbSpanExporter = require("./custom-implementations/exporters/InMemoryDbSpanExporter.cjs");
8
8
  var _wrappers = require("./custom-implementations/wrappers.cjs");
9
9
  var _InMemoryDbLogExporter = require("./custom-implementations/exporters/InMemoryDbLogExporter.cjs");
@@ -12,12 +12,10 @@ var _dynamicMultiSpanProcessor = require("./custom-implementations/processors/dy
12
12
  var _dynamicMultiLogProcessor = require("./custom-implementations/processors/dynamicMultiLogProcessor.cjs");
13
13
  var _semanticConventions = require("@opentelemetry/semantic-conventions");
14
14
  var _resources = require("@opentelemetry/resources");
15
- var _PluginSpanExporter = require("./custom-implementations/exporters/PluginSpanExporter.cjs");
16
- var _PluginLogExporter = require("./custom-implementations/exporters/PluginLogExporter.cjs");
17
- var _PluginMetricExporter = require("./custom-implementations/exporters/PluginMetricExporter.cjs");
15
+ var _bootConfig = require("../config/bootConfig.cjs");
18
16
  // GLOBAL REGISTRY of telemetry components, used by SDKs and controllers.
19
17
  const oasTelemetryResource = exports.oasTelemetryResource = (0, _resources.resourceFromAttributes)({
20
- [_semanticConventions.ATTR_SERVICE_NAME]: 'oas-telemetry-service'
18
+ [_semanticConventions.ATTR_SERVICE_NAME]: _bootConfig.bootEnvVariables.OASTLM_BOOT_SERVICE_NAME
21
19
  });
22
20
  // TRACES -------------------------------------------------------------------------------------
23
21
  // This is the main exporter for oas-telemetry spans. (Used by the traces controller)
@@ -26,15 +24,20 @@ const inMemoryDbSpanExporter = exports.inMemoryDbSpanExporter = new _InMemoryDbS
26
24
  const multiSpanExporter = exports.multiSpanExporter = new _wrappers.EnablerMultiSpanExporter();
27
25
  // This allows the addition of more processors at runtime
28
26
  const dynamicMultiSpanProcessor = exports.dynamicMultiSpanProcessor = new _dynamicMultiSpanProcessor.DynamicMultiSpanProcessor();
29
- const pluginSpanExporter = exports.pluginSpanExporter = new _PluginSpanExporter.PluginSpanExporter(); // This exporter sends spans to the plugin module.
30
27
  // LOGS ----------------------------------------------------------------------------------------
31
28
  const inMemoryDbLogExporter = exports.inMemoryDbLogExporter = new _InMemoryDbLogExporter.InMemoryDbLogExporter();
32
29
  const multiLogExporter = exports.multiLogExporter = new _wrappers.EnablerMultiLogExporter();
33
30
  const dynamicMultiLogProcessor = exports.dynamicMultiLogProcessor = new _dynamicMultiLogProcessor.DynamicMultiLogRecordProcessor();
34
- const pluginLogExporter = exports.pluginLogExporter = new _PluginLogExporter.PluginLogExporter(); // This exporter sends logs to the plugin module.
31
+ // Override console methods to emit logs via OpenTelemetry, like an instrumentation
32
+ const originalConsoleMethods = exports.originalConsoleMethods = {
33
+ log: console.log,
34
+ warn: console.warn,
35
+ error: console.error,
36
+ info: console.info,
37
+ debug: console.debug
38
+ };
35
39
  // METRICS -------------------------------------------------------------------------------------
36
40
  // Metrics follow a different pattern in OpenTelemetry
37
41
  const inMemoryDbMetricExporter = exports.inMemoryDbMetricExporter = new _InMemoryDbMetricExporter.InMemoryDbMetricExporter();
38
- const pluginMetricExporter = exports.pluginMetricExporter = new _PluginMetricExporter.PluginMetricExporter(); // This exporter sends metrics to the plugin module.
39
42
  // Readers and their exporters cannot be grouped together in a MultiReader or similar construct
40
43
  // due to differences in aggregation temporality and aggregation selection.
@@ -3,96 +3,66 @@
3
3
  Object.defineProperty(exports, "__esModule", {
4
4
  value: true
5
5
  });
6
- exports.getAgent = getAgent;
7
- var _openai = _interopRequireDefault(require("openai"));
6
+ exports.agent = agent;
8
7
  var _tools = require("./tools.cjs");
9
8
  var _logger = _interopRequireDefault(require("../utils/logger.cjs"));
10
9
  function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e }; }
11
- function getAgent(oasTlmConfig) {
12
- let openai;
13
- try {
14
- if (!oasTlmConfig.ai.openAIKey) {
15
- openai = null;
16
- } else {
17
- openai = new _openai.default({
18
- apiKey: oasTlmConfig.ai.openAIKey ?? undefined,
19
- dangerouslyAllowBrowser: true
20
- });
21
- }
22
- } catch {
23
- openai = null;
24
- }
25
- const messages = [{
26
- role: "assistant",
27
- 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."
28
- }];
29
- // Add extra context prompts if provided
30
- if (oasTlmConfig.ai.extraContextPrompts) {
31
- for (const prompt of oasTlmConfig.ai.extraContextPrompts) {
32
- messages.push({
33
- role: "system",
34
- content: prompt
35
- });
36
- }
37
- }
38
- async function agent(userInput) {
39
- if (!openai) {
40
- _logger.default.error("OpenAI client is not initialized. Please check your OpenAI API key.");
41
- return {
42
- content: "OpenAI client is not initialized. Please check your OpenAI API key."
43
- };
44
- }
45
- messages.push({
46
- role: "user",
47
- content: userInput
10
+ function ownKeys(e, r) { var t = Object.keys(e); if (Object.getOwnPropertySymbols) { var o = Object.getOwnPropertySymbols(e); r && (o = o.filter(function (r) { return Object.getOwnPropertyDescriptor(e, r).enumerable; })), t.push.apply(t, o); } return t; }
11
+ function _objectSpread(e) { for (var r = 1; r < arguments.length; r++) { var t = null != arguments[r] ? arguments[r] : {}; r % 2 ? ownKeys(Object(t), !0).forEach(function (r) { _defineProperty(e, r, t[r]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(e, Object.getOwnPropertyDescriptors(t)) : ownKeys(Object(t)).forEach(function (r) { Object.defineProperty(e, r, Object.getOwnPropertyDescriptor(t, r)); }); } return e; }
12
+ function _defineProperty(e, r, t) { return (r = _toPropertyKey(r)) in e ? Object.defineProperty(e, r, { value: t, enumerable: !0, configurable: !0, writable: !0 }) : e[r] = t, e; }
13
+ function _toPropertyKey(t) { var i = _toPrimitive(t, "string"); return "symbol" == typeof i ? i : i + ""; }
14
+ 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); }
15
+ async function agent(openai, messages, model = "gpt-3.5-turbo", extraPrompts = []) {
16
+ for (let i = 0; i < 5; i++) {
17
+ const modelResponse = await openai.chat.completions.create({
18
+ model,
19
+ messages,
20
+ tools: _tools.tools
48
21
  });
49
- for (let i = 0; i < 5; i++) {
50
- const response = await openai?.chat?.completions?.create?.({
51
- model: oasTlmConfig.ai.openAIModel,
52
- messages: messages,
53
- tools: _tools.tools
54
- });
55
- const {
56
- finish_reason,
57
- message
58
- } = response.choices[0];
59
- if (finish_reason === "tool_calls" && message.tool_calls) {
60
- _logger.default.debug("Tool calls detected:", message.tool_calls);
61
- const results = [];
62
- for (const toolCall of message.tool_calls) {
63
- const functionName = toolCall.function.name;
64
- const functionToCall = _tools.availableTools[functionName];
65
- const functionArgs = JSON.parse(toolCall.function.arguments);
66
- const functionArgsArr = Object.values(functionArgs);
67
- // @ts-expect-error yes
68
- // eslint-disable-next-line prefer-spread
69
- const functionResponse = await functionToCall.apply(null, functionArgsArr);
70
- results.push({
71
- name: functionName,
72
- response: functionResponse
73
- });
74
- }
75
- const resultMessage = results.map(({
76
- name,
77
- response
78
- }) => `Result from "${name}":\n${JSON.stringify(response, null, 2)}`).join("\n\n");
79
- messages.push({
80
- role: "function",
81
- name: "multiple_tool_calls",
82
- content: resultMessage
22
+ const {
23
+ finish_reason,
24
+ message
25
+ } = modelResponse.choices[0];
26
+ if (finish_reason === "tool_calls" && message.tool_calls) {
27
+ _logger.default.debug("Tool calls detected:", message.tool_calls);
28
+ const results = [];
29
+ for (const toolCall of message.tool_calls) {
30
+ const functionName = toolCall.function.name;
31
+ const functionToCall = _tools.availableTools[functionName];
32
+ const functionArgs = JSON.parse(toolCall.function.arguments);
33
+ const functionArgsArr = Object.values(functionArgs);
34
+ // @ts-expect-error yes
35
+ // eslint-disable-next-line prefer-spread
36
+ const functionResponse = await functionToCall.apply(null, functionArgsArr);
37
+ results.push({
38
+ name: functionName,
39
+ response: functionResponse
83
40
  });
84
- } else if (finish_reason === "stop") {
85
- messages.push(message);
86
- return message;
87
41
  }
42
+ const resultMessage = results.map(({
43
+ name,
44
+ response
45
+ }, idx) => {
46
+ const toolCall = message.tool_calls?.[idx];
47
+ const params = toolCall ? JSON.parse(toolCall.function.arguments) : {};
48
+ return `Tool "${name}" called with parameters:\n${JSON.stringify(params, null, 2)}\nResult:\n${JSON.stringify(response, null, 2)}`;
49
+ }).join("\n\n");
50
+ messages.push({
51
+ role: "function",
52
+ name: "multiple_tool_calls",
53
+ content: resultMessage,
54
+ timestamp: new Date().toISOString()
55
+ });
56
+ } else if (finish_reason === "stop") {
57
+ messages.push(_objectSpread(_objectSpread({}, message), {}, {
58
+ timestamp: new Date().toISOString()
59
+ }));
60
+ return;
88
61
  }
89
- return {
90
- content: "Se alcanzó el número máximo de iteraciones sin una respuesta adecuada. Intenta con una consulta más específica."
91
- };
92
62
  }
93
- return async function getAgentResponse(question) {
94
- const response = await agent(question);
95
- _logger.default.debug("Response from agent:", response);
96
- return response.content;
97
- };
63
+ messages.push({
64
+ role: "assistant",
65
+ content: "Maximum iterations reached without a suitable response. Try a more specific query.",
66
+ timestamp: new Date().toISOString()
67
+ });
98
68
  }