@plastichub/osr-log
Version:
Package basics
167 lines (153 loc) • 5.33 kB
text/typescript
import * as path from 'path'
import { createStream } from "rotating-file-stream"
import { BaseLogger, ILogObjMeta, ISettingsParam, Logger } from "tslog"
import { CONFIG_DEFAULT, resolve } from '@plastichub/osr-commons'
import { LogLevelEx } from './zod_schema'
import { sync as read } from '@plastichub/fs/read'
import { sync as write } from '@plastichub/fs/write'
import { sync as exists } from '@plastichub/fs/exists'
export * from './zod_schema'
import * as TransportStream from 'winston-transport'
const { SeqTransport } = require('@datalust/winston-seq')
import * as winston from 'winston'
export enum ELogTargets {
Console = 1 << 0,
FileText = 1 << 1,
FileJson = 1 << 2,
Seq = 1 << 3
}
export function createLogger(name: string, options?: ISettingsParam<any>) {
return new Logger<unknown>({
name,
type: 'pretty',
...options,
})
}
export const defaultLogger = createLogger('DefaultLogger', {
minLevel: LogLevelEx.info
})
export class CustomLogger<LogObj> extends BaseLogger<LogObj> {
constructor(settings?: ISettingsParam<LogObj>, logObj?: LogObj) {
super(settings, logObj, 5)
}
public custom(loggerName?: string, ...args: unknown[]): LogObj & ILogObjMeta {
return super.log(8, loggerName || 'Custom', ...args)
}
}
class JsonArrayFileTransport extends TransportStream {
filename: string;
constructor(opts) {
super(opts);
opts.filename = opts.filename
this.filename = opts.filename || 'logs.json';
setImmediate(() => this.emit('opened'))
}
log(info: any, next: () => void): void {
setImmediate(() => this.emit('logged', info))
const { level, message, exception, stack, ...props } = info;
const fileExists = exists(this.filename)
const existingLogs = fileExists
? read(this.filename, 'json') as []
: [];
const entry = {
level: info.level,
message: info.message,
timestamp: new Date().toISOString(),
...info
};
existingLogs.push(entry)
write(this.filename, existingLogs)
next()
}
close(): void {
setImmediate(() => this.emit('closed'))
}
flush(): Promise<any> {
return new Promise((resolve, reject) => {
resolve(true)
})
}
}
class TSLogTransport extends TransportStream {
constructor(opts) {
super(opts);
setImmediate(() => this.emit('opened'))
}
log(info: any, next: () => void): void {
setImmediate(() => this.emit('logged', info))
const { level, message, exception, stack, ...props } = info;
defaultLogger.info(info)
next()
}
}
export const winstonLogger = (name: string, file: string, targets: ELogTargets = ELogTargets.Console | ELogTargets.FileJson) => {
const logger = winston.createLogger({
defaultMeta: { service: name },
level: 'debug',
transports: []
})
if (targets & ELogTargets.Console) {
//logger.add(new TSLogTransport({}))
logger.add(new winston.transports.Console({
format: winston.format.combine(
winston.format.timestamp({ format: 'MM/DD/YYYY hh:mm:ss.SSS' }),
///winston.format.json(),
winston.format.colorize(),
winston.format.printf(info => {
let message = null
try {
message = JSON.stringify(info.message)
} catch (e) {
}
return `[${info.level}] [${name}] | message: ${message.substring(0, 200)}`
}))
}))
}
if (targets & ELogTargets.FileText) {
logger.add(new winston.transports.File({
format: winston.format.combine(
winston.format.timestamp(),
winston.format.timestamp({ format: 'MM/DD/YYYY hh:mm:ss.SSS' }),
winston.format.json(),
winston.format.printf(info => {
return JSON.stringify(info, null, 2);
})),
dirname: path.parse(file).dir,
filename: path.parse(file).base
}))
}
if (targets & ELogTargets.FileJson) {
logger.add(new JsonArrayFileTransport({
filename: file
}))
}
if (targets & ELogTargets.Seq) {
const config = CONFIG_DEFAULT() as any
if (config.seq) {
logger.add(new SeqTransport({
...config.seq,
//serverUrl: "https://localhost:5341",
//apiKey: "Qu6XPThyfnXo7ugXoRZS",
onError: (e => { })
}))
}
}
return logger
}
export const createFileLogger = (logger: Logger<unknown>, level: number, file: string): Logger<unknown> => {
const rfs = createStream(file,
{
size: "10M", // rotate every 10 MegaBytes written
interval: "1d", // rotate daily
compress: "gzip", // compress rotated files
});
const log = new Logger({
type: "json",
attachedTransports: [
(logObj) => {
rfs.write(JSON.stringify(logObj) + "\n");
},
],
});
return log
}