feat(app): 添加自动启动和日志滚动功能并优化上传逻辑
- 增加了运行时自动启动上传配置选项 - 实现了日志输出的滚动控制功能 - 优化了上传进度显示和状态同步机制 - 提升了HTTP客户端连接池配置至500 - 改进了文件上传完成后的清理逻辑 - 添加了上下文取消检查避免资源泄露 - 完善了上传开始时的日志信息输出
This commit is contained in:
@@ -35,6 +35,14 @@ func (a *App) startup(ctx context.Context) {
|
|||||||
}
|
}
|
||||||
}()
|
}()
|
||||||
|
|
||||||
|
// 后台 goroutine 持续推送运行状态
|
||||||
|
go func() {
|
||||||
|
for {
|
||||||
|
time.Sleep(500 * time.Millisecond)
|
||||||
|
runtime.EventsEmit(a.ctx, "is-run", a.isRun)
|
||||||
|
}
|
||||||
|
}()
|
||||||
|
|
||||||
//在程序启动时运行上传程序
|
//在程序启动时运行上传程序
|
||||||
a.uploaderCTX, a.uploaderCancel = context.WithCancel(a.ctx)
|
a.uploaderCTX, a.uploaderCancel = context.WithCancel(a.ctx)
|
||||||
if config.APPConfig.IsRunOnStart {
|
if config.APPConfig.IsRunOnStart {
|
||||||
|
|||||||
+21
-9
@@ -12,11 +12,13 @@ const token = ref('')
|
|||||||
const checkDir = ref('')
|
const checkDir = ref('')
|
||||||
const concurrentFiles = ref(1)
|
const concurrentFiles = ref(1)
|
||||||
const uploadThreads = ref(1)
|
const uploadThreads = ref(1)
|
||||||
|
const autoStart = ref(false)
|
||||||
|
|
||||||
const progress = ref(0)
|
const progress = ref(0)
|
||||||
const isRunning = ref(false)
|
const isRunning = ref(false)
|
||||||
const logOutput = ref<string[]>([])
|
const logOutput = ref<string[]>([])
|
||||||
const logContentRef = ref<HTMLElement>()
|
const logContentRef = ref<HTMLElement>()
|
||||||
|
const logRoll = ref(true)
|
||||||
|
|
||||||
interface FileProgress {
|
interface FileProgress {
|
||||||
name: string
|
name: string
|
||||||
@@ -32,7 +34,7 @@ const progressList = ref<FileProgress[]>([
|
|||||||
const addLog = (msg: string) => {
|
const addLog = (msg: string) => {
|
||||||
logOutput.value.push(`[${new Date().toLocaleString()}]` + msg)
|
logOutput.value.push(`[${new Date().toLocaleString()}]` + msg)
|
||||||
nextTick(() => {
|
nextTick(() => {
|
||||||
if (logContentRef.value) {
|
if (logContentRef.value && logRoll.value){
|
||||||
logContentRef.value.scrollTop = logContentRef.value.scrollHeight
|
logContentRef.value.scrollTop = logContentRef.value.scrollHeight
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
@@ -60,13 +62,6 @@ const startRun = () => {
|
|||||||
}
|
}
|
||||||
isRunning.value = true
|
isRunning.value = true
|
||||||
progress.value = 0
|
progress.value = 0
|
||||||
addLog("===============================================")
|
|
||||||
// addLog(`开始运行...`)
|
|
||||||
addLog(`服务器: ${serverUrl.value}`)
|
|
||||||
addLog(`检测目录: ${checkDir.value}`)
|
|
||||||
addLog(`同时处理文件数: ${concurrentFiles.value}`)
|
|
||||||
addLog(`单文件上传线程: ${uploadThreads.value}`)
|
|
||||||
addLog("===============================================")
|
|
||||||
StartUpload()
|
StartUpload()
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -100,6 +95,7 @@ try {
|
|||||||
checkDir.value = config.check_dir
|
checkDir.value = config.check_dir
|
||||||
concurrentFiles.value = config.handle_file_count
|
concurrentFiles.value = config.handle_file_count
|
||||||
uploadThreads.value = config.thread_count
|
uploadThreads.value = config.thread_count
|
||||||
|
autoStart.value = config.is_run_on_start
|
||||||
|
|
||||||
LogPrint(`[${new Date().toLocaleString()}] 配置已加载`)
|
LogPrint(`[${new Date().toLocaleString()}] 配置已加载`)
|
||||||
})
|
})
|
||||||
@@ -122,6 +118,9 @@ watch(concurrentFiles, () => {
|
|||||||
watch(uploadThreads, () => {
|
watch(uploadThreads, () => {
|
||||||
WriteConfig("thread-count", uploadThreads.value)
|
WriteConfig("thread-count", uploadThreads.value)
|
||||||
})
|
})
|
||||||
|
watch(autoStart, () => {
|
||||||
|
WriteConfig("is-run-on-start", autoStart.value)
|
||||||
|
})
|
||||||
|
|
||||||
EventsOn("log", (msg) => {
|
EventsOn("log", (msg) => {
|
||||||
addLog(msg)
|
addLog(msg)
|
||||||
@@ -129,6 +128,9 @@ EventsOn("log", (msg) => {
|
|||||||
EventsOn("progress", (progress) => {
|
EventsOn("progress", (progress) => {
|
||||||
progressList.value = progress
|
progressList.value = progress
|
||||||
})
|
})
|
||||||
|
EventsOn("is-run", (run) => {
|
||||||
|
isRunning.value = run
|
||||||
|
})
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
@@ -162,6 +164,10 @@ EventsOn("progress", (progress) => {
|
|||||||
<el-input-number v-model="uploadThreads" :min="1" :max="100" :disabled="isRunning"/>
|
<el-input-number v-model="uploadThreads" :min="1" :max="100" :disabled="isRunning"/>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<div class="form-item">
|
||||||
|
<el-checkbox v-model="autoStart" label="运行时自动启动上传" size="large" :disabled="isRunning"/>
|
||||||
|
</div>
|
||||||
|
|
||||||
<div class="form-item">
|
<div class="form-item">
|
||||||
<label>上传进度</label>
|
<label>上传进度</label>
|
||||||
<div class="progress-list">
|
<div class="progress-list">
|
||||||
@@ -181,7 +187,10 @@ EventsOn("progress", (progress) => {
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="right-panel">
|
<div class="right-panel">
|
||||||
<div class="log-header">日志输出</div>
|
<div class="log-header">
|
||||||
|
日志输出
|
||||||
|
<el-checkbox v-model="logRoll" label="开启日志滚动"/>
|
||||||
|
</div>
|
||||||
<div class="log-content" ref="logContentRef">
|
<div class="log-content" ref="logContentRef">
|
||||||
<div v-for="(log, index) in logOutput" :key="index" class="log-line">{{ log }}</div>
|
<div v-for="(log, index) in logOutput" :key="index" class="log-line">{{ log }}</div>
|
||||||
</div>
|
</div>
|
||||||
@@ -286,6 +295,9 @@ EventsOn("progress", (progress) => {
|
|||||||
font-size: 14px;
|
font-size: 14px;
|
||||||
font-weight: 500;
|
font-weight: 500;
|
||||||
color: #303133;
|
color: #303133;
|
||||||
|
display: flex;
|
||||||
|
justify-content: space-between;
|
||||||
|
align-items: center;
|
||||||
}
|
}
|
||||||
|
|
||||||
.log-content {
|
.log-content {
|
||||||
|
|||||||
+2
-2
@@ -11,8 +11,8 @@ import (
|
|||||||
|
|
||||||
var httpClient = &http.Client{
|
var httpClient = &http.Client{
|
||||||
Transport: &http.Transport{
|
Transport: &http.Transport{
|
||||||
MaxIdleConns: 200,
|
MaxIdleConns: 500,
|
||||||
MaxIdleConnsPerHost: 200,
|
MaxIdleConnsPerHost: 500,
|
||||||
IdleConnTimeout: 30 * time.Second,
|
IdleConnTimeout: 30 * time.Second,
|
||||||
},
|
},
|
||||||
Timeout: 30 * time.Second,
|
Timeout: 30 * time.Second,
|
||||||
|
|||||||
@@ -9,6 +9,7 @@ import (
|
|||||||
"fmt"
|
"fmt"
|
||||||
"os"
|
"os"
|
||||||
"path/filepath"
|
"path/filepath"
|
||||||
|
"strconv"
|
||||||
"strings"
|
"strings"
|
||||||
"sync"
|
"sync"
|
||||||
"sync/atomic"
|
"sync/atomic"
|
||||||
@@ -33,6 +34,13 @@ type Progress struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func StartLooking(ctx context.Context, logChan *chan string, lookingPath string) {
|
func StartLooking(ctx context.Context, logChan *chan string, lookingPath string) {
|
||||||
|
AddLog(logChan, "===============================================")
|
||||||
|
AddLog(logChan, `服务器: `+config.APPConfig.Url)
|
||||||
|
AddLog(logChan, `Token: `+config.APPConfig.Token)
|
||||||
|
AddLog(logChan, `检测目录: `+config.APPConfig.CheckDir)
|
||||||
|
AddLog(logChan, `同时处理文件数: `+strconv.Itoa(config.APPConfig.HandleFileCount))
|
||||||
|
AddLog(logChan, `单文件上传线程: `+strconv.Itoa(config.APPConfig.ThreadCount))
|
||||||
|
AddLog(logChan, "===============================================")
|
||||||
//推送上传进度
|
//推送上传进度
|
||||||
go func() {
|
go func() {
|
||||||
for {
|
for {
|
||||||
@@ -108,6 +116,7 @@ func uploadData(ctx context.Context, logChan *chan string, lookingPath string) {
|
|||||||
fileLines[filepath.Base(filePath)] = lineCount
|
fileLines[filepath.Base(filePath)] = lineCount
|
||||||
isAllEmpty = false
|
isAllEmpty = false
|
||||||
AddLog(logChan, fmt.Sprintf("%s 文件行数:%v", filepath.Base(filePath), lineCount))
|
AddLog(logChan, fmt.Sprintf("%s 文件行数:%v", filepath.Base(filePath), lineCount))
|
||||||
|
progress.Store(filepath.Base(filePath), Progress{FileName: filepath.Base(filePath), Total: lineCount, Uploaded: 0, Percentage: 0})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if isAllEmpty {
|
if isAllEmpty {
|
||||||
@@ -135,6 +144,10 @@ func uploadData(ctx context.Context, logChan *chan string, lookingPath string) {
|
|||||||
|
|
||||||
processFile(egctx, logChan, task.FilePath, task.FileLines)
|
processFile(egctx, logChan, task.FilePath, task.FileLines)
|
||||||
|
|
||||||
|
select {
|
||||||
|
case <-egctx.Done():
|
||||||
|
return egctx.Err()
|
||||||
|
default:
|
||||||
//上传完成,清空文件
|
//上传完成,清空文件
|
||||||
err := os.Truncate(task.FilePath, 0)
|
err := os.Truncate(task.FilePath, 0)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@@ -142,9 +155,14 @@ func uploadData(ctx context.Context, logChan *chan string, lookingPath string) {
|
|||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
select {
|
||||||
|
case <-ctx.Done():
|
||||||
|
return
|
||||||
|
default:
|
||||||
// 等待所有任务完成
|
// 等待所有任务完成
|
||||||
if err := g.Wait(); err != nil {
|
if err := g.Wait(); err != nil {
|
||||||
AddLog(logChan, fmt.Sprintf("任务执行出错: %v", err))
|
AddLog(logChan, fmt.Sprintf("任务执行出错: %v", err))
|
||||||
@@ -154,6 +172,7 @@ func uploadData(ctx context.Context, logChan *chan string, lookingPath string) {
|
|||||||
|
|
||||||
AddLog(logChan, fmt.Sprintf("上传完成,耗时:%s", time.Since(start).String()))
|
AddLog(logChan, fmt.Sprintf("上传完成,耗时:%s", time.Since(start).String()))
|
||||||
progress.Clear()
|
progress.Clear()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// 获取目录中的所有txt文件
|
// 获取目录中的所有txt文件
|
||||||
@@ -194,10 +213,15 @@ func processFile(ctx context.Context, logChan *chan string, filePath string, fil
|
|||||||
var countLine int32 = 0
|
var countLine int32 = 0
|
||||||
// 创建指定个worker同时处理文件上传
|
// 创建指定个worker同时处理文件上传
|
||||||
for i := 0; i < config.APPConfig.ThreadCount; i++ {
|
for i := 0; i < config.APPConfig.ThreadCount; i++ {
|
||||||
|
select {
|
||||||
|
case <-ctx.Done():
|
||||||
|
return
|
||||||
|
default:
|
||||||
wg.Go(func() {
|
wg.Go(func() {
|
||||||
processLines(ctx, logChan, &lines, i, filePath, &countLine)
|
processLines(ctx, logChan, &lines, i, filePath, &countLine)
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// 读取文件并发送到通道
|
// 读取文件并发送到通道
|
||||||
scanner := bufio.NewScanner(file)
|
scanner := bufio.NewScanner(file)
|
||||||
@@ -257,6 +281,7 @@ func processLines(ctx context.Context, logChan *chan string, lines *chan string,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// AddLog 添加日志
|
||||||
func AddLog(logChan *chan string, message string) {
|
func AddLog(logChan *chan string, message string) {
|
||||||
*logChan <- message
|
*logChan <- message
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user