@quanticjs/metrics 2.0.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/MetricsController.d.ts +7 -0
- package/dist/MetricsController.js +42 -0
- package/dist/MetricsService.d.ts +13 -0
- package/dist/MetricsService.js +58 -0
- package/dist/PerformanceBehavior.d.ts +10 -0
- package/dist/PerformanceBehavior.js +53 -0
- package/dist/QuanticMetricsModule.d.ts +4 -0
- package/dist/QuanticMetricsModule.js +37 -0
- package/dist/index.d.ts +4 -0
- package/dist/index.js +11 -0
- package/package.json +27 -0
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
|
|
3
|
+
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
4
|
+
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
|
5
|
+
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
|
|
6
|
+
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
7
|
+
};
|
|
8
|
+
var __metadata = (this && this.__metadata) || function (k, v) {
|
|
9
|
+
if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
|
|
10
|
+
};
|
|
11
|
+
var __param = (this && this.__param) || function (paramIndex, decorator) {
|
|
12
|
+
return function (target, key) { decorator(target, key, paramIndex); }
|
|
13
|
+
};
|
|
14
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
15
|
+
exports.MetricsController = void 0;
|
|
16
|
+
const common_1 = require("@nestjs/common");
|
|
17
|
+
const core_1 = require("@quanticjs/core");
|
|
18
|
+
const MetricsService_1 = require("./MetricsService");
|
|
19
|
+
let MetricsController = class MetricsController {
|
|
20
|
+
metrics;
|
|
21
|
+
constructor(metrics) {
|
|
22
|
+
this.metrics = metrics;
|
|
23
|
+
}
|
|
24
|
+
async getMetrics(res) {
|
|
25
|
+
const metricsOutput = await this.metrics.getMetrics();
|
|
26
|
+
res.set('Content-Type', this.metrics.getContentType());
|
|
27
|
+
res.end(metricsOutput);
|
|
28
|
+
}
|
|
29
|
+
};
|
|
30
|
+
exports.MetricsController = MetricsController;
|
|
31
|
+
__decorate([
|
|
32
|
+
(0, common_1.Get)('metrics'),
|
|
33
|
+
__param(0, (0, common_1.Res)()),
|
|
34
|
+
__metadata("design:type", Function),
|
|
35
|
+
__metadata("design:paramtypes", [Object]),
|
|
36
|
+
__metadata("design:returntype", Promise)
|
|
37
|
+
], MetricsController.prototype, "getMetrics", null);
|
|
38
|
+
exports.MetricsController = MetricsController = __decorate([
|
|
39
|
+
(0, core_1.Public)(),
|
|
40
|
+
(0, common_1.Controller)(),
|
|
41
|
+
__metadata("design:paramtypes", [MetricsService_1.MetricsService])
|
|
42
|
+
], MetricsController);
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import { OnModuleInit } from '@nestjs/common';
|
|
2
|
+
import { Registry, Counter, Histogram, Gauge } from 'prom-client';
|
|
3
|
+
export declare class MetricsService implements OnModuleInit {
|
|
4
|
+
readonly registry: Registry<"text/plain; version=0.0.4; charset=utf-8">;
|
|
5
|
+
readonly buildTotal: Counter<"status" | "tech_stack">;
|
|
6
|
+
readonly stageDuration: Histogram<"status" | "stage_type">;
|
|
7
|
+
readonly promptCacheHits: Counter<string>;
|
|
8
|
+
readonly queueDepth: Gauge<"queue">;
|
|
9
|
+
readonly handlerDuration: Histogram<"handler" | "result">;
|
|
10
|
+
onModuleInit(): void;
|
|
11
|
+
getMetrics(): Promise<string>;
|
|
12
|
+
getContentType(): string;
|
|
13
|
+
}
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
|
|
3
|
+
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
4
|
+
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
|
5
|
+
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
|
|
6
|
+
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
7
|
+
};
|
|
8
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
9
|
+
exports.MetricsService = void 0;
|
|
10
|
+
const common_1 = require("@nestjs/common");
|
|
11
|
+
const prom_client_1 = require("prom-client");
|
|
12
|
+
let MetricsService = class MetricsService {
|
|
13
|
+
registry = new prom_client_1.Registry();
|
|
14
|
+
buildTotal = new prom_client_1.Counter({
|
|
15
|
+
name: 'arex_build_total',
|
|
16
|
+
help: 'Total number of builds',
|
|
17
|
+
labelNames: ['status', 'tech_stack'],
|
|
18
|
+
registers: [this.registry],
|
|
19
|
+
});
|
|
20
|
+
stageDuration = new prom_client_1.Histogram({
|
|
21
|
+
name: 'arex_stage_duration_seconds',
|
|
22
|
+
help: 'Duration of pipeline stages in seconds',
|
|
23
|
+
labelNames: ['stage_type', 'status'],
|
|
24
|
+
buckets: [0.5, 1, 2, 5, 10, 30, 60, 120, 300],
|
|
25
|
+
registers: [this.registry],
|
|
26
|
+
});
|
|
27
|
+
promptCacheHits = new prom_client_1.Counter({
|
|
28
|
+
name: 'arex_prompt_cache_hits_total',
|
|
29
|
+
help: 'Total prompt cache hits',
|
|
30
|
+
registers: [this.registry],
|
|
31
|
+
});
|
|
32
|
+
queueDepth = new prom_client_1.Gauge({
|
|
33
|
+
name: 'arex_queue_depth',
|
|
34
|
+
help: 'Current depth of Bull job queue',
|
|
35
|
+
labelNames: ['queue'],
|
|
36
|
+
registers: [this.registry],
|
|
37
|
+
});
|
|
38
|
+
handlerDuration = new prom_client_1.Histogram({
|
|
39
|
+
name: 'arex_handler_duration_seconds',
|
|
40
|
+
help: 'Duration of command/query handlers in seconds',
|
|
41
|
+
labelNames: ['handler', 'result'],
|
|
42
|
+
buckets: [0.01, 0.05, 0.1, 0.25, 0.5, 1, 2, 5],
|
|
43
|
+
registers: [this.registry],
|
|
44
|
+
});
|
|
45
|
+
onModuleInit() {
|
|
46
|
+
(0, prom_client_1.collectDefaultMetrics)({ register: this.registry });
|
|
47
|
+
}
|
|
48
|
+
async getMetrics() {
|
|
49
|
+
return this.registry.metrics();
|
|
50
|
+
}
|
|
51
|
+
getContentType() {
|
|
52
|
+
return this.registry.contentType;
|
|
53
|
+
}
|
|
54
|
+
};
|
|
55
|
+
exports.MetricsService = MetricsService;
|
|
56
|
+
exports.MetricsService = MetricsService = __decorate([
|
|
57
|
+
(0, common_1.Injectable)()
|
|
58
|
+
], MetricsService);
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import { Result, PipelineBehavior, PipelineScope } from '@quanticjs/core';
|
|
2
|
+
import { MetricsService } from './MetricsService';
|
|
3
|
+
export declare class PerformanceBehavior implements PipelineBehavior {
|
|
4
|
+
private readonly metrics?;
|
|
5
|
+
readonly order: 20;
|
|
6
|
+
readonly scope: PipelineScope;
|
|
7
|
+
private readonly logger;
|
|
8
|
+
constructor(metrics?: MetricsService | undefined);
|
|
9
|
+
execute<T>(command: object, next: () => Promise<Result<T>>): Promise<Result<T>>;
|
|
10
|
+
}
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
|
|
3
|
+
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
4
|
+
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
|
5
|
+
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
|
|
6
|
+
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
7
|
+
};
|
|
8
|
+
var __metadata = (this && this.__metadata) || function (k, v) {
|
|
9
|
+
if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
|
|
10
|
+
};
|
|
11
|
+
var __param = (this && this.__param) || function (paramIndex, decorator) {
|
|
12
|
+
return function (target, key) { decorator(target, key, paramIndex); }
|
|
13
|
+
};
|
|
14
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
15
|
+
exports.PerformanceBehavior = void 0;
|
|
16
|
+
const common_1 = require("@nestjs/common");
|
|
17
|
+
const core_1 = require("@quanticjs/core");
|
|
18
|
+
const MetricsService_1 = require("./MetricsService");
|
|
19
|
+
const SLOW_THRESHOLD_MS = 500;
|
|
20
|
+
let PerformanceBehavior = class PerformanceBehavior {
|
|
21
|
+
metrics;
|
|
22
|
+
order = core_1.BehaviorOrder.PERFORMANCE;
|
|
23
|
+
scope = 'both';
|
|
24
|
+
logger = new common_1.Logger('PerformanceBehavior');
|
|
25
|
+
constructor(metrics) {
|
|
26
|
+
this.metrics = metrics;
|
|
27
|
+
}
|
|
28
|
+
async execute(command, next) {
|
|
29
|
+
const handlerName = command.constructor.name;
|
|
30
|
+
const startTime = Date.now();
|
|
31
|
+
const result = await next();
|
|
32
|
+
const durationMs = Date.now() - startTime;
|
|
33
|
+
const durationSec = durationMs / 1000;
|
|
34
|
+
const resultLabel = result.isSuccess ? 'success' : 'failure';
|
|
35
|
+
this.metrics?.handlerDuration
|
|
36
|
+
.labels(handlerName, resultLabel)
|
|
37
|
+
.observe(durationSec);
|
|
38
|
+
if (durationMs > SLOW_THRESHOLD_MS) {
|
|
39
|
+
this.logger.warn({
|
|
40
|
+
msg: `Slow handler detected: ${handlerName} took ${durationMs}ms`,
|
|
41
|
+
handler: handlerName,
|
|
42
|
+
durationMs,
|
|
43
|
+
});
|
|
44
|
+
}
|
|
45
|
+
return result;
|
|
46
|
+
}
|
|
47
|
+
};
|
|
48
|
+
exports.PerformanceBehavior = PerformanceBehavior;
|
|
49
|
+
exports.PerformanceBehavior = PerformanceBehavior = __decorate([
|
|
50
|
+
(0, common_1.Injectable)(),
|
|
51
|
+
__param(0, (0, common_1.Optional)()),
|
|
52
|
+
__metadata("design:paramtypes", [MetricsService_1.MetricsService])
|
|
53
|
+
], PerformanceBehavior);
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
|
|
3
|
+
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
4
|
+
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
|
5
|
+
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
|
|
6
|
+
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
7
|
+
};
|
|
8
|
+
var QuanticMetricsModule_1;
|
|
9
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
10
|
+
exports.QuanticMetricsModule = void 0;
|
|
11
|
+
const common_1 = require("@nestjs/common");
|
|
12
|
+
const core_1 = require("@quanticjs/core");
|
|
13
|
+
const MetricsService_1 = require("./MetricsService");
|
|
14
|
+
const MetricsController_1 = require("./MetricsController");
|
|
15
|
+
const PerformanceBehavior_1 = require("./PerformanceBehavior");
|
|
16
|
+
let QuanticMetricsModule = QuanticMetricsModule_1 = class QuanticMetricsModule {
|
|
17
|
+
static forRoot() {
|
|
18
|
+
return {
|
|
19
|
+
module: QuanticMetricsModule_1,
|
|
20
|
+
controllers: [MetricsController_1.MetricsController],
|
|
21
|
+
providers: [
|
|
22
|
+
MetricsService_1.MetricsService,
|
|
23
|
+
PerformanceBehavior_1.PerformanceBehavior,
|
|
24
|
+
{ provide: core_1.PIPELINE_BEHAVIOR, useExisting: PerformanceBehavior_1.PerformanceBehavior, multi: true },
|
|
25
|
+
],
|
|
26
|
+
exports: [
|
|
27
|
+
MetricsService_1.MetricsService,
|
|
28
|
+
PerformanceBehavior_1.PerformanceBehavior,
|
|
29
|
+
],
|
|
30
|
+
};
|
|
31
|
+
}
|
|
32
|
+
};
|
|
33
|
+
exports.QuanticMetricsModule = QuanticMetricsModule;
|
|
34
|
+
exports.QuanticMetricsModule = QuanticMetricsModule = QuanticMetricsModule_1 = __decorate([
|
|
35
|
+
(0, common_1.Global)(),
|
|
36
|
+
(0, common_1.Module)({})
|
|
37
|
+
], QuanticMetricsModule);
|
package/dist/index.d.ts
ADDED
package/dist/index.js
ADDED
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.QuanticMetricsModule = exports.PerformanceBehavior = exports.MetricsController = exports.MetricsService = void 0;
|
|
4
|
+
var MetricsService_1 = require("./MetricsService");
|
|
5
|
+
Object.defineProperty(exports, "MetricsService", { enumerable: true, get: function () { return MetricsService_1.MetricsService; } });
|
|
6
|
+
var MetricsController_1 = require("./MetricsController");
|
|
7
|
+
Object.defineProperty(exports, "MetricsController", { enumerable: true, get: function () { return MetricsController_1.MetricsController; } });
|
|
8
|
+
var PerformanceBehavior_1 = require("./PerformanceBehavior");
|
|
9
|
+
Object.defineProperty(exports, "PerformanceBehavior", { enumerable: true, get: function () { return PerformanceBehavior_1.PerformanceBehavior; } });
|
|
10
|
+
var QuanticMetricsModule_1 = require("./QuanticMetricsModule");
|
|
11
|
+
Object.defineProperty(exports, "QuanticMetricsModule", { enumerable: true, get: function () { return QuanticMetricsModule_1.QuanticMetricsModule; } });
|
package/package.json
ADDED
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@quanticjs/metrics",
|
|
3
|
+
"version": "2.0.0",
|
|
4
|
+
"description": "Prometheus metrics for quanticjs — handler duration, custom counters",
|
|
5
|
+
"main": "dist/index.js",
|
|
6
|
+
"types": "dist/index.d.ts",
|
|
7
|
+
"files": [
|
|
8
|
+
"dist"
|
|
9
|
+
],
|
|
10
|
+
"publishConfig": {
|
|
11
|
+
"registry": "https://registry.npmjs.org",
|
|
12
|
+
"access": "public"
|
|
13
|
+
},
|
|
14
|
+
"license": "MIT",
|
|
15
|
+
"scripts": {
|
|
16
|
+
"build": "tsc -p tsconfig.json",
|
|
17
|
+
"test": "jest --passWithNoTests",
|
|
18
|
+
"clean": "rm -rf dist"
|
|
19
|
+
},
|
|
20
|
+
"dependencies": {
|
|
21
|
+
"@quanticjs/core": "^2.0.0"
|
|
22
|
+
},
|
|
23
|
+
"peerDependencies": {
|
|
24
|
+
"@nestjs/common": "^11.0.0",
|
|
25
|
+
"prom-client": "^15.0.0"
|
|
26
|
+
}
|
|
27
|
+
}
|