76 lines
2.2 KiB
TypeScript
76 lines
2.2 KiB
TypeScript
import fs from 'node:fs/promises'
|
|
import path from 'node:path'
|
|
|
|
export interface BotLogEntry {
|
|
id: string
|
|
timestamp: string
|
|
platform: 'discord' | 'dingtalk' | 'lark' | 'telegram' | 'slack'
|
|
eventType: 'connection' | 'disconnection' | 'message_received' | 'message_sent' | 'error'
|
|
severity: 'info' | 'warning' | 'error'
|
|
message: string
|
|
details?: Record<string, unknown>
|
|
}
|
|
|
|
interface LogQueryOptions {
|
|
limit?: number
|
|
offset?: number
|
|
platform?: 'discord' | 'dingtalk' | 'lark' | 'telegram' | 'slack'
|
|
eventType?: string
|
|
severity?: 'info' | 'warning' | 'error'
|
|
}
|
|
|
|
export class BotLogger {
|
|
private static logs: BotLogEntry[] = []
|
|
private static maxLogs = 1000
|
|
private static logDir = path.join(process.cwd(), 'remote-control', 'data', 'logs')
|
|
private static idCounter = 0
|
|
|
|
static log(entry: Omit<BotLogEntry, 'id' | 'timestamp'>): void {
|
|
const logEntry: BotLogEntry = {
|
|
id: `log_${++this.idCounter}_${Date.now()}`,
|
|
timestamp: new Date().toISOString(),
|
|
...entry,
|
|
}
|
|
|
|
this.logs.unshift(logEntry)
|
|
if (this.logs.length > this.maxLogs) {
|
|
this.logs = this.logs.slice(0, this.maxLogs)
|
|
}
|
|
|
|
this.writeToFile(logEntry).catch(() => {})
|
|
}
|
|
|
|
static getLogs(options: LogQueryOptions = {}): { logs: BotLogEntry[]; total: number } {
|
|
let filtered = [...this.logs]
|
|
|
|
if (options.platform) {
|
|
filtered = filtered.filter(l => l.platform === options.platform)
|
|
}
|
|
if (options.eventType) {
|
|
filtered = filtered.filter(l => l.eventType === options.eventType)
|
|
}
|
|
if (options.severity) {
|
|
filtered = filtered.filter(l => l.severity === options.severity)
|
|
}
|
|
|
|
const total = filtered.length
|
|
const offset = options.offset || 0
|
|
const limit = options.limit || 100
|
|
const logs = filtered.slice(offset, offset + limit)
|
|
|
|
return { logs, total }
|
|
}
|
|
|
|
static clear(): void {
|
|
this.logs = []
|
|
}
|
|
|
|
private static async writeToFile(entry: BotLogEntry): Promise<void> {
|
|
await fs.mkdir(this.logDir, { recursive: true })
|
|
const date = new Date().toISOString().split('T')[0]
|
|
const logFile = path.join(this.logDir, `bot-${date}.log`)
|
|
const line = JSON.stringify(entry) + '\n'
|
|
await fs.appendFile(logFile, line, 'utf-8')
|
|
}
|
|
}
|