@icd-iot-aicf/nestjs-logger 0.1.6 → 0.1.8
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/README.md +226 -63
- package/dist/index.d.ts +1 -0
- package/dist/index.js +1 -0
- package/dist/index.js.map +1 -1
- package/dist/tsconfig.build.tsbuildinfo +1 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -1,85 +1,248 @@
|
|
|
1
|
-
|
|
2
|
-
<a href="http://nestjs.com/" target="blank"><img src="https://nestjs.com/img/logo-small.svg" width="120" alt="Nest Logo" /></a>
|
|
3
|
-
</p>
|
|
4
|
-
|
|
5
|
-
[circleci-image]: https://img.shields.io/circleci/build/github/nestjs/nest/master?token=abc123def456
|
|
6
|
-
[circleci-url]: https://circleci.com/gh/nestjs/nest
|
|
7
|
-
|
|
8
|
-
<p align="center">A progressive <a href="http://nodejs.org" target="_blank">Node.js</a> framework for building efficient and scalable server-side applications.</p>
|
|
9
|
-
<p align="center">
|
|
10
|
-
<a href="https://www.npmjs.com/~nestjscore" target="_blank"><img src="https://img.shields.io/npm/v/@nestjs/core.svg" alt="NPM Version" /></a>
|
|
11
|
-
<a href="https://www.npmjs.com/~nestjscore" target="_blank"><img src="https://img.shields.io/npm/l/@nestjs/core.svg" alt="Package License" /></a>
|
|
12
|
-
<a href="https://www.npmjs.com/~nestjscore" target="_blank"><img src="https://img.shields.io/npm/dm/@nestjs/common.svg" alt="NPM Downloads" /></a>
|
|
13
|
-
<a href="https://circleci.com/gh/nestjs/nest" target="_blank"><img src="https://img.shields.io/circleci/build/github/nestjs/nest/master" alt="CircleCI" /></a>
|
|
14
|
-
<a href="https://coveralls.io/github/nestjs/nest?branch=master" target="_blank"><img src="https://coveralls.io/repos/github/nestjs/nest/badge.svg?branch=master#9" alt="Coverage" /></a>
|
|
15
|
-
<a href="https://discord.gg/G7Qnnhy" target="_blank"><img src="https://img.shields.io/badge/discord-online-brightgreen.svg" alt="Discord"/></a>
|
|
16
|
-
<a href="https://opencollective.com/nest#backer" target="_blank"><img src="https://opencollective.com/nest/backers/badge.svg" alt="Backers on Open Collective" /></a>
|
|
17
|
-
<a href="https://opencollective.com/nest#sponsor" target="_blank"><img src="https://opencollective.com/nest/sponsors/badge.svg" alt="Sponsors on Open Collective" /></a>
|
|
18
|
-
<a href="https://paypal.me/kamilmysliwiec" target="_blank"><img src="https://img.shields.io/badge/Donate-PayPal-ff3f59.svg" alt="Donate us"/></a>
|
|
19
|
-
<a href="https://opencollective.com/nest#sponsor" target="_blank"><img src="https://img.shields.io/badge/Support%20us-Open%20Collective-41B883.svg" alt="Support us"></a>
|
|
20
|
-
<a href="https://twitter.com/nestframework" target="_blank"><img src="https://img.shields.io/twitter/follow/nestframework.svg?style=social&label=Follow" alt="Follow us on Twitter"></a>
|
|
21
|
-
</p>
|
|
22
|
-
<!--[](https://opencollective.com/nest#backer)
|
|
23
|
-
[](https://opencollective.com/nest#sponsor)-->
|
|
24
|
-
|
|
25
|
-
## Description นะจ้ะ
|
|
26
|
-
|
|
27
|
-
[Nest](https://github.com/nestjs/nest) framework TypeScript starter repository.
|
|
28
|
-
|
|
29
|
-
## Project setup
|
|
1
|
+
# @icd-iot-aicf/nestjs-logger
|
|
30
2
|
|
|
3
|
+
NestJS logging and metrics toolkit with opinionated formats (AICF, Cloudron, ESB), Winston-based logger, and Prometheus metrics. Ships with ready-to-use middleware, interceptors, and decorators for structured logs and service KPIs.
|
|
4
|
+
|
|
5
|
+
- Logger: Winston, JSON payloads, async-context aware
|
|
6
|
+
- Formats: aicf | cloudron | esb
|
|
7
|
+
- Metrics: Prometheus counters/gauges, HTTP middleware, manual API
|
|
8
|
+
- Extras: standard response codes, decorators, guards, utilities
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
## Install
|
|
12
|
+
|
|
13
|
+
```bash
|
|
14
|
+
npm install @icd-iot-aicf/nestjs-logger
|
|
15
|
+
```
|
|
16
|
+
Or
|
|
31
17
|
```bash
|
|
32
|
-
|
|
18
|
+
yarn add @icd-iot-aicf/nestjs-logger
|
|
33
19
|
```
|
|
34
20
|
|
|
35
|
-
|
|
21
|
+
Requirements:
|
|
22
|
+
- NestJS v11
|
|
23
|
+
- Express platform (default for Nest)
|
|
24
|
+
- Optional: set env C20_NAME to prefix Prometheus metric names
|
|
25
|
+
|
|
26
|
+
|
|
27
|
+
## Quick start
|
|
28
|
+
|
|
29
|
+
1) Configure the library (global) using AppLogConfigModule
|
|
30
|
+
|
|
31
|
+
```ts
|
|
32
|
+
import { Module, MiddlewareConsumer } from '@nestjs/common';
|
|
33
|
+
import {
|
|
34
|
+
AppLogConfigModule,
|
|
35
|
+
LoggerModule,
|
|
36
|
+
MetricsModule,
|
|
37
|
+
HTTPLogsMiddleware,
|
|
38
|
+
HTTPMetricsMiddleware,
|
|
39
|
+
} from '@icd-iot-aicf/nestjs-logger';
|
|
40
|
+
import { FORMAT_TYPE, DEBUG_MODE } from '@icd-iot-aicf/nestjs-logger';
|
|
41
|
+
|
|
42
|
+
@Module({
|
|
43
|
+
imports: [
|
|
44
|
+
AppLogConfigModule.forRoot({
|
|
45
|
+
appName: 'my-app',
|
|
46
|
+
componentName: 'http-api',
|
|
47
|
+
format: FORMAT_TYPE.AICF, // or FORMAT_TYPE.CLOUDRON, FORMAT_TYPE.ESB
|
|
48
|
+
logLevel: 'info', // 'info' | 'warning' | 'error' | 'debug'
|
|
49
|
+
debugLib: DEBUG_MODE.DISABLE,
|
|
50
|
+
// Optional: map result structure if your response is not the default
|
|
51
|
+
// structureResponse: { resultCode: 'resultCode', httpCode: 'httpCode', resultDescription: 'resultDescription' },
|
|
52
|
+
}),
|
|
53
|
+
LoggerModule,
|
|
54
|
+
MetricsModule.forRoot({ path: '/metrics' }), // optional options
|
|
55
|
+
],
|
|
56
|
+
})
|
|
57
|
+
export class AppModule {
|
|
58
|
+
configure(consumer: MiddlewareConsumer) {
|
|
59
|
+
consumer
|
|
60
|
+
.apply(HTTPLogsMiddleware, HTTPMetricsMiddleware)
|
|
61
|
+
.forRoutes('*');
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
```
|
|
36
65
|
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
66
|
+
2) Register the HTTP interceptor (correlation headers)
|
|
67
|
+
|
|
68
|
+
```ts
|
|
69
|
+
// main.ts
|
|
70
|
+
import { NestFactory } from '@nestjs/core';
|
|
71
|
+
import { AppModule } from './app.module';
|
|
72
|
+
import { HttpInterceptor } from '@icd-iot-aicf/nestjs-logger';
|
|
40
73
|
|
|
41
|
-
|
|
42
|
-
|
|
74
|
+
async function bootstrap() {
|
|
75
|
+
const app = await NestFactory.create(AppModule);
|
|
76
|
+
app.useGlobalInterceptors(new HttpInterceptor());
|
|
77
|
+
await app.listen(3000);
|
|
78
|
+
}
|
|
79
|
+
bootstrap();
|
|
80
|
+
```
|
|
43
81
|
|
|
44
|
-
|
|
45
|
-
|
|
82
|
+
3) Use decorators to name your operations (recommended for better logs/metrics)
|
|
83
|
+
|
|
84
|
+
```ts
|
|
85
|
+
import { Controller, Get } from '@nestjs/common';
|
|
86
|
+
import { RecordName, CommandInfo } from '@icd-iot-aicf/nestjs-logger';
|
|
87
|
+
|
|
88
|
+
@Controller('health')
|
|
89
|
+
export class HealthController {
|
|
90
|
+
@Get()
|
|
91
|
+
@RecordName('HealthCheck')
|
|
92
|
+
@CommandInfo({ CommandName: 'HealthCheck', Description: 'API liveness probe' })
|
|
93
|
+
ping() {
|
|
94
|
+
return { ok: true };
|
|
95
|
+
}
|
|
96
|
+
}
|
|
46
97
|
```
|
|
47
98
|
|
|
48
|
-
## Run tests
|
|
49
99
|
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
100
|
+
## Logger usage
|
|
101
|
+
|
|
102
|
+
Inject CustomLoggerService and log structured JSON or plain strings. The library will set appropriate level fields for the chosen format.
|
|
53
103
|
|
|
54
|
-
|
|
55
|
-
|
|
104
|
+
```ts
|
|
105
|
+
import { Injectable } from '@nestjs/common';
|
|
106
|
+
import { CustomLoggerService } from '@icd-iot-aicf/nestjs-logger';
|
|
56
107
|
|
|
57
|
-
|
|
58
|
-
|
|
108
|
+
@Injectable()
|
|
109
|
+
export class ExampleService {
|
|
110
|
+
constructor(private readonly logger: CustomLoggerService) {}
|
|
111
|
+
|
|
112
|
+
doWork() {
|
|
113
|
+
this.logger.log({ message: 'work started' });
|
|
114
|
+
// ...
|
|
115
|
+
this.logger.warn({ message: 'slower than expected' });
|
|
116
|
+
// ...
|
|
117
|
+
this.logger.error({ message: 'failure' }, 'optional-stack-trace');
|
|
118
|
+
}
|
|
119
|
+
}
|
|
59
120
|
```
|
|
60
121
|
|
|
61
|
-
|
|
122
|
+
Notes:
|
|
123
|
+
- log() is info level. Other methods: warn(), debug(), verbose(), error(message, trace?).
|
|
124
|
+
- Prefer structured objects; strings also work but won’t include format extras.
|
|
62
125
|
|
|
63
|
-
Check out a few resources that may come in handy when working with NestJS:
|
|
64
126
|
|
|
65
|
-
|
|
66
|
-
- For questions and support, please visit our [Discord channel](https://discord.gg/G7Qnnhy).
|
|
67
|
-
- To dive deeper and get more hands-on experience, check out our official video [courses](https://courses.nestjs.com/).
|
|
68
|
-
- Visualize your application graph and interact with the NestJS application in real-time using [NestJS Devtools](https://devtools.nestjs.com).
|
|
69
|
-
- Need help with your project (part-time to full-time)? Check out our official [enterprise support](https://enterprise.nestjs.com).
|
|
70
|
-
- To stay in the loop and get updates, follow us on [X](https://x.com/nestframework) and [LinkedIn](https://linkedin.com/company/nestjs).
|
|
71
|
-
- Looking for a job, or have a job to offer? Check out our official [Jobs board](https://jobs.nestjs.com).
|
|
127
|
+
## Automatic HTTP logs
|
|
72
128
|
|
|
73
|
-
|
|
129
|
+
- HTTPLogsMiddleware emits inbound/outbound logs per request using the configured format (AICF/Cloudron/ESB).
|
|
130
|
+
- Use @RecordName to categorize metrics/logs by endpoint/business name.
|
|
131
|
+
- HttpInterceptor reads correlation headers:
|
|
132
|
+
- x-ais-orderref: transaction id
|
|
133
|
+
- x-origin-session: session chain (if present)
|
|
74
134
|
|
|
75
|
-
Nest is an MIT-licensed open source project. It can grow thanks to the sponsors and support by the amazing backers. If you'd like to join them, please [read more here](https://docs.nestjs.com/support).
|
|
76
135
|
|
|
77
|
-
##
|
|
136
|
+
## Metrics
|
|
78
137
|
|
|
79
|
-
|
|
80
|
-
-
|
|
81
|
-
-
|
|
138
|
+
The library exposes a Prometheus endpoint (via @willsoto/nestjs-prometheus) and tracks:
|
|
139
|
+
- request totals by path/method/status
|
|
140
|
+
- time-bucket counters
|
|
141
|
+
- concurrent requests (current and max)
|
|
82
142
|
|
|
83
|
-
|
|
143
|
+
Setup was done in Quick start. Ensure C20_NAME is set in your environment to prefix metric names.
|
|
144
|
+
|
|
145
|
+
Manual metrics API:
|
|
146
|
+
|
|
147
|
+
```ts
|
|
148
|
+
import { Injectable } from '@nestjs/common';
|
|
149
|
+
import { MetricsManualService } from '@icd-iot-aicf/nestjs-logger';
|
|
150
|
+
import { RESULTS } from '@icd-iot-aicf/nestjs-logger';
|
|
151
|
+
|
|
152
|
+
@Injectable()
|
|
153
|
+
export class TaskRunner {
|
|
154
|
+
constructor(private readonly metrics: MetricsManualService) {}
|
|
155
|
+
|
|
156
|
+
async run() {
|
|
157
|
+
this.metrics.increment();
|
|
158
|
+
try {
|
|
159
|
+
// ... your work
|
|
160
|
+
this.metrics.finish('POST', RESULTS.SUCCESS);
|
|
161
|
+
} catch (e) {
|
|
162
|
+
this.metrics.finish('POST', RESULTS.INTERNAL_SERVER_ERROR);
|
|
163
|
+
throw e;
|
|
164
|
+
}
|
|
165
|
+
}
|
|
166
|
+
}
|
|
167
|
+
```
|
|
168
|
+
|
|
169
|
+
Customize metrics endpoint:
|
|
170
|
+
|
|
171
|
+
```ts
|
|
172
|
+
MetricsModule.forRoot({ path: '/custom-metrics', defaultMetrics: { enabled: true } });
|
|
173
|
+
```
|
|
174
|
+
|
|
175
|
+
|
|
176
|
+
## Decorators for external calls
|
|
84
177
|
|
|
85
|
-
|
|
178
|
+
Tag outbound calls (dependencies) to enrich detail/endpoint logs.
|
|
179
|
+
|
|
180
|
+
```ts
|
|
181
|
+
import { EXTCMDName, NodeName } from '@icd-iot-aicf/nestjs-logger';
|
|
182
|
+
|
|
183
|
+
@NodeName('user-service')
|
|
184
|
+
export class UserClient {
|
|
185
|
+
@EXTCMDName({ cmdName: 'GetUser', action: 'HTTP', subAction: 'GET' })
|
|
186
|
+
async getUser() {
|
|
187
|
+
// call your HTTP client here
|
|
188
|
+
}
|
|
189
|
+
}
|
|
190
|
+
```
|
|
191
|
+
|
|
192
|
+
|
|
193
|
+
## Standard responses (helpers)
|
|
194
|
+
|
|
195
|
+
Use pre-defined operation statuses for consistency.
|
|
196
|
+
|
|
197
|
+
```ts
|
|
198
|
+
import { RESULTS } from '@icd-iot-aicf/nestjs-logger';
|
|
199
|
+
import { HttpCode } from '@nestjs/common';
|
|
200
|
+
|
|
201
|
+
// in controller method
|
|
202
|
+
@HttpCode(RESULTS.SUCCESS.httpCode)
|
|
203
|
+
get() {
|
|
204
|
+
return { ...RESULTS.SUCCESS, data: { ok: true } };
|
|
205
|
+
}
|
|
206
|
+
```
|
|
207
|
+
|
|
208
|
+
If your response uses different field names, set structureResponse in AppLogConfigModule.forRoot so metrics can extract resultCode/httpCode.
|
|
209
|
+
|
|
210
|
+
|
|
211
|
+
## Configuration reference
|
|
212
|
+
|
|
213
|
+
AppLogConfigModule.forRoot({ ...config })
|
|
214
|
+
- appName: string (required)
|
|
215
|
+
- componentName: string (required)
|
|
216
|
+
- format: FORMAT_TYPE.AICF | FORMAT_TYPE.CLOUDRON | FORMAT_TYPE.ESB (required)
|
|
217
|
+
- logLevel?: 'info' | 'warning' | 'error' | 'debug' (default 'info')
|
|
218
|
+
- debugLib?: DEBUG_MODE (default DISABLE)
|
|
219
|
+
- structureResponse?: { resultCode?: string; httpCode?: string; resultDescription?: string }
|
|
220
|
+
|
|
221
|
+
Common enums
|
|
222
|
+
```ts
|
|
223
|
+
import { FORMAT_TYPE, DEBUG_MODE } from '@icd-iot-aicf/nestjs-logger';
|
|
224
|
+
```
|
|
225
|
+
|
|
226
|
+
|
|
227
|
+
## What’s exported
|
|
228
|
+
|
|
229
|
+
From the package root:
|
|
230
|
+
- Modules: LoggerModule, MetricsModule, AppLogConfigModule
|
|
231
|
+
- Services: CustomLoggerService, MetricsService, MetricsManualService
|
|
232
|
+
- Middleware: HTTPLogsMiddleware, HTTPMetricsMiddleware
|
|
233
|
+
- Interceptors: HttpInterceptor, CoreLogsInterceptor, AmqpInterceptor
|
|
234
|
+
- Decorators: RecordName, CommandInfo, EXTCMDName, NodeName, RecordManual
|
|
235
|
+
- Config: FORMAT_TYPE, DEBUG_MODE
|
|
236
|
+
- Helpers: RESULTS, STATUS_METHOD, dayJs
|
|
237
|
+
|
|
238
|
+
|
|
239
|
+
## Troubleshooting
|
|
240
|
+
- No logs? Ensure AppLogConfigModule.forRoot is imported before LoggerModule and that HTTPLogsMiddleware is applied.
|
|
241
|
+
- Missing correlation? Register HttpInterceptor globally.
|
|
242
|
+
- Metrics labels show undefined path? Use @RecordName; also ensure your controllers are hit after middleware.
|
|
243
|
+
- Metric names start with undefined_: set env C20_NAME in your process.
|
|
244
|
+
- Cloudron/ESB format specifics: pick FORMAT_TYPE matching your deployment pipeline; the library adjusts level fields automatically.
|
|
245
|
+
|
|
246
|
+
|
|
247
|
+
## License
|
|
248
|
+
UNLICENSED
|
package/dist/index.d.ts
CHANGED
|
@@ -19,3 +19,4 @@ export * from './logger/core/functions/global-function';
|
|
|
19
19
|
export * from './common/helper/response';
|
|
20
20
|
export * from './logger/core/services/summary-flush.service';
|
|
21
21
|
export * from './logger/core/database/hook-ingress.database';
|
|
22
|
+
export * from './logger/aicf/dtos/aicf.dto';
|
package/dist/index.js
CHANGED
|
@@ -35,4 +35,5 @@ __exportStar(require("./logger/core/functions/global-function"), exports);
|
|
|
35
35
|
__exportStar(require("./common/helper/response"), exports);
|
|
36
36
|
__exportStar(require("./logger/core/services/summary-flush.service"), exports);
|
|
37
37
|
__exportStar(require("./logger/core/database/hook-ingress.database"), exports);
|
|
38
|
+
__exportStar(require("./logger/aicf/dtos/aicf.dto"), exports);
|
|
38
39
|
//# sourceMappingURL=index.js.map
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;AAAA,2DAAyC;AACzC,4DAA0C;AAC1C,+DAA6C;AAC7C,mEAAiD;AACjD,yDAAuC;AACvC,0DAAwC;AACxC,gDAA8B;AAC9B,iEAA+C;AAC/C,0DAAwC;AACxC,qEAAmD;AACnD,4EAA0D;AAC1D,8DAA4C;AAC5C,wFAAsE;AACtE,0EAAwD;AACxD,yCAAuB;AACvB,wEAAsD;AACtD,0DAAwC;AACxC,0EAAwD;AACxD,2DAAyC;AACzC,+EAA6D;AAC7D,+EAA6D"}
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;AAAA,2DAAyC;AACzC,4DAA0C;AAC1C,+DAA6C;AAC7C,mEAAiD;AACjD,yDAAuC;AACvC,0DAAwC;AACxC,gDAA8B;AAC9B,iEAA+C;AAC/C,0DAAwC;AACxC,qEAAmD;AACnD,4EAA0D;AAC1D,8DAA4C;AAC5C,wFAAsE;AACtE,0EAAwD;AACxD,yCAAuB;AACvB,wEAAsD;AACtD,0DAAwC;AACxC,0EAAwD;AACxD,2DAAyC;AACzC,+EAA6D;AAC7D,+EAA6D;AAC7D,8DAA4C"}
|