Skip to content

Commit 97c9ba5

Browse files
committed
refactor: improvements
1 parent 1f40998 commit 97c9ba5

File tree

8 files changed

+300
-256
lines changed

8 files changed

+300
-256
lines changed

.eslintrc

Lines changed: 30 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,36 @@
2121
"semi": ["error", "always"],
2222
"@typescript-eslint/explicit-function-return-type": "off",
2323
"@typescript-eslint/no-explicit-any": "off",
24-
"@typescript-eslint/no-unused-vars": ["error", { "argsIgnorePattern": "^_" }]
24+
"@typescript-eslint/no-unused-vars": ["error", { "argsIgnorePattern": "^_" }],
25+
"object-curly-spacing": ["error", "always"],
26+
"@typescript-eslint/brace-style": ["error", "1tbs"],
27+
"@typescript-eslint/type-annotation-spacing": [
28+
"error",
29+
{
30+
"before": false,
31+
"after": true,
32+
"overrides": {
33+
"parameter": { "before": false, "after": true },
34+
"property": { "before": false, "after": true }
35+
}
36+
}
37+
],
38+
"space-before-function-paren": [
39+
"error",
40+
{
41+
"anonymous": "always",
42+
"named": "never",
43+
"asyncArrow": "always"
44+
}
45+
],
46+
"space-in-parens": ["error", "always"], // Enforce spaces inside parentheses
47+
"keyword-spacing": [
48+
"error",
49+
{
50+
"before": true,
51+
"after": true
52+
}
53+
]
2554
},
2655
"ignorePatterns": ["dist/", "dist/*"]
2756
}

CONTRIBUTING.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@
2727
```bash
2828
npm install
2929
npm run test
30-
npm run lint
30+
npm run lint: fix
3131
```
3232

3333
4. Commit your changes using semantic commits

src/interfaces.ts

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,10 @@
11
export interface MetricsConfig {
22
defaultLabels?: Record<string, string>;
33
defaultMetricsEnabled?: boolean;
4-
}
4+
}
5+
6+
export interface ReporterAsyncOptions {
7+
imports?: any[];
8+
useFactory: ( ...args: any[] )=> Promise<MetricsConfig> | MetricsConfig;
9+
inject?: any[];
10+
}

src/reporter/reporter.module.ts

Lines changed: 18 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -1,23 +1,15 @@
11
import { DynamicModule, Global, Module } from '@nestjs/common';
22
import { ReporterService } from './reporter.service';
33
import { collectDefaultMetrics, Registry } from 'prom-client';
4-
import { MetricsConfig } from '../interfaces';
4+
import { MetricsConfig, ReporterAsyncOptions } from '../interfaces';
55
import { MetricsService } from '../metrics/metrics.service';
66
import { MetricsController } from '../metrics/metrics.controller';
77

