@uber-clone/common 1.0.5 → 1.0.6
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/build/index.d.ts +1 -0
- package/build/index.js +1 -0
- package/build/metrics/app.metrics.d.ts +5 -0
- package/build/metrics/app.metrics.js +113 -0
- package/build/utils/logger.d.ts +8 -0
- package/build/utils/logger.js +42 -0
- package/package.json +3 -2
package/build/index.d.ts
CHANGED
package/build/index.js
CHANGED
|
@@ -29,3 +29,4 @@ __exportStar(require("./middlewares/validate-request"), exports);
|
|
|
29
29
|
__exportStar(require("./events/kafka-client"), exports);
|
|
30
30
|
__exportStar(require("./events/types"), exports);
|
|
31
31
|
__exportStar(require("./events/subjects"), exports);
|
|
32
|
+
__exportStar(require("./metrics/app.metrics"), exports);
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
import { Request, Response, NextFunction } from "express";
|
|
2
|
+
export declare const metricsMiddleware: (req: Request, res: Response, next: NextFunction) => void;
|
|
3
|
+
export declare const metricsEndpoint: (req: Request, res: Response) => Promise<void>;
|
|
4
|
+
export declare const trackDatabaseQuery: <T>(operation: string, collection: string, query: () => Promise<T>) => Promise<T>;
|
|
5
|
+
export declare const trackRedisOperation: <T>(operation: string, redisOp: () => Promise<T>) => Promise<T>;
|
|
@@ -0,0 +1,113 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
|
3
|
+
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
4
|
+
return new (P || (P = Promise))(function (resolve, reject) {
|
|
5
|
+
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
|
6
|
+
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
|
7
|
+
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
|
8
|
+
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
9
|
+
});
|
|
10
|
+
};
|
|
11
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
12
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
13
|
+
};
|
|
14
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
15
|
+
exports.trackRedisOperation = exports.trackDatabaseQuery = exports.metricsEndpoint = exports.metricsMiddleware = void 0;
|
|
16
|
+
const prom_client_1 = __importDefault(require("prom-client"));
|
|
17
|
+
// Create a Registry
|
|
18
|
+
const register = new prom_client_1.default.Registry();
|
|
19
|
+
// Add default metrics (CPU, memory, etc.)
|
|
20
|
+
prom_client_1.default.collectDefaultMetrics({ register });
|
|
21
|
+
// Custom Metrics
|
|
22
|
+
const httpRequestDuration = new prom_client_1.default.Histogram({
|
|
23
|
+
name: "http_request_duration_seconds",
|
|
24
|
+
help: "Duration of HTTP requests in seconds",
|
|
25
|
+
labelNames: ["method", "route", "status_code"],
|
|
26
|
+
buckets: [0.1, 0.5, 1, 2, 5],
|
|
27
|
+
registers: [register],
|
|
28
|
+
});
|
|
29
|
+
const httpRequestTotal = new prom_client_1.default.Counter({
|
|
30
|
+
name: "http_requests_total",
|
|
31
|
+
help: "Total number of HTTP requests",
|
|
32
|
+
labelNames: ["method", "route", "status_code"],
|
|
33
|
+
registers: [register],
|
|
34
|
+
});
|
|
35
|
+
const activeConnections = new prom_client_1.default.Gauge({
|
|
36
|
+
name: "active_connections",
|
|
37
|
+
help: "Number of active connections",
|
|
38
|
+
registers: [register],
|
|
39
|
+
});
|
|
40
|
+
const databaseQueryDuration = new prom_client_1.default.Histogram({
|
|
41
|
+
name: "database_query_duration_seconds",
|
|
42
|
+
help: "Duration of database queries in seconds",
|
|
43
|
+
labelNames: ["operation", "collection"],
|
|
44
|
+
buckets: [0.01, 0.05, 0.1, 0.5, 1],
|
|
45
|
+
registers: [register],
|
|
46
|
+
});
|
|
47
|
+
const redisOperationDuration = new prom_client_1.default.Histogram({
|
|
48
|
+
name: "redis_operation_duration_seconds",
|
|
49
|
+
help: "Duration of Redis operations in seconds",
|
|
50
|
+
labelNames: ["operation", "status"],
|
|
51
|
+
buckets: [0.001, 0.005, 0.01, 0.05, 0.1],
|
|
52
|
+
registers: [register],
|
|
53
|
+
});
|
|
54
|
+
// Middleware to track HTTP metrics
|
|
55
|
+
const metricsMiddleware = (req, res, next) => {
|
|
56
|
+
const start = Date.now();
|
|
57
|
+
activeConnections.inc();
|
|
58
|
+
res.on("finish", () => {
|
|
59
|
+
var _a;
|
|
60
|
+
const duration = (Date.now() - start) / 1000;
|
|
61
|
+
const route = ((_a = req.route) === null || _a === void 0 ? void 0 : _a.path) || req.path;
|
|
62
|
+
httpRequestDuration.observe({
|
|
63
|
+
method: req.method,
|
|
64
|
+
route: route,
|
|
65
|
+
status_code: res.statusCode,
|
|
66
|
+
}, duration);
|
|
67
|
+
httpRequestTotal.inc({
|
|
68
|
+
method: req.method,
|
|
69
|
+
route: route,
|
|
70
|
+
status_code: res.statusCode,
|
|
71
|
+
});
|
|
72
|
+
activeConnections.dec();
|
|
73
|
+
});
|
|
74
|
+
next();
|
|
75
|
+
};
|
|
76
|
+
exports.metricsMiddleware = metricsMiddleware;
|
|
77
|
+
// Metrics endpoint
|
|
78
|
+
const metricsEndpoint = (req, res) => __awaiter(void 0, void 0, void 0, function* () {
|
|
79
|
+
res.set("Content-Type", register.contentType);
|
|
80
|
+
const metrics = yield register.metrics();
|
|
81
|
+
res.end(metrics);
|
|
82
|
+
});
|
|
83
|
+
exports.metricsEndpoint = metricsEndpoint;
|
|
84
|
+
// Helper functions to track operations
|
|
85
|
+
const trackDatabaseQuery = (operation, collection, query) => __awaiter(void 0, void 0, void 0, function* () {
|
|
86
|
+
const end = databaseQueryDuration.startTimer({ operation, collection });
|
|
87
|
+
try {
|
|
88
|
+
const result = yield query();
|
|
89
|
+
end();
|
|
90
|
+
return result;
|
|
91
|
+
}
|
|
92
|
+
catch (error) {
|
|
93
|
+
end();
|
|
94
|
+
throw error;
|
|
95
|
+
}
|
|
96
|
+
});
|
|
97
|
+
exports.trackDatabaseQuery = trackDatabaseQuery;
|
|
98
|
+
const trackRedisOperation = (operation, redisOp) => __awaiter(void 0, void 0, void 0, function* () {
|
|
99
|
+
const end = redisOperationDuration.startTimer({
|
|
100
|
+
operation,
|
|
101
|
+
status: "success",
|
|
102
|
+
});
|
|
103
|
+
try {
|
|
104
|
+
const result = yield redisOp();
|
|
105
|
+
end();
|
|
106
|
+
return result;
|
|
107
|
+
}
|
|
108
|
+
catch (error) {
|
|
109
|
+
redisOperationDuration.labels(operation, "error").observe(0);
|
|
110
|
+
throw error;
|
|
111
|
+
}
|
|
112
|
+
});
|
|
113
|
+
exports.trackRedisOperation = trackRedisOperation;
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
exports.Logger = void 0;
|
|
7
|
+
// libs/common/src/utils/logger.ts
|
|
8
|
+
const winston_1 = __importDefault(require("winston"));
|
|
9
|
+
class Logger {
|
|
10
|
+
constructor(service) {
|
|
11
|
+
this.logger = winston_1.default.createLogger({
|
|
12
|
+
level: process.env.LOG_LEVEL || "info",
|
|
13
|
+
format: winston_1.default.format.combine(winston_1.default.format.timestamp(), winston_1.default.format.errors({ stack: true }), winston_1.default.format.json()),
|
|
14
|
+
defaultMeta: { service },
|
|
15
|
+
transports: [
|
|
16
|
+
new winston_1.default.transports.Console({
|
|
17
|
+
format: winston_1.default.format.combine(winston_1.default.format.colorize(), winston_1.default.format.simple()),
|
|
18
|
+
}),
|
|
19
|
+
new winston_1.default.transports.File({
|
|
20
|
+
filename: "logs/error.log",
|
|
21
|
+
level: "error",
|
|
22
|
+
}),
|
|
23
|
+
new winston_1.default.transports.File({
|
|
24
|
+
filename: "logs/combined.log",
|
|
25
|
+
}),
|
|
26
|
+
],
|
|
27
|
+
});
|
|
28
|
+
}
|
|
29
|
+
info(message, meta) {
|
|
30
|
+
this.logger.info(message, meta);
|
|
31
|
+
}
|
|
32
|
+
error(message, error) {
|
|
33
|
+
this.logger.error(message, { error });
|
|
34
|
+
}
|
|
35
|
+
warn(message, meta) {
|
|
36
|
+
this.logger.warn(message, meta);
|
|
37
|
+
}
|
|
38
|
+
debug(message, meta) {
|
|
39
|
+
this.logger.debug(message, meta);
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
exports.Logger = Logger;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@uber-clone/common",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.6",
|
|
4
4
|
"main": "./build/index.js",
|
|
5
5
|
"types": "./build/index.d.ts",
|
|
6
6
|
"files": [
|
|
@@ -28,6 +28,7 @@
|
|
|
28
28
|
"express-validator": "^7.2.1",
|
|
29
29
|
"jsonwebtoken": "^9.0.2",
|
|
30
30
|
"kafkajs": "^2.2.4",
|
|
31
|
-
"
|
|
31
|
+
"prom-client": "^15.1.3",
|
|
32
|
+
"winston": "^3.18.3"
|
|
32
33
|
}
|
|
33
34
|
}
|