From 2dcd3340b98e70ee451232e8d8b31298575466e2 Mon Sep 17 00:00:00 2001 From: Cyber Dracula <1976475+CyberDracula@users.noreply.github.com> Date: Tue, 4 Apr 2023 23:32:35 +0300 Subject: [PATCH 1/5] adding traceId posibility and better formating of log line --- src/common/config.ts | 1 + src/common/string-builder.ts | 20 +++++++++++++++++--- src/common/types.ts | 3 +++ src/logger/request.ts | 1 + src/logger/response.ts | 1 + 5 files changed, 23 insertions(+), 3 deletions(-) diff --git a/src/common/config.ts b/src/common/config.ts index 54aa650..9c5a225 100644 --- a/src/common/config.ts +++ b/src/common/config.ts @@ -11,6 +11,7 @@ let globalConfig: Required = { prefixText: 'Axios', dateFormat: false, headers: false, + traceId: false, }; function getGlobalConfig() { diff --git a/src/common/string-builder.ts b/src/common/string-builder.ts index 7a92288..ddaf14d 100644 --- a/src/common/string-builder.ts +++ b/src/common/string-builder.ts @@ -4,18 +4,20 @@ import chalk from 'chalk'; class StringBuilder { private config: GlobalLogConfig; + private lineHeader: Array; private printQueue: Array; private filteredHeaderList: Array; constructor(config: GlobalLogConfig) { this.config = config; + this.lineHeader = []; this.printQueue = []; this.filteredHeaderList = ['common', 'delete', 'get', 'head', 'post', 'put', 'patch', 'content-type', 'content-length', 'vary', 'date', 'connection', 'content-security-policy']; } makeLogTypeWithPrefix(logType: string) { const prefix = this.config.prefixText === false ? `[${logType}]` : `[${this.config.prefixText || 'Axios'}][${logType}]`; - this.printQueue.push(chalk.green(prefix)); + this.lineHeader.push(chalk.green(prefix)); return this; } @@ -24,7 +26,14 @@ class StringBuilder { if (this.config.dateFormat !== false) { // @ts-ignore const dateFormat = dateformat(date, this.config.dateFormat || 'isoDateTime'); - this.printQueue.push(dateFormat); + this.lineHeader.push(`[${dateFormat}]`); + } + return this; + } + + makeTraceId() { + if (this.config.traceId !== false) { + this.lineHeader.push(`[${chalk.blue(this.config.traceId)}]`); } return this; } @@ -76,8 +85,13 @@ class StringBuilder { return this; } + buildLineHeader() { + return this.lineHeader.join(); + } + build() { - return this.printQueue.join(' '); + const lineStart = this.buildLineHeader(); + return `${lineStart} ` + this.printQueue.join(' '); } /** diff --git a/src/common/types.ts b/src/common/types.ts index 42c8e9e..95a5fb8 100644 --- a/src/common/types.ts +++ b/src/common/types.ts @@ -12,18 +12,21 @@ export interface GlobalLogConfig extends CommonConfig { url?: boolean, status?: boolean, statusText?: boolean, + traceId?: string | boolean, } export interface RequestLogConfig extends CommonConfig { data?: boolean, method?: boolean, url?: boolean, + traceId?: string | boolean, } export interface ResponseLogConfig extends CommonConfig { data?: boolean, status?: boolean, statusText?: boolean, + traceId?: string | boolean, } export interface ErrorLogConfig extends CommonConfig { diff --git a/src/logger/request.ts b/src/logger/request.ts index 33646e2..26dea80 100644 --- a/src/logger/request.ts +++ b/src/logger/request.ts @@ -12,6 +12,7 @@ function requestLogger(request: AxiosRequestConfig, config: RequestLogConfig = { const log = stringBuilder .makeLogTypeWithPrefix('Request') .makeDateFormat(new Date()) + .makeTraceId() .makeMethod(method) .makeUrl(url, baseURL) .makeParams(params) diff --git a/src/logger/response.ts b/src/logger/response.ts index 0ff56ef..4f311bd 100644 --- a/src/logger/response.ts +++ b/src/logger/response.ts @@ -12,6 +12,7 @@ function responseLogger(response: AxiosResponse, config: ResponseLogConfig = {}) const log = stringBuilder .makeLogTypeWithPrefix('Response') .makeDateFormat(new Date()) + .makeTraceId() .makeMethod(method) .makeUrl(url, baseURL) .makeParams(params) From 5637731daa7969e8f9d17bfad83449504274794a Mon Sep 17 00:00:00 2001 From: Cyber Dracula <1976475+CyberDracula@users.noreply.github.com> Date: Wed, 5 Apr 2023 00:08:31 +0300 Subject: [PATCH 2/5] fix tests --- src/common/__test__/config.spec.js | 3 +++ src/common/__test__/string-builder.spec.js | 14 ++++++++++++++ src/common/string-builder.ts | 3 +-- src/logger/error.ts | 1 + 4 files changed, 19 insertions(+), 2 deletions(-) diff --git a/src/common/__test__/config.spec.js b/src/common/__test__/config.spec.js index ba5dda8..25159f5 100644 --- a/src/common/__test__/config.spec.js +++ b/src/common/__test__/config.spec.js @@ -15,6 +15,7 @@ test('Default globalConfig properties should be equal to default values', () => dateFormat: false, prefixText: DEFAULT_PREFIX, headers: false, + traceId: false, }); }); @@ -37,6 +38,7 @@ test('setGlobalConfig should set config. getGlobalConfig should return globalCon dateFormat: false, prefixText: DEFAULT_PREFIX, headers: false, + traceId: false, }); }); @@ -64,5 +66,6 @@ test('assembleBuildConfig should return merged with globalConfig object.', () => dateFormat: 'hh:mm:ss', prefixText: DEFAULT_PREFIX, headers: false, + traceId: false, }); }); diff --git a/src/common/__test__/string-builder.spec.js b/src/common/__test__/string-builder.spec.js index cbf329f..810f97b 100644 --- a/src/common/__test__/string-builder.spec.js +++ b/src/common/__test__/string-builder.spec.js @@ -1,5 +1,6 @@ import StringBuilder from '../string-builder'; import { getGlobalConfig } from '../config'; +import chalk from 'chalk'; test('makeLogTypeWithPrefix should add prefix text', () => { const sb = new StringBuilder(getGlobalConfig()); @@ -85,3 +86,16 @@ test('makeData should not stringify data if configured not to', () => { const result = sb.makeData(a).build(); expect(result).toEqual(''); }); + +test('makeTraceId should add a string if configured', () => { + const testId = '1324567890987654321'; + const config = { + ...getGlobalConfig(), + traceId: testId, + }; + + const sb = new StringBuilder(config); + const result = sb.makeTraceId().build(); + + expect(result).toContain(`[${chalk.blue(testId)}]`); +}); diff --git a/src/common/string-builder.ts b/src/common/string-builder.ts index ddaf14d..1863ffc 100644 --- a/src/common/string-builder.ts +++ b/src/common/string-builder.ts @@ -90,8 +90,7 @@ class StringBuilder { } build() { - const lineStart = this.buildLineHeader(); - return `${lineStart} ` + this.printQueue.join(' '); + return this.buildLineHeader() ? `${this.buildLineHeader()} ` + this.printQueue.join(' ') : this.printQueue.join(' '); } /** diff --git a/src/logger/error.ts b/src/logger/error.ts index 4cb9bcb..274d089 100644 --- a/src/logger/error.ts +++ b/src/logger/error.ts @@ -24,6 +24,7 @@ function errorLoggerWithoutPromise(error: AxiosError, config: ErrorLogConfig = { const log = stringBuilder .makeLogTypeWithPrefix('Error') .makeDateFormat(new Date()) + .makeTraceId() .makeMethod(method) .makeUrl(url, baseURL) .makeParams(params) From c7b29072da0d84a086d8ccbc73c09ae8467456d3 Mon Sep 17 00:00:00 2001 From: Cyber Dracula <1976475+CyberDracula@users.noreply.github.com> Date: Wed, 5 Apr 2023 00:21:06 +0300 Subject: [PATCH 3/5] small fix --- src/common/string-builder.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/common/string-builder.ts b/src/common/string-builder.ts index 1863ffc..1931c6a 100644 --- a/src/common/string-builder.ts +++ b/src/common/string-builder.ts @@ -86,7 +86,7 @@ class StringBuilder { } buildLineHeader() { - return this.lineHeader.join(); + return this.lineHeader.join(''); } build() { From 496a5923ad54e37818e68f7c37971b17e7eae078 Mon Sep 17 00:00:00 2001 From: Cyber Dracula <1976475+CyberDracula@users.noreply.github.com> Date: Wed, 5 Apr 2023 01:05:31 +0300 Subject: [PATCH 4/5] adding a full test scenario --- src/logger/__test__/request.spec.js | 30 ++++++++++++++++++++++ src/logger/__test__/response.spec.js | 38 ++++++++++++++++++++++++++++ 2 files changed, 68 insertions(+) diff --git a/src/logger/__test__/request.spec.js b/src/logger/__test__/request.spec.js index 72299c3..7276fd8 100644 --- a/src/logger/__test__/request.spec.js +++ b/src/logger/__test__/request.spec.js @@ -1,4 +1,5 @@ import { requestLogger, setGlobalConfig } from '../../index'; +import chalk from 'chalk'; const printLog = jest.fn(() => {}); @@ -91,3 +92,32 @@ test('if baseUrl is taken into consideration', () => { expect(printLog).toHaveBeenCalled(); expect(printLog).toBeCalledWith(expect.stringContaining(axiosRequestConfig.url)); }); + +test('test a full request', () => { + const globalConfig = { + prefixText: 'TEST', + dateFormat: 'dd-mm-yyyy HH:MM:ss.l', + status: true, + method: true, + headers: true, + data: true, + traceId: '1324567890987654321', + }; + + setGlobalConfig(globalConfig); + requestLogger({ ...axiosRequestConfig, baseURL: 'https://github.com/', url: '/hg-pyun' }); + expect(printLog).toHaveBeenCalled(); + expect(printLog).toBeCalledWith(expect.stringContaining('[TEST]')); + expect(printLog).toBeCalledWith(expect.stringContaining('[Request]')); + expect(printLog).toBeCalledWith(expect.stringContaining(`[${chalk.blue('1324567890987654321')}]`)); + expect(printLog).toBeCalledWith( + expect.stringMatching( + new RegExp( + /\[[01]?\d-(([0-2]?\d)|([3][01]))-((199\d)|([2-9]\d{3})) ([0-1]\d|[2][0-3]):([0-5]\d):([0-5]\d).(\d{0,3})\]/ + ) + ) + ); + expect(printLog).toBeCalledWith(expect.stringContaining(axiosRequestConfig.method)); + expect(printLog).toBeCalledWith(expect.stringContaining(axiosRequestConfig.url)); + expect(printLog).toBeCalledWith(expect.stringContaining(JSON.stringify(axiosRequestConfig.data))); +}); diff --git a/src/logger/__test__/response.spec.js b/src/logger/__test__/response.spec.js index 54ecd61..8da5471 100644 --- a/src/logger/__test__/response.spec.js +++ b/src/logger/__test__/response.spec.js @@ -1,4 +1,5 @@ import { responseLogger, setGlobalConfig } from '../../index'; +import chalk from 'chalk'; const printLog = jest.fn(() => {}); @@ -104,3 +105,40 @@ test('if baseUrl is taken into consideration', () => { expect(printLog).toHaveBeenCalled(); expect(printLog).toBeCalledWith(expect.stringContaining(axiosResponse.config.url)); }); + +test('test a full response', () => { + const globalConfig = { + prefixText: 'TEST', + dateFormat: 'dd-mm-yyyy HH:MM:ss.l', + status: true, + method: true, + headers: true, + data: true, + traceId: '1324567890987654321', + }; + + const { + status, + statusText, + data, + config: { url, method }, + } = axiosResponse; + + setGlobalConfig(globalConfig); + responseLogger(axiosResponse); + expect(printLog).toHaveBeenCalled(); + expect(printLog).toBeCalledWith(expect.stringContaining('[TEST]')); + expect(printLog).toBeCalledWith(expect.stringContaining('[Response]')); + expect(printLog).toBeCalledWith(expect.stringContaining(`[${chalk.blue('1324567890987654321')}]`)); + expect(printLog).toBeCalledWith( + expect.stringMatching( + new RegExp( + /\[[01]?\d-(([0-2]?\d)|([3][01]))-((199\d)|([2-9]\d{3})) ([0-1]\d|[2][0-3]):([0-5]\d):([0-5]\d).(\d{0,3})\]/ + ) + ) + ); + expect(printLog).toBeCalledWith(expect.stringContaining(method)); + expect(printLog).toBeCalledWith(expect.stringContaining(url)); + expect(printLog).toBeCalledWith(expect.stringContaining(`${status}:${statusText}`)); + expect(printLog).toBeCalledWith(expect.stringContaining(data)); +}); From 9f2caa1ef242d1b9c9482d9fddee8213a05bcfc7 Mon Sep 17 00:00:00 2001 From: Vlad Dumitru <1976475+vladdumitru@users.noreply.github.com> Date: Fri, 30 Jun 2023 02:49:43 +0300 Subject: [PATCH 5/5] add traceId to readme --- README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/README.md b/README.md index 2b2cb02..86512f5 100644 --- a/README.md +++ b/README.md @@ -131,6 +131,7 @@ instance.interceptors.request.use((request) => { | `prefixText` | string \| `false` | `'Axios'` | `false` => no prefix, otherwise, customize the prefix wanted. | | `dateFormat` | [dateformat](https://github.com/felixge/node-dateformat) \| `false` | `false` | `false` => no timestamp, otherwise, customize its format | | `logger` | function | `console.log` | Allows users to customize the logger function to be used. e.g. Winston's `logger.info` could be leveraged, like this: `logger.info.bind(this)` | +| `traceId` | string \| `false` | `false` | Allows users to add a string to be used as a traceable id between request/response (or a sequence of them). | ## CONTRIBUTE