-
Notifications
You must be signed in to change notification settings - Fork 1
๐ก How To? JavaScript SDK ๊ฐ๋ฐํ๊ธฐ
LogBat JavaScript SDK๋ ์น ์ ํ๋ฆฌ์ผ์ด์ ์์ ๋ก๊ทธ๋ฅผ ํจ์จ์ ์ผ๋ก ์์งํ๊ณ ์ค์ ์๋ฒ๋ก ์ ์กํ๋ ๊ธฐ๋ฅ์ ์ ๊ณตํฉ๋๋ค. ์ด SDK์ ์ฃผ์ ๊ตฌํ ๋จ๊ณ์ ํน์ง์ ์ดํด๋ณด๊ฒ ์ต๋๋ค.
class LogBat {
private static appKey: string = '';
private static apiEndpoint: string = '<https://api.logbat.info/logs>';
private static originalConsole: { ... };
private static isInitialized: boolean = false;
private static logQueue: Array<{level: string, data: string, timestamp: string}> = [];
private static batchInterval: number = 1000; // 1 second
private static batchTimeoutId: number | null = null;
private static maxQueueSize: number = 100 * 1024; // 100 KB
private static currentQueueSize: number = 0;
// ... ๋ฉ์๋๋ค
}
- ์ ์ ํด๋์ค๋ก ๊ตฌํํ์ฌ ์ฑ๊ธํค ํจํด์ ์ ์ฉํ์ต๋๋ค.
- ์ฃผ์ ์ค์ ๊ฐ๊ณผ ์ํ๋ฅผ private ์ ์ ํ๋๋ก ๊ด๋ฆฌํฉ๋๋ค.
public static init(config: { appKey: string }): void {
if (this.isInitialized) {
console.warn('LogBat SDK is already initialized. Ignoring repeated initialization.');
return;
}
this.appKey = config.appKey;
this.overrideConsoleMethods();
this.isInitialized = true;
this.scheduleBatch();
}
- ์ฌ์ฉ์๊ฐ ์ ๊ณตํ appKey๋ก SDK๋ฅผ ์ด๊ธฐํํฉ๋๋ค.
- ์ค๋ณต ์ด๊ธฐํ๋ฅผ ๋ฐฉ์งํ๊ธฐ ์ํ ๊ฒ์ฌ๋ฅผ ์ํํฉ๋๋ค.
- ์ฝ์ ๋ฉ์๋๋ฅผ ์ค๋ฒ๋ผ์ด๋ํ๊ณ ๋ฐฐ์น ์ฒ๋ฆฌ๋ฅผ ์ค์ผ์ค๋งํฉ๋๋ค.
private static originalConsole: {
trace: typeof console.trace
debug: typeof console.debug
info: typeof console.info
log: typeof console.log
warn: typeof console.warn
error: typeof console.error
};
private static overrideConsoleMethods(): void {
this.originalConsole = {
trace: console.trace,
debug: console.debug,
info: console.info,
log: console.log,
warn: console.warn,
error: console.error
};
console.trace = (...args: any[]): void => { this.trace(...args); };
console.debug = (...args: any[]): void => { this.debug(...args); };
console.info = (...args: any[]): void => { this.info(...args); };
console.log = (...args: any[]): void => { this.log(...args); };
console.warn = (...args: any[]): void => { this.warn(...args); };
console.error = (...args: any[]): void => { this.error(...args); };
}
public static trace(...args: any[]): void {
this.originalConsole.trace(...args);
this.queueLog('trace', args);
}
// ๋ค๋ฅธ ๋ฉ์๋๋ค (debug, info, log, warn, error)๋ ์ ์ฌํ ๋ฐฉ์์ผ๋ก ๊ตฌํ
- JavaScript์ ๋์ ํน์ฑ์ ํ์ฉํ์ฌ ๊ธฐ์กด
console
๋ฉ์๋๋ค์originalConsole
๊ฐ์ฒด์ ์ ์ฅํ ํ ์ฌ์ ์ํฉ๋๋ค. - ๊ฐ ์ค๋ฒ๋ผ์ด๋๋ ๋ฉ์๋๋ ๋จผ์
originalConsole
์ ํด๋น ๋ฉ์๋๋ฅผ ํธ์ถํ์ฌ ๊ธฐ์กด ์ฝ์ ๊ธฐ๋ฅ์ ๊ทธ๋๋ก ์ ์งํฉ๋๋ค. - ๊ทธ ํ์ ๋ก๊ทธ๋ฅผ ํ์ ์ถ๊ฐํ๋
queueLog
๋ฉ์๋๋ฅผ ํธ์ถํ์ฌ ๋ก๊ทธ ์์ง ๊ธฐ๋ฅ์ ์ํํฉ๋๋ค.
-
๊ธฐ์กด ๊ธฐ๋ฅ ๋ณด์กด: ๊ฐ๋ฐ์๋ค์ ์ฌ์ ํ ์ต์ํ ๋ฐฉ์์ผ๋ก
console.log()
,console.error()
๋ฑ์ ์ฌ์ฉํ ์ ์์ต๋๋ค. ์ด ๋ฉ์๋๋ค์ ์ฌ์ ํ ๋ธ๋ผ์ฐ์ ์ฝ์์ ์ถ๋ ฅ๋ฉ๋๋ค. - ํฌ๋ช ํ ํตํฉ: LogBat SDK๋ฅผ ์ ์ฉํด๋ ์ ํ๋ฆฌ์ผ์ด์ ์ ๊ธฐ์กด ๋ก๊น ๋์์ด ๋ณ๊ฒฝ๋์ง ์์ต๋๋ค. ์ด๋ ๊ธฐ์กด ํ๋ก์ ํธ์ ์ฝ๊ฒ ํตํฉํ ์ ์์์ ์๋ฏธํฉ๋๋ค.
- ๋๋ฒ๊น ์ฉ์ด์ฑ: ๊ฐ๋ฐ ๊ณผ์ ์์ ๋ธ๋ผ์ฐ์ ์ฝ์์ ํตํ ๋๋ฒ๊น ์ด ์ฌ์ ํ ๊ฐ๋ฅํฉ๋๋ค. LogBat์ผ๋ก์ ๋ก๊ทธ ์ ์ก๊ณผ ๋ณ๊ฐ๋ก ์ฝ์ ์ถ๋ ฅ์ด ์ ์ง๋ฉ๋๋ค.
- ์ ์ฐ์ฑ: ํ์์ ๋ฐ๋ผ ํน์ ๋ก๊ทธ๋ฅผ ์ฝ์์๋ง ์ถ๋ ฅํ๊ฑฐ๋ LogBat์ผ๋ก๋ง ์ ์กํ๋ ๋ฑ์ ์ธ๋ฐํ ์ ์ด๊ฐ ๊ฐ๋ฅํฉ๋๋ค.
- ํ์ ํธํ์ฑ: ๊ธฐ์กด์ console ๋ฉ์๋๋ฅผ ์ฌ์ฉํ๋ ์๋ํํฐ ๋ผ์ด๋ธ๋ฌ๋ฆฌ๋ ๋ ๊ฑฐ์ ์ฝ๋์์ ํธํ์ฑ์ด ์ ์ง๋ฉ๋๋ค.
์ด๋ฌํ ๋ฐฉ์์ผ๋ก ๊ตฌํํจ์ผ๋ก์จ, LogBat SDK๋ ๊ธฐ์กด ๋ก๊น ์์คํ ์ ๋ฐฉํดํ์ง ์์ผ๋ฉด์๋ ์ถ๊ฐ์ ์ธ ๋ก๊ทธ ์์ง ๋ฐ ์ค์ํ ๊ธฐ๋ฅ์ ์ ๊ณตํฉ๋๋ค. ์ด๋ ๊ฐ๋ฐ์ ๊ฒฝํ์ ํด์น์ง ์์ผ๋ฉด์ ๊ฐ๋ ฅํ ๋ก๊น ๊ธฐ๋ฅ์ ์ถ๊ฐํ ์ ์๊ฒ ํด์ฃผ๋ ์ฐ์ํ ํด๊ฒฐ์ฑ ์ ๋๋ค.
private static queueLog(level: string, args: any[]): void {
const logData = {
level: level,
data: args.map(arg =>
typeof arg === 'object' ? JSON.stringify(arg) : String(arg)
).join(' '),
timestamp: new Date().toISOString()
};
const logSize = JSON.stringify(logData).length;
this.logQueue.push(logData);
this.currentQueueSize += logSize;
if (this.currentQueueSize > this.maxQueueSize) {
this.sendBatch();
}
else {
this.scheduleBatch();
}
}
- ๋ก๊ทธ๋ฅผ ์ฆ์ ์ ์กํ์ง ์๊ณ ํ์ ์ถ๊ฐํฉ๋๋ค.
- ํ ํฌ๊ธฐ๊ฐ ์๊ณ๊ฐ(100KB)์ ์ด๊ณผํ๋ฉด ์ฆ์ ์ ์ก์ ์์ํฉ๋๋ค.
- ๊ทธ๋ ์ง ์์ผ๋ฉด ๋ฐฐ์น ์ ์ก์ ์ค์ผ์ค๋งํฉ๋๋ค.
private static async sendBatch(): Promise<void> {
if (this.logQueue.length === 0) return;
const batchToSend = [...this.logQueue];
this.logQueue = [];
this.currentQueueSize = 0;
try {
const response = await fetch(this.apiEndpoint, {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'App-Key': this.appKey
},
body: JSON.stringify(batchToSend),
});
if (!response.ok) {
throw new Error(`HTTP error! status: ${response.status}`);
}
} catch (err) {
this.originalConsole.error('Failed to send log batch:', err);
}
}
- ๋์ ๋ ๋ก๊ทธ๋ฅผ ๋น๋๊ธฐ์ ์ผ๋ก ์๋ฒ์ ์ ์กํฉ๋๋ค.
-
fetch
API๋ฅผ ์ฌ์ฉํ์ฌ HTTP ์์ฒญ์ ๋ณด๋ ๋๋ค. - ์ ์ก ์คํจ ์ ์๋์ ์ฝ์์ ์ค๋ฅ๋ฅผ ๊ธฐ๋กํฉ๋๋ค.
if (typeof window !== 'undefined') {
(window as any).LogBat = LogBat;
}
export default LogBat;
- ๋ธ๋ผ์ฐ์ ํ๊ฒฝ์์
window
๊ฐ์ฒด์LogBat
์ ์ถ๊ฐํ์ฌ ์ ์ญ ์ ๊ทผ์ ๊ฐ๋ฅํ๊ฒ ํฉ๋๋ค. - ๋ชจ๋ ์์คํ ์ ํตํ ์ํฌํธ๋ ์ง์ํฉ๋๋ค.
์ด๋ฌํ ๊ตฌํ์ ํตํด LogBat JavaScript SDK๋ ํจ์จ์ ์ด๊ณ ์ฌ์ฉํ๊ธฐ ์ฌ์ด ๋ก๊น ์๋ฃจ์ ์ ์ ๊ณตํฉ๋๋ค. JavaScript์ ๋์ ํน์ฑ์ ํ์ฉํ์ฌ ๊ธฐ์กด ์ฝ์ ๊ธฐ๋ฅ์ ํ์ฅํ๋ฉด์๋, ๋น๋๊ธฐ ์ฒ๋ฆฌ์ ๋ฐฐ์น ์ ์ก์ ํตํด ์ฑ๋ฅ ์ํฅ์ ์ต์ํํ์ต๋๋ค.
- ๐ก How To? Chat-GPT ๋ฆฌ๋ทฐ์ด ๋์ ํ๊ธฐ
- ๐ก How To? ๋๋ฉ์ธ ์ค์ ํ๊ธฐ
- ๐ก How To? NGINX๋ก CORS ์ค์ ํ๊ธฐ
- ๐ก How To? JavaScript SDK ๊ฐ๋ฐํ๊ธฐ
- ๐ก How To? Java SDK ๊ฐ๋ฐํ๊ธฐ
- ๐ก How To? AWS Lambda๋ก ๋ถํ ํ ์คํธ ์งํํ๊ธฐ
- ๐ก How To? Terraform + Locust๋ก ๋ถํ ํ ์คํธ ์งํํ๊ธฐ
- โ๏ธ Refactoring: ๋ก๊ทธ ์ ์ฅ์ ํ๋ฒ์ ํ์!
- ๐จ ์๋ฒฝํ์ง ์์ ์๋๋ฐ์ค ํ ์คํธ๊ฐ ๋ถ๋ฌ์จ ํญํ
- ๐ก How To? ๋๋ฒ๊น ์ฉ ๊ฒฝ์์ด ๋ฐ์ํ์ง ์๋ Long ์นด์ดํฐ ๋ง๋ค๊ธฐ!
- ๐ก How To? Queue์ poll๊ณผ push๋ ์ ํ ์ค๋ ๋์์ ๋ด๋นํ๊ฒ ํ์๊น?