diff --git a/agent/jboard-agent/Makefile b/agent/jboard-agent/Makefile index 7aae31f..4f53ed2 100644 --- a/agent/jboard-agent/Makefile +++ b/agent/jboard-agent/Makefile @@ -1,5 +1,5 @@ BINARY := jboard-agent -VERSION := 3.0.1 +VERSION := 3.0.2 LDFLAGS := -s -w .PHONY: build build-linux clean diff --git a/agent/jboard-agent/cmd/agent/main.go b/agent/jboard-agent/cmd/agent/main.go index 403664f..4448933 100644 --- a/agent/jboard-agent/cmd/agent/main.go +++ b/agent/jboard-agent/cmd/agent/main.go @@ -12,7 +12,7 @@ import ( "github.com/jboard/jboard-agent/internal/probe" ) -const version = "3.0.1" +const version = "3.0.2" func main() { debug.SetGCPercent(50) diff --git a/agent/jboard-agent/internal/probe/xraylog.go b/agent/jboard-agent/internal/probe/xraylog.go index 0a84a3b..24052a0 100644 --- a/agent/jboard-agent/internal/probe/xraylog.go +++ b/agent/jboard-agent/internal/probe/xraylog.go @@ -20,7 +20,7 @@ import ( const maxXrayReadBytes int64 = 2 * 1024 * 1024 const maxXrayEventsPerPush = 300 -var xrayAccessLinePattern = regexp.MustCompile(`^(\d{4}/\d{2}/\d{2} \d{2}:\d{2}:\d{2})\s+(\S+)\s+(accepted|rejected)\s+(?:(tcp|udp):)?(\S+)\s+\[([^\]]+)\](?:.*?\bemail:\s*([^\s]+))?`) +var xrayAccessLinePattern = regexp.MustCompile(`^(\d{4}/\d{2}/\d{2} \d{2}:\d{2}:\d{2}(?:\.\d+)?)\s+(?:from\s+)?(\S+)\s+(accepted|rejected)\s+(?:(tcp|udp):)?(\S+)\s+\[([^\]]+)\](?:.*?\bemail:\s*([^\s]+))?`) type xrayLogState struct { Path string `json:"path"` diff --git a/agent/jboard-agent/internal/probe/xraylog_test.go b/agent/jboard-agent/internal/probe/xraylog_test.go index f851757..37b7579 100644 --- a/agent/jboard-agent/internal/probe/xraylog_test.go +++ b/agent/jboard-agent/internal/probe/xraylog_test.go @@ -44,6 +44,37 @@ func TestParseXrayAccessLineWithIPv6Source(t *testing.T) { } } +func TestParseXrayAccessLineWithFromAndFractionalTimestamp(t *testing.T) { + line := "2026/04/29 09:20:06.006542 from tcp:220.240.111.193:59433 accepted udp:71.18.167.208:443 [inbound-17583 >> direct] email: user@test.com-cmojtnp3" + got, ok := parseXrayAccessLine(line) + if !ok { + t.Fatal("parseXrayAccessLine() failed") + } + if got.SourceIP != "220.240.111.193" { + t.Fatalf("SourceIP = %q", got.SourceIP) + } + if got.ClientEmail != "user@test.com-cmojtnp3" { + t.Fatalf("ClientEmail = %q", got.ClientEmail) + } + if got.InboundTag != "inbound-17583" { + t.Fatalf("InboundTag = %q", got.InboundTag) + } + if got.Network != "udp" || got.TargetHost != "71.18.167.208" || got.TargetPort != 443 { + t.Fatalf("target = %s %s:%d", got.Network, got.TargetHost, got.TargetPort) + } +} + +func TestParseXrayAccessLineWithFromPlainSource(t *testing.T) { + line := "2026/04/29 09:20:05.982584 from 220.240.111.193:59425 accepted tcp:webcast3-core-c-lf.amemv.com:443 [inbound-17583 >> direct] email: user@test.com-cmojtnp3" + got, ok := parseXrayAccessLine(line) + if !ok { + t.Fatal("parseXrayAccessLine() failed") + } + if got.SourceIP != "220.240.111.193" || got.Network != "tcp" || got.TargetHost != "webcast3-core-c-lf.amemv.com" { + t.Fatalf("parsed = %+v", got) + } +} + func TestAggregateXrayAccessLines(t *testing.T) { lines := []string{ "2026/04/29 10:11:12 203.0.113.9:51820 accepted tcp:example.com:443 [proxy] email: user@example.com-cabc1234",