mirror of
https://github.com/hicccc77/WeFlow.git
synced 2026-03-24 23:06:51 +00:00
Merge pull request #430 from Wythehard/codex/cleanup-monitor-debug-logs
chore: remove temporary monitor debug logs and add log clear action
This commit is contained in:
@@ -972,6 +972,17 @@ function registerIpcHandlers() {
|
|||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
|
ipcMain.handle('log:clear', async () => {
|
||||||
|
try {
|
||||||
|
const logPath = join(app.getPath('userData'), 'logs', 'wcdb.log')
|
||||||
|
await mkdir(dirname(logPath), { recursive: true })
|
||||||
|
await writeFile(logPath, '', 'utf8')
|
||||||
|
return { success: true }
|
||||||
|
} catch (e) {
|
||||||
|
return { success: false, error: String(e) }
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
ipcMain.handle('diagnostics:getExportCardLogs', async (_, options?: { limit?: number }) => {
|
ipcMain.handle('diagnostics:getExportCardLogs', async (_, options?: { limit?: number }) => {
|
||||||
return exportCardDiagnosticsService.snapshot(options?.limit)
|
return exportCardDiagnosticsService.snapshot(options?.limit)
|
||||||
})
|
})
|
||||||
|
|||||||
@@ -70,6 +70,7 @@ contextBridge.exposeInMainWorld('electronAPI', {
|
|||||||
log: {
|
log: {
|
||||||
getPath: () => ipcRenderer.invoke('log:getPath'),
|
getPath: () => ipcRenderer.invoke('log:getPath'),
|
||||||
read: () => ipcRenderer.invoke('log:read'),
|
read: () => ipcRenderer.invoke('log:read'),
|
||||||
|
clear: () => ipcRenderer.invoke('log:clear'),
|
||||||
debug: (data: any) => ipcRenderer.send('log:debug', data)
|
debug: (data: any) => ipcRenderer.send('log:debug', data)
|
||||||
},
|
},
|
||||||
|
|
||||||
|
|||||||
@@ -359,16 +359,15 @@ class ChatService {
|
|||||||
// 这种方式更高效,且不占用 JS 线程,并能直接监听 session/message 目录变更
|
// 这种方式更高效,且不占用 JS 线程,并能直接监听 session/message 目录变更
|
||||||
wcdbService.setMonitor((type, json) => {
|
wcdbService.setMonitor((type, json) => {
|
||||||
this.handleSessionStatsMonitorChange(type, json)
|
this.handleSessionStatsMonitorChange(type, json)
|
||||||
|
const windows = BrowserWindow.getAllWindows()
|
||||||
// 广播给所有渲染进程窗口
|
// 广播给所有渲染进程窗口
|
||||||
BrowserWindow.getAllWindows().forEach((win) => {
|
windows.forEach((win) => {
|
||||||
if (!win.isDestroyed()) {
|
if (!win.isDestroyed()) {
|
||||||
win.webContents.send('wcdb-change', { type, json })
|
win.webContents.send('wcdb-change', { type, json })
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 预热 media 数据库列表缓存(后台异步执行)
|
* 预热 media 数据库列表缓存(后台异步执行)
|
||||||
|
|||||||
@@ -173,7 +173,6 @@ export class WcdbCore {
|
|||||||
}
|
}
|
||||||
} catch {}
|
} catch {}
|
||||||
}
|
}
|
||||||
|
|
||||||
this.connectMonitorPipe(pipePath)
|
this.connectMonitorPipe(pipePath)
|
||||||
return true
|
return true
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
@@ -194,8 +193,14 @@ export class WcdbCore {
|
|||||||
|
|
||||||
let buffer = ''
|
let buffer = ''
|
||||||
this.monitorPipeClient.on('data', (data: Buffer) => {
|
this.monitorPipeClient.on('data', (data: Buffer) => {
|
||||||
buffer += data.toString('utf8')
|
const rawChunk = data.toString('utf8')
|
||||||
const lines = buffer.split('\n')
|
// macOS 侧可能使用 '\0' 或无换行分隔,统一归一化并兜底拆包
|
||||||
|
const normalizedChunk = rawChunk
|
||||||
|
.replace(/\u0000/g, '\n')
|
||||||
|
.replace(/}\s*{/g, '}\n{')
|
||||||
|
|
||||||
|
buffer += normalizedChunk
|
||||||
|
const lines = buffer.split(/\r?\n/)
|
||||||
buffer = lines.pop() || ''
|
buffer = lines.pop() || ''
|
||||||
for (const line of lines) {
|
for (const line of lines) {
|
||||||
if (line.trim()) {
|
if (line.trim()) {
|
||||||
@@ -207,9 +212,23 @@ export class WcdbCore {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 兜底:如果没有分隔符但已形成完整 JSON,则直接上报
|
||||||
|
const tail = buffer.trim()
|
||||||
|
if (tail.startsWith('{') && tail.endsWith('}')) {
|
||||||
|
try {
|
||||||
|
const parsed = JSON.parse(tail)
|
||||||
|
this.monitorCallback?.(parsed.action || 'update', tail)
|
||||||
|
buffer = ''
|
||||||
|
} catch {
|
||||||
|
// 不可解析则继续等待下一块数据
|
||||||
|
}
|
||||||
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
this.monitorPipeClient.on('error', () => {})
|
this.monitorPipeClient.on('error', () => {
|
||||||
|
// 保持静默,与现有错误处理策略一致
|
||||||
|
})
|
||||||
|
|
||||||
this.monitorPipeClient.on('close', () => {
|
this.monitorPipeClient.on('close', () => {
|
||||||
this.monitorPipeClient = null
|
this.monitorPipeClient = null
|
||||||
|
|||||||
@@ -136,7 +136,7 @@ export class WcdbService {
|
|||||||
*/
|
*/
|
||||||
setMonitor(callback: (type: string, json: string) => void): void {
|
setMonitor(callback: (type: string, json: string) => void): void {
|
||||||
this.monitorListener = callback;
|
this.monitorListener = callback;
|
||||||
this.callWorker('setMonitor').catch(() => { });
|
this.callWorker<{ success?: boolean }>('setMonitor').catch(() => { });
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -20,15 +20,17 @@ if (parentPort) {
|
|||||||
result = { success: true }
|
result = { success: true }
|
||||||
break
|
break
|
||||||
case 'setMonitor':
|
case 'setMonitor':
|
||||||
core.setMonitor((type, json) => {
|
{
|
||||||
|
const monitorOk = core.setMonitor((type, json) => {
|
||||||
parentPort!.postMessage({
|
parentPort!.postMessage({
|
||||||
id: -1,
|
id: -1,
|
||||||
type: 'monitor',
|
type: 'monitor',
|
||||||
payload: { type, json }
|
payload: { type, json }
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
result = { success: true }
|
result = { success: monitorOk }
|
||||||
break
|
break
|
||||||
|
}
|
||||||
case 'testConnection':
|
case 'testConnection':
|
||||||
result = await core.testConnection(payload.dbPath, payload.hexKey, payload.wxid)
|
result = await core.testConnection(payload.dbPath, payload.hexKey, payload.wxid)
|
||||||
break
|
break
|
||||||
|
|||||||
@@ -897,6 +897,21 @@ function SettingsPage({ onClose }: SettingsPageProps = {}) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const handleClearLog = async () => {
|
||||||
|
const confirmed = window.confirm('确定清空 wcdb.log 吗?')
|
||||||
|
if (!confirmed) return
|
||||||
|
try {
|
||||||
|
const result = await window.electronAPI.log.clear()
|
||||||
|
if (!result.success) {
|
||||||
|
showMessage(result.error || '清空日志失败', false)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
showMessage('日志已清空', true)
|
||||||
|
} catch (e: any) {
|
||||||
|
showMessage(`清空日志失败: ${e}`, false)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
const handleClearAnalyticsCache = async () => {
|
const handleClearAnalyticsCache = async () => {
|
||||||
if (isClearingCache) return
|
if (isClearingCache) return
|
||||||
setIsClearingAnalyticsCache(true)
|
setIsClearingAnalyticsCache(true)
|
||||||
@@ -1427,6 +1442,9 @@ function SettingsPage({ onClose }: SettingsPageProps = {}) {
|
|||||||
<button className="btn btn-secondary" onClick={handleCopyLog}>
|
<button className="btn btn-secondary" onClick={handleCopyLog}>
|
||||||
<Copy size={16} /> 复制日志内容
|
<Copy size={16} /> 复制日志内容
|
||||||
</button>
|
</button>
|
||||||
|
<button className="btn btn-secondary" onClick={handleClearLog}>
|
||||||
|
<Trash2 size={16} /> 清空日志
|
||||||
|
</button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
1
src/types/electron.d.ts
vendored
1
src/types/electron.d.ts
vendored
@@ -69,6 +69,7 @@ export interface ElectronAPI {
|
|||||||
log: {
|
log: {
|
||||||
getPath: () => Promise<string>
|
getPath: () => Promise<string>
|
||||||
read: () => Promise<{ success: boolean; content?: string; error?: string }>
|
read: () => Promise<{ success: boolean; content?: string; error?: string }>
|
||||||
|
clear: () => Promise<{ success: boolean; error?: string }>
|
||||||
debug: (data: any) => void
|
debug: (data: any) => void
|
||||||
}
|
}
|
||||||
diagnostics: {
|
diagnostics: {
|
||||||
|
|||||||
Reference in New Issue
Block a user