Skip to content
This repository was archived by the owner on Feb 9, 2026. It is now read-only.

Commit 771bb21

Browse files
dharmendra kumarDamianDunajski
authored andcommitted
ROC-3285 Integrate logging with Azure Application Insights (#28)
1 parent 3f757ad commit 771bb21

File tree

15 files changed

+208
-1966
lines changed

15 files changed

+208
-1966
lines changed

README.md

Lines changed: 27 additions & 60 deletions
Original file line numberDiff line numberDiff line change
@@ -2,13 +2,14 @@
22

33
[![Greenkeeper badge](https://badges.greenkeeper.io/hmcts/nodejs-logging.svg)](https://greenkeeper.io/)
44

5-
A logging component used by Reform's Node.js applications. Some background info:
6-
* there are 8 log levels: `ALL`, `TRACE`, `DEBUG`, `INFO`, `WARN`, `ERROR`, `FATAL` and `OFF`.
7-
* a level can be set via an environment variable `LOG_LEVEL`, the default is `INFO`.
8-
* there are 3 types of logging output which is set via an environment variable `LOG_OUTPUT`, the default is `human`:
9-
- `human` - single line of a human readable output
10-
- `single` - a single line of JSON output
11-
- `multi` - a multiline formatted JSON output
5+
A logging component used by Reform's Node.js applications.
6+
7+
**This is not compatible with Reform tactical logging spec. Logger 2.x should be used for tactical applications.**
8+
9+
Some background info:
10+
* there are 6 log levels: `silly` (5), `debug` (4), `verbose` (3), `info` (2), `warn` (1) and `error` (0).
11+
* log level can be set via an environment variable `LOG_LEVEL`, the default is `info`.
12+
* logging output in JSON format can be enabled by setting environment variable `JSON_PRINT` to `true`, the default is `false`:
1213
* by default logging is turned off when running the unit tests.
1314

1415
## Usage
@@ -25,82 +26,48 @@ Require it:
2526
const { Logger } = require('@hmcts/nodejs-logging')
2627
```
2728

28-
Set the logging configuration. Should be done once at application startup:
29-
30-
```javascript
31-
Logger.config({
32-
microservice: 'your-service-name',
33-
team: 'your-team',
34-
environment: 'some-environemnt'
35-
})
36-
```
37-
3829
Then you can create a logger instance and use it to log information:
3930

4031
```javascript
4132
const logger = Logger.getLogger('app.js') // app.js is just an example, can be anything that's meaningful to you
33+
```
4234

35+
Usage are:
36+
37+
```
4338
logger.info({
4439
message: 'Yay, logging!'
4540
})
4641
```
4742

48-
### Access logging for Express applications
49-
50-
Optionally you can use the built-in Express access logger:
51-
52-
```javascript
53-
const { Express } = require('@hmcts/nodejs-logging')
54-
55-
app.use(Express.accessLogger())
56-
```
57-
58-
It will log all requests made against your application. For example, a typical HTTP 404 log error when encountering an error would look like the following:
43+
or
5944

6045
```
61-
{
62-
responseCode: 404,
63-
message: 'Not Found',
64-
fields: [],
65-
level: 'ERROR',
66-
environment: 'some-environemnt',
67-
hostname: 'My-MacBook-Pro.local',
68-
rootRequestId: '',
69-
requestId: '',
70-
originRequestId: '',
71-
type: 'nodejs',
72-
microservice: 'your-service-name',
73-
team: 'your-team',
74-
timestamp: '2017-01-27T11:27:23+00:00'
75-
}
46+
logger.log({
47+
level: 'info',
48+
message: 'What time is the testing at?'
49+
});
7650
```
7751

78-
### Request tracing for Express applications
52+
Above will result in the following log printed (if JSON format is enabled).
7953

80-
An Express middleware is provided which automatically populates request headers with request tracing IDs. Sample usage:
81-
82-
```javascript
83-
const { RequestTracing } = require('@hmcts/nodejs-logging')
84-
85-
app.use(RequestTracing.middleware)
54+
```
55+
{ level: 'info',
56+
message: 'What time is the testing at?',
57+
label: 'app.js',
58+
timestamp: '2017-09-30T03:57:26.875Z' }
8659
```
8760

88-
Assuming your Express application servers as the system's entry point which serves user UI, this middleware will intercept user requests and set `Root-Request-Id` and `Request-Id` headers on it. If the incoming request comes from a different service which already populated those values, they will be forwarded.
61+
### Access logging for Express applications
8962

90-
Apart from populating the headers, access to request tracing information is available at any point during request processing, e.g.:
63+
Optionally you can use the built-in Express access logger:
9164

9265
```javascript
93-
const id = RequestTracing.getCurrentRequestId()
94-
```
95-
96-
We can also access the original request:
66+
const { Express } = require('@hmcts/nodejs-logging')
9767

98-
```javascript
99-
const request = RequestTracing.retrieveInitialRequest()
68+
app.use(Express.accessLogger())
10069
```
10170

102-
These features are enabled by [continuation-local-storage module](https://github.com/othiym23/node-continuation-local-storage).
103-
10471
## Units Tests
10572

10673
Just do

index.js

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,5 @@
22

33
module.exports = {
44
Logger: require('./log/Logger'),
5-
LoggingConfig: require('./log/config'),
6-
RequestTracing: require('./log/tracing/requestTracing'),
7-
RequestTracingHeaders: require('./log/tracing/headers'),
85
Express: require('./log/express')
96
}

log/Logger.js

Lines changed: 15 additions & 112 deletions
Original file line numberDiff line numberDiff line change
@@ -1,123 +1,26 @@
1-
const merge = require('lodash.merge');
2-
const moment = require('moment');
3-
const { logging, outputTypes } = require('./config');
4-
const levels = logging.log4js.levels;
1+
const moment = require('moment')
2+
const winston = require('winston')
53

6-
const RequestTracing = require('./tracing/requestTracing');
4+
const container = new winston.Container()
75

8-
let userConfig = {};
6+
function timestamp() {
7+
return moment().format('YYYY-MM-DDTHH:mm:ssZ')
8+
}
99

10-
function isBlank (str) {
11-
return !str || str.trim().length === 0;
10+
function transport(label) {
11+
return new winston.transports.Console({
12+
level: (process.env.LOG_LEVEL || 'INFO').toLowerCase(),
13+
json: process.env.JSON_PRINT || false,
14+
timestamp: timestamp,
15+
label: label
16+
})
1217
}
1318

1419
class Logger {
1520

16-
//----------------------------------------------------
17-
// Public functions
18-
//----------------------------------------------------
19-
20-
constructor() {
21-
}
22-
23-
trace(logEntry) {
24-
logEntry = this._wrap(logEntry);
25-
logEntry.level = levels.TRACE.toString();
26-
return this._log(logEntry);
27-
}
28-
29-
debug(logEntry) {
30-
logEntry = this._wrap(logEntry);
31-
logEntry.level = levels.DEBUG.toString();
32-
return this._log(logEntry);
33-
}
34-
35-
info(logEntry) {
36-
logEntry = this._wrap(logEntry);
37-
logEntry.level = levels.INFO.toString();
38-
return this._log(logEntry);
39-
}
40-
41-
warn(logEntry) {
42-
logEntry = this._wrap(logEntry);
43-
logEntry.level = levels.WARN.toString();
44-
return this._log(logEntry);
45-
}
46-
47-
error(logEntry) {
48-
logEntry = this._wrap(logEntry);
49-
logEntry.level = levels.ERROR.toString();
50-
return this._log(logEntry);
51-
}
52-
53-
fatal(logEntry) {
54-
logEntry = this._wrap(logEntry);
55-
logEntry.level = levels.FATAL.toString();
56-
return this._log(logEntry);
57-
}
58-
59-
//----------------------------------------------------
60-
// Public static functions
61-
//----------------------------------------------------
62-
6321
static getLogger(name) {
64-
const logger = new Logger();
65-
logger.logger = logging.log4js.getLogger(name);
66-
67-
return logger;
68-
}
69-
70-
static config(config) {
71-
userConfig = config || {};
22+
return container.add(name, {transports: [transport(name)]})
7223
}
73-
74-
//----------------------------------------------------
75-
// Private functions
76-
//----------------------------------------------------
77-
78-
_log(logEntry) {
79-
logEntry = merge({ }, logging.defaultLogEntry, logEntry);
80-
this._addTracingInformation(logEntry)
81-
logEntry.timestamp = moment().format(logging.timestampFormat);
82-
const level = logEntry.level.toLowerCase();
83-
84-
logEntry.microservice = userConfig.microservice || 'not-configured';
85-
logEntry.team = userConfig.team || 'not-configured';
86-
logEntry.environment = userConfig.environment || 'not-configured';
87-
88-
if (logging.output === outputTypes.single) {
89-
this.logger[level](JSON.stringify(logEntry));
90-
} else if (logging.output === outputTypes.multi) {
91-
this.logger[level](logEntry);
92-
} else {
93-
this.logger[level](`${logEntry.timestamp} ${logEntry.level} ${this.logger.category}: ${logEntry.message}`)
94-
}
95-
96-
return logEntry;
97-
};
98-
99-
_addTracingInformation (logEntry) {
100-
if (isBlank(logEntry.requestId)) {
101-
logEntry.requestId = RequestTracing.getCurrentRequestId() || logging.defaultLogEntry.requestId;
102-
}
103-
if (isBlank(logEntry.originRequestId)) {
104-
logEntry.originRequestId = RequestTracing.getOriginRequestId() || logging.defaultLogEntry.originRequestId;
105-
}
106-
if (isBlank(logEntry.rootRequestId)) {
107-
logEntry.rootRequestId = RequestTracing.getRootRequestId() || logging.defaultLogEntry.rootRequestId;
108-
}
109-
}
110-
111-
_wrap(message) {
112-
if (typeof message === 'string') {
113-
return { message: message };
114-
} else if (message instanceof String) {
115-
return { message: message.toString() };
116-
} else {
117-
return message;
118-
}
119-
}
120-
12124
}
12225

123-
module.exports = Logger;
26+
module.exports = Logger

log/config.js

Lines changed: 0 additions & 63 deletions
This file was deleted.

log/tracing/headers.js

Lines changed: 0 additions & 5 deletions
This file was deleted.

log/tracing/localStorage.js

Lines changed: 0 additions & 24 deletions
This file was deleted.

0 commit comments

Comments
 (0)