Skip to content

๐Ÿ’ก How To? JavaScript SDK ๊ฐœ๋ฐœํ•˜๊ธฐ

CodingLuizy edited this page Sep 3, 2024 · 2 revisions

LogBat JavaScript SDK ๊ตฌํ˜„ ๊ณผ์ •

LogBat JavaScript SDK๋Š” ์›น ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์—์„œ ๋กœ๊ทธ๋ฅผ ํšจ์œจ์ ์œผ๋กœ ์ˆ˜์ง‘ํ•˜๊ณ  ์ค‘์•™ ์„œ๋ฒ„๋กœ ์ „์†กํ•˜๋Š” ๊ธฐ๋Šฅ์„ ์ œ๊ณตํ•ฉ๋‹ˆ๋‹ค. ์ด SDK์˜ ์ฃผ์š” ๊ตฌํ˜„ ๋‹จ๊ณ„์™€ ํŠน์ง•์„ ์‚ดํŽด๋ณด๊ฒ ์Šต๋‹ˆ๋‹ค.

1. ํด๋ž˜์Šค ๊ตฌ์กฐ ์„ค์ •

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 ์ •์  ํ•„๋“œ๋กœ ๊ด€๋ฆฌํ•ฉ๋‹ˆ๋‹ค.

2. ์ดˆ๊ธฐํ™” ๋ฉ”์„œ๋“œ ๊ตฌํ˜„

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๋ฅผ ์ดˆ๊ธฐํ™”ํ•ฉ๋‹ˆ๋‹ค.
  • ์ค‘๋ณต ์ดˆ๊ธฐํ™”๋ฅผ ๋ฐฉ์ง€ํ•˜๊ธฐ ์œ„ํ•œ ๊ฒ€์‚ฌ๋ฅผ ์ˆ˜ํ–‰ํ•ฉ๋‹ˆ๋‹ค.
  • ์ฝ˜์†” ๋ฉ”์„œ๋“œ๋ฅผ ์˜ค๋ฒ„๋ผ์ด๋“œํ•˜๊ณ  ๋ฐฐ์น˜ ์ฒ˜๋ฆฌ๋ฅผ ์Šค์ผ€์ค„๋งํ•ฉ๋‹ˆ๋‹ค.

3. ์ฝ˜์†” ๋ฉ”์„œ๋“œ ์˜ค๋ฒ„๋ผ์ด๋”ฉ

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 ๋ฉ”์„œ๋“œ๋ฅผ ํ˜ธ์ถœํ•˜์—ฌ ๋กœ๊ทธ ์ˆ˜์ง‘ ๊ธฐ๋Šฅ์„ ์ˆ˜ํ–‰ํ•ฉ๋‹ˆ๋‹ค.

originalConsole ํ™œ์šฉ์˜ ์ด์ 

  1. ๊ธฐ์กด ๊ธฐ๋Šฅ ๋ณด์กด: ๊ฐœ๋ฐœ์ž๋“ค์€ ์—ฌ์ „ํžˆ ์ต์ˆ™ํ•œ ๋ฐฉ์‹์œผ๋กœ console.log(), console.error() ๋“ฑ์„ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์ด ๋ฉ”์„œ๋“œ๋“ค์€ ์—ฌ์ „ํžˆ ๋ธŒ๋ผ์šฐ์ € ์ฝ˜์†”์— ์ถœ๋ ฅ๋ฉ๋‹ˆ๋‹ค.
  2. ํˆฌ๋ช…ํ•œ ํ†ตํ•ฉ: LogBat SDK๋ฅผ ์ ์šฉํ•ด๋„ ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์˜ ๊ธฐ์กด ๋กœ๊น… ๋™์ž‘์ด ๋ณ€๊ฒฝ๋˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค. ์ด๋Š” ๊ธฐ์กด ํ”„๋กœ์ ํŠธ์— ์‰ฝ๊ฒŒ ํ†ตํ•ฉํ•  ์ˆ˜ ์žˆ์Œ์„ ์˜๋ฏธํ•ฉ๋‹ˆ๋‹ค.
  3. ๋””๋ฒ„๊น… ์šฉ์ด์„ฑ: ๊ฐœ๋ฐœ ๊ณผ์ •์—์„œ ๋ธŒ๋ผ์šฐ์ € ์ฝ˜์†”์„ ํ†ตํ•œ ๋””๋ฒ„๊น…์ด ์—ฌ์ „ํžˆ ๊ฐ€๋Šฅํ•ฉ๋‹ˆ๋‹ค. LogBat์œผ๋กœ์˜ ๋กœ๊ทธ ์ „์†ก๊ณผ ๋ณ„๊ฐœ๋กœ ์ฝ˜์†” ์ถœ๋ ฅ์ด ์œ ์ง€๋ฉ๋‹ˆ๋‹ค.
  4. ์œ ์—ฐ์„ฑ: ํ•„์š”์— ๋”ฐ๋ผ ํŠน์ • ๋กœ๊ทธ๋ฅผ ์ฝ˜์†”์—๋งŒ ์ถœ๋ ฅํ•˜๊ฑฐ๋‚˜ LogBat์œผ๋กœ๋งŒ ์ „์†กํ•˜๋Š” ๋“ฑ์˜ ์„ธ๋ฐ€ํ•œ ์ œ์–ด๊ฐ€ ๊ฐ€๋Šฅํ•ฉ๋‹ˆ๋‹ค.
  5. ํ•˜์œ„ ํ˜ธํ™˜์„ฑ: ๊ธฐ์กด์˜ console ๋ฉ”์„œ๋“œ๋ฅผ ์‚ฌ์šฉํ•˜๋Š” ์„œ๋“œํŒŒํ‹ฐ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๋‚˜ ๋ ˆ๊ฑฐ์‹œ ์ฝ”๋“œ์™€์˜ ํ˜ธํ™˜์„ฑ์ด ์œ ์ง€๋ฉ๋‹ˆ๋‹ค.

