Просмотр исходного кода

feat: enhance morgan-like format with color support for log messages

Yuki Takei 1 день назад
Родитель
Сommit
4057139964

+ 7 - 3
packages/logger/src/dev/morgan-like-format-options.spec.ts

@@ -3,6 +3,10 @@ import { describe, expect, it } from 'vitest';
 
 import { morganLikeFormatOptions } from './morgan-like-format-options';
 
+// Strip ANSI escape codes for plain-text assertions (avoids control-char lint rule)
+const ANSI_RE = new RegExp(`${String.fromCharCode(27)}\\[\\d+m`, 'g');
+const strip = (s: string) => s.replace(ANSI_RE, '');
+
 function fakeReq(method: string, url: string): IncomingMessage {
   return { method, url } as IncomingMessage;
 }
@@ -19,7 +23,7 @@ describe('morganLikeFormatOptions', () => {
         fakeRes(200),
         12.4,
       );
-      expect(msg).toBe('GET /page/path 200 - 12ms');
+      expect(strip(msg)).toBe('GET /page/path 200 - 12ms');
     });
 
     it('rounds responseTime to nearest integer', () => {
@@ -28,7 +32,7 @@ describe('morganLikeFormatOptions', () => {
         fakeRes(201),
         0.7,
       );
-      expect(msg).toBe('POST /api 201 - 1ms');
+      expect(strip(msg)).toBe('POST /api 201 - 1ms');
     });
   });
 
@@ -39,7 +43,7 @@ describe('morganLikeFormatOptions', () => {
         fakeRes(500),
         new Error('db timeout'),
       );
-      expect(msg).toBe('PUT /data 500 - db timeout');
+      expect(strip(msg)).toBe('PUT /data 500 - db timeout');
     });
   });
 

+ 16 - 2
packages/logger/src/dev/morgan-like-format-options.ts

@@ -10,6 +10,18 @@ import type { IncomingMessage, ServerResponse } from 'node:http';
  *   pinoHttp({ ...morganLikeFormatOptions, logger })
  */
 
+const NO_COLOR = Boolean(process.env.NO_COLOR);
+const RESET = NO_COLOR ? '' : '\x1b[0m';
+const DIM = NO_COLOR ? '' : '\x1b[2m';
+
+function statusAnsi(status: number): string {
+  if (NO_COLOR) return '';
+  if (status >= 500) return '\x1b[31m'; // red
+  if (status >= 400) return '\x1b[33m'; // yellow
+  if (status >= 300) return '\x1b[36m'; // cyan
+  return '\x1b[32m'; // green
+}
+
 type CustomSuccessMessage = (
   req: IncomingMessage,
   res: ServerResponse,
@@ -36,11 +48,13 @@ export const morganLikeFormatOptions: {
   customLogLevel: CustomLogLevel;
 } = {
   customSuccessMessage: (req, res, responseTime) => {
-    return `${req.method} ${req.url} ${res.statusCode} - ${Math.round(responseTime)}ms`;
+    const sc = statusAnsi(res.statusCode);
+    return `${req.method} ${RESET}${req.url} ${sc}${res.statusCode}${RESET} - ${DIM}${Math.round(responseTime)}ms${RESET}`;
   },
 
   customErrorMessage: (req, res, error) => {
-    return `${req.method} ${req.url} ${res.statusCode} - ${error.message}`;
+    const sc = statusAnsi(res.statusCode);
+    return `${req.method} ${RESET}${req.url} ${sc}${res.statusCode}${RESET} - ${error.message}`;
   },
 
   customLogLevel: (_req, res, error) => {