Skip to content

Commit c32799c

Browse files
Merge pull request #1 from composable-software/feature/pino-logger
Add pino logger middleware
2 parents d8de1ad + e2cb9ce commit c32799c

File tree

16 files changed

+4388
-0
lines changed

16 files changed

+4388
-0
lines changed

.eslintrc.yml

Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
env:
2+
es6: true
3+
node: true
4+
jest: true
5+
6+
extends:
7+
- 'standard'
8+
- 'eslint:recommended'
9+
- 'plugin:@typescript-eslint/eslint-recommended'
10+
- 'plugin:@typescript-eslint/recommended'
11+
- 'plugin:@typescript-eslint/recommended-requiring-type-checking'
12+
13+
plugins:
14+
- '@typescript-eslint'
15+
- '@typescript-eslint/eslint-plugin'
16+
17+
parser: '@typescript-eslint/parser'
18+
parserOptions:
19+
ecmaVersion: 2018
20+
sourceType: module
21+
project: ['./tsconfig.eslint.json']
22+
23+
rules:
24+
'@typescript-eslint/member-delimiter-style': [ error, { multiline: { delimiter: none } } ]
25+
'@typescript-eslint/explicit-function-return-type': off
26+
'@typescript-eslint/no-non-null-assertion': off
27+
'@typescript-eslint/no-misused-promises': off
28+
'@typescript-eslint/require-await': off
29+
'@typescript-eslint/no-unsafe-call': off
30+
'@typescript-eslint/no-unsafe-assignment': off
31+
padded-blocks: 0
32+
operator-linebreak: [ error, before ]
33+
comma-dangle: [ error, always-multiline ]
34+
key-spacing: [ error, { align: value } ]
35+
no-multi-spaces: 0
36+
camelcase: 0
37+
array-callback-return: 0
38+
space-before-function-paren: 0
39+
no-useless-constructor: 0
40+
no-void: 0
41+
no-console: 1
42+
indent:
43+
- error
44+
- 2
45+
46+
overrides:
47+
- files: ['tests/**']
48+
rules:
49+
'@typescript-eslint/no-explicit-any': off
50+
'@typescript-eslint/no-unsafe-assignment': off
51+
'@typescript-eslint/no-unsafe-call': off
52+
'@typescript-eslint/unbound-method': off
53+
'@typescript-eslint/no-unsafe-return': off
54+
55+
ignorePatterns: ['.eslintrc.yml', 'example']

.github/workflows/ci.yml

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
---
2+
name: "ci"
3+
4+
on:
5+
push:
6+
branches:
7+
- master
8+
pull_request:
9+
branches:
10+
- master
11+
jobs:
12+
ci:
13+
runs-on: "ubuntu-latest"
14+
15+
steps:
16+
- uses: actions/checkout@v2
17+
18+
- name: Use Node.js
19+
uses: actions/setup-node@v3
20+
with:
21+
node-version: 18
22+
23+
- name: Install
24+
run: yarn
25+
26+
- name: Build
27+
run: yarn build
28+
29+
- name: Lint
30+
run: yarn lint
31+
32+
- name: Test
33+
run: yarn test

.gitignore

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
node_modules/
2+
dist/
3+
.idea
4+
.vscode
5+
example

.npmignore

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
src
2+
tests
3+
yarn.lock
4+
.eslintrc.yml
5+
.github
6+
npm-debug.log
7+
tsconfig.json
8+
tsconfig.eslint.json
9+
.idea

.release-it.json

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
{
2+
"git": {
3+
"requireBranch": "master",
4+
"commitMessage": "chore: release v${version}"
5+
},
6+
"github": {
7+
"release": true,
8+
"autoGenerate": true,
9+
"web": true
10+
},
11+
"npm": {
12+
"publish": false
13+
}
14+
}

README.md

