Skip to content

Commit cc720ce

Browse files
committed
refactor: metrics_rotuer final pass (MORE TESTS REQUIRED)
1 parent 163cb62 commit cc720ce

File tree

3 files changed

+217
-0
lines changed

3 files changed

+217
-0
lines changed

core/database/CMakeLists.txt

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@ if( ENABLE_FOXX_TESTS )
3333
add_test(NAME foxx_task_router COMMAND "${CMAKE_CURRENT_SOURCE_DIR}/tests/test_foxx.sh" -t "unit_task_router:")
3434
add_test(NAME foxx_authz_router COMMAND "${CMAKE_CURRENT_SOURCE_DIR}/tests/test_foxx.sh" -t "unit_authz_router:")
3535
add_test(NAME foxx_query_router COMMAND "${CMAKE_CURRENT_SOURCE_DIR}/tests/test_foxx.sh" -t "unit_query_router:")
36+
add_test(NAME foxx_metrics_router COMMAND "${CMAKE_CURRENT_SOURCE_DIR}/tests/test_foxx.sh" -t "unit_metrics_router:")
3637
add_test(NAME foxx_unit_user_token COMMAND "${CMAKE_CURRENT_SOURCE_DIR}/tests/test_foxx.sh" -t "unit_user_token:")
3738
add_test(NAME foxx_unit_user_model COMMAND "${CMAKE_CURRENT_SOURCE_DIR}/tests/test_foxx.sh" -t "unit_user_model:")
3839
add_test(NAME foxx_unit_globus_collection_model COMMAND "${CMAKE_CURRENT_SOURCE_DIR}/tests/test_foxx.sh" -t "unit_globus_collection_model:")
@@ -55,6 +56,7 @@ if( ENABLE_FOXX_TESTS )
5556
set_tests_properties(foxx_validation_repo PROPERTIES FIXTURES_REQUIRED Foxx)
5657
set_tests_properties(foxx_path PROPERTIES FIXTURES_REQUIRED Foxx)
5758
set_tests_properties(foxx_user_router PROPERTIES FIXTURES_REQUIRED "Foxx;FoxxDBFixtures")
59+
set_tests_properties(foxx_metrics_router PROPERTIES FIXTURES_REQUIRED Foxx)
5860
set_tests_properties(foxx_version_router PROPERTIES FIXTURES_REQUIRED Foxx)
5961
set_tests_properties(foxx_tag_router PROPERTIES FIXTURES_REQUIRED Foxx)
6062
set_tests_properties(foxx_query_router PROPERTIES FIXTURES_REQUIRED Foxx)

core/database/foxx/api/metrics_router.js

Lines changed: 119 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,12 +5,23 @@ const router = createRouter();
55
const g_db = require("@arangodb").db;
66
const g_lib = require("./support");
77
const joi = require("joi");
8+
const logger = require("./lib/logger");
89

910
module.exports = router;
1011

12+
const basePath = "metrics";
1113
router
1214
.post("/msg_count/update", function (req, res) {
15+
const client = g_lib.getUserFromClientID(req.queryParams.client);
1316
try {
17+
logger.logRequestStarted({
18+
client: client?._id,
19+
correlationId: req.headers["x-correlation-id"],
20+
httpVerb: "GET",
21+
routePath: basePath + "/msg_count/update",
22+
status: "Started",
23+
description: "Update message metrics",
24+
});
1425
var i,
1526
u,
1627
ts = req.body.timestamp,
@@ -33,7 +44,26 @@ router
3344
};
3445
g_db.metrics.save(obj);
3546
}
47+
logger.logRequestSuccess({
48+
client: client?._id,
49+
correlationId: req.headers["x-correlation-id"],
50+
httpVerb: "GET",
51+
routePath: basePath + "/msg_count/update",
52+
status: "Success",
53+
description: "Update message metrics",
54+
extra: obj,
55+
});
3656
} catch (e) {
57+
logger.logRequestFailure({
58+
client: client?._id,
59+
correlationId: req.headers["x-correlation-id"],
60+
httpVerb: "GET",
61+
routePath: basePath + "/msg_count/update",
62+
status: "Failure",
63+
description: "Update message metrics",
64+
extra: obj,
65+
error: e,
66+
});
3767
g_lib.handleException(e, res);
3868
}
3969
})
@@ -43,7 +73,16 @@ router
4373

