@unito/integration-sdk 2.3.3 → 2.3.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/src/index.cjs
CHANGED
|
@@ -3,6 +3,7 @@
|
|
|
3
3
|
var integrationApi = require('@unito/integration-api');
|
|
4
4
|
var cachette = require('cachette');
|
|
5
5
|
var crypto = require('crypto');
|
|
6
|
+
var util = require('util');
|
|
6
7
|
var express = require('express');
|
|
7
8
|
var busboy = require('busboy');
|
|
8
9
|
var https = require('https');
|
|
@@ -161,7 +162,12 @@ class Logger {
|
|
|
161
162
|
status: logLevel,
|
|
162
163
|
};
|
|
163
164
|
if (process.env.NODE_ENV === 'development') {
|
|
164
|
-
|
|
165
|
+
const coloredMessage = Logger.colorize(message, processedLogs, logLevel);
|
|
166
|
+
const metadata = {
|
|
167
|
+
date: new Date(processedLogs.date).toISOString(),
|
|
168
|
+
...processedMetadata,
|
|
169
|
+
};
|
|
170
|
+
console[logLevel](`${coloredMessage} ${JSON.stringify(metadata, null, 2)}`);
|
|
165
171
|
}
|
|
166
172
|
else {
|
|
167
173
|
console[logLevel](JSON.stringify(processedLogs));
|
|
@@ -204,6 +210,56 @@ class Logger {
|
|
|
204
210
|
}
|
|
205
211
|
return prunedMetadata;
|
|
206
212
|
}
|
|
213
|
+
/**
|
|
214
|
+
* Colorizes the log message based on the log level and status codes.
|
|
215
|
+
* @param message The message to colorize.
|
|
216
|
+
* @param metadata The metadata associated with the log.
|
|
217
|
+
* @param logLevel The log level of the message.
|
|
218
|
+
* @returns The colorized output string.
|
|
219
|
+
*/
|
|
220
|
+
static colorize(message, metadata, logLevel) {
|
|
221
|
+
if (!process.stdout.isTTY) {
|
|
222
|
+
return message;
|
|
223
|
+
}
|
|
224
|
+
const logOutput = `${logLevel}: ${message}`;
|
|
225
|
+
// Extract status code from logs
|
|
226
|
+
let statusCode;
|
|
227
|
+
if (metadata.http && typeof metadata.http === 'object' && !Array.isArray(metadata.http)) {
|
|
228
|
+
const statusCodeValue = metadata.http.status_code;
|
|
229
|
+
if (typeof statusCodeValue === 'number') {
|
|
230
|
+
statusCode = statusCodeValue;
|
|
231
|
+
}
|
|
232
|
+
else if (typeof statusCodeValue === 'string') {
|
|
233
|
+
statusCode = parseInt(statusCodeValue, 10);
|
|
234
|
+
}
|
|
235
|
+
}
|
|
236
|
+
// Color based on status code first
|
|
237
|
+
if (statusCode) {
|
|
238
|
+
if (statusCode >= 400) {
|
|
239
|
+
return util.styleText('red', logOutput);
|
|
240
|
+
}
|
|
241
|
+
else if (statusCode >= 300) {
|
|
242
|
+
return util.styleText('yellow', logOutput);
|
|
243
|
+
}
|
|
244
|
+
else if (statusCode >= 200) {
|
|
245
|
+
return util.styleText('green', logOutput);
|
|
246
|
+
}
|
|
247
|
+
}
|
|
248
|
+
// Fall back to log level if no status code found
|
|
249
|
+
switch (logLevel) {
|
|
250
|
+
case LogLevel.ERROR:
|
|
251
|
+
return util.styleText('red', logOutput);
|
|
252
|
+
case LogLevel.WARN:
|
|
253
|
+
return util.styleText('yellow', logOutput);
|
|
254
|
+
case LogLevel.INFO:
|
|
255
|
+
case LogLevel.LOG:
|
|
256
|
+
return util.styleText('green', logOutput);
|
|
257
|
+
case LogLevel.DEBUG:
|
|
258
|
+
return util.styleText('cyan', logOutput);
|
|
259
|
+
default:
|
|
260
|
+
return logOutput;
|
|
261
|
+
}
|
|
262
|
+
}
|
|
207
263
|
}
|
|
208
264
|
const NULL_LOGGER = new Logger({}, true);
|
|
209
265
|
|
|
@@ -68,6 +68,14 @@ export default class Logger {
|
|
|
68
68
|
private send;
|
|
69
69
|
private static snakifyKeys;
|
|
70
70
|
private static pruneSensitiveMetadata;
|
|
71
|
+
/**
|
|
72
|
+
* Colorizes the log message based on the log level and status codes.
|
|
73
|
+
* @param message The message to colorize.
|
|
74
|
+
* @param metadata The metadata associated with the log.
|
|
75
|
+
* @param logLevel The log level of the message.
|
|
76
|
+
* @returns The colorized output string.
|
|
77
|
+
*/
|
|
78
|
+
private static colorize;
|
|
71
79
|
}
|
|
72
80
|
export declare const NULL_LOGGER: Logger;
|
|
73
81
|
export {};
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { styleText } from 'util';
|
|
1
2
|
var LogLevel;
|
|
2
3
|
(function (LogLevel) {
|
|
3
4
|
LogLevel["ERROR"] = "error";
|
|
@@ -133,7 +134,12 @@ export default class Logger {
|
|
|
133
134
|
status: logLevel,
|
|
134
135
|
};
|
|
135
136
|
if (process.env.NODE_ENV === 'development') {
|
|
136
|
-
|
|
137
|
+
const coloredMessage = Logger.colorize(message, processedLogs, logLevel);
|
|
138
|
+
const metadata = {
|
|
139
|
+
date: new Date(processedLogs.date).toISOString(),
|
|
140
|
+
...processedMetadata,
|
|
141
|
+
};
|
|
142
|
+
console[logLevel](`${coloredMessage} ${JSON.stringify(metadata, null, 2)}`);
|
|
137
143
|
}
|
|
138
144
|
else {
|
|
139
145
|
console[logLevel](JSON.stringify(processedLogs));
|
|
@@ -176,5 +182,55 @@ export default class Logger {
|
|
|
176
182
|
}
|
|
177
183
|
return prunedMetadata;
|
|
178
184
|
}
|
|
185
|
+
/**
|
|
186
|
+
* Colorizes the log message based on the log level and status codes.
|
|
187
|
+
* @param message The message to colorize.
|
|
188
|
+
* @param metadata The metadata associated with the log.
|
|
189
|
+
* @param logLevel The log level of the message.
|
|
190
|
+
* @returns The colorized output string.
|
|
191
|
+
*/
|
|
192
|
+
static colorize(message, metadata, logLevel) {
|
|
193
|
+
if (!process.stdout.isTTY) {
|
|
194
|
+
return message;
|
|
195
|
+
}
|
|
196
|
+
const logOutput = `${logLevel}: ${message}`;
|
|
197
|
+
// Extract status code from logs
|
|
198
|
+
let statusCode;
|
|
199
|
+
if (metadata.http && typeof metadata.http === 'object' && !Array.isArray(metadata.http)) {
|
|
200
|
+
const statusCodeValue = metadata.http.status_code;
|
|
201
|
+
if (typeof statusCodeValue === 'number') {
|
|
202
|
+
statusCode = statusCodeValue;
|
|
203
|
+
}
|
|
204
|
+
else if (typeof statusCodeValue === 'string') {
|
|
205
|
+
statusCode = parseInt(statusCodeValue, 10);
|
|
206
|
+
}
|
|
207
|
+
}
|
|
208
|
+
// Color based on status code first
|
|
209
|
+
if (statusCode) {
|
|
210
|
+
if (statusCode >= 400) {
|
|
211
|
+
return styleText('red', logOutput);
|
|
212
|
+
}
|
|
213
|
+
else if (statusCode >= 300) {
|
|
214
|
+
return styleText('yellow', logOutput);
|
|
215
|
+
}
|
|
216
|
+
else if (statusCode >= 200) {
|
|
217
|
+
return styleText('green', logOutput);
|
|
218
|
+
}
|
|
219
|
+
}
|
|
220
|
+
// Fall back to log level if no status code found
|
|
221
|
+
switch (logLevel) {
|
|
222
|
+
case LogLevel.ERROR:
|
|
223
|
+
return styleText('red', logOutput);
|
|
224
|
+
case LogLevel.WARN:
|
|
225
|
+
return styleText('yellow', logOutput);
|
|
226
|
+
case LogLevel.INFO:
|
|
227
|
+
case LogLevel.LOG:
|
|
228
|
+
return styleText('green', logOutput);
|
|
229
|
+
case LogLevel.DEBUG:
|
|
230
|
+
return styleText('cyan', logOutput);
|
|
231
|
+
default:
|
|
232
|
+
return logOutput;
|
|
233
|
+
}
|
|
234
|
+
}
|
|
179
235
|
}
|
|
180
236
|
export const NULL_LOGGER = new Logger({}, true);
|
|
@@ -129,7 +129,7 @@ describe('Logger', () => {
|
|
|
129
129
|
{ id: 2, organization_id: 'b' },
|
|
130
130
|
]);
|
|
131
131
|
});
|
|
132
|
-
it('prunes sensitive Metadata',
|
|
132
|
+
it('prunes sensitive Metadata', testContext => {
|
|
133
133
|
const logSpy = testContext.mock.method(global.console, 'log', () => { });
|
|
134
134
|
assert.strictEqual(logSpy.mock.calls.length, 0);
|
|
135
135
|
const metadata = {
|
|
@@ -177,4 +177,77 @@ describe('Logger', () => {
|
|
|
177
177
|
assert.strictEqual(infoSpy.mock.calls.length, 0);
|
|
178
178
|
assert.strictEqual(debugSpy.mock.calls.length, 0);
|
|
179
179
|
});
|
|
180
|
+
it('colorizes logs by status codes over log levels', () => {
|
|
181
|
+
const originalEnv = process.env.NODE_ENV;
|
|
182
|
+
const originalIsTTY = process.stdout.isTTY;
|
|
183
|
+
try {
|
|
184
|
+
process.env.NODE_ENV = 'development';
|
|
185
|
+
Object.defineProperty(process.stdout, 'isTTY', {
|
|
186
|
+
value: true,
|
|
187
|
+
configurable: true,
|
|
188
|
+
});
|
|
189
|
+
// 4xx status with warn level, should be red
|
|
190
|
+
const metadataWith400 = {
|
|
191
|
+
http: { status_code: 400 },
|
|
192
|
+
};
|
|
193
|
+
const redResult = Logger['colorize']('Some error', metadataWith400, 'warn');
|
|
194
|
+
// warn level without status code, should be yellow
|
|
195
|
+
const metadataNoStatus = {};
|
|
196
|
+
const yellowResult = Logger['colorize']('Some warning', metadataNoStatus, 'warn');
|
|
197
|
+
// Results should be different colors
|
|
198
|
+
assert.notEqual(redResult, yellowResult);
|
|
199
|
+
assert.ok(redResult.includes('\x1b[31m')); // Red color code
|
|
200
|
+
assert.ok(yellowResult.includes('\x1b[33m')); // Yellow color code
|
|
201
|
+
}
|
|
202
|
+
finally {
|
|
203
|
+
// Restore original values
|
|
204
|
+
process.env.NODE_ENV = originalEnv;
|
|
205
|
+
Object.defineProperty(process.stdout, 'isTTY', {
|
|
206
|
+
value: originalIsTTY,
|
|
207
|
+
configurable: true,
|
|
208
|
+
});
|
|
209
|
+
}
|
|
210
|
+
});
|
|
211
|
+
it('colorizes logs with different status code ranges', () => {
|
|
212
|
+
const originalEnv = process.env.NODE_ENV;
|
|
213
|
+
const originalIsTTY = process.stdout.isTTY;
|
|
214
|
+
try {
|
|
215
|
+
process.env.NODE_ENV = 'development';
|
|
216
|
+
Object.defineProperty(process.stdout, 'isTTY', {
|
|
217
|
+
value: true,
|
|
218
|
+
configurable: true,
|
|
219
|
+
});
|
|
220
|
+
// 2xx status codes should be green
|
|
221
|
+
const successMetadata = {
|
|
222
|
+
http: { status_code: 200 },
|
|
223
|
+
};
|
|
224
|
+
const greenResult = Logger['colorize']('Success', successMetadata, 'info');
|
|
225
|
+
assert.ok(greenResult.includes('\x1b[32m')); // Green color code
|
|
226
|
+
// 3xx status codes should be yellow
|
|
227
|
+
const redirectMetadata = {
|
|
228
|
+
http: { status_code: 301 },
|
|
229
|
+
};
|
|
230
|
+
const yellowResult = Logger['colorize']('Redirect', redirectMetadata, 'info');
|
|
231
|
+
assert.ok(yellowResult.includes('\x1b[33m')); // Yellow color code
|
|
232
|
+
// 4xx status codes should be red
|
|
233
|
+
const clientErrorMetadata = {
|
|
234
|
+
http: { status_code: 404 },
|
|
235
|
+
};
|
|
236
|
+
const redResult = Logger['colorize']('Not Found', clientErrorMetadata, 'warn');
|
|
237
|
+
assert.ok(redResult.includes('\x1b[31m')); // Red color code
|
|
238
|
+
// 5xx status codes should be red
|
|
239
|
+
const serverErrorMetadata = {
|
|
240
|
+
http: { status_code: 500 },
|
|
241
|
+
};
|
|
242
|
+
const redResult2 = Logger['colorize']('Server Error', serverErrorMetadata, 'error');
|
|
243
|
+
assert.ok(redResult2.includes('\x1b[31m')); // Red color code
|
|
244
|
+
}
|
|
245
|
+
finally {
|
|
246
|
+
process.env.NODE_ENV = originalEnv;
|
|
247
|
+
Object.defineProperty(process.stdout, 'isTTY', {
|
|
248
|
+
value: originalIsTTY,
|
|
249
|
+
configurable: true,
|
|
250
|
+
});
|
|
251
|
+
}
|
|
252
|
+
});
|
|
180
253
|
});
|
package/package.json
CHANGED
package/src/resources/logger.ts
CHANGED
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
import { styleText } from 'util';
|
|
2
|
+
|
|
1
3
|
const enum LogLevel {
|
|
2
4
|
ERROR = 'error',
|
|
3
5
|
WARN = 'warn',
|
|
@@ -162,7 +164,14 @@ export default class Logger {
|
|
|
162
164
|
};
|
|
163
165
|
|
|
164
166
|
if (process.env.NODE_ENV === 'development') {
|
|
165
|
-
|
|
167
|
+
const coloredMessage = Logger.colorize(message, processedLogs, logLevel);
|
|
168
|
+
|
|
169
|
+
const metadata = {
|
|
170
|
+
date: new Date(processedLogs.date).toISOString(),
|
|
171
|
+
...processedMetadata,
|
|
172
|
+
};
|
|
173
|
+
|
|
174
|
+
console[logLevel](`${coloredMessage} ${JSON.stringify(metadata, null, 2)}`);
|
|
166
175
|
} else {
|
|
167
176
|
console[logLevel](JSON.stringify(processedLogs));
|
|
168
177
|
}
|
|
@@ -209,6 +218,59 @@ export default class Logger {
|
|
|
209
218
|
|
|
210
219
|
return prunedMetadata;
|
|
211
220
|
}
|
|
221
|
+
|
|
222
|
+
/**
|
|
223
|
+
* Colorizes the log message based on the log level and status codes.
|
|
224
|
+
* @param message The message to colorize.
|
|
225
|
+
* @param metadata The metadata associated with the log.
|
|
226
|
+
* @param logLevel The log level of the message.
|
|
227
|
+
* @returns The colorized output string.
|
|
228
|
+
*/
|
|
229
|
+
private static colorize(message: string, metadata: Value, logLevel: LogLevel): string {
|
|
230
|
+
if (!process.stdout.isTTY) {
|
|
231
|
+
return message;
|
|
232
|
+
}
|
|
233
|
+
|
|
234
|
+
const logOutput = `${logLevel}: ${message}`;
|
|
235
|
+
|
|
236
|
+
// Extract status code from logs
|
|
237
|
+
let statusCode: number | undefined;
|
|
238
|
+
if (metadata.http && typeof metadata.http === 'object' && !Array.isArray(metadata.http)) {
|
|
239
|
+
const statusCodeValue = metadata.http.status_code;
|
|
240
|
+
|
|
241
|
+
if (typeof statusCodeValue === 'number') {
|
|
242
|
+
statusCode = statusCodeValue;
|
|
243
|
+
} else if (typeof statusCodeValue === 'string') {
|
|
244
|
+
statusCode = parseInt(statusCodeValue, 10);
|
|
245
|
+
}
|
|
246
|
+
}
|
|
247
|
+
|
|
248
|
+
// Color based on status code first
|
|
249
|
+
if (statusCode) {
|
|
250
|
+
if (statusCode >= 400) {
|
|
251
|
+
return styleText('red', logOutput);
|
|
252
|
+
} else if (statusCode >= 300) {
|
|
253
|
+
return styleText('yellow', logOutput);
|
|
254
|
+
} else if (statusCode >= 200) {
|
|
255
|
+
return styleText('green', logOutput);
|
|
256
|
+
}
|
|
257
|
+
}
|
|
258
|
+
|
|
259
|
+
// Fall back to log level if no status code found
|
|
260
|
+
switch (logLevel) {
|
|
261
|
+
case LogLevel.ERROR:
|
|
262
|
+
return styleText('red', logOutput);
|
|
263
|
+
case LogLevel.WARN:
|
|
264
|
+
return styleText('yellow', logOutput);
|
|
265
|
+
case LogLevel.INFO:
|
|
266
|
+
case LogLevel.LOG:
|
|
267
|
+
return styleText('green', logOutput);
|
|
268
|
+
case LogLevel.DEBUG:
|
|
269
|
+
return styleText('cyan', logOutput);
|
|
270
|
+
default:
|
|
271
|
+
return logOutput;
|
|
272
|
+
}
|
|
273
|
+
}
|
|
212
274
|
}
|
|
213
275
|
|
|
214
276
|
export const NULL_LOGGER = new Logger({}, true);
|
|
@@ -155,7 +155,7 @@ describe('Logger', () => {
|
|
|
155
155
|
]);
|
|
156
156
|
});
|
|
157
157
|
|
|
158
|
-
it('prunes sensitive Metadata',
|
|
158
|
+
it('prunes sensitive Metadata', testContext => {
|
|
159
159
|
const logSpy = testContext.mock.method(global.console, 'log', () => {});
|
|
160
160
|
assert.strictEqual(logSpy.mock.calls.length, 0);
|
|
161
161
|
|
|
@@ -209,4 +209,86 @@ describe('Logger', () => {
|
|
|
209
209
|
assert.strictEqual(infoSpy.mock.calls.length, 0);
|
|
210
210
|
assert.strictEqual(debugSpy.mock.calls.length, 0);
|
|
211
211
|
});
|
|
212
|
+
|
|
213
|
+
it('colorizes logs by status codes over log levels', () => {
|
|
214
|
+
const originalEnv = process.env.NODE_ENV;
|
|
215
|
+
const originalIsTTY = process.stdout.isTTY;
|
|
216
|
+
|
|
217
|
+
try {
|
|
218
|
+
process.env.NODE_ENV = 'development';
|
|
219
|
+
Object.defineProperty(process.stdout, 'isTTY', {
|
|
220
|
+
value: true,
|
|
221
|
+
configurable: true,
|
|
222
|
+
});
|
|
223
|
+
|
|
224
|
+
// 4xx status with warn level, should be red
|
|
225
|
+
const metadataWith400 = {
|
|
226
|
+
http: { status_code: 400 },
|
|
227
|
+
};
|
|
228
|
+
const redResult = Logger['colorize']('Some error', metadataWith400, 'warn' as any);
|
|
229
|
+
|
|
230
|
+
// warn level without status code, should be yellow
|
|
231
|
+
const metadataNoStatus = {};
|
|
232
|
+
const yellowResult = Logger['colorize']('Some warning', metadataNoStatus, 'warn' as any);
|
|
233
|
+
|
|
234
|
+
// Results should be different colors
|
|
235
|
+
assert.notEqual(redResult, yellowResult);
|
|
236
|
+
assert.ok(redResult.includes('\x1b[31m')); // Red color code
|
|
237
|
+
assert.ok(yellowResult.includes('\x1b[33m')); // Yellow color code
|
|
238
|
+
} finally {
|
|
239
|
+
// Restore original values
|
|
240
|
+
process.env.NODE_ENV = originalEnv;
|
|
241
|
+
Object.defineProperty(process.stdout, 'isTTY', {
|
|
242
|
+
value: originalIsTTY,
|
|
243
|
+
configurable: true,
|
|
244
|
+
});
|
|
245
|
+
}
|
|
246
|
+
});
|
|
247
|
+
|
|
248
|
+
it('colorizes logs with different status code ranges', () => {
|
|
249
|
+
const originalEnv = process.env.NODE_ENV;
|
|
250
|
+
const originalIsTTY = process.stdout.isTTY;
|
|
251
|
+
|
|
252
|
+
try {
|
|
253
|
+
process.env.NODE_ENV = 'development';
|
|
254
|
+
Object.defineProperty(process.stdout, 'isTTY', {
|
|
255
|
+
value: true,
|
|
256
|
+
configurable: true,
|
|
257
|
+
});
|
|
258
|
+
|
|
259
|
+
// 2xx status codes should be green
|
|
260
|
+
const successMetadata = {
|
|
261
|
+
http: { status_code: 200 },
|
|
262
|
+
};
|
|
263
|
+
const greenResult = Logger['colorize']('Success', successMetadata, 'info' as any);
|
|
264
|
+
assert.ok(greenResult.includes('\x1b[32m')); // Green color code
|
|
265
|
+
|
|
266
|
+
// 3xx status codes should be yellow
|
|
267
|
+
const redirectMetadata = {
|
|
268
|
+
http: { status_code: 301 },
|
|
269
|
+
};
|
|
270
|
+
const yellowResult = Logger['colorize']('Redirect', redirectMetadata, 'info' as any);
|
|
271
|
+
assert.ok(yellowResult.includes('\x1b[33m')); // Yellow color code
|
|
272
|
+
|
|
273
|
+
// 4xx status codes should be red
|
|
274
|
+
const clientErrorMetadata = {
|
|
275
|
+
http: { status_code: 404 },
|
|
276
|
+
};
|
|
277
|
+
const redResult = Logger['colorize']('Not Found', clientErrorMetadata, 'warn' as any);
|
|
278
|
+
assert.ok(redResult.includes('\x1b[31m')); // Red color code
|
|
279
|
+
|
|
280
|
+
// 5xx status codes should be red
|
|
281
|
+
const serverErrorMetadata = {
|
|
282
|
+
http: { status_code: 500 },
|
|
283
|
+
};
|
|
284
|
+
const redResult2 = Logger['colorize']('Server Error', serverErrorMetadata, 'error' as any);
|
|
285
|
+
assert.ok(redResult2.includes('\x1b[31m')); // Red color code
|
|
286
|
+
} finally {
|
|
287
|
+
process.env.NODE_ENV = originalEnv;
|
|
288
|
+
Object.defineProperty(process.stdout, 'isTTY', {
|
|
289
|
+
value: originalIsTTY,
|
|
290
|
+
configurable: true,
|
|
291
|
+
});
|
|
292
|
+
}
|
|
293
|
+
});
|
|
212
294
|
});
|