go-proxy/log/access.go
Virgil 0ab02e9e4b docs(ax): clarify public api examples
Co-Authored-By: Virgil <virgil@lethean.io>
2026-04-04 13:07:29 +00:00

112 lines
2.2 KiB
Go

// Package log implements append-only access and share logging for the proxy.
//
// al, result := log.NewAccessLog("/var/log/proxy-access.log")
// bus.Subscribe(proxy.EventLogin, al.OnLogin)
// bus.Subscribe(proxy.EventClose, al.OnClose)
package log
import (
"fmt"
"os"
"sync"
"dappco.re/go/core/proxy"
)
// AccessLog writes one CONNECT line on login and one CLOSE line on disconnect.
//
// al := log.NewAccessLog("/var/log/proxy-access.log")
// bus.Subscribe(proxy.EventLogin, al.OnLogin)
// bus.Subscribe(proxy.EventClose, al.OnClose)
type AccessLog struct {
path string
mu sync.Mutex
f *os.File
closed bool
}
// NewAccessLog returns a lazy append-only logger for a single path.
//
// al := log.NewAccessLog("/var/log/proxy-access.log")
func NewAccessLog(path string) *AccessLog {
return &AccessLog{path: path}
}
// OnLogin writes `2026-04-04T12:00:00Z CONNECT 10.0.0.1 WALLET XMRig/6.21.0`.
//
// al.OnLogin(proxy.Event{Miner: miner})
func (l *AccessLog) OnLogin(event proxy.Event) {
if event.Miner == nil {
return
}
line := fmt.Sprintf("%s CONNECT %s %s %s\n",
timestamp(),
event.Miner.IP(),
event.Miner.User(),
event.Miner.Agent(),
)
l.writeLine(line)
}
// OnClose writes `2026-04-04T12:00:00Z CLOSE 10.0.0.1 WALLET rx=512 tx=4096`.
//
// al.OnClose(proxy.Event{Miner: miner})
func (l *AccessLog) OnClose(event proxy.Event) {
if event.Miner == nil {
return
}
line := fmt.Sprintf("%s CLOSE %s %s rx=%d tx=%d\n",
timestamp(),
event.Miner.IP(),
event.Miner.User(),
event.Miner.RX(),
event.Miner.TX(),
)
l.writeLine(line)
}
// Close releases the append-only file handle if it has been opened.
//
// al.Close()
func (l *AccessLog) Close() {
if l == nil {
return
}
l.mu.Lock()
defer l.mu.Unlock()
if l.closed {
return
}
l.closed = true
if l.f != nil {
_ = l.f.Close()
l.f = nil
}
}
func (l *AccessLog) writeLine(line string) {
if l == nil || l.path == "" {
return
}
l.mu.Lock()
defer l.mu.Unlock()
if l.closed {
return
}
if l.f == nil {
file, errorValue := os.OpenFile(l.path, os.O_APPEND|os.O_CREATE|os.O_WRONLY, 0o644)
if errorValue != nil {
return
}
l.f = file
}
_, _ = l.f.WriteString(line)
}