log.ts 3.27 KB
Newer Older
liuzhe-lz's avatar
liuzhe-lz committed
1
2
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT license.
Deshui Yu's avatar
Deshui Yu committed
3

4
import fs from 'fs';
Deshui Yu's avatar
Deshui Yu committed
5
import { Writable } from 'stream';
6
import util from 'util';
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25

/* log level constants */

export const DEBUG = 10;
export const INFO = 20;
export const WARNING = 30;
export const ERROR = 40;
export const CRITICAL = 50;

export const TRACE = 1;
export const FATAL = 50;

const levelNames = new Map<number, string>([
    [CRITICAL, 'CRITICAL'],
    [ERROR, 'ERROR'],
    [WARNING, 'WARNING'],
    [INFO, 'INFO'],
    [DEBUG, 'DEBUG'],
    [TRACE, 'TRACE'],
26
]);
Deshui Yu's avatar
Deshui Yu committed
27

28
/* global_ states */
Deshui Yu's avatar
Deshui Yu committed
29

30
31
let logLevel: number = 0;
const loggers = new Map<string, Logger>();
Deshui Yu's avatar
Deshui Yu committed
32

33
/* major api */
Deshui Yu's avatar
Deshui Yu committed
34

35
36
37
38
39
export class Logger {
    private name: string;

    constructor(name: string = 'root') {
        this.name = name;
Deshui Yu's avatar
Deshui Yu committed
40
41
    }

42
43
44
    public trace(...args: any[]): void {
        this.log(TRACE, args);
    }
45

46
47
48
    public debug(...args: any[]): void {
        this.log(DEBUG, args);
    }
SparkSnail's avatar
SparkSnail committed
49

50
51
    public info(...args: any[]): void {
        this.log(INFO, args);
52
53
    }

54
55
    public warning(...args: any[]): void {
        this.log(WARNING, args);
Deshui Yu's avatar
Deshui Yu committed
56
57
    }

58
59
    public error(...args: any[]): void {
        this.log(ERROR, args);
60
61
    }

62
63
    public critical(...args: any[]): void {
        this.log(CRITICAL, args);
Deshui Yu's avatar
Deshui Yu committed
64
65
    }

66
67
    public fatal(...args: any[]): void {
        this.log(FATAL, args);
Deshui Yu's avatar
Deshui Yu committed
68
69
    }

70
    private log(level: number, args: any[]): void {
71
        const logFile: Writable | undefined = (global as any).logFile;
J-shang's avatar
J-shang committed
72
        if (level < logLevel) {
73
            return;
Deshui Yu's avatar
Deshui Yu committed
74
75
        }

76
77
78
79
80
        const zeroPad = (num: number): string => num.toString().padStart(2, '0');
        const now = new Date();
        const date = now.getFullYear() + '-' + zeroPad(now.getMonth() + 1) + '-' + zeroPad(now.getDate());
        const time = zeroPad(now.getHours()) + ':' + zeroPad(now.getMinutes()) + ':' + zeroPad(now.getSeconds());
        const datetime = date + ' ' + time;
81
82
83

        const levelName = levelNames.has(level) ? levelNames.get(level) : level.toString();

84
        const message = args.map(arg => (typeof arg === 'string' ? arg : util.inspect(arg))).join(' ');
85
        
86
        const record = `[${datetime}] ${levelName} (${this.name}) ${message}\n`;
J-shang's avatar
J-shang committed
87
88
89
90
91
92

        if (logFile === undefined) {
            console.log(record);
        } else {
            logFile.write(record);
        }
Deshui Yu's avatar
Deshui Yu committed
93
    }
94
}
Deshui Yu's avatar
Deshui Yu committed
95

96
97
98
99
100
export function getLogger(name: string = 'root'): Logger {
    let logger = loggers.get(name);
    if (logger === undefined) {
        logger = new Logger(name);
        loggers.set(name, logger);
Deshui Yu's avatar
Deshui Yu committed
101
    }
102
103
104
105
106
107
108
109
110
111
112
113
114
    return logger;
}

/* management functions */

export function setLogLevel(levelName: string): void {
    if (levelName) {
        const level = module.exports[levelName.toUpperCase()];
        if (typeof level === 'number') {
            logLevel = level;
        } else {
            console.log('[ERROR] Bad log level:', levelName);
            getLogger('logging').error('Bad log level:', levelName);
SparkSnail's avatar
SparkSnail committed
115
        }
Deshui Yu's avatar
Deshui Yu committed
116
117
118
    }
}

119
export function startLogging(logPath: string): void {
120
    (global as any).logFile = fs.createWriteStream(logPath, {
121
122
123
124
        flags: 'a+',
        encoding: 'utf8',
        autoClose: true
    });
Deshui Yu's avatar
Deshui Yu committed
125
126
}

127
export function stopLogging(): void {
128
129
130
    if ((global as any).logFile !== undefined) {
        (global as any).logFile.end();
        (global as any).logFile = undefined;
131
132
    }
}