@oas-tools/oas-telemetry 0.5.1 → 0.6.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.cjs CHANGED
@@ -12,6 +12,7 @@ var _authMiddleware = require("./middleware/authMiddleware.cjs");
12
12
  var _authRoutes = _interopRequireDefault(require("./routes/authRoutes.cjs"));
13
13
  var _telemetryRoutes = require("./routes/telemetryRoutes.cjs");
14
14
  var _InMemoryDbExporter = require("./exporters/InMemoryDbExporter.cjs");
15
+ var _metricsRoutes = _interopRequireDefault(require("./routes/metricsRoutes.cjs"));
15
16
  function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
16
17
  let dbglog = () => {};
17
18
  if (process.env.OTDEBUG == "true") dbglog = console.log;
@@ -25,6 +26,7 @@ if (process.env.OTDEBUG == "true") dbglog = console.log;
25
26
  * @param {Object} [OasTlmConfig.spec] The OpenAPI spec object.
26
27
  * @param {string} [OasTlmConfig.specFileName] Alternative to `spec`: the path to the OpenAPI spec file.
27
28
  * @param {boolean} [OasTlmConfig.autoActivate=true] Whether to start telemetry automatically on load.
29
+ * @param {boolean} [OasTlmConfig.authEnabled=true] Whether to enable authentication middleware.
28
30
  * @param {number} [OasTlmConfig.apiKeyMaxAge=1800000] The maximum age of the API key in milliseconds.
29
31
  * @param {string} [OasTlmConfig.defaultApiKey] The default API key to use.
30
32
  * @param {OasTlmExporter} [OasTlmConfig.exporter=InMemoryExporter] The exporter to use. Must implement the `OasTlmExporter` interface.
@@ -50,12 +52,12 @@ function oasTelemetry(OasTlmConfig) {
50
52
  console.error("No spec available !");
51
53
  }
52
54
  }
53
- router.use((0, _cookieParser.default)());
55
+ let allAuthMiddlewares = getWrappedMiddlewares(() => _config.globalOasTlmConfig.authEnabled, [(0, _cookieParser.default)(), _authRoutes.default, _authMiddleware.authMiddleware]);
54
56
  const baseURL = _config.globalOasTlmConfig.baseURL;
55
57
  router.use((0, _express.json)());
56
- router.use(baseURL, _authRoutes.default);
57
- router.use(baseURL, _authMiddleware.authMiddleware); // Add the auth middleware
58
+ router.use(baseURL, allAuthMiddlewares);
58
59
  router.use(baseURL, _telemetryRoutes.telemetryRoutes);
60
+ router.use(baseURL + "/metrics", _metricsRoutes.default);
59
61
  if (_config.globalOasTlmConfig.autoActivate) {
60
62
  _config.globalOasTlmConfig.dynamicExporter.exporter?.start();
61
63
  }
