@plastichub/osr-log
Version:
Package basics
221 lines • 20.9 kB
JSON
[
{
"level": "info",
"message": {
"id": "gen-1735403516-VXYI2m6G49gcDhKAV2jn",
"provider": "Amazon Bedrock",
"model": "anthropic/claude-3.5-sonnet",
"object": "chat.completion",
"created": 1735403516,
"choices": [
{
"logprobs": null,
"finish_reason": "tool_calls",
"index": 0,
"message": {
"role": "assistant",
"content": "Here's the modified code with logging flags:",
"refusal": null,
"tool_calls": [
{
"id": "tooluse_A7Q_pHrKSFiK_PgaTLEofw",
"index": 0,
"type": "function",
"function": {
"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
}
}
],
"parsed": null
}
}
],
"usage": {
"prompt_tokens": 3253,
"completion_tokens": 48,
"total_tokens": 3301
}
},
"timestamp": "2024-12-28T16:32:28.806Z",
"service": "collector:onChatCompletion"
},
{
"level": "info",
"message": {
"id": "gen-1735403549-0WCO3oLODp2nKgQOaJcy",
"provider": "Anthropic",
"model": "anthropic/claude-3.5-sonnet",
"object": "chat.completion",
"created": 1735403549,
"choices": [
{
"logprobs": null,
"finish_reason": "end_turn",
"index": 0,
"message": {
"role": "assistant",
"content": "\n\nUsage example:\n\n```typescript\n// Create a logger with all transports enabled\nconst logger = winstonLogger('MyApp', 'app-logs', {\n enableConsole: true,\n enableJsonFile: true,\n enableTextFile: true,\n enableSeq: true,\n seqConfig: {\n serverUrl: 'https://localhost:5341',\n apiKey: 'your-api-key'\n }\n});\n\n// Create a logger with only console and JSON file\nconst simpleLogger = winstonLogger('SimpleApp', 'simple-logs', {\n enableConsole: true,\n enableJsonFile: true\n});\n```\n\nThe changes include:\n1. Added LoggerOptions interface to control which transports are enabled\n2. Modified winstonLogger to accept LoggerOptions parameter\n3. Made all transports optional and controlled by flags\n4. Separated JSON and text file logging into different options\n5. Made Seq transport configurable through options\n6. Improved file naming for different transport types",
"refusal": "",
"tool_calls": [],
"parsed": null
}
}
],
"usage": {
"prompt_tokens": 4838,
"completion_tokens": 244,
"total_tokens": 5082
}
},
"timestamp": "2024-12-28T16:32:34.537Z",
"service": "collector:onChatCompletion"
},
{
"level": "info",
"message": {
"id": "gen-1735403610-g09e80z2EcjZ4JD0gkCk",
"provider": "Amazon Bedrock",
"model": "anthropic/claude-3.5-sonnet",
"object": "chat.completion",
"created": 1735403610,
"choices": [
{
"logprobs": null,
"finish_reason": "tool_calls",
"index": 0,
"message": {
"role": "assistant",
"content": null,
"refusal": null,
"tool_calls": [
{
"id": "tooluse_cGLs2BqoQDWWXnZiGOg7nA",
"index": 0,
"type": "function",
"function": {
"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
}
}
],
"parsed": null
}
}
],
"usage": {
"prompt_tokens": 3263,
"completion_tokens": 37,
"total_tokens": 3300
}
},
"timestamp": "2024-12-28T16:33:57.704Z",
"service": "collector:onChatCompletion"
},
{
"level": "info",
"message": {
"id": "gen-1735403638-odBPhVn2ldki7jfTo4vG",
"provider": "Amazon Bedrock",
"model": "anthropic/claude-3.5-sonnet",
"object": "chat.completion",
"created": 1735403638,
"choices": [
{
"logprobs": null,
"finish_reason": "end_turn",
"index": 0,
"message": {
"role": "assistant",
"content": "",
"refusal": "",
"tool_calls": [],
"parsed": null
}
}
],
"usage": {
"prompt_tokens": 4648,
"completion_tokens": 3,
"total_tokens": 4651
}
},
"timestamp": "2024-12-28T16:34:01.430Z",
"service": "collector:onChatCompletion"
},
{
"level": "info",
"message": {
"id": "gen-1735403737-v33uBQ8zgU1Gl3xly0Vz",
"provider": "Amazon Bedrock",
"model": "anthropic/claude-3.5-sonnet",
"object": "chat.completion",
"created": 1735403737,
"choices": [
{
"logprobs": null,
"finish_reason": "tool_calls",
"index": 0,
"message": {
"role": "assistant",
"content": null,
"refusal": null,
"tool_calls": [
{
"id": "tooluse_hzlaYz6gTV-8LX8sPySSOQ",
"index": 0,
"type": "function",
"function": {
"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
}
}
],
"parsed": null
}
}
],
"usage": {
"prompt_tokens": 3268,
"completion_tokens": 41,
"total_tokens": 3309
}
},
"timestamp": "2024-12-28T16:36:12.770Z",
"service": "collector:onChatCompletion"
},
{
"level": "info",
"message": {
"id": "gen-1735403773-oUTvveEvZcSFJfmYwPKs",
"provider": "Amazon Bedrock",
"model": "anthropic/claude-3.5-sonnet",
"object": "chat.completion",
"created": 1735403773,
"choices": [
{
"logprobs": null,
"finish_reason": "end_turn",
"index": 0,
"message": {
"role": "assistant",
"content": "",
"refusal": "",
"tool_calls": [],
"parsed": null
}
}
],
"usage": {
"prompt_tokens": 4838,
"completion_tokens": 3,
"total_tokens": 4841
}
},
"timestamp": "2024-12-28T16:36:16.082Z",
"service": "collector:onChatCompletion"
}
]