import { readFile } from 'fs/promises'; import moment from 'moment'; interface ParseFunc { (value: string | null): {[key: string]: string | null} } interface SpecialKeysOptions { key: string, parseFunc: ParseFunc } export interface HandleLogRowOptions { timeKey?: string; keys: string[]; kvSeparator?: string; specialKeys?: SpecialKeysOptions[]; } export async function readLogFile(filePath: string): Promise { const fileContent = await readFile(filePath, { encoding: 'utf-8' }); const content = fileContent.split('\n'); return Promise.resolve(content); } export function parseLogTime(log: string): string | null { const time = /:(\d+-\d+-\d+\s\d+:\d+:\d+\.\d+)\s/.exec(log); if (time) { return moment(time[1]).format('DD/MM/YYYY HH:mm:ss'); } return null; } /** * 将一行log解析为对象 * @param log * @param keys */ export function parseLogKV( log: string, keys: string[] = [], kvSeparator = '=', ): {[key: string]: string} { if (keys.length === 0) { return {}; } const res:{[key: string]: string} = {}; const KVList = log.split(' '); keys.forEach((key) => { const reg = new RegExp(`^${key}${kvSeparator}`); const item = KVList.find((KVItem) => reg.test(KVItem)); if (item) { const splitIndex = item.indexOf(kvSeparator); const value = item.substring(splitIndex + 1); res[key] = value; } }); return res; } export function parseSpecialKeys( row: string, options: SpecialKeysOptions[], kvSeparator = '=', ):{[key: string]: string | null} { const obj = parseLogKV(row, options.map((item) => item.key), kvSeparator); let res = {}; options.forEach((item) => { res = { ...res, ...item.parseFunc(obj[item.key]) }; }); return res; } export function handleLogRow( log: string, options: HandleLogRowOptions, ): {[key: string]: string | null} { let res: {[key: string]: string | null} = {}; const { timeKey = 'create_time', kvSeparator = '=', keys = [], specialKeys = [], } = options; res[timeKey] = parseLogTime(log); res = { ...res, ...parseLogKV(log, keys, kvSeparator) }; res = { ...res, ...parseSpecialKeys(log, specialKeys, kvSeparator) }; return res; }