4474
router
4575
.get("/msg_count", function (req, res) {
76+
const client = g_lib.getUserFromClientID(req.queryParams.client);
4677
try {
78+
logger.logRequestStarted({
79+
client: client?._id,
80+
correlationId: req.headers["x-correlation-id"],
81+
httpVerb: "GET",
82+
routePath: basePath + "/msg_count",
83+
status: "Started",
84+
description: "Update message metrics",
85+
});
4786
var par = {
4887
now: Date.now() / 1000,
4988
since: 60 * (req.queryParams.since ? req.queryParams.since : 60),
@@ -71,7 +110,26 @@ router
71110
}
72111

73112
res.send(result);
113+
logger.logRequestSuccess({
114+
client: client?._id,
115+
correlationId: req.headers["x-correlation-id"],
116+
httpVerb: "GET",
117+
routePath: basePath + "/msg_count",
118+
status: "Success",
119+
description: "Update message metrics",
120+
extra: result,
121+
});
74122
} catch (e) {
123+
logger.logRequestFailure({
124+
client: client?._id,
125+
correlationId: req.headers["x-correlation-id"],
126+
httpVerb: "GET",
127+
routePath: basePath + "/msg_count",
128+
status: "Failure",
129+
description: "Update message metrics",
130+
extra: result,
131+
error: e,
132+
});
75133
g_lib.handleException(e, res);
76134
}
77135
})
@@ -87,7 +145,19 @@ router
87145

88146
router
89147
.get("/users/active", function (req, res) {
148+
const client = req.queryParams.client
149+
? g_lib.getUserFromClientID(req.queryParams.client)
150+
: null;
90151
try {
152+
logger.logRequestStarted({
153+
client: client?._id,
154+
correlationId: req.headers["x-correlation-id"],
155+
httpVerb: "GET",
156+
routePath: basePath + "/users/active",
157+
status: "Started",
158+
description: "Get recently active users from metrics",
159+
});
160+
91161
var cnt = {},
92162
u,
93163
r,
@@ -111,7 +181,27 @@ router
111181
}
112182

113183
res.json(cnt);
184+
logger.logRequestSuccess({
185+
client: client?._id,
186+
correlationId: req.headers["x-correlation-id"],
187+
httpVerb: "GET",
188+
routePath: basePath + "/users/active",
189+
status: "Success",
190+
description: "Get recently active users from metrics",
191+
extra: cnt,
192+
});
114193
} catch (e) {
194+
logger.logRequestFailure({
195+
client: client?._id,
196+
correlationId: req.headers["x-correlation-id"],
197+
httpVerb: "GET",
198+
routePath: basePath + "/users/active",
199+
status: "Failure",
200+
description: "Get recently active users from metrics",
201+
extra: cnt,
202+
error: e,
203+
});
204+
115205
g_lib.handleException(e, res);
116206
}
117207
})
@@ -125,7 +215,17 @@ router
125215

