@mists/nestjs-metrics
v0.0.2
Published
A NestJs plugin for metrics
Downloads
12
Readme
NestJs Metrics Module
What's measured improves - Peter Drucker
@mists/nestjs-metrics desires to be a collection of metric modules adapted for the implementation and usage of metrics within NodeJs projects.
Getting Started
Prerequisites / Dependencies
Depends on the following modules:
- node-statsd-client (with the additonal
@types/node-statsd-client
for TypeScript) - prom-client
Installation
npm install -S @mists/nestjs-metrics
# yarn add @mists/nestjs-metrics
Development
git clone https://github.com/mists-aside/nestjs-metrics your_project
cd your_project
rm -rf .git
git init
git add remote origin https://url/to/your/project/repository
git add .
git commit -am "init"
git push origin master
npm run change:language -- javascript # to use javascript
# or
# npm run change:language -- typescript # to use typescript
npm install
# yarn install
# pnpm install
Requirements
- Please install NodeJs. We support version 10.x and above.
- Please instal a JavaScript/TypeScript IDE
- Visual Studio Code with ITMCDev Babel Extension Pack or ITMCDev TypeScript Extension Pack
- Jetbrains WebStorm
- Vim with neoclide/coc.nvim and HerringtonDarkholme/yats.vim extensions.
- Any other IDE you trust.
Testing
Run unit tests using npm run test
.
Testing is currently set to use unittest.
Single Tests
Run single unit tests file, by calling make test:single -- test/path/to/file.test.js
make test:single -- test/path/to/index.test.js
Deployment
Please check release-it for making releases to npmjs.com or any other repository tool, then run:
npm run release
Documentation
API
For a better understanding of the API, the the following API documentation.
Metrics
Counter
Counters are used for counting events. They can only grow, never decrease or reset.
Reflected by
Gauge
Gauges are used for counting events (with the possibility of decreasing or resetting a value as well) and for timing them
Reflected by
Histogram
Histograms are similar to Gauge, but used for tracking sized and frequency of events
Reflected by
PromClient.Histogram
- StatsD does not know the concept of summary, so we emulated it using the
StatsDClient.histogram
methods.
Summary
Summaries are similar to Histogram, but used to calculate percentiles of observed values
Reflected by
PromClient.Summary
- on the side of
statsd
, to support compatibility (not sure if it's good or bad, yet), the same methods as forHistogram
Registering Module
Using (sync) register()
method:
@Module({
imports: [MetricsModule.register({/* ... */})],
})
export class AppModule {}
Using async registerAsync()
method:
import { Module } from "@nestjs/common";
import { MetricsModule } from "@mists/nestjs-metrics";
@Injectable()
export class StatsOptionsService implements StatsOptionsFactory {
createStatsOptions(): StatsOptions {
return new Promise(resolve => ({
/* see the MetricsModule::register() options */
}));
}
}
@Module({
imports: [MetricsModule.registerAsync({
useClass: StatsOptionsService,
inject: [StatsOptionsService],
})],
})
export class AppModule {}
Registering Metrics
You will need to create a metric provider first. This will be done using the
makeMetricProvider
method.
See more details about MetricsModuleOptions before you continue.
import { Module } from "@nestjs/common";
import { MetricsModule, MetricsController, Counter, } from "@mists/nestjs-metrics";
@Module({
controllers: [MetricsController],
imports: [MetricsModule.register({/* ... */})],
providers: [
makeMetricProvider(Metrics.Counter, 'metrics_injector', {})
],
})
export class AppModule {}
Then, inject your new metric in the controller class like this:
@Controller('/route')
export class MetricsController {
constructor(@InjectMetric('metrics_injector') protected counter: Counter) {}
@Get()
public yourMetricMethod(): string {
// ...
this.counter.inc();
// ...
}
}
Registering Metrics Controller
The Metrics controller used currently by Prometheus only
import { Module } from "@nestjs/common";
import { MetricsModule, MetricsController } from "@mists/nestjs-metrics";
@Module({
controllers: [MetricsController],
imports: [MetricsModule.register({
prometheus: {
route: '/metrics',
// ...
}
})],
})
export class AppModule {}
Metric Decorators
Do not rely on decorators only since they have a very limited scope.
Decorators do not require providers, as they have their own mechanism of instantiation, based on the one that creates the providers.
First step is to create a decorator using the default created wrappers:
import { Controller, Get } from "@nestjs/common";
import { generateMetricDecorator, metricIncrementWrapper } from '@mists/nestjs-metrics';
const Increment = generateMetricDecorator(Metrics.Counter, 'metrics_counter_decorator', metricIncrementWrapper, genericOptions);
const GaugeIncrement = generateMetricDecorator(
Metrics.Gauge,
'metrics_gauge_decorator',
metricGaugeIncrementWrapper,
genericOptions,
);
const GaugeDecrement = generateMetricDecorator(
Metrics.Gauge,
'metrics_gauge_decorator',
metricGaugeDecrementWrapper,
genericOptions,
);
const Gauge = generateMetricDecorator(Metrics.Gauge, 'metrics_gauge_decorator', metricGaugeSetWrapper, genericOptions);
const GaugeTiming = generateMetricDecorator(Metrics.Gauge, 'metrics_gauge_decorator', metricTimingWrapper, genericOptions);
const HistogramObserve = generateMetricDecorator(
Metrics.Histogram,
'metrics_histogram_decorator',
metricObserveWrapper,
genericOptions,
);
const HistogramTiming = generateMetricDecorator(
Metrics.Histogram,
'metrics_histogram_decorator',
metricTimingWrapper,
genericOptions,
);
const SummaryObserve = generateMetricDecorator(Metrics.Summary, 'metrics_summary_decorator', metricObserveWrapper, genericOptions);
const SummaryTiming = generateMetricDecorator(Metrics.Summary, 'metrics_summary_decorator', metricTimingWrapper, genericOptions);
const IncrementHttpCalls = generateMetricDecorator(
Metrics.Counter,
'metric_http_calls',
metricIncrementWrapper
);
Or by defining your own metric wrapper:
export const customMetricWrapper: MetricWrapper = (
metricArgs: MetricNumericArgs,
metric: any,
oldMethod: GenericMethod,
target: any,
propertyKey: string | symbol,
descriptor: PropertyDescriptor,
): GenericMethod => (...args: any[]): any => {
(metric as Gauge).inc(...metricArgs);
return oldMethod.call(target, ...args);
};
const CustomIncrementHttpCalls = generateMetricDecorator(
Metrics.Gauge,
'metric_http_calls_custom',
customMetricWrapper
);
Then apply the decorator on a controller method:
@Controller('/test')
class CustomController {
@Get()
@IncrementHttpCalls()
@CustomIncrementHttpCalls(1, { serverId: 'server_1' })
testMethod() {}
}
Authors
- Dragos Cirjan - Initial work
Issues / Support
Add a set of links to the issues page/website, so people can know where to add issues/bugs or ask for support.
License
(If the package is public, add licence) This project is licensed under the MIT License - see the LICENSE.md file for details