From 69467914fc057b29595b2dc262fa6ce203f400f0 Mon Sep 17 00:00:00 2001 From: ryan Date: Sun, 12 Jul 2026 19:02:52 +0800 Subject: [PATCH] =?UTF-8?q?fix(server):=20=E4=BF=AE=E5=A4=8D=20Agent=20?= =?UTF-8?q?=E4=B8=8A=E6=8A=A5=E8=AE=BF=E9=97=AE=E6=97=A5=E5=BF=97=E7=9A=84?= =?UTF-8?q?=20`bytes=5Fsent`=20=E5=9C=A8=20Server=20=E5=85=A5=E5=BA=93?= =?UTF-8?q?=E9=93=BE=E8=B7=AF=E4=B8=A2=E5=A4=B1=EF=BC=8C=E5=AF=BC=E8=87=B4?= =?UTF-8?q?=20Zone=20=E6=A6=82=E8=A7=88=E2=80=9C=E5=B7=B2=E6=8F=90?= =?UTF-8?q?=E4=BE=9B=E7=9A=84=E6=95=B0=E6=8D=AE=E6=80=BB=E8=AE=A1=E2=80=9D?= =?UTF-8?q?=E9=95=BF=E6=9C=9F=E4=B8=BA=200=20=E7=9A=84=E9=97=AE=E9=A2=98?= =?UTF-8?q?=E3=80=82?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- docs/changelog/index.md | 1 + .../apps/openflare/agent/observability.go | 15 +++++---- .../openflare/agent/observability_test.go | 33 +++++++++++++++++++ .../analytics/node_access_log_test.go | 5 ++- .../analytics/node_access_log_writer.go | 3 +- 5 files changed, 48 insertions(+), 9 deletions(-) create mode 100644 internal/apps/openflare/agent/observability_test.go diff --git a/docs/changelog/index.md b/docs/changelog/index.md index 5aadaa8c..81127050 100644 --- a/docs/changelog/index.md +++ b/docs/changelog/index.md @@ -41,6 +41,7 @@ sidebar: false ### 修复 +- 修复 Agent 上报访问日志的 `bytes_sent` 在 Server 入库链路丢失,导致 Zone 概览“已提供的数据总计”长期为 0 的问题。 - 修复嵌入式静态前端访问 `/websites/:zoneId` 时回退到首页 HTML,导致 Zone 详情页显示总览并触发 React hydration error 的问题。 - Docker ClickHouse 性能配置改为单文件挂载,避免覆盖镜像内置的 Docker 网络监听配置,导致宿主机无法通过 8123/9000 访问服务。 diff --git a/internal/apps/openflare/agent/observability.go b/internal/apps/openflare/agent/observability.go index 8d7a81d9..0edfa849 100644 --- a/internal/apps/openflare/agent/observability.go +++ b/internal/apps/openflare/agent/observability.go @@ -19,13 +19,13 @@ import ( ) const ( - healthEventStatusActive = "active" - healthEventStatusResolved = "resolved" - healthSeverityInfo = "info" - healthSeverityWarning = "warning" - healthSeverityCritical = "critical" - accessLogPathMaxLength = 100 - healthEventMessageMaxLength = 4096 + healthEventStatusActive = "active" + healthEventStatusResolved = "resolved" + healthSeverityInfo = "info" + healthSeverityWarning = "warning" + healthSeverityCritical = "critical" + accessLogPathMaxLength = 100 + healthEventMessageMaxLength = 4096 ) // PersistHeartbeatObservability stores profile, snapshots, traffic, access logs, and health events. @@ -221,6 +221,7 @@ func buildNodeAccessLogRecords(nodeID string, direct []NodeAccessLog, buffered [ Host: strings.TrimSpace(item.Host), Path: truncateForDatabase(strings.TrimSpace(item.Path), accessLogPathMaxLength), StatusCode: item.StatusCode, + BytesSent: item.BytesSent, } if resolver != nil { record.Region = resolver.Resolve(record.RemoteAddr) diff --git a/internal/apps/openflare/agent/observability_test.go b/internal/apps/openflare/agent/observability_test.go new file mode 100644 index 00000000..7151ffb3 --- /dev/null +++ b/internal/apps/openflare/agent/observability_test.go @@ -0,0 +1,33 @@ +// Copyright 2026 Arctel.net +// SPDX-License-Identifier: Apache-2.0 + +package agent + +import ( + "testing" + "time" +) + +func TestBuildNodeAccessLogRecordsPreservesBytesSent(t *testing.T) { + reportedAt := time.Date(2026, 7, 12, 10, 0, 0, 0, time.UTC) + + records, err := buildNodeAccessLogRecords("node-a", []NodeAccessLog{ + { + LoggedAtUnix: reportedAt.Unix(), + RemoteAddr: "203.0.113.10", + Host: "api.example.com", + Path: "/v1/ping", + StatusCode: 200, + BytesSent: 4096, + }, + }, nil, reportedAt) + if err != nil { + t.Fatalf("buildNodeAccessLogRecords() error = %v", err) + } + if len(records) != 1 { + t.Fatalf("expected one access log record, got %d", len(records)) + } + if records[0].BytesSent != 4096 { + t.Fatalf("BytesSent = %d, want 4096", records[0].BytesSent) + } +} diff --git a/internal/repository/analytics/node_access_log_test.go b/internal/repository/analytics/node_access_log_test.go index 6434490f..79a8fce6 100644 --- a/internal/repository/analytics/node_access_log_test.go +++ b/internal/repository/analytics/node_access_log_test.go @@ -39,6 +39,7 @@ func TestBatchInsertNodeAccessLogs_UsesModelBatchSQL(t *testing.T) { Host: "example.com", Path: "/alpha", StatusCode: 200, + BytesSent: 2048, CreatedAt: loggedAt, }, }) @@ -48,4 +49,6 @@ func TestBatchInsertNodeAccessLogs_UsesModelBatchSQL(t *testing.T) { assert.True(t, mockBatch.sendCalled) require.Len(t, mockBatch.rows, 1) assert.Equal(t, "node-a", mockBatch.rows[0][1]) -} \ No newline at end of file + require.Len(t, mockBatch.rows[0], 10) + assert.Equal(t, uint64(2048), mockBatch.rows[0][8]) +} diff --git a/internal/repository/analytics/node_access_log_writer.go b/internal/repository/analytics/node_access_log_writer.go index 88b02336..0382931c 100644 --- a/internal/repository/analytics/node_access_log_writer.go +++ b/internal/repository/analytics/node_access_log_writer.go @@ -47,6 +47,7 @@ func BatchInsertNodeAccessLogs(ctx context.Context, logs []analyticsmodel.NodeAc logItem.Host, logItem.Path, logItem.StatusCode, + logItem.BytesSent, createdAt.UTC(), ); err != nil { return fmt.Errorf("append node access log to batch: %w", err) @@ -57,4 +58,4 @@ func BatchInsertNodeAccessLogs(ctx context.Context, logs []analyticsmodel.NodeAc return fmt.Errorf("send clickhouse batch: %w", err) } return nil -} \ No newline at end of file +}