Skip to content

Commit aec146a

Browse files
authored
Merge pull request #19 from JawherKl/feature/16-add-metrics-api
add new feature CRUD api for metrics process and nodejs server data
2 parents 94e2deb + 7dd77b2 commit aec146a

File tree

5 files changed

+170
-4
lines changed

5 files changed

+170
-4
lines changed

.dependencygraph/setting.json

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
{
2+
"entryFilePath": "index.js",
3+
"alias": false,
4+
"resolveExtensions": [
5+
".js",
6+
".jsx",
7+
".ts",
8+
".tsx",
9+
".vue",
10+
".scss",
11+
".less"
12+
]
13+
}

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -129,3 +129,4 @@ dist
129129
.yarn/install-state.gz
130130
.pnp.*
131131
.clinic/
132+
features.md

controllers/metricsController.js

Lines changed: 107 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,6 @@
1+
const Metrics = require('../models/metrics');
12
const client = require('prom-client');
3+
const jwt = require('jsonwebtoken');
24

35
// Create a Registry to register metrics
46
const register = new client.Registry();
@@ -25,9 +27,113 @@ const trackRequests = (req, res, next) => {
2527
};
2628

2729
// Metrics endpoint handler
30+
/*
2831
const getMetrics = async (req, res) => {
2932
res.set('Content-Type', register.contentType);
3033
res.send(await register.metrics());
3134
};
35+
*/
3236

33-
module.exports = { trackRequests, getMetrics };
37+
const getMetrics = async (req, res) => {
38+
try {
39+
// Get the Authorization header
40+
const authHeader = req.headers['authorization'];
41+
if (!authHeader || !authHeader.startsWith('Bearer ')) {
42+
return res.status(401).json({ error: 'Unauthorized: No token provided' });
43+
}
44+
45+
// Extract the token
46+
const token = authHeader.split(' ')[1];
47+
48+
// Verify and decode the token
49+
const decoded = jwt.verify(token, process.env.JWT_SECRET);
50+
const userId = decoded.userId; // Ensure your JWT payload contains a `userId`
51+
52+
if (!userId) {
53+
return res.status(400).json({ error: 'Invalid token: userId missing' });
54+
}
55+
56+
// Set content type and retrieve metrics
57+
res.set('Content-Type', register.contentType);
58+
const metricsText = await register.metrics();
59+
const metrics = parseMetrics(metricsText); // Helper function to parse metrics.
60+
61+
// Save metrics to the database
62+
await Metrics.saveMetricsToDatabase(userId, metrics);
63+
64+
// Send the metrics as a response
65+
res.set('Content-Type', register.contentType);
66+
res.send(metricsText);
67+
} catch (error) {
68+
console.error("Error in getMetrics:", error);
69+
res.status(500).send({ error: "Failed to process metrics" });
70+
}
71+
};
72+
73+
function parseMetrics(metricsText) {
74+
const lines = metricsText.split("\n");
75+
const metrics = [];
76+
77+
lines.forEach(line => {
78+
// Look for metric lines that follow the format: 'metric_name value'
79+
if (!line.startsWith("#") && line.trim() !== "") {
80+
const [metricName, metricValue] = line.split(/\s+/);
81+
if (metricName && metricValue) {
82+
metrics.push({ metricName, metricValue });
83+
}
84+
}
85+
});
86+
87+
return metrics;
88+
}
89+
90+
91+
const createMetric = async (req, res) => {
92+
const { userId, metricName, metricValue } = req.body;
93+
try {
94+
const metric = await Metrics.create({ userId, metricName, metricValue });
95+
res.status(201).json(metric);
96+
} catch (error) {
97+
res.status(500).json({ error: 'Failed to create metric' });
98+
}
99+
};
100+
101+
const getMetricsByUser = async (req, res) => {
102+
const { userId } = req.params;
103+
try {
104+
const metrics = await Metrics.findByUserId(userId);
105+
res.status(200).json(metrics);
106+
} catch (error) {
107+
res.status(500).json({ error: 'Failed to fetch metrics' });
108+
}
109+
};
110+
111+
const updateMetric = async (req, res) => {
112+
const { id } = req.params;
113+
const { metricName, metricValue } = req.body;
114+
try {
115+
const metric = await Metrics.update(id, { metricName, metricValue });
116+
res.status(200).json(metric);
117+
} catch (error) {
118+
res.status(500).json({ error: 'Failed to update metric' });
119+
}
120+
};
121+
122+
const deleteMetric = async (req, res) => {
123+
const { id } = req.params;
124+
try {
125+
await Metrics.delete(id);
126+
res.status(200).json({ message: 'Metric deleted successfully' });
127+
} catch (error) {
128+
res.status(500).json({ error: 'Failed to delete metric' });
129+
}
130+
};
131+
132+
module.exports = {
133+
trackRequests,
134+
getMetrics,
135+
createMetric,
136+
getMetricsByUser,
137+
updateMetric,
138+
deleteMetric,
139+
};

models/metrics.js

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
const pool = require('../config/db');
2+
3+
class Metrics {
4+
static async create({ userId, metricName, metricValue }) {
5+
const result = await pool.query(
6+
'INSERT INTO metrics (user_id, metric_name, metric_value) VALUES ($1, $2, $3) RETURNING *',
7+
[userId, metricName, metricValue]
8+
);
9+
return result.rows[0];
10+
}
11+
12+
static async findByUserId(userId) {
13+
const result = await pool.query('SELECT * FROM metrics WHERE user_id = $1', [userId]);
14+
return result.rows;
15+
}
16+
17+
static async update(id, { metricName, metricValue }) {
18+
const result = await pool.query(
19+
'UPDATE metrics SET metric_name = $1, metric_value = $2, updated_at = NOW() WHERE id = $3 RETURNING *',
20+
[metricName, metricValue, id]
21+
);
22+
return result.rows[0];
23+
}
24+
25+
static async delete(id) {
26+
await pool.query('DELETE FROM metrics WHERE id = $1', [id]);
27+
}
28+
29+
static async saveMetricsToDatabase(userId, metrics) {
30+
for (const metric of metrics) {
31+
const { metricName, metricValue } = metric;
32+
33+
// Use your database library to insert data, e.g., with PostgreSQL:
34+
await pool.query(
35+
"INSERT INTO metrics (user_id, metric_name, metric_value) VALUES ($1, $2, $3)",
36+
[userId, metricName, metricValue]
37+
);
38+
}
39+
}
40+
}
41+
42+
module.exports = Metrics;

routes/metricsRoutes.js

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,13 @@
11
const express = require('express');
2-
const { getMetrics } = require('../controllers/metricsController');
3-
42
const router = express.Router();
3+
const metricsController = require('../controllers/metricsController');
4+
const authenticateToken = require('../middleware/auth');
55

66
// Metrics endpoint
7-
router.get('/', getMetrics);
7+
router.get('/', authenticateToken, metricsController.getMetrics);
8+
router.post('/', authenticateToken, metricsController.createMetric);
9+
router.get('/user/:userId', authenticateToken, metricsController.getMetricsByUser);
10+
router.put('/:id', authenticateToken, metricsController.updateMetric);
11+
router.delete('/:id', authenticateToken, metricsController.deleteMetric);
812

913
module.exports = router;

0 commit comments

Comments
 (0)