From ce7aef1119a98716e0e8acd6f651404950c13c29 Mon Sep 17 00:00:00 2001 From: cles <208023732@qq.com> Date: Thu, 4 Sep 2025 16:00:30 +0800 Subject: [PATCH] =?UTF-8?q?feat:=20=E6=B7=BB=E5=8A=A0=20electron-log=20?= =?UTF-8?q?=E4=BE=9D=E8=B5=96=E5=B9=B6=E9=9B=86=E6=88=90=E6=97=A5=E5=BF=97?= =?UTF-8?q?=E8=AE=B0=E5=BD=95=E5=8A=9F=E8=83=BD=E5=88=B0=20IPC=20=E5=A4=84?= =?UTF-8?q?=E7=90=86?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- package-lock.json | 10 +++++++ package.json | 1 + src/main/index.js | 9 ++++++- src/main/ipcRouter.js | 63 +++++++++++++++++++++++++++++++------------ 4 files changed, 65 insertions(+), 18 deletions(-) diff --git a/package-lock.json b/package-lock.json index 707831a..faa1a99 100644 --- a/package-lock.json +++ b/package-lock.json @@ -15,6 +15,7 @@ "ahooks": "^3.9.5", "antd": "^5.27.1", "chart.js": "^4.5.0", + "electron-log": "^5.4.3", "electron-updater": "^6.3.9", "konva": "^9.3.22", "react": "^18.0.0", @@ -4611,6 +4612,15 @@ "node": ">= 10.0.0" } }, + "node_modules/electron-log": { + "version": "5.4.3", + "resolved": "https://registry.npmmirror.com/electron-log/-/electron-log-5.4.3.tgz", + "integrity": "sha512-sOUsM3LjZdugatazSQ/XTyNcw8dfvH1SYhXWiJyfYodAAKOZdHs0txPiLDXFzOZbhXgAgshQkshH2ccq0feyLQ==", + "license": "MIT", + "engines": { + "node": ">= 14" + } + }, "node_modules/electron-publish": { "version": "25.1.7", "resolved": "https://registry.npmmirror.com/electron-publish/-/electron-publish-25.1.7.tgz", diff --git a/package.json b/package.json index 120c4d9..23398bd 100644 --- a/package.json +++ b/package.json @@ -24,6 +24,7 @@ "ahooks": "^3.9.5", "antd": "^5.27.1", "chart.js": "^4.5.0", + "electron-log": "^5.4.3", "electron-updater": "^6.3.9", "konva": "^9.3.22", "react": "^18.0.0", diff --git a/src/main/index.js b/src/main/index.js index 2165aee..75aa1bd 100644 --- a/src/main/index.js +++ b/src/main/index.js @@ -3,6 +3,12 @@ import { join } from 'path' import { electronApp, optimizer, is } from '@electron-toolkit/utils' import icon from '../../resources/icon.png?asset' import { registerIpRouter } from './ipcRouter' +import log from 'electron-log' + +// 开发环境日志写到项目根目录 logs 文件夹 +if (is.dev) { + log.transports.file.resolvePathFn = () => `${process.cwd()}/logs/main.log` +} function createWindow() { const mainWindow = new BrowserWindow({ width: 1440, @@ -15,7 +21,7 @@ function createWindow() { sandbox: false } }) - + mainWindow.setMenu(null) mainWindow.on('ready-to-show', () => { mainWindow.show() }) @@ -33,6 +39,7 @@ function createWindow() { } app.whenReady().then(() => { + log.info('Electron 应用已启动') electronApp.setAppUserModelId('com.electron') app.on('browser-window-created', (_, window) => { diff --git a/src/main/ipcRouter.js b/src/main/ipcRouter.js index 1977fbe..3f753cd 100644 --- a/src/main/ipcRouter.js +++ b/src/main/ipcRouter.js @@ -2,7 +2,7 @@ import { ipcMain } from 'electron' import dgram from 'dgram' import net from 'net' import { IPC_EVENT } from '../renderer/src/common/ipcEvents.js' -import fs from 'fs' +import log from 'electron-log' const TIMEOUT = 10000 // 10秒超时 const END_SEQUENCE = '\n\n' // 消息结束标志 // 全局保存所有TCP连接和相关信息 @@ -10,6 +10,12 @@ const tcpClients = new Map() // 保存待处理的请求,用于关联响应 const pendingRequests = new Map() +// 记录IPC命令的通用函数(事件类型自动拼接) +const logIPCCommand = (ip, command) => { + const eventType = `${command.command?.toUpperCase()}_${command.type?.toUpperCase()}` + log.info(`IPC Command from renderer - ${eventType} to ${ip}:`, command) +} + export function registerIpRouter() { ipcMain.on(IPC_EVENT.DEVICE_SEARCH, searchDevice) ipcMain.on(IPC_EVENT.DEVICE_CONNECT, connectDevice) @@ -49,10 +55,10 @@ const searchDevice = (event) => { udpClient.setBroadcast(true) udpClient.send(message, 0, message.length, PORT, BROADCAST_ADDR, (err) => { if (err) { - console.error('UDP send failed', err) + log.error('UDP send failed', err) udpClient.close() } else { - console.log('UDP send successful') + log.info('UDP send successful') } }) }) @@ -64,18 +70,18 @@ const searchDevice = (event) => { data: msg.toString() }) } catch (e) { - console.error('parse UDP message failed:', e) + log.error('UDP message parse error', e) } if (timer) clearTimeout(timer) timer = setTimeout(() => { udpClient.close() - console.log('UDP socket closed after timeout') + log.info('UDP socket closed after timeout') event.reply && event.reply(IPC_EVENT.DEVICE_SEARCH_REPLY, Array.from(resultMap.values())) }, 1000) }) udpClient.on('error', (err) => { - console.error('UDP error:', err) + log.error('UDP error:', err) udpClient.close() event.reply && event.reply(IPC_EVENT.DEVICE_SEARCH_REPLY, Array.from(resultMap.values())) }) @@ -121,13 +127,12 @@ const connectDevice = (event, { ip, port }) => { try { msg = JSON.parse(line) } catch (e) { - console.error('TCP data parse error:', e) - fs.appendFileSync('error_log.txt', line + '\n') + log.error('TCP data parse error:', e) continue } if (!msg || !msg.command) { - console.warn('invalid msg format:', msg) + log.warn('invalid msg format:', msg) continue } @@ -137,6 +142,7 @@ const connectDevice = (event, { ip, port }) => { }) client.on('error', (err) => { + log.error('TCP connection error:', err) event.reply(IPC_EVENT.DEVICE_CONNECT_REPLY, { success: false, error: err.message }) client.destroy() tcpClients.delete(ip) @@ -145,6 +151,7 @@ const connectDevice = (event, { ip, port }) => { }) client.on('close', () => { + log.info(`TCP connection to ${ip} closed`) tcpClients.delete(ip) clearPendingRequestsByIp(ip) }) @@ -168,7 +175,17 @@ const handleTcpResponse = async (ip, msg) => { const connectionInfo = tcpClients.get(ip) if (!connectionInfo) return - switch (`${msg.command}:${msg.type}`) { + // 记录TCP响应数据 + const commandType = `${msg.command}:${msg.type}` + if ( + commandType !== IPC_EVENT.RESULT_REPLY && + commandType !== IPC_EVENT.IMAGE_REPLY && + commandType !== IPC_EVENT.HEARTBEAT_REPLY + ) { + log.info(`TCP Response from ${ip}:`, commandType, msg.values || msg) + } + + switch (commandType) { case IPC_EVENT.RESULT_REPLY: connectionInfo.eventSender.send(IPC_EVENT.RESULT_REPLY, { ip, ...msg }) break @@ -407,6 +424,7 @@ const sensorLoad = async (event, { ip }) => { // 发送传感器加载命令 const command = { command: 'sensors', type: 'get', values: '' } const message = JSON.stringify(command) + END_SEQUENCE + logIPCCommand(ip, command) connectionInfo.client.write(message, (err) => { if (err) { @@ -451,6 +469,7 @@ const sensorSet = async (event, { ip, sensors }) => { // 发送传感器设置命令 const command = { command: 'sensors', type: 'set', values: sensors } const message = JSON.stringify(command) + END_SEQUENCE + logIPCCommand(ip, command) connectionInfo.client.write(message, (err) => { if (err) { @@ -495,6 +514,7 @@ const imageSendTimeGet = async (event, { ip }) => { // 发送图像发送间隔获取命令 const command = { command: 'imageSendTime', type: 'get', values: '' } const message = JSON.stringify(command) + END_SEQUENCE + logIPCCommand(ip, command) connectionInfo.client.write(message, (err) => { if (err) { @@ -539,6 +559,7 @@ const imageSendTimeSet = async (event, { ip, value }) => { // 发送图像发送间隔设置命令 const command = { command: 'imageSendTime', type: 'set', values: value } const message = JSON.stringify(command) + END_SEQUENCE + logIPCCommand(ip, command) connectionInfo.client.write(message, (err) => { if (err) { @@ -579,6 +600,7 @@ const zeroCountGet = async (event, { ip }) => { const command = { command: 'zeroCount', type: 'get', values: '' } const message = JSON.stringify(command) + END_SEQUENCE + logIPCCommand(ip, command) connectionInfo.client.write(message, (err) => { if (err) { @@ -619,6 +641,7 @@ const zeroCountSet = async (event, { ip, value }) => { const command = { command: 'zeroCount', type: 'set', values: value } const message = JSON.stringify(command) + END_SEQUENCE + logIPCCommand(ip, command) connectionInfo.client.write(message, (err) => { if (err) { @@ -659,6 +682,7 @@ const resultCountGet = async (event, { ip }) => { const command = { command: 'resultCount', type: 'get', values: '' } const message = JSON.stringify(command) + END_SEQUENCE + logIPCCommand('RESULT_COUNT_GET', ip, command) connectionInfo.client.write(message, (err) => { if (err) { @@ -699,6 +723,7 @@ const resultCountSet = async (event, { ip, value }) => { const command = { command: 'resultCount', type: 'set', values: value } const message = JSON.stringify(command) + END_SEQUENCE + logIPCCommand(ip, command) connectionInfo.client.write(message, (err) => { if (err) { @@ -739,7 +764,7 @@ const dataFpsGet = async (event, { ip }) => { const command = { command: 'dataFps', type: 'get', values: '' } const message = JSON.stringify(command) + END_SEQUENCE - + logIPCCommand(ip, command) connectionInfo.client.write(message, (err) => { if (err) { pendingRequests.delete(requestKey) @@ -779,6 +804,7 @@ const dataFpsSet = async (event, { ip, value }) => { const command = { command: 'dataFps', type: 'set', values: value } const message = JSON.stringify(command) + END_SEQUENCE + logIPCCommand(ip, command) connectionInfo.client.write(message, (err) => { if (err) { pendingRequests.delete(requestKey) @@ -818,7 +844,7 @@ const videoFpsGet = async (event, { ip }) => { const command = { command: 'videoFps', type: 'get', values: '' } const message = JSON.stringify(command) + END_SEQUENCE - + logIPCCommand(ip, command) connectionInfo.client.write(message, (err) => { if (err) { pendingRequests.delete(requestKey) @@ -858,7 +884,7 @@ const videoFpsSet = async (event, { ip, value }) => { const command = { command: 'videoFps', type: 'set', values: value } const message = JSON.stringify(command) + END_SEQUENCE - + logIPCCommand(ip, command) connectionInfo.client.write(message, (err) => { if (err) { pendingRequests.delete(requestKey) @@ -898,7 +924,7 @@ const thresholdGet = async (event, { ip }) => { const command = { command: 'threshold', type: 'get', values: '' } const message = JSON.stringify(command) + END_SEQUENCE - + logIPCCommand(ip, command) connectionInfo.client.write(message, (err) => { if (err) { pendingRequests.delete(requestKey) @@ -938,7 +964,7 @@ const thresholdSet = async (event, { ip, value }) => { const command = { command: 'threshold', type: 'set', values: value } const message = JSON.stringify(command) + END_SEQUENCE - + logIPCCommand(ip, command) connectionInfo.client.write(message, (err) => { if (err) { pendingRequests.delete(requestKey) @@ -978,7 +1004,7 @@ const invalidDataCountGet = async (event, { ip }) => { const command = { command: 'invalidDataCount', type: 'get', values: '' } const message = JSON.stringify(command) + END_SEQUENCE - + logIPCCommand(ip, command) connectionInfo.client.write(message, (err) => { if (err) { pendingRequests.delete(requestKey) @@ -1018,7 +1044,7 @@ const invalidDataCountSet = async (event, { ip, value }) => { const command = { command: 'invalidDataCount', type: 'set', values: value } const message = JSON.stringify(command) + END_SEQUENCE - + logIPCCommand(ip, command) connectionInfo.client.write(message, (err) => { if (err) { pendingRequests.delete(requestKey) @@ -1057,6 +1083,7 @@ const imageSendEnabledSet = async (event, { ip, value }) => { const command = { command: 'imageSendEnabled', type: 'set', values: value } const message = JSON.stringify(command) + END_SEQUENCE + logIPCCommand(ip, command) connectionInfo.client.write(message, (err) => { if (err) { @@ -1095,6 +1122,8 @@ const isClearZeroSet = async (event, { ip, value }) => { const command = { command: 'isClearZero', type: 'set', values: value } const message = JSON.stringify(command) + END_SEQUENCE + logIPCCommand(ip, command) + connectionInfo.client.write(message, (err) => { if (err) { pendingRequests.delete(requestKey)