fix(log): align access log formats with RFC

Co-Authored-By: Virgil <virgil@lethean.io>
This commit is contained in:
Virgil 2026-04-04 22:29:00 +00:00
parent 0c746e4ea7
commit 9b6a251145
3 changed files with 57 additions and 14 deletions

View file

@ -50,17 +50,17 @@ func (l *accessLogSink) OnLogin(e Event) {
if l == nil || e.Miner == nil {
return
}
l.writeLine("CONNECT", e.Miner.IP(), e.Miner.User(), e.Miner.Agent(), 0, 0)
l.writeConnectLine(e.Miner.IP(), e.Miner.User(), e.Miner.Agent())
}
func (l *accessLogSink) OnClose(e Event) {
if l == nil || e.Miner == nil {
return
}
l.writeLine("CLOSE", e.Miner.IP(), e.Miner.User(), "", e.Miner.RX(), e.Miner.TX())
l.writeCloseLine(e.Miner.IP(), e.Miner.User(), e.Miner.RX(), e.Miner.TX())
}
func (l *accessLogSink) writeLine(kind, ip, user, agent string, rx, tx uint64) {
func (l *accessLogSink) writeConnectLine(ip, user, agent string) {
l.mu.Lock()
defer l.mu.Unlock()
if strings.TrimSpace(l.path) == "" {
@ -76,13 +76,38 @@ func (l *accessLogSink) writeLine(kind, ip, user, agent string, rx, tx uint64) {
var builder strings.Builder
builder.WriteString(time.Now().UTC().Format(time.RFC3339))
builder.WriteByte(' ')
builder.WriteString(kind)
builder.WriteString("CONNECT")
builder.WriteString(" ")
builder.WriteString(ip)
builder.WriteString(" ")
builder.WriteString(user)
builder.WriteString(" ")
builder.WriteString(agent)
builder.WriteByte('\n')
_, _ = l.file.WriteString(builder.String())
}
func (l *accessLogSink) writeCloseLine(ip, user string, rx, tx uint64) {
l.mu.Lock()
defer l.mu.Unlock()
if strings.TrimSpace(l.path) == "" {
return
}
if l.file == nil {
file, err := os.OpenFile(l.path, os.O_CREATE|os.O_WRONLY|os.O_APPEND, 0o644)
if err != nil {
return
}
l.file = file
}
var builder strings.Builder
builder.WriteString(time.Now().UTC().Format(time.RFC3339))
builder.WriteByte(' ')
builder.WriteString("CLOSE")
builder.WriteString(" ")
builder.WriteString(ip)
builder.WriteString(" ")
builder.WriteString(user)
builder.WriteString(" rx=")
builder.WriteString(formatUint(rx))
builder.WriteString(" tx=")

View file

@ -44,7 +44,7 @@ func TestProxy_AccessLog_WritesLifecycleLines(t *testing.T) {
t.Fatalf("read access log: %v", err)
}
text := string(data)
if !strings.Contains(text, "CONNECT 10.0.0.1 WALLET XMRig/6.21.0 rx=0 tx=0") {
if !strings.Contains(text, "CONNECT 10.0.0.1 WALLET XMRig/6.21.0") {
t.Fatalf("expected CONNECT line, got %q", text)
}
if !strings.Contains(text, "CLOSE 10.0.0.1 WALLET rx=512 tx=4096") {
@ -82,11 +82,11 @@ func TestProxy_AccessLog_WritesFixedColumns(t *testing.T) {
t.Fatalf("read access log: %v", err)
}
text := string(data)
if !strings.Contains(text, "CONNECT 10.0.0.1 WALLET rx=0 tx=0") {
t.Fatalf("expected CONNECT line with zero counters, got %q", text)
if !strings.Contains(text, "CONNECT 10.0.0.1 WALLET") {
t.Fatalf("expected CONNECT line without counters, got %q", text)
}
if !strings.Contains(text, "CLOSE 10.0.0.1 WALLET rx=0 tx=0") {
t.Fatalf("expected CLOSE line with zero counters, got %q", text)
t.Fatalf("expected CLOSE line with counters only, got %q", text)
}
}

View file

@ -19,7 +19,7 @@ func (l *AccessLog) OnLogin(e proxy.Event) {
if l == nil || e.Miner == nil {
return
}
l.writeLine("CONNECT", e.Miner.IP(), e.Miner.User(), e.Miner.Agent(), 0, 0)
l.writeConnectLine(e.Miner.IP(), e.Miner.User(), e.Miner.Agent())
}
// OnClose writes a CLOSE line with byte counts.
@ -27,7 +27,7 @@ func (l *AccessLog) OnClose(e proxy.Event) {
if l == nil || e.Miner == nil {
return
}
l.writeLine("CLOSE", e.Miner.IP(), e.Miner.User(), "", e.Miner.RX(), e.Miner.TX())
l.writeCloseLine(e.Miner.IP(), e.Miner.User(), e.Miner.RX(), e.Miner.TX())
}
// NewShareLog creates an append-only share log.
@ -51,7 +51,7 @@ func (l *ShareLog) OnReject(e proxy.Event) {
l.writeRejectLine(e.Miner.User(), e.Error)
}
func (accessLog *AccessLog) writeLine(kind, ip, user, agent string, rx, tx uint64) {
func (accessLog *AccessLog) writeConnectLine(ip, user, agent string) {
accessLog.mu.Lock()
defer accessLog.mu.Unlock()
if err := accessLog.ensureFile(); err != nil {
@ -60,13 +60,31 @@ func (accessLog *AccessLog) writeLine(kind, ip, user, agent string, rx, tx uint6
var builder strings.Builder
builder.WriteString(time.Now().UTC().Format(time.RFC3339))
builder.WriteByte(' ')
builder.WriteString(kind)
builder.WriteString("CONNECT")
builder.WriteString(" ")
builder.WriteString(ip)
builder.WriteString(" ")
builder.WriteString(user)
builder.WriteString(" ")
builder.WriteString(agent)
builder.WriteByte('\n')
_, _ = accessLog.f.WriteString(builder.String())
}
func (accessLog *AccessLog) writeCloseLine(ip, user string, rx, tx uint64) {
accessLog.mu.Lock()
defer accessLog.mu.Unlock()
if err := accessLog.ensureFile(); err != nil {
return
}
var builder strings.Builder
builder.WriteString(time.Now().UTC().Format(time.RFC3339))
builder.WriteByte(' ')
builder.WriteString("CLOSE")
builder.WriteString(" ")
builder.WriteString(ip)
builder.WriteString(" ")
builder.WriteString(user)
builder.WriteString(" rx=")
builder.WriteString(strconv.FormatUint(rx, 10))
builder.WriteString(" tx=")