summaryrefslogtreecommitdiff
path: root/internal/engine/logger.go
diff options
context:
space:
mode:
authorsergei <sergei@em-sysadmin.xyz>2026-04-14 06:23:55 +0400
committersergei <sergei@em-sysadmin.xyz>2026-04-14 06:23:55 +0400
commit3d51aa455006903345f554a2dd90034993796114 (patch)
tree62a7be2faf047f5eb7886feebc3b815556f03d7f /internal/engine/logger.go
downloadvpnem-3d51aa455006903345f554a2dd90034993796114.tar.gz
vpnem-3d51aa455006903345f554a2dd90034993796114.tar.bz2
vpnem-3d51aa455006903345f554a2dd90034993796114.zip
vpnem: VPN infrastructure with load-balanced multi-protocol nodesHEADmain
- Multi-protocol VPS nodes (VLESS-REALITY + Hysteria2 + SOCKS5) - Smart load balancing via recommendation API - Windows/Linux client (Go + Wails + sing-box) - Server API with RealIP detection and connection tracking - Auto-deployment via vpnui control plane - Silent Windows installer with UAC elevation - Load-based server recommendation (no sticky sessions) - Best Server one-click connection workflow
Diffstat (limited to 'internal/engine/logger.go')
-rw-r--r--internal/engine/logger.go62
1 files changed, 62 insertions, 0 deletions
diff --git a/internal/engine/logger.go b/internal/engine/logger.go
new file mode 100644
index 0000000..c448a56
--- /dev/null
+++ b/internal/engine/logger.go
@@ -0,0 +1,62 @@
+package engine
+
+import (
+ "os"
+ "path/filepath"
+ "sync"
+)
+
+// RingLog keeps last N log lines in memory and optionally writes to file.
+type RingLog struct {
+ mu sync.Mutex
+ lines []string
+ max int
+ file *os.File
+}
+
+// NewRingLog creates a ring buffer logger.
+func NewRingLog(maxLines int, dataDir string) *RingLog {
+ rl := &RingLog{
+ lines: make([]string, 0, maxLines),
+ max: maxLines,
+ }
+ if dataDir != "" {
+ f, err := os.OpenFile(filepath.Join(dataDir, "vpnem.log"),
+ os.O_CREATE|os.O_WRONLY|os.O_APPEND, 0o644)
+ if err == nil {
+ rl.file = f
+ }
+ }
+ return rl
+}
+
+// Add appends a line.
+func (rl *RingLog) Add(line string) {
+ rl.mu.Lock()
+ defer rl.mu.Unlock()
+
+ if len(rl.lines) >= rl.max {
+ rl.lines = rl.lines[1:]
+ }
+ rl.lines = append(rl.lines, line)
+
+ if rl.file != nil {
+ rl.file.WriteString(line + "\n")
+ }
+}
+
+// Lines returns all current lines.
+func (rl *RingLog) Lines() []string {
+ rl.mu.Lock()
+ defer rl.mu.Unlock()
+ cp := make([]string, len(rl.lines))
+ copy(cp, rl.lines)
+ return cp
+}
+
+// Close closes the log file.
+func (rl *RingLog) Close() {
+ if rl.file != nil {
+ rl.file.Close()
+ }
+}