@heyhru/app-dms-server 0.6.0 → 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.
- package/dist/index.js +51 -1
- package/package.json +10 -9
package/dist/index.js
CHANGED
|
@@ -4,6 +4,42 @@ import { createPgDb } from "@heyhru/server-plugin-pg";
|
|
|
4
4
|
// src/app.ts
|
|
5
5
|
import Fastify from "fastify";
|
|
6
6
|
import cors from "@fastify/cors";
|
|
7
|
+
import { metricsPlugin } from "@heyhru/server-plugin-metrics";
|
|
8
|
+
|
|
9
|
+
// src/metrics.ts
|
|
10
|
+
import { Histogram, Counter, Gauge, register } from "@heyhru/server-plugin-metrics";
|
|
11
|
+
import { getPoolStats } from "@heyhru/business-dms-datasource";
|
|
12
|
+
var sqlDuration = new Histogram({
|
|
13
|
+
name: "dms_sql_duration_seconds",
|
|
14
|
+
help: "SQL execution duration in seconds",
|
|
15
|
+
labelNames: ["data_source_id", "sql_type", "status"],
|
|
16
|
+
buckets: [0.1, 0.5, 1, 2, 5, 10, 30],
|
|
17
|
+
registers: [register]
|
|
18
|
+
});
|
|
19
|
+
var authLoginTotal = new Counter({
|
|
20
|
+
name: "dms_auth_login_total",
|
|
21
|
+
help: "Total login attempts",
|
|
22
|
+
labelNames: ["status"],
|
|
23
|
+
registers: [register]
|
|
24
|
+
});
|
|
25
|
+
var dbPoolActive = new Gauge({
|
|
26
|
+
name: "dms_db_pool_active",
|
|
27
|
+
help: "Active connections per data source pool",
|
|
28
|
+
labelNames: ["data_source_id"],
|
|
29
|
+
registers: [register]
|
|
30
|
+
});
|
|
31
|
+
var dbPoolWaiting = new Gauge({
|
|
32
|
+
name: "dms_db_pool_waiting",
|
|
33
|
+
help: "Waiting requests per data source pool",
|
|
34
|
+
labelNames: ["data_source_id"],
|
|
35
|
+
registers: [register]
|
|
36
|
+
});
|
|
37
|
+
function refreshPoolMetrics() {
|
|
38
|
+
for (const { dataSourceId, active, waiting } of getPoolStats()) {
|
|
39
|
+
if (active !== null) dbPoolActive.set({ data_source_id: dataSourceId }, active);
|
|
40
|
+
if (waiting !== null) dbPoolWaiting.set({ data_source_id: dataSourceId }, waiting);
|
|
41
|
+
}
|
|
42
|
+
}
|
|
7
43
|
|
|
8
44
|
// src/auth/auth.middleware.ts
|
|
9
45
|
import { verifyToken as jwtVerify } from "@heyhru/server-plugin-jwt";
|
|
@@ -122,10 +158,12 @@ async function authLogin(req, reply) {
|
|
|
122
158
|
const user = await getUserByUsername(username);
|
|
123
159
|
if (!user || !await verifyPassword(password, user.password_hash)) {
|
|
124
160
|
req.log.warn("Login failed for user: %s", username);
|
|
161
|
+
authLoginTotal.inc({ status: "fail" });
|
|
125
162
|
return reply.code(401).send({ error: "\u7528\u6237\u540D\u6216\u5BC6\u7801\u9519\u8BEF" });
|
|
126
163
|
}
|
|
127
164
|
const payload = { id: user.id, username: user.username, role: user.role };
|
|
128
165
|
const token = signToken(payload, config.jwtSecret, config.jwtExpiresIn);
|
|
166
|
+
authLoginTotal.inc({ status: "success" });
|
|
129
167
|
req.log.info("User logged in: %s", username);
|
|
130
168
|
return reply.send({ ...payload, token });
|
|
131
169
|
}
|
|
@@ -237,7 +275,15 @@ async function sqlExecute({ dataSourceId, database, sql, userId, ip }) {
|
|
|
237
275
|
return ds ? getPool(ds) : null;
|
|
238
276
|
})();
|
|
239
277
|
if (!pool) throw new Error("\u6570\u636E\u6E90\u672A\u627E\u5230");
|
|
240
|
-
const
|
|
278
|
+
const end = sqlDuration.startTimer({ data_source_id: dataSourceId, sql_type: category });
|
|
279
|
+
let rows;
|
|
280
|
+
try {
|
|
281
|
+
rows = await pool.execute(sql);
|
|
282
|
+
end({ status: "success" });
|
|
283
|
+
} catch (err) {
|
|
284
|
+
end({ status: "failed" });
|
|
285
|
+
throw err;
|
|
286
|
+
}
|
|
241
287
|
await writeAuditLog({
|
|
242
288
|
userId,
|
|
243
289
|
dataSourceId,
|
|
@@ -345,6 +391,10 @@ function savedSqlController(app) {
|
|
|
345
391
|
async function buildApp() {
|
|
346
392
|
const app = Fastify({ loggerInstance: logger });
|
|
347
393
|
await app.register(cors, { origin: true, credentials: true });
|
|
394
|
+
await app.register(metricsPlugin);
|
|
395
|
+
app.addHook("onResponse", () => {
|
|
396
|
+
refreshPoolMetrics();
|
|
397
|
+
});
|
|
348
398
|
app.decorateRequest("user", null);
|
|
349
399
|
app.addHook("preHandler", authHook);
|
|
350
400
|
app.addHook("onError", (req, _reply, error, done) => {
|
package/package.json
CHANGED
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
"publishConfig": {
|
|
4
4
|
"access": "public"
|
|
5
5
|
},
|
|
6
|
-
"version": "0.
|
|
6
|
+
"version": "0.7.0",
|
|
7
7
|
"description": "DMS backend API server built on Fastify",
|
|
8
8
|
"type": "module",
|
|
9
9
|
"main": "./dist/index.mjs",
|
|
@@ -19,15 +19,16 @@
|
|
|
19
19
|
},
|
|
20
20
|
"dependencies": {
|
|
21
21
|
"@fastify/cors": "^11.2.0",
|
|
22
|
-
"@heyhru/business-dms-approval": "0.6.
|
|
23
|
-
"@heyhru/business-dms-audit": "0.6.
|
|
24
|
-
"@heyhru/business-dms-datasource": "0.
|
|
25
|
-
"@heyhru/business-dms-saved-sql": "0.6.
|
|
26
|
-
"@heyhru/business-dms-user": "0.6.
|
|
22
|
+
"@heyhru/business-dms-approval": "0.6.1",
|
|
23
|
+
"@heyhru/business-dms-audit": "0.6.1",
|
|
24
|
+
"@heyhru/business-dms-datasource": "0.7.0",
|
|
25
|
+
"@heyhru/business-dms-saved-sql": "0.6.1",
|
|
26
|
+
"@heyhru/business-dms-user": "0.6.1",
|
|
27
27
|
"@heyhru/common-util-logger": "0.6.0",
|
|
28
28
|
"@heyhru/server-plugin-jwt": "0.6.0",
|
|
29
|
-
"@heyhru/server-plugin-
|
|
30
|
-
"@heyhru/server-plugin-
|
|
29
|
+
"@heyhru/server-plugin-metrics": "0.7.0",
|
|
30
|
+
"@heyhru/server-plugin-mysql": "0.7.0",
|
|
31
|
+
"@heyhru/server-plugin-pg": "0.7.0",
|
|
31
32
|
"@heyhru/server-util-crypto": "0.6.0",
|
|
32
33
|
"fastify": "^5.8.4",
|
|
33
34
|
"node-sql-parser": "^5.4.0",
|
|
@@ -41,5 +42,5 @@
|
|
|
41
42
|
"typescript": "^6.0.2",
|
|
42
43
|
"vitest": "^4.1.4"
|
|
43
44
|
},
|
|
44
|
-
"gitHead": "
|
|
45
|
+
"gitHead": "b9097b9ad29ac4c0c3610a39cb0db83f74a11fb8"
|
|
45
46
|
}
|