electron-egg vue2日志上传、保存到本地
时间: 2025-04-02 22:13:53 浏览: 69
<think>嗯,用户想在Electron和Egg.js框架中用Vue2实现日志上传并保存到本地。首先,我得理清楚各个技术栈的职责。Electron负责客户端,处理本地日志的生成和上传;Egg.js作为服务端,接收并存储日志到数据库和本地文件;Vue2作为前端框架,可能用于展示日志或触发上传操作。
首先,Electron端的日志记录。Electron有主进程和渲染进程,用户可能需要在这两个进程中记录日志。可以考虑使用electron-log库,它支持多进程日志记录,自动保存到本地文件。安装后,在主进程和渲染进程中引入,配置日志文件的路径和级别。比如,设置日志存储在用户目录的特定文件夹下,按日期分割,避免文件过大。
然后是日志上传功能。在Electron中,可以通过渲染进程的Vue组件触发上传操作。比如,添加一个按钮,点击后调用上传方法。上传可以使用axios或fetch发送POST请求到Egg.js服务端。需要处理上传的时机,比如实时上传还是定时上传,或者达到一定大小后上传。同时,要考虑网络异常的情况,如果上传失败,可能需要将日志暂存,等待下次重试。
接下来是Egg.js服务端的实现。Egg.js处理文件上传通常有两种模式:File和Stream。这里上传的是日志文件,可能比较大,Stream模式更高效。需要配置路由,比如POST /api/logs,然后在控制器中使用ctx.getFileStream()获取上传的文件流。接着,将文件流保存到本地指定目录,比如app/logs/日期/,并同时将日志信息写入MySQL数据库。数据库设计可能需要包含日志内容、上传时间、用户ID等字段。
另外,需要注意安全性问题,比如文件上传的类型检查、大小限制,避免恶意文件上传。Egg.js可以通过配置config.default.js中的multipart选项来限制文件类型和大小。同时,日志文件保存到本地时,要确保目录存在,可以使用fs-extra库来创建目录。
Vue2部分主要负责用户界面,展示上传状态或历史日志。可能需要调用Electron的IPC通信,通知主进程执行上传操作,或者直接在前端组件中调用上传API。上传过程中显示加载状态,成功或失败后给出反馈。
整个流程的难点可能在于多进程日志的记录和上传的协同,以及服务端高效处理文件上传和存储。需要确保Electron端日志文件的正确生成和轮转,避免磁盘空间被占满。服务端在保存文件时,要考虑并发写入的问题,可能需要对文件写入加锁或使用唯一文件名。
另外,错误处理也很重要。比如Electron端日志上传失败后的重试机制,服务端数据库写入失败时的回滚操作,以及日志文件保存的异常处理。可能需要引入日志监控,当上传或保存失败时,及时通知开发人员。
最后,测试各个环节是否正常运作。在Electron中模拟日志生成和上传,检查服务端是否正确接收并存储到数据库和本地文件。同时,验证前端界面是否能正确显示上传状态和日志历史。</think>### 分步实现方法
#### 一、Electron 客户端实现本地日志记录
1. **安装依赖**
在Electron项目中安装日志库:
```bash
npm install electron-log
```
2. **配置日志模块**
```javascript
// 主进程与渲染进程通用配置
const log = require('electron-log');
log.transports.file.level = 'info';
log.transports.file.format = '{y}-{m}-{d} {h}:{i}:{s} [{level}] {text}';
log.transports.file.resolvePath = () => path.join(app.getPath('userData'), 'logs/app.log'); // 存储到用户数据目录
```
3. **日志分级记录示例**
```javascript
log.info('用户登录成功');
log.error('文件读取失败', { error: err.stack });
```
#### 二、Vue2 前端触发日志上传
```vue
<template>
<button @click="uploadLogs">上传日志</button>
</template>
<script>
export default {
methods: {
async uploadLogs() {
try {
const logPath = require('electron').remote.app.getPath('userData') + '/logs/app.log';
const formData = new FormData();
formData.append('log', new File([await fs.promises.readFile(logPath)], 'app.log'));
await axios.post('http://localhost:7001/api/logs', formData);
this.$message.success('上传成功');
} catch (err) {
console.error('上传失败:', err);
}
}
}
}
</script>
```
#### 三、Egg.js 服务端接收与存储
1. **配置上传中间件**
```javascript
// config/config.default.js
exports.multipart = {
mode: 'stream', // 使用流模式处理大文件
fileSize: '50mb',
whitelist: ['.log'] // 仅允许日志文件
};
```
2. **实现上传接口**
```javascript
// app/controller/log.js
const fs = require('fs-extra');
const path = require('path');
async upload() {
const { ctx } = this;
const stream = await ctx.getFileStream();
// 保存到本地
const saveDir = path.join(this.config.baseDir, 'logs', new Date().toISOString().slice(0,10));
await fs.ensureDir(saveDir);
const writer = fs.createWriteStream(path.join(saveDir, `app_${Date.now()}.log`));
stream.pipe(writer);
// 写入数据库
const logEntry = {
content: stream.fields.description,
path: writer.path,
upload_time: new Date()
};
await ctx.model.Log.create(logEntry);
ctx.body = { code: 0 };
}
```
3. **MySQL 表结构**
```sql
CREATE TABLE logs (
id INT AUTO_INCREMENT PRIMARY KEY,
content TEXT,
path VARCHAR(255),
upload_time DATETIME
);
```
#### 四、增强功能实现
1. **日志文件轮转**
在Electron中增加日志清理逻辑:
```javascript
const MAX_LOG_DAYS = 7;
setInterval(() => {
const logDir = path.dirname(log.transports.file.getFile().path);
fs.readdir(logDir, (err, files) => {
files.forEach(file => {
const ctime = fs.statSync(path.join(logDir, file)).ctime;
if (Date.now() - ctime > MAX_LOG_DAYS*86400000) {
fs.unlinkSync(path.join(logDir, file));
}
});
});
}, 86400000); // 每天执行
```
2. **断点续传机制**
在Vue组件中增加上传状态管理:
```javascript
const uploadChunk = async (file, chunkSize = 1024*1024) => {
const totalChunks = Math.ceil(file.size / chunkSize);
for (let i = 0; i < totalChunks; i++) {
const chunk = file.slice(i*chunkSize, (i+1)*chunkSize);
await axios.post('/api/logs/chunk', { chunk, index: i });
}
};
```
### 注意事项
1. **安全加固**
- 服务端校验文件MD5哈希值
- 限制单个IP上传频率
- 使用HTTPS传输
2. **性能优化**
```javascript
// Egg.js中使用管道加速文件保存
const pipeline = util.promisify(stream.pipeline);
await pipeline(stream, writer);
```
3. **错误追踪**
在Electron主进程增加未捕获异常处理:
```javascript
process.on('uncaughtException', (err) => {
log.error('主进程崩溃:', err);
dialog.showErrorBox('应用异常', err.toString());
});
```
阅读全文
相关推荐


















