Skip to content

Commit ec15565

Browse files
committed
fix: fix loggger encode & decode issues
1 parent 60ccd6d commit ec15565

File tree

6 files changed

+114
-162
lines changed

6 files changed

+114
-162
lines changed

package-lock.json

Lines changed: 13 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

src/commands/index.ts

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,4 @@
11
#! /usr/bin/env node
2-
3-
// Apply terminal encoding before any other imports to ensure proper output
4-
import { applyTerminalEncoding } from '../common/encoding';
5-
applyTerminalEncoding();
6-
72
import { Command } from 'commander';
83
import { clearContext, getContext, getIamInfo, getVersion, logger, setContext } from '../common';
94
import { validate } from './validate';

src/common/encoding.ts

Lines changed: 0 additions & 145 deletions
This file was deleted.

src/common/index.ts

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,4 @@
11
export * from './providerEnum';
2-
export * from './encoding';
32
export * from './logger';
43
export * from './getVersion';
54
export * from './rosClient';

src/common/logger.ts

Lines changed: 101 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,108 @@
11
import pino from 'pino';
2+
import pinoPretty from 'pino-pretty';
3+
import { execSync } from 'child_process';
4+
import iconv from 'iconv-lite';
5+
import { Writable } from 'stream';
26

3-
const logger = pino({
4-
name: 'ServerlessInsight',
5-
level: ['ServerlessInsight', '*'].includes(process.env.DEBUG || '') ? 'debug' : 'info',
6-
transport: {
7-
target: 'pino-pretty',
8-
options: {
7+
const CODE_PAGE_TO_ENCODING: Record<number, string> = {
8+
932: 'shift_jis', // Japanese
9+
936: 'gbk', // Simplified Chinese
10+
949: 'euc-kr', // Korean
11+
950: 'big5', // Traditional Chinese
12+
1250: 'windows-1250', // Central European
13+
1251: 'windows-1251', // Cyrillic
14+
1252: 'windows-1252', // Latin I
15+
1253: 'windows-1253', // Greek
16+
1254: 'windows-1254', // Turkish
17+
1255: 'windows-1255', // Hebrew
18+
1256: 'windows-1256', // Arabic
19+
1257: 'windows-1257', // Baltic
20+
1258: 'windows-1258', // Vietnamese
21+
65001: 'utf8', // UTF-8
22+
1200: 'utf16le', // UTF-16 LE
23+
1201: 'utf16be', // UTF-16 BE
24+
20127: 'ascii', // ASCII
25+
28591: 'iso-8859-1', // Latin-1
26+
};
27+
28+
const getSystemEncoding = (): string => {
29+
if (process.platform === 'win32') {
30+
try {
31+
const codePageOutput = execSync('chcp', {
32+
encoding: 'utf8',
33+
stdio: ['pipe', 'pipe', 'pipe'],
34+
}).toString();
35+
const codePageMatch = codePageOutput.match(/(\d+)\s*$/m);
36+
if (codePageMatch) {
37+
const codePage = parseInt(codePageMatch[1], 10);
38+
39+
return CODE_PAGE_TO_ENCODING[codePage] || 'utf8';
40+
}
41+
} catch {
42+
// fallback to environment variable detection
43+
}
44+
}
45+
46+
const langEnv = (
47+
process.env.LANG ||
48+
process.env.LC_ALL ||
49+
process.env.LC_CTYPE ||
50+
''
51+
).toLowerCase();
52+
if (['utf8', 'utf-8'].find((lang) => langEnv.includes(lang))) {
53+
return 'utf8';
54+
}
55+
if (['gbk', 'gb2312'].find((lang) => langEnv.includes(lang))) {
56+
return 'gbk';
57+
}
58+
if (['shift_jis', 'sjis'].find((lang) => langEnv.includes(lang))) {
59+
return 'shift_jis';
60+
}
61+
if (langEnv.includes('big5')) {
62+
return 'big5';
63+
}
64+
65+
return 'utf8';
66+
};
67+
68+
class EncodingTransformStream extends Writable {
69+
private encoding: string;
70+
private formatLog: (inputData: unknown) => string;
71+
72+
constructor(encoding: string) {
73+
super();
74+
this.encoding = encoding;
75+
76+
this.formatLog = pinoPretty.prettyFactory({
977
colorize: true,
1078
translateTime: 'HH:MM:ss',
1179
ignore: 'pid,hostname',
1280
messageFormat: '{msg}',
13-
},
14-
},
15-
});
81+
});
82+
}
83+
84+
_write(chunk: string | Buffer, encoding: string, callback: (error?: Error | null) => void): void {
85+
try {
86+
const stringChunk = typeof chunk === 'string' ? chunk : chunk.toString();
87+
const formattedChunk = this.formatLog(stringChunk);
1688

17-
export { logger };
89+
if (this.encoding !== 'utf8' && iconv.encodingExists(this.encoding)) {
90+
process.stdout.write(iconv.toEncoding(formattedChunk, 'utf8'));
91+
} else {
92+
process.stdout.write(formattedChunk);
93+
}
94+
95+
callback();
96+
} catch (error) {
97+
callback(error as Error);
98+
}
99+
}
100+
}
101+
102+
export const logger = pino(
103+
{
104+
name: 'ServerlessInsight',
105+
level: ['ServerlessInsight', '*'].includes(process.env.DEBUG || '') ? 'debug' : 'info',
106+
},
107+
new EncodingTransformStream(getSystemEncoding()),
108+
);

tsconfig.json

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,6 @@
22
"compilerOptions": {
33
"target": "ES2020",
44
"module": "commonjs",
5-
"declaration": true,
65
"esModuleInterop": true,
76
"forceConsistentCasingInFileNames": true,
87
"strict": true,

0 commit comments

Comments
 (0)