์ด๋Ÿฌํ•œ ๋ฐฉ์‹์œผ๋กœ ๊ตฌํ˜„ํ•จ์œผ๋กœ์จ, LogBat SDK๋Š” ๊ธฐ์กด ๋กœ๊น… ์‹œ์Šคํ…œ์„ ๋ฐฉํ•ดํ•˜์ง€ ์•Š์œผ๋ฉด์„œ๋„ ์ถ”๊ฐ€์ ์ธ ๋กœ๊ทธ ์ˆ˜์ง‘ ๋ฐ ์ค‘์•™ํ™” ๊ธฐ๋Šฅ์„ ์ œ๊ณตํ•ฉ๋‹ˆ๋‹ค. ์ด๋Š” ๊ฐœ๋ฐœ์ž ๊ฒฝํ—˜์„ ํ•ด์น˜์ง€ ์•Š์œผ๋ฉด์„œ ๊ฐ•๋ ฅํ•œ ๋กœ๊น… ๊ธฐ๋Šฅ์„ ์ถ”๊ฐ€ํ•  ์ˆ˜ ์žˆ๊ฒŒ ํ•ด์ฃผ๋Š” ์šฐ์•„ํ•œ ํ•ด๊ฒฐ์ฑ…์ž…๋‹ˆ๋‹ค.

4. ๋กœ๊ทธ ํ์ž‰ ๋ฐ ๋ฐฐ์น˜ ์ฒ˜๋ฆฌ

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)์„ ์ดˆ๊ณผํ•˜๋ฉด ์ฆ‰์‹œ ์ „์†ก์„ ์‹œ์ž‘ํ•ฉ๋‹ˆ๋‹ค.
  • ๊ทธ๋ ‡์ง€ ์•Š์œผ๋ฉด ๋ฐฐ์น˜ ์ „์†ก์„ ์Šค์ผ€์ค„๋งํ•ฉ๋‹ˆ๋‹ค.

5. ๋น„๋™๊ธฐ ๋ฐฐ์น˜ ์ „์†ก

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 ์š”์ฒญ์„ ๋ณด๋ƒ…๋‹ˆ๋‹ค.
  • ์ „์†ก ์‹คํŒจ ์‹œ ์›๋ž˜์˜ ์ฝ˜์†”์— ์˜ค๋ฅ˜๋ฅผ ๊ธฐ๋กํ•ฉ๋‹ˆ๋‹ค.

6. ๊ธ€๋กœ๋ฒŒ ๊ฐ์ฒด์— ๋…ธ์ถœ

if (typeof window !== 'undefined') {
    (window as any).LogBat = LogBat;
}

export default LogBat;
  • ๋ธŒ๋ผ์šฐ์ € ํ™˜๊ฒฝ์—์„œ window ๊ฐ์ฒด์— LogBat์„ ์ถ”๊ฐ€ํ•˜์—ฌ ์ „์—ญ ์ ‘๊ทผ์„ ๊ฐ€๋Šฅํ•˜๊ฒŒ ํ•ฉ๋‹ˆ๋‹ค.
  • ๋ชจ๋“ˆ ์‹œ์Šคํ…œ์„ ํ†ตํ•œ ์ž„ํฌํŠธ๋„ ์ง€์›ํ•ฉ๋‹ˆ๋‹ค.

์ด๋Ÿฌํ•œ ๊ตฌํ˜„์„ ํ†ตํ•ด LogBat JavaScript SDK๋Š” ํšจ์œจ์ ์ด๊ณ  ์‚ฌ์šฉํ•˜๊ธฐ ์‰ฌ์šด ๋กœ๊น… ์†”๋ฃจ์…˜์„ ์ œ๊ณตํ•ฉ๋‹ˆ๋‹ค. JavaScript์˜ ๋™์  ํŠน์„ฑ์„ ํ™œ์šฉํ•˜์—ฌ ๊ธฐ์กด ์ฝ˜์†” ๊ธฐ๋Šฅ์„ ํ™•์žฅํ•˜๋ฉด์„œ๋„, ๋น„๋™๊ธฐ ์ฒ˜๋ฆฌ์™€ ๋ฐฐ์น˜ ์ „์†ก์„ ํ†ตํ•ด ์„ฑ๋Šฅ ์˜ํ–ฅ์„ ์ตœ์†Œํ™”ํ–ˆ์Šต๋‹ˆ๋‹ค.


๊ด€๋ จ PR

๐Ÿงซ ํŒ€ ๋ฌธํ™”

โš™๏ธ ๊ตฌ์„ฑ

๐Ÿ”จ ๊ฐœ๋ฐœ ์œ„ํ‚ค

๐Ÿž Bug Report

๐Ÿงช Test Logs

Clone this wiki locally