Lines changed: 105 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1 +1,106 @@
11
# commercetools-pino-middleware
2+
3+
![npm](https://img.shields.io/npm/v/@composable-commerce/commercetools-pino-middleware?color=blue) ![npm](https://img.shields.io/npm/l/@composable-commerce/commercetools-pino-middleware)
4+
5+
## Overview
6+
7+
`commercetools-pino-middleware` is a library that provides a seamless integration of Pino logger with the commercetools SDK. It allows you to easily log SDK requests, responses, and other relevant information with Pino, a fast and minimalist Node.js logger. The middleware is designed to be flexible and can be set up with either an auto-generated Pino instance or a custom Pino logger with specific configurations.
8+
9+
## Installation
10+
11+
You can install the library via npm:
12+
13+
```bash
14+
npm install @composable-commerce/commercetools-pino-middleware
15+
```
16+
or with yarn
17+
```bash
18+
yarn add @composable-commerce/commercetools-pino-middleware
19+
```
20+
21+
## Usage
22+
23+
### 1. Using Auto-generated Pino Instance
24+
25+
If you prefer a hassle-free setup, you can let the middleware create and configure the Pino instance for you. Simply pass an empty object when setting up the middleware:
26+
27+
```javascript
28+
import { createPinoMiddleware } from 'commercetools-pino-middleware';
29+
import { ClientBuilder } from '@commercetools/sdk-client-v2';
30+
31+
/**
32+
* Middleware with automatic Pino factory
33+
*/
34+
const client = new ClientBuilder()
35+
.withMiddleware(createPinoMiddleware({}))
36+
.build();
37+
```
38+
39+
In this method, the middleware will handle the instantiation and configuration of the Pino logger automatically.
40+
41+
### 2. Using a Custom Pino Instance
42+
43+
If you need a more customized Pino logger, you can pass your own Pino instance through options:
44+
45+
```javascript
46+
import pino from 'pino';
47+
import { createPinoMiddleware } from 'commercetools-pino-middleware';
48+
import { ClientBuilder } from '@commercetools/sdk-client-v2';
49+
50+
/**
51+
* Custom Pino logger instance that can be passed to the middleware
52+
*/
53+
const logger = pino({
54+
name: 'custom-logger',
55+
level: 'info',
56+
});
57+
58+
const options = {
59+
logger: logger,
60+
};
61+
62+
const client = new ClientBuilder()
63+
.withMiddleware(createPinoMiddleware(options))
64+
.build();
65+
```
66+
67+
In this case, the middleware will use the provided Pino instance to log the information, allowing you to have full control over the logger's configuration.
68+
69+
## Logging Details
70+
71+
The `commercetools-pino-middleware` logs essential details related to SDK requests and responses, including:
72+
73+
- Request method and URL
74+
- Request headers
75+
- Request body (if applicable)
76+
- Response status code
77+
- Response headers
78+
- Response body (if applicable)
79+
80+
All logs are output in a structured JSON format, which makes it easy to parse and analyze the logged data.
81+
82+
## Examples
83+
84+
Here are some examples of how the middleware logs different scenarios:
85+
86+
- **Successful Request:**
87+
88+
```json
89+
{"level":"info","time":1678376443924,"msg":"Request sent","method":"POST","url":"https://api.commercetools.com/products","headers":{"Authorization":"Bearer <access_token>","Content-Type":"application/json"},"body":{"typeId":"product","id":"abc123","version":5}}
90+
{"level":"info","time":1678376453920,"msg":"Response received","status":201,"headers":{"x-request-id":"abc123","content-type":"application/json"},"body":{"id":"abc123","version":5}}
91+
```
92+
93+
- **Failed Request:**
94+
95+
```json
96+
{"level":"error","time":1678376463922,"msg":"Request failed","method":"GET","url":"https://api.commercetools.com/products/xyz789","headers":{"Authorization":"Bearer <access_token>"}}
97+
{"level":"error","time":1678376473923,"msg":"Response received with error","status":404,"headers":{"x-request-id":"xyz789"},"body":{"statusCode":404,"message":"Not Found"}}
98+
```
99+
100+
## Contributing
101+
102+
We welcome contributions from the community! If you encounter any issues or have suggestions for improvements, please feel free to open an issue or submit a pull request on our [GitHub repository](https://github.com/your-github-account/commercetools-pino-middleware).
103+
104+
## License
105+
106+
This library is licensed under the [MIT License](https://opensource.org/licenses/MIT). See the [LICENSE](./LICENSE) file for more details.

package.json

Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,63 @@
1+
{
2+
"name": "@composable-commerce/commercetools-pino-middleware",
3+
"version": "1.0.0",
4+
"description": "Pino logger for commercetools SDK",
5+
"main": "dist/index.js",
6+
"license": "MIT",
7+
"scripts": {
8+
"prebuild": "rimraf dist",
9+
"prepack": "yarn build",
10+
"build": "tsc",
11+
"release": "release-it",
12+
"lint": "eslint \"{src,tests}/**/*.ts\" --fix",
13+
"test": "jest --coverage"
14+
},
15+
"keywords": [
16+
"commercetools",
17+
"pino",
18+
"middleware",
19+
"logger"
20+
],
21+
"homepage": "https://github.com/composable-software/commercetools-pino-middleware",
22+
"bugs": "https://github.com/composable-software/commercetools-pino-middleware/issues",
23+
"devDependencies": {
24+
"@commercetools/sdk-client-v2": "^2.2.0",
25+
"@types/jest": "^27.0.2",
26+
"@types/node": "^16.10.2",
27+
"@typescript-eslint/eslint-plugin": "^4.31.2",
28+
"@typescript-eslint/parser": "^4.31.2",
29+
"eslint": "^7.32.0",
30+
"eslint-config-standard": "^16.0.3",
31+
"eslint-plugin-import": "^2.24.2",
32+
"eslint-plugin-jest": "^24.4.2",
33+
"eslint-plugin-node": "^11.1.0",
34+
"eslint-plugin-promise": "^5.1.0",
35+
"jest": "^27.2.4",
36+
"pino": "^8.14.1",
37+
"rambda": "^8.2.0",
38+
"rimraf": "^3.0.2",
39+
"ts-jest": "^27.0.5",
40+
"type-fest": "^4.0.0",
41+
"typescript": "^4.4.3"
42+
},
43+
"jest": {
44+
"moduleFileExtensions": [
45+
"js",
46+
"json",
47+
"ts"
48+
],
49+
"testRegex": "(/tests/(.*))\\.test.ts$",
50+
"transform": {
51+
"^.+\\.(t|j)s$": "ts-jest"
52+
},
53+
"collectCoverageFrom": [
54+
"src/*.ts",
55+
"src/**/*.ts"
56+
],
57+
"coverageDirectory": "../coverage",
58+
"testEnvironment": "node"
59+
},
60+
"peerDependencies": {
61+
"pino": "^8.14.1"
62+
}
63+
}

src/index.ts

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
export * from './types'
2+
3+
export { default as createPinoMiddleware } from './middleware'

src/logger.ts

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
import pino, { Logger } from 'pino'
2+
3+
import { PinoLoggerOptions } from './types'
4+
5+
export const getLogger = (options: PinoLoggerOptions): Logger => {
6+
if (options.logger) {
7+
return options.logger
8+
}
9+
10+
return pino({
11+
name: 'commercetools',
12+
level: 'info',
13+
})
14+
}

src/middleware.ts

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
import type { Middleware, Dispatch, MiddlewareRequest, MiddlewareResponse } from '@commercetools/sdk-client-v2'
2+
3+
import type { PinoLoggerOptions, Logger } from './types'
4+
import { getLogger } from './logger'
5+
6+
export default function createPinoMiddleware(options: PinoLoggerOptions): Middleware {
7+
return (next: Dispatch): Dispatch => (
8+
request: MiddlewareRequest,
9+
response: MiddlewareResponse,
10+
) => {
11+
// pino factory
12+
const logger: Logger = getLogger(options)
13+
14+
logger.info(request, 'request')
15+
logger.info(response, 'response')
16+
17+
return next(request, response)
18+
}
19+
}

0 commit comments

Comments
 (0)