digikare / nestjs-prom Goto Github PK
View Code? Open in Web Editor NEWA prometheus module for nestjs
A prometheus module for nestjs
Upgrade dependency and migrate the middleware to version 6
getCounterMetric
only accept name
as params, and inside it calls findOrCreateCounter
with the name
, but findOrCreateCounter
can accept labelNames
as well.
When I call counter.inc({ uri: '/abc' }, 1)
, it throws error:
Added label "uri" is not included in initial labelset: []
Hey, great module.
Are you still maintaining this ?
hey so i am having an issue where HMR is re-registering metrics after a request to the server. From the documentation and cursory look through the source I haven't been able to figure out how to access the register
here is the open github issue i am trying to solve:
if you guys let me know i can pr the docs, thank you.
responseTime()
time param in callback in ms (according to response-time
lib docs), and in histogram.observe
the value is divided by 1000 So I guess the values are in seconds. I think this should be stated in the docs.
Also I think it might be a good idea to add to the docs a simple prom query & graph to show the values. This is sometimes a huge help for getting up and running quickly
A gql request with an exception give this exception :
TypeError: Cannot read property 'baseUrl' of undefined", " at PromCatchAllExceptionsFilter.catch
Some info to use gql context :
https://docs.nestjs.com/graphql/other-features#exception-filters
https://docs.nestjs.com/fundamentals/execution-context#current-application-context
It is not possible (as far as I understand) to initialise PromModule as a dynamic module.
This is important in order to config the prom client dynamically using configurations given at runtime
I've added the PromModule to my top level module and in a service like below. From the docs i assumed /metrics would return a line starting with app_classname_update_... but i only get process, nodejs and http metrics. Am I missing something in the setup? (i tried also to add the PromModule to the module the service is in without success)
top level module:
@Module({
imports: [
PromModule.forRoot({
withHttpMiddleware: {
enable: true,
},
}),
...
service:
@PromMethodCounter()
async update(
entity: BlockchainNetwork,
name?: string,
type?: ClusterServiceType,
size?: ClusterServiceSize,
forceJob = false
): Promise<BlockchainNetwork> {
return this.genericUpdate(entity, name, type, size, forceJob);
}
I couldn't find a way of hiding the prom endpoint from our public swagger output.
PromModule.forRoot({
metricPath: '/heartbeat/metrics',
});
Is there a way to pass the ApiExcludeEndpoint
decorator to Prometheus?
import { ApiExcludeEndpoint } from '@nestjs/swagger';
@Controlle('hello-world')
class HelloWorld {
@ApiExcludeEndpoint()
@Get('/hide-from-swagger-json')
privateEndpoint() {
return { hidden: true };
}
}
tslint solution was merged into eslint.
review dependency
Something controller: MyCustomController
in the options should do.
The expected behavior is:
withDefaultController
= true + controller
= MyCustomController
Then MyCustomController should be load over defaultController.withDefaultController
= false + controller
= MyCustomController
Then MyCustomController should be load over defaultController.withDefaultController
= false + controller
= null Then no controller should be loaded.I have the following histogram
this.usersHistogram = this.promService.getHistogram({
name: 'users_histogram',
help: 'Request duration',
buckets: [0.1, 0.3, 0.5],
labelNames: ['a1'],
});
but if I remove the labelNames
param, I get this error when starting the application
TypeError: Cannot read property 'forEach' of undefined
at validateInput (/home/matheus/node_modules/@digikare/nestjs-prom/node_modules/prom-client/lib/histogram.js:166:9)
at new Histogram (/home/matheus/node_modules/@digikare/nestjs-prom/node_modules/prom-client/lib/histogram.js:44:3)
at findOrCreateMetric (/home/matheus/node_modules/@digikare/nestjs-prom/dist/common/prom.utils.js:50:20)
at Object.findOrCreateHistogram (/home/matheus/node_modules/@digikare/nestjs-prom/dist/common/prom.utils.js:87:12)
at PromService.getHistogram (/home/matheus/node_modules/@digikare/nestjs-prom/dist/prom.service.js:26:29)
And if I remove the buckets
param, I get this error
TypeError: Cannot read property 'reduce' of undefined
at new Histogram (/home/matheus/node_modules/@digikare/nestjs-prom/node_modules/prom-client/lib/histogram.js:51:40)
at findOrCreateMetric (/home/matheus/node_modules/@digikare/nestjs-prom/dist/common/prom.utils.js:50:20)
at Object.findOrCreateHistogram (/home/matheus/node_modules/@digikare/nestjs-prom/dist/common/prom.utils.js:87:12)
at PromService.getHistogram (/home/matheus/node_modules/@digikare/nestjs-prom/dist/prom.service.js:26:29)
I'm trying to remove these params because the IHistogramMetricArguments
says they are not required.
export interface IHistogramMetricArguments extends IMetricArguments {
buckets?: number[];
}
export interface IMetricArguments {
name: string;
help?: string;
labelNames?: string[];
registry?: PromClient.Registry;
}
I'm using version 1.0.0
On the example folder, adding a simple nestjs project with the lib
I setup defaultLabels
option in forRoot, but it seems not working.
NestJS >= 8.0.0 is not compatible with @digikare/[email protected]
NPM says:
npm ERR! Found: @nestjs/[email protected]
npm ERR! node_modules/@nestjs/common
npm ERR! @nestjs/common@"^8.2.2" from the root project
npm ERR!
npm ERR! Could not resolve dependency:
npm ERR! peer @nestjs/common@"^6.0.0 || ^7.0.0" from @digikare/[email protected]
npm ERR! node_modules/@digikare/nestjs-prom
npm ERR! @digikare/nestjs-prom@"^1.0.0" from the root project
Is there an example project to quickly get things started
Nestjs 7.x versions are out, need to bump nestjs-prom to use latest peerDeps of 7.x.x versions
Give the possibility to disable it and let's the possibility to setup one manually, by adding new param withDefaultController
on PromModule.forRoot()
[Nest] 26184 - 01/14/2020, 3:24:49 PM [ExceptionHandler] Nest can't resolve dependencies of the TestService (ControlAndReportApiService, ?). Please make sure that the argument at index [1] is available in the ControlAndReportModule context. +2ms
Error: Nest can't resolve dependencies of the TestService (ControlAndReportApiService, ?). Please make sure that the argument at index [1] is available in the ControlAndReportModule context.
at Injector.lookupComponentInExports (D:\nestjs-prom-master\provision-alerter\node_modules@nestjs\core\injector\injector.js:183:19)
at processTicksAndRejections (internal/process/task_queues.js:93:5)
at async Injector.resolveComponentInstance (D:\nestjs-prom-master\provision-alerter\node_modules@nestjs\core\injector\injector.js:143:33)
at async resolveParam (D:\nestjs-prom-master\provision-alerter\node_modules@nestjs\core\injector\injector.js:96:38)
at async Promise.all (index 1)
at async Injector.resolveConstructorParams (D:\nestjs-prom-master\provision-alerter\node_modules@nestjs\core\injector\injector.js:112:27)
at async Injector.loadInstance (D:\nestjs-prom-master\provision-alerter\node_modules@nestjs\core\injector\injector.js:78:9)
at async Injector.loadProvider (D:\nestjs-prom-master\provision-alerter\node_modules@nestjs\core\injector\injector.js:35:9)
at async Promise.all (index 4)
at async InstanceLoader.createInstancesOfProviders (D:\nestjs-prom-master\provision-alerter\node_modules@nestjs\core\injector\instance-loader.js:41:9)
Current behavior
Whenever I do npm run start it gives me the above error and I am using the below code.
I followed the ReadMe instructions to used the digikare/nestjs-prom library into our project.
I added the following:
In app.module.ts :
@module({
imports: [
PromModule.forRoot({
defaultLabels: {
app: 'provision_alerter',
},
customUrl: 'order/metrics'
}),]
In test.module.ts:
@module({
imports:[
PromModule.forMetrics([
{
type: MetricType.Counter,
configuration: {
name: 'index_counter',
help: 'get count of test orders',
}
}]),
],
providers:[TestService, ControlAndReportApiService],
controllers:[TestController]
})
export class TestModule{}
In test.service.ts:
constructor(private readonly controlAndReportApiService: ControlAndReportApiService,
@InjectCounterMetric('index_counter') private readonly _counterMetric: CounterMetric,
) { }
async findTestOrders(): Promise<Order[]> {
const testOrders: Order[] = await getTestOrders();
this._counterMetric.inc(testOrders.length, new Date());
return testOrders;
}
Can someone please help me with this issue and let me know in case I am missing out something here?
this work well thanks. however, I have a service that has multiple functions and I would like to split and track each separately. the easiest way is to name the stat with the function, even append the name when it's invoked in the function? just starting the conversation cause I am not completely clear on how you implemented yet
@PromMethodCounter({ name: "test_label" })
error TS2554: Expected 0 arguments, but got 1
npm ERR! Found: [email protected]
npm ERR! node_modules/rxjs
npm ERR! rxjs@"^7.1.0" from the root project
npm ERR!
npm ERR! Could not resolve dependency:
npm ERR! peer rxjs@"^6.0.0" from @nestjs/[email protected]
All tests are passing, but I get the following output:
Test Suites: 1 passed, 1 total
Tests: 5 passed, 5 total
Snapshots: 0 total
Time: 19.384 s, estimated 20 s
Ran all test suites.
Jest has detected the following 1 open handle potentially keeping Jest from exiting:
โ RANDOMBYTESREQUEST
at rng (node_modules/@nestjs/common/node_modules/uuid/dist/rng.js:18:21)
at Object.v4 (node_modules/@nestjs/common/node_modules/uuid/dist/v4.js:17:63)
at Object.createParamDecorator (node_modules/@nestjs/common/decorators/http/create-route-param-metadata.decorator.js:14:30)
at Object.<anonymous> (node_modules/@digikare/nestjs-prom/dist/common/prom-counter.decorator.js:6:32)
I added a timeout of 1000ms to afterEach and afterAll to give the system more time but I still get the error. I am even more confused since I am not using the decorators but only the promService to interact with prometheus.
Update readme on how to setup:
Adding new boolean withDefaultsMetrics
on PromModuleOptions
to disable or enable collectDefaultMetrics
FInd out how to manage registry
Property based injections for PromService doesn't work, here is a minimal reproduction repo: https://github.com/snigdha920/nestjs-promservice-reproduction-repo
While starting the app, you will see that the property defined using the property injection is undefined
but using the constructor injection is okay:
[Nest] 36696 - 11/07/2022, 12:05:45 PM LOG [NestFactory] Starting Nest application...
[Nest] 36696 - 11/07/2022, 12:05:45 PM LOG [InstanceLoader] PromCoreModule dependencies initialized +19ms
promServiceProperyInjection inside AppService constructor - undefined
promServiceConstructorInjection inside AppService constructor - PromService {}
[Nest] 36696 - 11/07/2022, 12:05:45 PM LOG [InstanceLoader] PromModule dependencies initialized +1ms
[Nest] 36696 - 11/07/2022, 12:05:45 PM LOG [InstanceLoader] AppModule dependencies initialized +0ms
[Nest] 36696 - 11/07/2022, 12:05:45 PM LOG [RoutesResolver] AppController {/}: +2ms
[Nest] 36696 - 11/07/2022, 12:05:45 PM LOG [RouterExplorer] Mapped {/, GET} route +1ms
[Nest] 36696 - 11/07/2022, 12:05:45 PM LOG [RoutesResolver] PromController {/metrics}: +0ms
[Nest] 36696 - 11/07/2022, 12:05:45 PM LOG [RouterExplorer] Mapped {/metrics, GET} route +0ms
[Nest] 36696 - 11/07/2022, 12:05:45 PM LOG [NestApplication] Nest application successfully started +1ms
@digikare/nestjs-prom
version: 0.2.5
I am trying to remove the /api/metrics
from the autogenerated swagger spec.
const MyPromModule = PromModule.forRoot({
defaultLabels: {
app: 'my-api'
},
withDefaultsMetrics: true,
withDefaultController: false, // set to false so custom controller is used
useHttpCounterMiddleware: true
})
MyPromModule.controllers = [PromController.forRoot('api/metrics')]
and then PromController is a copy paste from source(but with @ApiExcludeEndpoint
)
import { Controller, Get, Header } from "@nestjs/common";
import * as client from 'prom-client';
import { PATH_METADATA } from '@nestjs/common/constants';
import { ApiExcludeEndpoint } from "@nestjs/swagger";
@Controller()
export class PromController {
@Get()
@ApiExcludeEndpoint()
@Header('Content-Type', client.register.contentType)
index() {
console.log('test')
return client.register.metrics();
}
public static forRoot(path = 'metrics') {
Reflect.defineMetadata(PATH_METADATA, path, PromController);
return PromController;
}
}
When I hit /api/metrics
, client.register.metrics();
always returns empty string.
Adding tests
Hi,
the compiler outputs some errors for this library, so it's not possible to use it when your CI/CD contains type checking.
> tsc --noEmit
node_modules/@digikare/nestjs-prom/dist/common/prom.utils.d.ts:10:7 - error TS2314: Generic type 'Metric' requires 1 type argument(s).
10 }) => client.Metric;
~~~~~~~~~~~~~
node_modules/@digikare/nestjs-prom/dist/common/prom.utils.d.ts:15:7 - error TS2314: Generic type 'Counter<T>' requires 1 type argument(s).
15 }) => client.Counter;
~~~~~~~~~~~~~~
node_modules/@digikare/nestjs-prom/dist/common/prom.utils.d.ts:20:7 - error TS2314: Generic type 'Gauge<T>' requires 1 type argument(s).
20 }) => client.Gauge;
~~~~~~~~~~~~
node_modules/@digikare/nestjs-prom/dist/common/prom.utils.d.ts:25:7 - error TS2314: Generic type 'Histogram<T>' requires 1 type argument(s).
25 }) => client.Histogram;
~~~~~~~~~~~~~~~~
node_modules/@digikare/nestjs-prom/dist/common/prom.utils.d.ts:30:7 - error TS2314: Generic type 'Summary<T>' requires 1 type argument(s).
30 }) => client.Summary;
~~~~~~~~~~~~~~
node_modules/@digikare/nestjs-prom/dist/interfaces/index.d.ts:4:44 - error TS2314: Generic type 'Counter<T>' requires 1 type argument(s).
4 export declare class CounterMetric extends PromClient.Counter {
~~~~~~~~~~~~~~~~~~
node_modules/@digikare/nestjs-prom/dist/interfaces/index.d.ts:6:42 - error TS2314: Generic type 'Gauge<T>' requires 1 type argument(s).
6 export declare class GaugeMetric extends PromClient.Gauge {
~~~~~~~~~~~~~~~~
node_modules/@digikare/nestjs-prom/dist/interfaces/index.d.ts:8:46 - error TS2314: Generic type 'Histogram<T>' requires 1 type argument(s).
8 export declare class HistogramMetric extends PromClient.Histogram {
~~~~~~~~~~~~~~~~~~~~
node_modules/@digikare/nestjs-prom/dist/interfaces/index.d.ts:10:44 - error TS2314: Generic type 'Summary<T>' requires 1 type argument(s).
10 export declare class SummaryMetric extends PromClient.Summary {
~~~~~~~~~~~~~~~~~~
node_modules/@digikare/nestjs-prom/dist/interfaces/metric.type.d.ts:14:20 - error TS2314: Generic type 'CounterConfiguration<T>' requires 1 type argument(s).
14 configuration: PromClient.CounterConfiguration;
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
node_modules/@digikare/nestjs-prom/dist/interfaces/metric.type.d.ts:18:20 - error TS2314: Generic type 'GaugeConfiguration<T>' requires 1 type argument(s).
18 configuration: PromClient.GaugeConfiguration;
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
node_modules/@digikare/nestjs-prom/dist/interfaces/metric.type.d.ts:22:20 - error TS2314: Generic type 'HistogramConfiguration<T>' requires 1 type argument(s).
22 configuration: PromClient.HistogramConfiguration;
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
node_modules/@digikare/nestjs-prom/dist/interfaces/metric.type.d.ts:26:20 - error TS2314: Generic type 'SummaryConfiguration<T>' requires 1 type argument(s).
26 configuration: PromClient.SummaryConfiguration;
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
node_modules/@digikare/nestjs-prom/dist/prom.module.d.ts:7:38 - error TS2314: Generic type 'CounterConfiguration<T>' requires 1 type argument(s).
7 static forCounter(configuration: client.CounterConfiguration): DynamicModule;
~~~~~~~~~~~~~~~~~~~~~~~~~~~
node_modules/@digikare/nestjs-prom/dist/prom.module.d.ts:8:36 - error TS2314: Generic type 'GaugeConfiguration<T>' requires 1 type argument(s).
8 static forGauge(configuration: client.GaugeConfiguration): DynamicModule;
~~~~~~~~~~~~~~~~~~~~~~~~~
node_modules/@digikare/nestjs-prom/dist/prom.module.d.ts:9:40 - error TS2314: Generic type 'HistogramConfiguration<T>' requires 1 type argument(s).
9 static forHistogram(configuration: client.HistogramConfiguration): DynamicModule;
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
node_modules/@digikare/nestjs-prom/dist/prom.module.d.ts:10:38 - error TS2314: Generic type 'SummaryConfiguration<T>' requires 1 type argument(s).
10 static forSummary(configuration: client.SummaryConfiguration): DynamicModule;
~~~~~~~~~~~~~~~~~~~~~~~~~~~
Found 17 errors.
When using the PromMethodCounter
decorator on a controller function it will break the API documentation beginning from the line where the decorator was added.
Example
The following code generates API documentation for ApiOperation
, ApiResponse
and Data
.
But it will not generate documentation for the query parameters.
@Get()
@ApiOperation({ title: 'Get something by query string' })
@ApiResponse({ status: 200, type: Data, description: 'List of Data objects' })
@PromMethodCounter()
public async getAllData(@Query() query: GetByQuery): Promise<Data[]> {
this.logger.info(`GET / by query`);
return await this.dataService.loadAllData().toPromise();
}
When I switch the order of decorators, only the basic documentation for the GET function is generated. Everything else is missing (also the model for Data
)
@Get()
@PromMethodCounter()
@ApiOperation({ title: 'Get something by query string' })
@ApiResponse({ status: 200, type: Data, description: 'List of Data objects' })
public async getAllData(@Query() query: GetByQuery): Promise<Data[]> {
this.logger.info(`GET / by query`);
return await this.dataService.loadAllData().toPromise();
}
When I remove PromMethodCounter
the API documentation is working as expected.
Find out how we can display registry based on path
A declarative, efficient, and flexible JavaScript library for building user interfaces.
๐ Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. ๐๐๐
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google โค๏ธ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.