88
@Global()
99
@Module( {} )
1010
export class ReporterModule {
1111
static forRoot( config: MetricsConfig = {} ): DynamicModule {
12-
const registry = new Registry();
13-
14-
if ( config.defaultLabels ) {
15-
registry.setDefaultLabels( config.defaultLabels );
16-
}
17-
18-
if ( config.defaultMetricsEnabled === true ) {
19-
collectDefaultMetrics( { register: registry } );
20-
}
12+
const registry = this.configureRegistry( config );
2113

2214
return {
2315
module: ReporterModule,
@@ -34,11 +26,7 @@ export class ReporterModule {
3426
};
3527
}
3628

37-
static forRootAsync( options: {
38-
imports?: any[];
39-
useFactory: ( ...args: any[] ) => Promise<MetricsConfig> | MetricsConfig;
40-
inject?: any[];
41-
} ): DynamicModule {
29+
static forRootAsync( options: ReporterAsyncOptions ): DynamicModule {
4230
return {
4331
module: ReporterModule,
4432
imports: options.imports,
@@ -51,17 +39,7 @@ export class ReporterModule {
5139
{
5240
provide: Registry,
5341
useFactory: async ( config: MetricsConfig ) => {
54-
const registry = new Registry();
55-
56-
if ( config.defaultLabels ) {
57-
registry.setDefaultLabels( config.defaultLabels );
58-
}
59-
60-
if ( config.defaultMetricsEnabled === true ) {
61-
collectDefaultMetrics( { register: registry } );
62-
}
63-
64-
return registry;
42+
return ReporterModule.configureRegistry( config );
6543
},
6644
inject: [ 'CONFIG_OPTIONS' ],
6745
},
@@ -72,4 +50,18 @@ export class ReporterModule {
7250
exports: [ ReporterService ]
7351
};
7452
}
53+
54+
private static configureRegistry( config: MetricsConfig = {} ): Registry {
55+
const registry = new Registry();
56+
57+
if ( config.defaultLabels ) {
58+
registry.setDefaultLabels( config.defaultLabels );
59+
}
60+
61+
if ( config.defaultMetricsEnabled ) {
62+
collectDefaultMetrics( { register: registry } );
63+
}
64+
65+
return registry;
66+
}
7567
}

src/reporter/reporter.service.ts

Lines changed: 18 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -7,39 +7,49 @@ export class ReporterService implements OnApplicationBootstrap {
77
private static metricsService: MetricsService;
88

99
constructor( private readonly metrics: MetricsService ) {}
10+
1011
onApplicationBootstrap() {
1112
ReporterService.metricsService = this.metrics;
1213
}
1314

14-
static counter(key: string, labels?: Record<string, string | number>): void {
15+
static counter( key: string, labels?: Record<string, string | number> ): void {
1516
try {
1617
ReporterService.metricsService.incCounter( key, labels );
1718
} catch ( error ) {
18-
this.logger.error( `Error while incrementing counter - ${ key }`, error );
19+
this.logError( 'increment counter', key, labels, error );
1920
}
2021
}
2122

22-
static gauge(key: string, value: number, labels?: Record<string, string | number>): void {
23+
static gauge( key: string, value: number, labels?: Record<string, string | number> ): void {
2324
try {
2425
ReporterService.metricsService.setGauge( key, value, labels );
2526
} catch ( error ) {
26-
this.logger.error( `Error while setting gauge - ${ key }, ${ value }`, error );
27+
this.logError( 'set gauge', key, labels, error );
2728
}
2829
}
2930

30-
static histogram(key: string, value: number, labels?: Record<string, string | number>, buckets?: number[]): void {
31+
static histogram( key: string, value: number, labels?: Record<string, string | number>, buckets?: number[] ): void {
3132
try {
3233
ReporterService.metricsService.observeHistogram( key, value, labels, buckets );
3334
} catch ( error ) {
34-
this.logger.error( `Error while observing histogram - ${ key }, ${ value }`, error );
35+
this.logError( 'observe histogram', key, labels, error );
3536
}
3637
}
3738

38-
static summary(key: string, value: number, labels?: Record<string, string | number>, percentiles?: number[]): void {
39+
static summary( key: string, value: number, labels?: Record<string, string | number>, percentiles?: number[] ): void {
3940
try {
4041
ReporterService.metricsService.observeSummary( key, value, labels, percentiles );
4142
} catch ( error ) {
42-
this.logger.error( `Error while observing summary - ${ key }, ${ value }`, error );
43+
this.logError( 'observe summary', key, labels, error );
4344
}
4445
}
46+
47+
private static logError( action: string, key: string, labels: Record<string, string | number> | undefined, error: unknown ): void {
48+
this.logger.error( {
49+
message: `Failed to ${action}`,
50+
metric: key,
51+
labels,
52+
error: error instanceof Error ? error.message : String( error ),
53+
} );
54+
}
4555
}

tests/metrics.controller.spec.ts

Lines changed: 28 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -2,56 +2,56 @@ import { Test, TestingModule } from '@nestjs/testing';
22
import { Registry, Counter } from 'prom-client';
33
import { MetricsController } from '../src';
44

5-
describe('MetricsController', () => {
5+
describe( 'MetricsController', () => {
66
let controller: MetricsController;
77
let registry: Registry;
88

9-
beforeEach(async () => {
9+
beforeEach( async () => {
1010
registry = new Registry();
11-
const module: TestingModule = await Test.createTestingModule({
11+
const module: TestingModule = await Test.createTestingModule( {
1212
controllers: [MetricsController],
1313
providers: [
1414
{
1515
provide: Registry,
1616
useValue: registry,
1717
},
1818
],
19-
}).compile();
19+
} ).compile();
2020

21-
controller = module.get<MetricsController>(MetricsController);
22-
});
21+
controller = module.get<MetricsController>( MetricsController );
22+
} );
2323

24-
afterEach(() => {
24+
afterEach( () => {
2525
registry.clear();
26-
});
26+
} );
2727

28-
describe('getMetrics', () => {
29-
it('should return prometheus metrics', async () => {
30-
const counter = new Counter({
28+
describe( 'getMetrics', () => {
29+
it( 'should return prometheus metrics', async () => {
30+
const counter = new Counter( {
3131
name: 'test_counter',
3232
help: 'test counter help',
3333
registers: [registry]
34-
});
34+
} );
3535

3636
counter.inc();
3737

3838
const metrics = await controller.getMetrics();
39-
expect(metrics).toBeDefined();
40-
expect(typeof metrics).toBe('string');
41-
expect(metrics).toContain('# HELP test_counter test counter help');
42-
expect(metrics).toContain('test_counter 1');
43-
});
39+
expect( metrics ).toBeDefined();
40+
expect( typeof metrics ).toBe( 'string' );
41+
expect( metrics ).toContain( '# HELP test_counter test counter help' );
42+
expect( metrics ).toContain( 'test_counter 1' );
43+
} );
4444

45-
it('should handle empty metrics registry', async () => {
45+
it( 'should handle empty metrics registry', async () => {
4646
const metrics = await controller.getMetrics();
47-
expect(metrics).toBeDefined();
48-
expect(typeof metrics).toBe('string');
49-
expect(metrics.trim()).toBe('');
50-
});
47+
expect( metrics ).toBeDefined();
48+
expect( typeof metrics ).toBe( 'string' );
49+
expect( metrics.trim() ).toBe( '' );
50+
} );
5151

52-
it('should handle registry errors', async () => {
53-
jest.spyOn(registry, 'metrics').mockRejectedValue(new Error('Registry error'));
54-
await expect(controller.getMetrics()).rejects.toThrow('Registry error');
55-
});
56-
});
57-
});
52+
it( 'should handle registry errors', async () => {
53+
jest.spyOn( registry, 'metrics' ).mockRejectedValue( new Error( 'Registry error' ) );
54+
await expect( controller.getMetrics() ).rejects.toThrow( 'Registry error' );
55+
} );
56+
} );
57+
} );

0 commit comments

Comments
 (0)