npm package: @ringcentral-pro-serv/psi-logging-system
Description: ProServ Innovation team logger for backend apps
Author: John Celoria
Latest version: 1.0.5

# logging-system
TODO: Flesh this out  with examples and what not.

## Installation

TESTING Time
Right now, I'm pulling the image into an express app just by having npm install from the local app directory (`npm install /path/to/psi-logging-system`) for this 
logging system. Those are the instructions I'll give.

Pre-reqs:
* Node v14.17.x or higher (required for crypto to generate a UUID)
* Git

### Clone the repo locally
```bash
$ git clone https://github.com/RingCentral-Pro-Services/psi-logging-system.git
$ cd psi-logging-system
```

### Install Typescript globally
```bash
$ npm install -g typescript
```

### Install dependencies
```bash
$ npm install
```

### Compile the app code
```bash
$ tsc
```

If you're going to be working actively on the code in the `/src` directory, you'll need `tsc` to run 
every time you make a change. To make that simpler, dedicate a terminal window to the following task

```bash
$ tsc --watch
```
This will have the typescript compiler run in the background, and monitor file changes in your app directory

## Usage
This logging system can be used in an application, or service. It comes with an express middleware for adding a header
to all requests and responses for ease of use in Grafana, but it is not required to use it.

### Middleware for Express
Firstly, you must register the `ps-request-id` middleware. This will add a unique request id to the request object, 
response object, and response headers.

```typescript
const express = require('express')
const app = express()
const port = 3000

const {addPsRequestId} = require('psi-logging-system'); // import middleware

app.use(addPsRequestId); // register middleware
```

### Logger
Next, you need to create a Winston logger instance using our init method. This logger has a formatter
that will add request/response labels to log entries, if you provide a request/response object to your log output.

```typescript
const {init} = require('../logging-system');

const logger = init({
    host: process.env.LOKI_HOST || "http://localhost:3100",
    labels: {
        app: process.env.LOKI_APP_NAME || "someAppName",
        service: process.env.LOKI_SERVICE_NAME || "someServiceForThisApp"
    },
    stdout: true // if you want to see the logs in the terminal. not recommended for production
});

module.exports = logger;
```

Now you can import this logger into any route or js file you want to log from. Using the example above, you can log 
from any route by doing the following

```typescript
// src/index.js

const express = require('express')
const app = express()
const port = 3000

const logger = require('/path/to/your/logger-instance'); // where I put my logger file

const {addPsRequestId} = require('psi-logging-system'); // import middleware

app.use(addPsRequestId); // register middleware

app.get('/', (req, res) => {
    logger.info({
        message: "New Inbound Request",
        request: req
    })
    
    res
        .send('Hello World!')
        .then(() =>{
            logger.info({
                message: "Successfully responed to GET request",
                response: res
            });
        })
        .catch(e =>{
            logger.error({
                message: "Something went wrong!",
                response: res,
                errorInfo: e // this would send the ENTIRE error object, not just the message
            });
        })
})

app.listen(port, () => {
  logger.debug(`Example app listening on port ${port}`)
})
```

This would result in two logs being sent to OpenSearch. The first log would be the request, and the second would be the 
successful response message, or the failed response error message.

### Init Options

| **Parameter**       | **Description**                                                | **Example**                 | **Default** |
|---------------------|----------------------------------------------------------------|-----------------------------|-------------|
| __`host`__          | URL for Grafana Loki                                           | http://127.0.0.1:3100       | null        |
| `stdout`            | Option to print to terminal. Should not be used in production  | true                        | false       |
| `interval`          | The interval at which batched logs are sent in seconds         | 30                          | 5           |
| `json`              | Use JSON instead of Protobuf for transport                     | true                        | false       |
| `batching`          | If batching is not used, the logs are sent as they come        | true                        | true        |
| `clearOnError`      | Discard any logs that result in an error during transport      | true                        | false       |
| `replaceTimestamp`  | Replace any log timestamps with Date.now()                     | true                        | false       |
| `labels`            | custom labels, key-value pairs                                 | { module: 'http' }          | undefined   |
| `format`            | winston format (https://github.com/winstonjs/winston#formats)  | simple()                    | undefined   |
| `gracefulShutdown`  | Enable/disable graceful shutdown (wait for any unsent batches) | false                       | true        |
| `timeout`           | timeout for requests to grafana loki in ms                     | 30000                       | undefined   | 
| `basicAuth`         | basic authentication credentials to access Loki over HTTP      | username:password           | undefined   | 
| `onConnectionError` | Loki error connection handler                                  | (err) => console.error(err) | undefined   |