@ringcentral-pro-serv/psi-logging-system
v1.0.5
Published
ProServ Innovation team logger for backend apps
Downloads
344
Keywords
Readme
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
$ git clone https://github.com/RingCentral-Pro-Services/psi-logging-system.git
$ cd psi-logging-system
Install Typescript globally
$ npm install -g typescript
Install dependencies
$ npm install
Compile the app code
$ 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
$ 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.
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.
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
// 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 |