UNPKG

@plastichub/osr-log

Version:

Package basics

58 lines 15.3 kB
[ { "level": "info", "message": { "name": "create_file", "arguments": { "file": { "path": "logger.ts", "content": "import * as path from 'path'\nimport { createStream } from 'rotating-file-stream'\nimport { BaseLogger, ILogObjMeta, ISettingsParam, Logger } from 'tslog'\nimport { LogLevelEx } from './zod_schema'\nimport { sync as read } from '@plastichub/fs/read'\nimport { sync as write } from '@plastichub/fs/write'\nimport { sync as exists } from '@plastichub/fs/exists'\nexport * from './zod_schema'\n\nimport * as TransportStream from 'winston-transport'\nconst { SeqTransport } = require('@datalust/winston-seq')\nimport * as winston from 'winston'\n\nexport interface LoggerOptions {\n enableConsole?: boolean;\n enableJsonFile?: boolean;\n enableTextFile?: boolean;\n enableSeq?: boolean;\n seqConfig?: {\n serverUrl: string;\n apiKey: string;\n }\n}\n\nexport function createLogger(name: string, options?: ISettingsParam<any>) {\n return new Logger<unknown>({\n name,\n type: 'pretty',\n ...options,\n })\n}\n\nexport const defaultLogger = createLogger('DefaultLogger', {\n minLevel: LogLevelEx.info\n})\n\nexport class CustomLogger<LogObj> extends BaseLogger<LogObj> {\n constructor(settings?: ISettingsParam<LogObj>, logObj?: LogObj) {\n super(settings, logObj, 5)\n }\n public custom(loggerName?: string, ...args: unknown[]): LogObj & ILogObjMeta {\n return super.log(8, loggerName || 'Custom', ...args)\n }\n}\n\nclass JsonArrayFileTransport extends TransportStream {\n filename: string;\n constructor(opts) {\n super(opts);\n opts.filename = opts.filename\n this.filename = opts.filename || 'logs.json';\n setImmediate(() => this.emit('opened'))\n }\n log(info: any, next: () => void): void {\n setImmediate(() => this.emit('logged', info))\n const { level, message, exception, stack, ...props } = info;\n setImmediate(() => this.emit('logged', info))\n const fileExists = exists(this.filename)\n const existingLogs = fileExists\n ? read(this.filename, 'json') as []\n : [];\n\n const entry = {\n level: info.level,\n message: info.message,\n timestamp: new Date().toISOString(),\n ...info\n };\n existingLogs.push(entry)\n write(this.filename, existingLogs)\n next()\n }\n close(): void {\n setImmediate(() => this.emit('closed'))\n }\n flush(): Promise<any> {\n return new Promise((resolve) => {\n resolve(true)\n })\n }\n}\n\nexport type WinstonLoggerType = 'JSON' | 'Markdown'\nexport const winstonLogger = (name: string, file: string, loggerOptions: LoggerOptions = {}) => {\n const logger = winston.createLogger({\n defaultMeta: { service: name },\n level: 'debug',\n transports: []\n })\n\n if (loggerOptions.enableConsole) {\n logger.add(new winston.transports.Console({\n format: winston.format.combine(\n winston.format.timestamp(),\n winston.format.timestamp({ format: 'MM/DD/YYYY hh:mm:ss.SSS' }),\n winston.format.json(),\n winston.format.colorize(),\n winston.format.printf(info => {\n return `[${info.level}] [${name}] : ${info.message}`;\n }))\n }))\n }\n\n if (loggerOptions.enableJsonFile) {\n logger.add(new JsonArrayFileTransport({ filename: `${file}.json` }))\n }\n\n if (loggerOptions.enableTextFile) {\n logger.add(new winston.transports.File({\n format: winston.format.combine(\n winston.format.timestamp(),\n winston.format.timestamp({ format: 'MM/DD/YYYY hh:mm:ss.SSS' }),\n winston.format.printf(info => {\n return `[${info.timestamp}] [${info.level}] [${name}] : ${info.message}`;\n })),\n dirname: path.parse(file).dir,\n filename: `${path.parse(file).base}.log`\n }))\n }\n\n if (loggerOptions.enableSeq && loggerOptions.seqConfig) {\n logger.add(new SeqTransport({\n serverUrl: loggerOptions.seqConfig.serverUrl,\n apiKey: loggerOptions.seqConfig.apiKey,\n onError: (e => { console.error('Seq transport error:', e) }),\n }))\n }\n\n return logger\n}\n\nexport const createFileLogger = (logger: Logger<unknown>, level: number, file: string): Logger<unknown> => {\n const rfs = createStream(file,\n {\n size: '10M',\n interval: '1d',\n compress: 'gzip',\n });\n\n const log = new Logger({\n type: 'json',\n attachedTransports: [\n (logObj) => {\n rfs.write(JSON.stringify(logObj) + '\n');\n },\n ],\n });\n return log\n}" } }, "parsed_arguments": null, "timestamp": "2024-12-28T16:32:28.812Z", "sessionId": "1735403514828", "query": "introduce logging flags to enable targets : file (text, json (JsonArrayFileTransport), console and SeqTransport" }, "timestamp": "2024-12-28T16:32:28.812Z", "service": "collector:onToolCall" }, { "level": "info", "message": { "name": "create_file", "arguments": { "file": { "path": "src/index.ts", "content": "import * as path from 'path'\nimport { createStream } from \"rotating-file-stream\"\nimport { BaseLogger, ILogObjMeta, ISettingsParam, Logger } from \"tslog\"\nimport { LogLevelEx } from './zod_schema'\nimport { sync as read } from '@plastichub/fs/read'\nimport { sync as write } from '@plastichub/fs/write'\nimport { sync as exists } from '@plastichub/fs/exists'\nexport * from './zod_schema'\n\nimport * as TransportStream from 'winston-transport'\nconst { SeqTransport } = require('@datalust/winston-seq')\nimport * as winston from 'winston'\n\nexport enum LogTarget {\n None = 0,\n Console = 1 << 0,\n TextFile = 1 << 1,\n JsonFile = 1 << 2,\n Seq = 1 << 3,\n All = ~(~0 << 4)\n}\n\nexport interface LoggerOptions {\n name: string;\n file?: string;\n seqUrl?: string;\n seqApiKey?: string;\n logTargets?: LogTarget;\n}\n\nexport function createLogger(options: LoggerOptions) {\n const logger = winston.createLogger({\n defaultMeta: { service: options.name },\n level: 'debug',\n transports: []\n });\n\n if (options.logTargets & LogTarget.Console) {\n logger.add(new winston.transports.Console({\n format: winston.format.combine(\n winston.format.timestamp(),\n winston.format.timestamp({ format: 'MM/DD/YYYY hh:mm:ss.SSS' }),\n winston.format.json(),\n winston.format.colorize(),\n winston.format.printf(info => {\n return `[${info.level}] [${options.name}] : ${info.message}`;\n }))\n }));\n }\n\n if (options.file) {\n if (options.logTargets & LogTarget.TextFile) {\n logger.add(new winston.transports.File({\n format: winston.format.combine(\n winston.format.timestamp(),\n winston.format.timestamp({ format: 'MM/DD/YYYY hh:mm:ss.SSS' }),\n winston.format.printf(info => {\n return `[${info.timestamp}] [${info.level}] [${options.name}] : ${info.message}`;\n })),\n dirname: path.parse(options.file).dir,\n filename: path.parse(options.file).base\n }));\n }\n\n if (options.logTargets & LogTarget.JsonFile) {\n logger.add(new JsonArrayFileTransport({ filename: options.file }));\n }\n }\n\n if (options.logTargets & LogTarget.Seq && options.seqUrl) {\n logger.add(new SeqTransport({\n serverUrl: options.seqUrl,\n apiKey: options.seqApiKey,\n onError: (e => { console.error('Seq transport error:', e) }),\n }));\n }\n\n return logger;\n}\n\nclass JsonArrayFileTransport extends TransportStream {\n filename: string;\n constructor(opts) {\n super(opts);\n opts.filename = opts.filename\n this.filename = opts.filename || 'logs.json';\n setImmediate(() => this.emit('opened'))\n }\n log(info: any, next: () => void): void {\n setImmediate(() => this.emit('logged', info))\n const { level, message, exception, stack, ...props } = info;\n setImmediate(() => this.emit('logged', info))\n const fileExists = exists(this.filename)\n const existingLogs = fileExists\n ? read(this.filename, 'json') as []\n : [];\n\n const entry = {\n level: info.level,\n message: info.message,\n timestamp: new Date().toISOString(),\n ...info\n };\n existingLogs.push(entry)\n write(this.filename, existingLogs)\n next()\n }\n close(): void {\n setImmediate(() => this.emit('closed'))\n }\n flush(): Promise<any> {\n return new Promise((resolve) => {\n resolve(true)\n })\n }\n}\n\n// Example usage:\n/*\nconst logger = createLogger({\n name: 'MyApp',\n file: 'logs/app.log',\n seqUrl: 'http://localhost:5341',\n seqApiKey: 'your-api-key',\n logTargets: LogTarget.Console | LogTarget.JsonFile | LogTarget.Seq\n});\n*/" } }, "parsed_arguments": null, "timestamp": "2024-12-28T16:33:57.706Z", "sessionId": "1735403609532", "query": "introduce logging flags (enum) to enable targets : file (text, json (JsonArrayFileTransport), console and SeqTransport, in src/index.ts" }, "timestamp": "2024-12-28T16:33:57.708Z", "service": "collector:onToolCall" }, { "level": "info", "message": { "name": "modify_project_files", "arguments": { "files": [ { "path": "src/index.ts", "content": "import * as path from 'path'\nimport { createStream } from \"rotating-file-stream\"\nimport { BaseLogger, ILogObjMeta, ISettingsParam, Logger } from \"tslog\"\nimport { LogLevelEx } from './zod_schema'\nimport { sync as read } from '@plastichub/fs/read'\nimport { sync as write } from '@plastichub/fs/write'\nimport { sync as exists } from '@plastichub/fs/exists'\nexport * from './zod_schema'\n\nimport * as TransportStream from 'winston-transport'\nconst { SeqTransport } = require('@datalust/winston-seq')\nimport * as winston from 'winston'\n\nexport enum LogTarget {\n Console = 1 << 0,\n FileText = 1 << 1,\n FileJson = 1 << 2,\n Seq = 1 << 3\n}\n\nexport function createLogger(name: string, options?: ISettingsParam<any>) {\n return new Logger<unknown>({\n name,\n type: 'pretty',\n ...options,\n })\n}\nexport const defaultLogger = createLogger('DefaultLogger', {\n minLevel: LogLevelEx.info\n})\nexport class CustomLogger<LogObj> extends BaseLogger<LogObj> {\n constructor(settings?: ISettingsParam<LogObj>, logObj?: LogObj) {\n super(settings, logObj, 5)\n }\n public custom(loggerName?: string, ...args: unknown[]): LogObj & ILogObjMeta {\n return super.log(8, loggerName || 'Custom', ...args)\n }\n}\n\nclass JsonArrayFileTransport extends TransportStream {\n filename: string;\n constructor(opts) {\n super(opts);\n opts.filename = opts.filename\n this.filename = opts.filename || 'logs.json';\n setImmediate(() => this.emit('opened'))\n }\n log(info: any, next: () => void): void {\n setImmediate(() => this.emit('logged', info))\n const { level, message, exception, stack, ...props } = info;\n setImmediate(() => this.emit('logged', info))\n const fileExists = exists(this.filename)\n const existingLogs = fileExists\n ? read(this.filename, 'json') as []\n : [];\n\n const entry = {\n level: info.level,\n message: info.message,\n timestamp: new Date().toISOString(),\n ...info\n };\n existingLogs.push(entry)\n write(this.filename, existingLogs)\n next()\n }\n close(): void {\n setImmediate(() => this.emit('closed'))\n }\n flush(): Promise<any> {\n return new Promise((resolve, reject) => {\n resolve(true)\n })\n }\n}\nexport type WinstonLoggerType = 'JSON' | 'Markdown'\nexport const winstonLogger = (name: string, file: string, targets: LogTarget = LogTarget.Console) => {\n const logger = winston.createLogger({\n defaultMeta: { service: name },\n level: 'debug',\n transports: []\n })\n\n if (targets & LogTarget.Console) {\n logger.add(new winston.transports.Console({\n format: winston.format.combine(\n winston.format.timestamp(),\n winston.format.timestamp({ format: 'MM/DD/YYYY hh:mm:ss.SSS' }),\n winston.format.json(),\n winston.format.colorize(),\n winston.format.printf(info => {\n return `[${info.level}] [${name}] : ${info.message}`;\n }))\n }))\n }\n\n if (targets & LogTarget.FileText) {\n logger.add(new winston.transports.File({\n format: winston.format.combine(\n winston.format.timestamp(),\n winston.format.timestamp({ format: 'MM/DD/YYYY hh:mm:ss.SSS' }),\n winston.format.json(),\n winston.format.printf(info => {\n return JSON.stringify(info, null, 2);\n })),\n dirname: path.parse(file).dir,\n filename: path.parse(file).base\n }))\n }\n\n if (targets & LogTarget.FileJson) {\n logger.add(new JsonArrayFileTransport({ filename: file }))\n }\n\n if (targets & LogTarget.Seq) {\n logger.add(new SeqTransport({\n serverUrl: \"https://localhost:5341\",\n apiKey: \"Qu6XPThyfnXo7ugXoRZS\",\n onError: (e => { })\n }))\n }\n\n return logger\n}\n\nexport const createFileLogger = (logger: Logger<unknown>, level: number, file: string): Logger<unknown> => {\n const rfs = createStream(file,\n {\n size: \"10M\", // rotate every 10 MegaBytes written\n interval: \"1d\", // rotate daily\n compress: \"gzip\", // compress rotated files\n });\n\n const log = new Logger({\n type: \"json\",\n attachedTransports: [\n (logObj) => {\n rfs.write(JSON.stringify(logObj) + \"\\n\");\n },\n ],\n });\n return log\n}\n" } ] }, "parsed_arguments": null, "timestamp": "2024-12-28T16:36:12.772Z", "sessionId": "1735403736112", "query": "introduce logging flags (enum) to enable targets : file (text, json (JsonArrayFileTransport), console and SeqTransport, in src/index.ts::winstonLogger" }, "timestamp": "2024-12-28T16:36:12.773Z", "service": "collector:onToolCall" } ]