mtcute/packages/core/src/utils/logger.ts

116 lines
2.9 KiB
TypeScript
Raw Normal View History

import { _defaultLoggingHandler } from './platform/logging'
let defaultLogLevel = 2
if (typeof process !== 'undefined') {
const envLogLevel = parseInt(process.env.MTCUTE_LOG_LEVEL!)
if (!isNaN(envLogLevel)) {
defaultLogLevel = envLogLevel
}
} else if (typeof localStorage !== 'undefined') {
const localLogLevel = parseInt(localStorage.MTCUTE_LOG_LEVEL)
if (!isNaN(localLogLevel)) {
defaultLogLevel = localLogLevel
}
}
const FORMATTER_RE = /%[a-zA-Z]/g
/**
* Logger created by {@link LogManager}
*/
export class Logger {
private color: number
constructor(readonly mgr: LogManager, readonly tag: string) {
let hash = 0
for (let i = 0; i < tag.length; i++) {
hash = (hash << 5) - hash + tag.charCodeAt(i)
hash |= 0 // convert to 32bit int
}
this.color = Math.abs(hash) % 6
}
log(level: number, fmt: string, ...args: any[]): void {
if (level > this.mgr.level) return
// custom formatters
if (
fmt.indexOf('%h') > -1 ||
fmt.indexOf('%b') > -1 ||
fmt.indexOf('%j') > -1
) {
let idx = 0
fmt = fmt.replace(FORMATTER_RE, (m) => {
if (m === '%h' || m === '%b' || m === '%j') {
const val = args[idx]
args.splice(idx, 1)
if (m === '%h') return val.toString('hex')
if (m === '%b') return !!val + ''
if (m === '%j') return JSON.stringify(val)
}
idx++
return m
})
}
this.mgr.handler(this.color, level, this.tag, fmt, args)
}
readonly error = this.log.bind(this, LogManager.ERROR)
readonly warn = this.log.bind(this, LogManager.WARN)
readonly info = this.log.bind(this, LogManager.INFO)
readonly debug = this.log.bind(this, LogManager.DEBUG)
readonly request = this.log.bind(this, LogManager.REQUEST)
/**
* Create a {@link Logger} with the given tag
* from the same {@link LogManager} as the current
* Logger.
*
* @param tag Logger tag
*/
create(tag: string): Logger {
return this.mgr.create(tag)
}
}
/**
* Log manager.
*
* Does nothing by itself, but allows managing instance logs
*/
export class LogManager {
static OFF = 0
static ERROR = 1
static WARN = 2
static INFO = 3
static DEBUG = 4
static REQUEST = 5
private _cache: Record<string, Logger> = {}
level = defaultLogLevel
handler = _defaultLoggingHandler
disable(): void {
this.level = 0
}
/**
* Create a {@link Logger} with the given tag
*
* @param tag Logger tag
*/
create(tag: string): Logger {
if (!(tag in this._cache)) {
this._cache[tag] = new Logger(this, tag)
}
return this._cache[tag]
}
}