@@ -77,4 +79,32 @@ function oasTelemetry(OasTlmConfig) {
77
79
  * @method {Promise<void>} forceFlush() Exports any pending data that has not yet been processed.
78
80
  * @property {Array} plugins An array of plugins that can be activated by the exporter.
79
81
  */
82
+
83
+ /**
84
+ * This function wraps the provided middleware functions with a condition callback.
85
+ * If the condition callback returns true, the middleware/router will be executed.
86
+ * If the condition callback returns false, the middleware/router will be skipped.
87
+ *
88
+ * @callback {function} conditionCallback A callback function that returns a boolean to determine if the middleware should be used.
89
+ * @param {Array} middlewares An array of middleware or routers to be wrapped.
90
+ * @returns {Array} An array of wrapped middleware functions.
91
+ */
92
+ function getWrappedMiddlewares(conditionCallback, middlewares) {
93
+ return middlewares.map(middleware => {
94
+ return function (req, res, next) {
95
+ if (conditionCallback()) {
96
+ if (typeof middleware === 'function') {
97
+ // look for handle property, if it exists, it's a router. If not call middleware
98
+ if (middleware.handle) {
99
+ middleware.handle(req, res, next);
100
+ } else {
101
+ middleware(req, res, next);
102
+ }
103
+ }
104
+ } else {
105
+ next();
106
+ }
107
+ };
108
+ });
109
+ }
80
110
  module.exports = exports.default;
@@ -4,10 +4,14 @@ var _sdkNode = require("@opentelemetry/sdk-node");
4
4
  var _resources = require("@opentelemetry/resources");
5
5
  var _instrumentationHttp = require("@opentelemetry/instrumentation-http");
6
6
  var _config = require("./config.cjs");
7
+ var _systemMetrics = require("./systemMetrics.cjs");
7
8
  // import { getNodeAutoInstrumentations } from '@opentelemetry/auto-instrumentations-node';
8
9
 
10
+ // Import system metrics functions
11
+
9
12
  // DynamicExporter allows changing to any exporter at runtime;
10
13
  const traceExporter = _config.globalOasTlmConfig.dynamicExporter;
14
+ // Alternative 1: Using NodeSDK
11
15
  const sdk = new _sdkNode.NodeSDK({
12
16
  resource: new _resources.Resource({
13
17
  service: 'oas-telemetry-service'
@@ -15,6 +19,40 @@ const sdk = new _sdkNode.NodeSDK({
15
19
  traceExporter,
16
20
  instrumentations: [new _instrumentationHttp.HttpInstrumentation()]
17
21
  });
22
+
23
+ // Collect and export system metrics
24
+ setInterval(() => {
25
+ const cpuUsageData = (0, _systemMetrics.getCpuUsageData)();
26
+ const processCpuUsageData = (0, _systemMetrics.getProcessCpuUsageData)();
27
+ const memoryData = (0, _systemMetrics.getMemoryData)();
28
+ const processMemoryData = (0, _systemMetrics.getProcessMemoryData)();
29
+ const metrics = {
30
+ timestamp: Date.now(),
31
+ cpuUsageData,
32
+ processCpuUsageData,
33
+ memoryData,
34
+ processMemoryData
35
+ };
36
+
37
+ // Export the collected metrics using the InMemoryDBMetricsExporter
38
+ const inMemoryDbMetricExporter = _config.globalOasTlmConfig.metricsExporter;
39
+ inMemoryDbMetricExporter.export(metrics, result => {});
40
+ }, _config.globalOasTlmConfig.systemMetricsInterval);
41
+ console.log('✅ OpenTelemetry System Metrics initialized.');
18
42
  if (process.env.OASTLM_MODULE_DISABLED !== 'true') {
19
43
  sdk.start();
20
- }
44
+ }
45
+
46
+ // Alternative 2:
47
+ // const provider = new NodeTracerProvider();
48
+ // provider.addSpanProcessor(new SimpleSpanProcessor(traceExporter));
49
+
50
+ // if (process.env.OASTLM_MODULE_DISABLED !== 'true') {
51
+ // provider.register();
52
+ // registerInstrumentations({
53
+ // instrumentations: [
54
+ // new HttpInstrumentation(),
55
+ // new ExpressInstrumentation(),
56
+ // ],
57
+ // });
58
+ // }
@@ -0,0 +1,15 @@
1
+ "use strict";
2
+
3
+ Object.defineProperty(exports, "__esModule", {
4
+ value: true
5
+ });
6
+ exports.metricsRoutes = exports.default = void 0;
7
+ var _express = require("express");
8
+ var _metricsController = require("../controllers/metricsController.cjs");
9
+ const metricsRoutes = exports.metricsRoutes = (0, _express.Router)();
10
+
11
+ // Metrics Control
12
+ metricsRoutes.get('/', _metricsController.listMetrics);
13
+ metricsRoutes.post('/find', _metricsController.findMetrics);
14
+ metricsRoutes.get('/reset', _metricsController.resetMetrics);
15
+ var _default = exports.default = metricsRoutes;
@@ -0,0 +1,97 @@
1
+ "use strict";
2
+
3
+ Object.defineProperty(exports, "__esModule", {
4
+ value: true
5
+ });
6
+ exports.getCpuUsageData = getCpuUsageData;
7
+ exports.getMemoryData = getMemoryData;
8
+ exports.getProcessCpuUsageData = getProcessCpuUsageData;
9
+ exports.getProcessMemoryData = getProcessMemoryData;
10
+ var _os = require("os");
11
+ const MILLISECOND = 1 / 1e3;
12
+ const MICROSECOND = 1 / 1e6;
13
+ let prevOsData = {
14
+ time: Date.now(),
15
+ cpus: (0, _os.cpus)()
16
+ };
17
+ function getCpuUsageData() {
18
+ const currentTime = Date.now();
19
+ const timeElapsed = currentTime - prevOsData.time;
20
+ const currentOsData = {
21
+ time: currentTime,
22
+ cpus: (0, _os.cpus)()
23
+ };
24
+ const usageData = currentOsData.cpus.map((cpu, cpuNumber) => {
25
+ const prevTimes = prevOsData.cpus[cpuNumber].times;
26
+ const currTimes = cpu.times;
27
+ const idle = currTimes.idle * MILLISECOND;
28
+ const user = currTimes.user * MILLISECOND;
29
+ const system = currTimes.sys * MILLISECOND;
30
+ const interrupt = currTimes.irq * MILLISECOND;
31
+ const nice = currTimes.nice * MILLISECOND;
32
+ const idleP = (currTimes.idle - prevTimes.idle) / timeElapsed;
33
+ const userP = (currTimes.user - prevTimes.user) / timeElapsed;
34
+ const systemP = (currTimes.sys - prevTimes.sys) / timeElapsed;
35
+ const interruptP = (currTimes.irq - prevTimes.irq) / timeElapsed;
36
+ const niceP = (currTimes.nice - prevTimes.nice) / timeElapsed;
37
+ return {
38
+ cpuNumber: String(cpuNumber),
39
+ idle,
40
+ user,
41
+ system,
42
+ interrupt,
43
+ nice,
44
+ userP,
45
+ systemP,
46
+ idleP,
47
+ interruptP,
48
+ niceP
49
+ };
50
+ });
51
+ prevOsData = currentOsData;
52
+ return usageData;
53
+ }
54
+ let prevProcData = {
55
+ time: Date.now(),
56
+ usage: process.cpuUsage()
57
+ };
58
+ function getProcessCpuUsageData() {
59
+ const currentTime = Date.now();
60
+ const currentUsage = process.cpuUsage();
61
+ const prevUsage = prevProcData.usage;
62
+ const timeElapsed = (currentTime - prevProcData.time) * 1000;
63
+ const cpusTimeElapsed = timeElapsed * prevOsData.cpus.length;
64
+ const user = currentUsage.user * MICROSECOND;
65
+ const system = currentUsage.system * MICROSECOND;
66
+ const userP = (currentUsage.user - prevUsage.user) / cpusTimeElapsed;
67
+ const systemP = (currentUsage.system - prevUsage.system) / cpusTimeElapsed;
68
+ prevProcData = {
69
+ time: currentTime,
70
+ usage: currentUsage
71
+ };
72
+ return {
73
+ user,
74
+ system,
75
+ userP,
76
+ systemP
77
+ };
78
+ }
79
+ function getMemoryData() {
80
+ const total = (0, _os.totalmem)();
81
+ const free = (0, _os.freemem)();
82
+ const used = total - free;
83
+ const freeP = free / total;
84
+ const usedP = used / total;
85
+ return {
86
+ used: used,
87
+ free: free,
88
+ usedP: usedP,
89
+ freeP: freeP
90
+ };
91
+ }
92
+ function getProcessMemoryData() {
93
+ if (process.memoryUsage.rss) {
94
+ return process.memoryUsage.rss();
95
+ }
96
+ return process.memoryUsage().rss;
97
+ }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@oas-tools/oas-telemetry",
3
- "version": "0.5.1",
3
+ "version": "0.6.0",
4
4
  "description": "This package exports an Express middleware that traces requests and responses of an Express application using OpenTelemetry.",
5
5
  "author": "Manuel Otero",
6
6
  "contributors": [
@@ -19,6 +19,7 @@
19
19
  "testPerformance": "npm i && cd test/performance/ && ./test.sh",
20
20
  "pretest": "npm run build",
21
21
  "test": "npm run testCJS && npm run testMJS",
22
+ "build:dockerTest": "npm run build && docker build -t oastlm-test-ks-api -f ./test/performance/ks-api/Dockerfile .",
22
23
  "testCJS": "npm run preTestCJS && npm run launchTestCJS && npm run postTestCJS",
23
24
  "preTestCJS": "node test/functional/otTestServer.cjs &",
24
25
  "launchTestCJS": "npx -y wait-on http://localhost:3000/api/v1/pets && npm run sendRequests && sleep 4 && npm run checkRequestsLog",
@@ -44,9 +45,11 @@
44
45
  "default": "./src/index.js"
45
46
  },
46
47
  "dependencies": {
48
+ "@opentelemetry/host-metrics": "^0.35.5",
47
49
  "@opentelemetry/instrumentation-http": "^0.51.0",
48
50
  "@opentelemetry/resources": "^1.24.0",
49
51
  "@opentelemetry/sdk-node": "^0.49.1",
52
+ "@seald-io/nedb": "^4.0.4",
50
53
  "axios": "^1.6.8",
51
54
  "cookie-parser": "^1.4.7",
52
55
  "dynamic-installer": "^1.1.1",
@@ -55,7 +58,6 @@
55
58
  "import-from-string": "^0.0.4",
56
59
  "js-yaml": "^4.1.0",
57
60
  "jsonwebtoken": "^9.0.2",
58
- "nedb": "^1.8.0",
59
61
  "readline": "^1.3.0",
60
62
  "v8": "^0.1.0"
61
63
  },
package/src/config.js CHANGED
@@ -1,14 +1,19 @@
1
+ import { metrics } from "@opentelemetry/api";
1
2
  import DynamicExporter from "./exporters/dynamicExporter.js";
3
+ import { InMemoryDBMetricsExporter } from "./exporters/InMemoryDBMetricsExporter.js";
2
4
 
3
5
  //Environment variables
4
6
  //OASTLM_MODULE_DISABLED = 'true' //Disables the module (empty middleware and no tracing)
5
7
 
6
8
  export const globalOasTlmConfig = {
7
9
  dynamicExporter: new DynamicExporter(),
10
+ metricsExporter: new InMemoryDBMetricsExporter(),
11
+ systemMetricsInterval: 1000 * 5, // 5 seconds
8
12
  baseURL: "/telemetry",
9
13
  spec: null,
10
14
  specFileName: "",
11
15
  autoActivate: true,
16
+ authEnabled: false,
12
17
  apiKeyMaxAge: 1000 * 60 * 60, // 1 hour
13
18
  password: "oas-telemetry-password",
14
19
  jwtSecret: "oas-telemetry-secret",
@@ -0,0 +1,30 @@
1
+ import { globalOasTlmConfig } from '../config.js';
2
+
3
+ export const listMetrics = async (req, res) => {
4
+ try {
5
+ const metrics = await globalOasTlmConfig.metricsExporter.getFinishedMetrics();
6
+ res.send({ metricsCount: metrics.length, metrics: metrics });
7
+ } catch (err) {
8
+ console.error(err);
9
+ res.status(500).send({ error: 'Failed to list metrics data' });
10
+ }
11
+ }
12
+
13
+ export const findMetrics = (req, res) => {
14
+ const body = req.body;
15
+ const search = body?.search ? body.search : {};
16
+ globalOasTlmConfig.metricsExporter.find(search, (err, docs) => {
17
+ if (err) {
18
+ console.error(err);
19
+ res.status(404).send({ metricsCount: 0, metrics: [], error: err });
20
+ return;
21
+ }
22
+ const metrics = docs;
23
+ res.send({ metricsCount: metrics.length, metrics: metrics });
24
+ });
25
+ }
26
+
27
+ export const resetMetrics = (req, res) => {
28
+ globalOasTlmConfig.metricsExporter.reset();
29
+ res.send('Metrics reset');
30
+ }
@@ -55,6 +55,7 @@ export const findTelemetry = (req, res) => {
55
55
  res.status(404).send({ spansCount: 0, spans: [], error: e });
56
56
  return;
57
57
  }
58
+ }
58
59
  globalOasTlmConfig.dynamicExporter.exporter.find(search,(err, docs) => {
59
60
  if (err) {
60
61
  console.error(err);
@@ -64,5 +65,5 @@ export const findTelemetry = (req, res) => {
64
65
  const spans = docs;
65
66
  res.send({ spansCount: spans.length, spans: spans });
66
67
  });
67
- }
68
+
68
69
  }
@@ -0,0 +1,111 @@
1
+ import { ExportResultCode } from '@opentelemetry/core';
2
+ import dataStore from '@seald-io/nedb';
3
+
4
+ export class InMemoryDBMetricsExporter {
5
+ constructor() {
6
+ this._metrics = new dataStore();
7
+ this._stopped = false;
8
+ }
9
+
10
+ export(metrics, resultCallback) {
11
+ try {
12
+ if (!this._stopped) {
13
+ // metrics = metrics?.scopeMetrics;
14
+ // const cleanMetrics = metrics.map(metric => applyNesting(metric));
15
+ this._metrics.insert(metrics, (err, newDoc) => {
16
+ if (err) {
17
+ console.error('Insertion Error:', err);
18
+ return;
19
+ }
20
+ });
21
+ }
22
+ setTimeout(() => resultCallback({ code: ExportResultCode.SUCCESS }), 0);
23
+ } catch (error) {
24
+ console.error('Error exporting metrics\n' + error.message + '\n' + error.stack);
25
+ return resultCallback({
26
+ code: ExportResultCode.FAILED,
27
+ error: new Error('Error exporting metrics\n' + error.message + '\n' + error.stack),
28
+ });
29
+ }
30
+ }
31
+
32
+ start() {
33
+ this._stopped = false;
34
+ }
35
+
36
+ stop() {
37
+ this._stopped = true;
38
+ }
39
+
40
+ isRunning() {
41
+ return !this._stopped;
42
+ }
43
+
44
+ shutdown() {
45
+ this._stopped = true;
46
+ this._metrics = new dataStore();
47
+ return this.forceFlush();
48
+ }
49
+
50
+ forceFlush() {
51
+ return Promise.resolve();
52
+ }
53
+
54
+ find(search, callback) {
55
+ this._metrics.find(search, callback);
56
+ }
57
+
58
+ reset() {
59
+ this._metrics = new dataStore();
60
+ }
61
+
62
+ getFinishedMetrics() {
63
+ return this._metrics.getAllData();
64
+ }
65
+ }
66
+
67
+ function convertToNestedObject(obj) {
68
+ const result = {};
69
+
70
+ for (const key in obj) {
71
+ const keys = key.split('.');
72
+ let temp = result;
73
+
74
+ for (let i = 0; i < keys.length; i++) {
75
+ const currentKey = keys[i];
76
+
77
+ if (i === keys.length - 1) {
78
+ // Last key, set the value
79
+ temp[currentKey] = obj[key];
80
+ } else {
81
+ // Intermediate key, ensure the object exists
82
+ if (!temp[currentKey]) {
83
+ temp[currentKey] = {};
84
+ }
85
+ temp = temp[currentKey];
86
+ }
87
+ }
88
+ }
89
+
90
+ return result;
91
+ }
92
+
93
+ /**
94
+ * Applies nesting to all dot-separated keys within an object.
95
+ *
96
+ * @param {Object} obj - The object to apply nesting to.
97
+ * @returns {Object} - The transformed object with nested structures.
98
+ */
99
+ function applyNesting(obj) {
100
+
101
+
102
+ for (const key in obj) {
103
+ if (typeof obj[key] === 'object' && obj[key] !== null) {
104
+ obj[key] = applyNesting(obj[key]);
105
+ }
106
+ }
107
+
108
+
109
+ return obj;
110
+ }
111
+
@@ -6,7 +6,7 @@ if (process.env.OTDEBUG == "true")
6
6
  dbglog = console.log;
7
7
 
8
8
  //import in memory database
9
- import dataStore from 'nedb';
9
+ import dataStore from '@seald-io/nedb';
10
10
 
11
11
  export class InMemoryExporter {
12
12
  constructor() {
package/src/index.js CHANGED
@@ -6,6 +6,7 @@ import { authMiddleware } from './middleware/authMiddleware.js';
6
6
  import authRoutes from './routes/authRoutes.js';
7
7
  import { telemetryRoutes } from './routes/telemetryRoutes.js';
8
8
  import { InMemoryExporter } from './exporters/InMemoryDbExporter.js';
9
+ import metricsRoutes from './routes/metricsRoutes.js';
9
10
 
10
11
 
11
12
  let dbglog = () => { };
@@ -22,6 +23,7 @@ if (process.env.OTDEBUG == "true")
22
23
  * @param {Object} [OasTlmConfig.spec] The OpenAPI spec object.
23
24
  * @param {string} [OasTlmConfig.specFileName] Alternative to `spec`: the path to the OpenAPI spec file.
24
25
  * @param {boolean} [OasTlmConfig.autoActivate=true] Whether to start telemetry automatically on load.
26
+ * @param {boolean} [OasTlmConfig.authEnabled=true] Whether to enable authentication middleware.
25
27
  * @param {number} [OasTlmConfig.apiKeyMaxAge=1800000] The maximum age of the API key in milliseconds.
26
28
  * @param {string} [OasTlmConfig.defaultApiKey] The default API key to use.
27
29
  * @param {OasTlmExporter} [OasTlmConfig.exporter=InMemoryExporter] The exporter to use. Must implement the `OasTlmExporter` interface.
@@ -51,13 +53,12 @@ export default function oasTelemetry(OasTlmConfig) {
51
53
  console.error("No spec available !");
52
54
  }
53
55
  }
54
-
55
- router.use(cookieParser());
56
+ let allAuthMiddlewares = getWrappedMiddlewares(() => globalOasTlmConfig.authEnabled, [cookieParser(),authRoutes,authMiddleware]);
56
57
  const baseURL = globalOasTlmConfig.baseURL;
57
58
  router.use(json());
58
- router.use(baseURL, authRoutes);
59
- router.use(baseURL, authMiddleware); // Add the auth middleware
59
+ router.use(baseURL, allAuthMiddlewares);
60
60
  router.use(baseURL, telemetryRoutes);
61
+ router.use(baseURL + "/metrics", metricsRoutes);
61
62
 
62
63
  if (globalOasTlmConfig.autoActivate) {
63
64
  globalOasTlmConfig.dynamicExporter.exporter?.start();
@@ -67,7 +68,6 @@ export default function oasTelemetry(OasTlmConfig) {
67
68
  }
68
69
 
69
70
 
70
-
71
71
  /**
72
72
  * @typedef OasTlmExporter
73
73
  * Represents an exporter that processes and manages telemetry data.
@@ -83,3 +83,32 @@ export default function oasTelemetry(OasTlmConfig) {
83
83
  * @method {Promise<void>} forceFlush() Exports any pending data that has not yet been processed.
84
84
  * @property {Array} plugins An array of plugins that can be activated by the exporter.
85
85
  */
86
+
87
+ /**
88
+ * This function wraps the provided middleware functions with a condition callback.
89
+ * If the condition callback returns true, the middleware/router will be executed.
90
+ * If the condition callback returns false, the middleware/router will be skipped.
91
+ *
92
+ * @callback {function} conditionCallback A callback function that returns a boolean to determine if the middleware should be used.
93
+ * @param {Array} middlewares An array of middleware or routers to be wrapped.
94
+ * @returns {Array} An array of wrapped middleware functions.
95
+ */
96
+ function getWrappedMiddlewares(conditionCallback, middlewares) {
97
+ return middlewares.map(middleware => {
98
+ return function (req, res, next) {
99
+ if (conditionCallback()) {
100
+ if (typeof middleware === 'function') {
101
+ // look for handle property, if it exists, it's a router. If not call middleware
102
+ if (middleware.handle) {
103
+ middleware.handle(req, res, next);
104
+ } else {
105
+ middleware(req, res, next);
106
+ }
107
+ }
108
+ } else {
109
+ next();
110
+ }
111
+ };
112
+ }
113
+ );
114
+ }
@@ -1,22 +1,58 @@
1
-
2
1
  import { NodeSDK } from '@opentelemetry/sdk-node';
3
2
  // import { getNodeAutoInstrumentations } from '@opentelemetry/auto-instrumentations-node';
4
3
  import { Resource } from '@opentelemetry/resources';
5
4
  import { HttpInstrumentation } from '@opentelemetry/instrumentation-http';
6
5
  import { globalOasTlmConfig } from './config.js';
6
+ import { getCpuUsageData, getProcessCpuUsageData, getMemoryData, getProcessMemoryData } from './systemMetrics.js'; // Import system metrics functions
7
+
8
+ // DynamicExporter allows changing to any exporter at runtime;
9
+ const traceExporter = globalOasTlmConfig.dynamicExporter;
10
+ // Alternative 1: Using NodeSDK
11
+ const sdk = new NodeSDK({
12
+ resource: new Resource({
13
+ service: 'oas-telemetry-service'
14
+ }),
15
+ traceExporter,
16
+ instrumentations: [new HttpInstrumentation()]
17
+ });
18
+
19
+
20
+ // Collect and export system metrics
21
+ setInterval(() => {
22
+ const cpuUsageData = getCpuUsageData();
23
+ const processCpuUsageData = getProcessCpuUsageData();
24
+ const memoryData = getMemoryData();
25
+ const processMemoryData = getProcessMemoryData();
26
+
27
+ const metrics = {
28
+ timestamp: Date.now(),
29
+ cpuUsageData,
30
+ processCpuUsageData,
31
+ memoryData,
32
+ processMemoryData,
33
+ };
34
+
35
+ // Export the collected metrics using the InMemoryDBMetricsExporter
36
+ const inMemoryDbMetricExporter = globalOasTlmConfig.metricsExporter;
37
+ inMemoryDbMetricExporter.export(metrics, (result) => {});
38
+ }, globalOasTlmConfig.systemMetricsInterval);
7
39
 
40
+ console.log('✅ OpenTelemetry System Metrics initialized.');
8
41
 
9
- // DynamicExporter allows changing to any exporter at runtime;
10
- const traceExporter = globalOasTlmConfig.dynamicExporter;
42
+ if (process.env.OASTLM_MODULE_DISABLED !== 'true') {
43
+ sdk.start()
44
+ }
11
45
 
12
- const sdk = new NodeSDK({
13
- resource: new Resource({
14
- service: 'oas-telemetry-service'
15
- }),
16
- traceExporter,
17
- instrumentations: [new HttpInstrumentation()]
18
- });
46
+ // Alternative 2:
47
+ // const provider = new NodeTracerProvider();
48
+ // provider.addSpanProcessor(new SimpleSpanProcessor(traceExporter));
19
49
 
20
- if (process.env.OASTLM_MODULE_DISABLED !== 'true') {
21
- sdk.start()
22
- }
50
+ // if (process.env.OASTLM_MODULE_DISABLED !== 'true') {
51
+ // provider.register();
52
+ // registerInstrumentations({
53
+ // instrumentations: [
54
+ // new HttpInstrumentation(),
55
+ // new ExpressInstrumentation(),
56
+ // ],
57
+ // });
58
+ // }
@@ -0,0 +1,15 @@
1
+ import { Router } from 'express';
2
+ import {
3
+ listMetrics,
4
+ findMetrics,
5
+ resetMetrics
6
+ } from '../controllers/metricsController.js';
7
+
8
+ export const metricsRoutes = Router();
9
+
10
+ // Metrics Control
11
+ metricsRoutes.get('/', listMetrics);
12
+ metricsRoutes.post('/find', findMetrics);
13
+ metricsRoutes.get('/reset', resetMetrics);
14
+
15
+ export default metricsRoutes;
@@ -1,17 +1,17 @@
1
-
2
-
3
- // WARNING: This file is autogenerated. DO NOT EDIT!
4
- //This file is autogenerated by dev/ui/exportHtmlToUi.js
5
- const ui = (baseURL) => {
6
- if(!baseURL) return htmlMap;
7
- return Object.keys(htmlMap).reduce((acc, key) => {
8
- acc[key] = htmlMap[key].replace(/\/telemetry/g, baseURL);
9
- return acc;
10
- }, {});
11
- }
12
-
13
- export const htmlMap =
14
- {
1
+
2
+
3
+ // WARNING: This file is autogenerated. DO NOT EDIT!
4
+ //This file is autogenerated by dev/ui/exportHtmlToUi.js
5
+ const ui = (baseURL) => {
6
+ if(!baseURL) return htmlMap;
7
+ return Object.keys(htmlMap).reduce((acc, key) => {
8
+ acc[key] = htmlMap[key].replace(/\/telemetry/g, baseURL);
9
+ return acc;
10
+ }, {});
11
+ }
12
+
13
+ export const htmlMap =
14
+ {
15
15
  detail: `<!DOCTYPE html>
16
16
  <html lang="en">
17
17
 
@@ -632,7 +632,7 @@ detail: `<!DOCTYPE html>
632
632
 
633
633
  </body>
634
634
 
635
- </html>`,
635
+ </html>`,
636
636
  login: `<!DOCTYPE html>
637
637
  <html lang="en">
638
638
  <head>
@@ -813,7 +813,7 @@ login: `<!DOCTYPE html>
813
813
  </script>
814
814
  </body>
815
815
  </html>
816
- `,
816
+ `,
817
817
  main: `<!DOCTYPE html>
818
818
  <html lang="en">
819
819
 
@@ -1513,8 +1513,8 @@ main: `<!DOCTYPE html>
1513
1513
  </script>
1514
1514
  </body>
1515
1515
 
1516
- </html>`,
1517
- };
1518
-
1519
-
1520
- export default ui
1516
+ </html>`,
1517
+ };
1518
+
1519
+
1520
+ export default ui