# nodejs-owslogger

Logger for emitting logs in specified ows format for JS applications.

## Install Dependencies

It is assumed you have installed the following:

-   [Node](https://nodejs.org/en/download/)
-   [Yarn](https://classic.yarnpkg.com/en/docs/install)

## Running Locally

```sh
$ git clone git@github.com:cieloazure/nodejs-owslogger.git
$ yarn install
```

## Running tests

Tests are written using Jest.

```sh
$ yarn test
```

## Contributing

PR to nodejs-owslogger are always welcome. However, in the interest of smooth operation of CI/CD pipeline
[nodejs-owslogger-pipeline](https://pipeline.theorchard.io/job/nodejs-owslogger-pipeline/) you need to update the
version in `package.json` whenever you make an update.

## Examples

### Standalone Logger

The logger can be used as a independent logger in following way

#### Creating a new logger

In Javascript,

```javascript
import { createOwsLogger } from 'owslogger';

const opts = {
    dsn: 'udp://<fluentd-udp-hostname>:<fluentd-udp-port>',
    environment: 'dev',
    loggerName: 'owslogger',
    serviceName: 'gateway-social-auth',
    serviceVersion: '1.0.0'
};

const logger = createOwsLogger(opts);
```

In Typescript,

```javascript
import { createOwsLogger, OwsLoggerOptions } from 'owslogger';

const opts: OwsLoggerOptions = {
    dsn: 'udp://<fluentd-udp-hostname>:<fluentd-udp-port>',
    environment: 'dev',
    loggerName: 'owslogger',
    serviceName: 'gateway-social-auth',
    serviceVersion: '1.0.0',
    isAutologEnabled: true
};

const logger: OwsLogger = createOwsLogger(opts);
```

#### Using the logger

Logger created above is now ready to send logs. Following are the types of logs you can send.

```javascript
logger.debug('This is a DEBUG log');
logger.info('This is a INFO log');
logger.notice('This is a NOTICE log');
logger.warning('This is a WARNING log');
logger.error('This is a ERROR log');
logger.crit('This is CRITICAL log');
logger.alert('This is still a CRITICAL log');
logger.emerg('This is still a CRITICAL log');
```

#### Modifying fields to be logger

The logger can be customized to change value of the field to be logger by using the `with()` method on the logger. The fields to be modified can be any in the `OwsMeta` interface.

```javascript
logger.with({ correlation_id: '1234' }).info('...');
logger
    .with({ service_name: 'my-custom-service', service_version: '1.0.0' })
    .info('...');
logger.with({ environment: 'custom-debug' }).info('...');
```

#### Logging to console

If you don't want UDP transport, you can log to console by simply omitting the `dsn` field in `OwsLoggerOptions`.

NOTE: If this field is not mentioned, it will always default to console logger

```javascript
const logger = createOwsLogger();
logger.info('I am displayed on CONSOLE');
```

#### Logging with resources

If you want to log with some extra resources, you can use pass `resources` option to the logger.

NOTE: Only the `resources` tag is extracted in the logs.

```javascript
const logger = createOwsLogger();
logger.info('I am INFO with RESOURCES', {
    resources: { upc: 'awesome', isrc: 'incredible' }
});
```

#### Logging to Http service

You can also use http/https based dsn for transporting your logs.

```javascript
const logger = createOwsLogger({
    dsn: 'https://localhost:5000/log',
    environment: 'test',
    loggerLevel: 'debug',
    serviceName: 'gateway-social-auth',
    serviceVersion: '1.0.0'
});
logger.info('I am logged to an HTTP service');
```

#### Waiting for all logs to be transmitted

The logs are sent in an asynchronous manner. If you want to ensure all logs have been transmitted before terminating your application you can wait for logger to end by using the `done()` method.

```javascript
process.on('exit', () => {
    logger.done().then(() => {});
});
```

### Express Logger

`owslogger` can be used as a middleware in express application for logging requests and responses. The logger is scoped per request and can be found in `res.locals.GLOBAL_LOGGER`. In order to use `owslogger` in express middleware, import `expressOwsLogger` from `owslogger`.

In your `app.ts` or `app.js`,

```javascript
import express from 'express';
import { expressOwsLogger } from 'owslogger';

const app = express();
const opts = {
    dsn: 'udp://<fluentd-udp-hostname>:<fluentd-udp-port>',
    environment: 'dev',
    loggerName: 'owslogger',
    serviceName: 'gateway-social-auth',
    serviceVersion: '1.0.0'
};
app.use(expressOwsLogger(opts));
```

#### Correlation Id

In order to track the request across the microservices, this logger also gives you the convinience of setting correlation id for a request if one is not already present. If one is present in the request header it reuses that.

If a correlation id is created for the request. It will emit a debug log with following message

```
Correlation-Id 1 created
```

If a correlation id is received from a request. It will emit a debug log with following message.

```
Correlation-Id 1 received
```

#### Autologging

`expressOwsLogger` gives you the functionality of autologging. You can pass in the option `autolog: true` while creating expressOwsLogger in order to get the convinience in an express application.

```javascript
import express from 'express';
import { expressOwsLogger } from 'owslogger';

const app = express();
const opts = {
    dsn: 'udp://<fluentd-udp-hostname>:<fluentd-udp-port>',
    environment: 'dev',
    loggerName: 'owslogger',
    serviceName: 'gateway-social-auth',
    serviceVersion: '1.0.0',
    autolog: true
};
app.use(expressOwsLogger(opts));
```

By doing this, you will be able to log responses to your express application. For eg.

```
200 - GET /hello
```

This log will be set in the message field of the json log.

#### Application Logging

If any application level logs need to be emitted during the processing of the request. The logger object is set in the `res.locals` object in express. It can be used in the following way -

```javascript
res.locals.GLOBAL_LOGGER.info('Hello world');
```