126216
router
127217
.post("/purge", function (req, res) {
218+
const client = g_lib.getUserFromClientID(req.queryParams.client);
128219
try {
220+
logger.logRequestStarted({
221+
client: client?._id,
222+
correlationId: req.headers["x-correlation-id"],
223+
httpVerb: "GET",
224+
routePath: basePath + "/purge",
225+
status: "Started",
226+
description: "Purge older metrics",
227+
});
228+
129229
g_db.metrics.save({
130230
timestamp: Math.floor(Date.now() / 1000),
131231
type: "purge",
@@ -135,7 +235,26 @@ router
135235
g_db._query("for i in metrics filter i.timestamp < @ts remove i in metrics", {
136236
ts: req.queryParams.timestamp,
137237
});
238+
logger.logRequestSuccess({
239+
client: client?._id,
240+
correlationId: req.headers["x-correlation-id"],
241+
httpVerb: "GET",
242+
routePath: basePath + "/purge",
243+
status: "Success",
244+
description: "Purge older metrics",
245+
extra: "undefined",
246+
});
138247
} catch (e) {
248+
logger.logRequestFailure({
249+
client: client?._id,
250+
correlationId: req.headers["x-correlation-id"],
251+
httpVerb: "GET",
252+
routePath: basePath + "/purge",
253+
status: "Failure",
254+
description: "Purge older metrics",
255+
extra: "undefined",
256+
error: e,
257+
});
139258
g_lib.handleException(e, res);
140259
}
141260
})
Lines changed: 96 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,96 @@
1+
"use strict";
2+
3+
const g_lib = require("../api/support");
4+
const { expect } = require("chai");
5+
const request = require("@arangodb/request");
6+
const { baseUrl } = module.context;
7+
const { db } = require("@arangodb");
8+
9+
const metrics_base_url = `${baseUrl}/metrics`;
10+
11+
describe("unit_metrics_router: /users/active endpoint", () => {
12+
after(function () {
13+
const collections = ["metrics"];
14+
collections.forEach((name) => {
15+
let col = db._collection(name);
16+
if (col) col.truncate();
17+
});
18+
});
19+
beforeEach(() => {
20+
const collections = ["metrics"];
21+
collections.forEach((name) => {
22+
let col = db._collection(name);
23+
if (col) {
24+
col.truncate();
25+
} else {
26+
db._create(name);
27+
}
28+
});
29+
});
30+
31+
it("should return active users within the default 15 minutes", () => {
32+
const now = Math.floor(Date.now() / 1000);
33+
34+
db.metrics.save([
35+
{
36+
_key: "m1",
37+
type: "msgcnt_user",
38+
uid: "u/fakeUser",
39+
total: 5,
40+
timestamp: now - 60 * 5, // 5 minutes ago
41+
},
42+
{
43+
_key: "m2",
44+
type: "msgcnt_user",
45+
uid: "u/otherUser",
46+
total: 10,
47+
timestamp: now - 60 * 20, // 20 minutes ago
48+
},
49+
]);
50+
51+
const request_string = `${metrics_base_url}/users/active`;
52+
const response = request.get(request_string);
53+
54+
expect(response.status).to.equal(200);
55+
56+
const body = JSON.parse(response.body);
57+
58+
// u/fakeUser should appear, u/otherUser should not
59+
expect(body).to.have.property("u/fakeUser");
60+
expect(body["u/fakeUser"]).to.equal(5);
61+
expect(body).to.not.have.property("u/otherUser");
62+
});
63+
64+
it("should respect the 'since' query parameter", () => {
65+
const now = Math.floor(Date.now() / 1000);
66+
67+
db.metrics.save([
68+
{
69+
_key: "m3",
70+
type: "msgcnt_user",
71+
uid: "u/fakeUser",
72+
total: 7,
73+
timestamp: now - 60 * 30, // 30 minutes ago
74+
},
75+
]);
76+
77+
// since=45 → include 30-min-old record
78+
let response = request.get(`${metrics_base_url}/users/active?since=45`);
79+
expect(response.status).to.equal(200);
80+
let body = JSON.parse(response.body);
81+
expect(body).to.have.property("u/fakeUser");
82+
83+
// since=15 → exclude 30-min-old record
84+
response = request.get(`${metrics_base_url}/users/active?since=15`);
85+
expect(response.status).to.equal(200);
86+
body = JSON.parse(response.body);
87+
expect(body).to.not.have.property("u/fakeUser");
88+
});
89+
90+
it("should return an empty object if no users are active", () => {
91+
const response = request.get(`${metrics_base_url}/users/active`);
92+
expect(response.status).to.equal(200);
93+
const body = JSON.parse(response.body);
94+
expect(body).to.deep.equal({});
95+
});
96+
});

0 commit comments

Comments
 (0)