mirror of
https://gitcode.com/JianFeeeee/webui4frpc.git
synced 2026-09-21 09:27:57 +00:00
webui4frpc: 独立可用的可视化 frpc 控制器 (M0)
- 零 frp 源码依赖,单二进制 (Go + Vue3 + VueFlow + Element Plus) - 画布多对多连线,渲染 tcp/udp/http/https frpc 配置 - worker 进程管理:自愈、日志轮转、崩溃退避重启 - frpc 一键安装 (GitHub Releases) + 手动指定路径 - 三页 UI:状态(默认)/连接配置/设置 - 状态页实时节点/转发状态,节点可增删改启停 - 画布冲突检查:端口/域名冲突标红 + 弹窗拦截保存 - backend 单测覆盖 store/render/process/httpapi/install - plan.md + FRPC_FEATURES_AUDIT.md 文档
This commit is contained in:
73
internal/process/rotating.go
Normal file
73
internal/process/rotating.go
Normal file
@ -0,0 +1,73 @@
|
||||
package process
|
||||
|
||||
import (
|
||||
"os"
|
||||
"path/filepath"
|
||||
"sync"
|
||||
)
|
||||
|
||||
// rotatingFile appends to a log file and rotates it once it exceeds maxSize.
|
||||
type rotatingFile struct {
|
||||
mu sync.Mutex
|
||||
path string
|
||||
maxSize int64
|
||||
f *os.File
|
||||
size int64
|
||||
}
|
||||
|
||||
func newRotatingFile(path string, maxSize int64) (*rotatingFile, error) {
|
||||
if maxSize <= 0 {
|
||||
maxSize = 10 * 1024 * 1024
|
||||
}
|
||||
if err := os.MkdirAll(filepath.Dir(path), 0o755); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
f, err := os.OpenFile(path, os.O_WRONLY|os.O_CREATE|os.O_APPEND, 0o644)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
info, err := f.Stat()
|
||||
if err != nil {
|
||||
_ = f.Close()
|
||||
return nil, err
|
||||
}
|
||||
return &rotatingFile{path: path, maxSize: maxSize, f: f, size: info.Size()}, nil
|
||||
}
|
||||
|
||||
func (r *rotatingFile) Write(p []byte) (int, error) {
|
||||
r.mu.Lock()
|
||||
defer r.mu.Unlock()
|
||||
|
||||
if r.f == nil {
|
||||
f, err := os.OpenFile(r.path, os.O_WRONLY|os.O_CREATE|os.O_APPEND, 0o644)
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
r.f = f
|
||||
}
|
||||
if r.size > 0 && r.size+int64(len(p)) > r.maxSize {
|
||||
_ = r.f.Close()
|
||||
_ = os.Rename(r.path, r.path+".1")
|
||||
f, err := os.OpenFile(r.path, os.O_WRONLY|os.O_CREATE|os.O_TRUNC, 0o644)
|
||||
if err != nil {
|
||||
r.f = nil
|
||||
return 0, err
|
||||
}
|
||||
r.f = f
|
||||
r.size = 0
|
||||
}
|
||||
n, err := r.f.Write(p)
|
||||
r.size += int64(n)
|
||||
return n, err
|
||||
}
|
||||
|
||||
func (r *rotatingFile) Close() error {
|
||||
r.mu.Lock()
|
||||
defer r.mu.Unlock()
|
||||
if r.f != nil {
|
||||
err := r.f.Close()
|
||||
r.f = nil
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
||||
Reference in New Issue
Block a user