mirror of
https://github.com/Rain-kl/OpenFlare.git
synced 2026-10-07 16:16:37 +08:00
feat(obs): 访问日志 SSOT 与 edge_health,去掉协议兼容层
Agent 仅上报 host_metrics/edge_health/access_logs;业务流量与 UV 由 Server 侧访问日志聚合。新增 of_node_edge_health 与 of_access_log_hourly, 删除 request_reports/openresty 吞吐路径;API 不再暴露 traffic_reports 与 openresty_rx|tx。心跳/离线默认阈值与回填迁移一并入库。
This commit is contained in:
@@ -25,52 +25,25 @@ func TestBuildTrafficTrendPointsFromHourlyBucketsByHour(t *testing.T) {
|
||||
if len(points) != observabilityTrendBuckets {
|
||||
t.Fatalf("BuildTrafficTrendPointsFromHourly() len = %d, want %d", len(points), observabilityTrendBuckets)
|
||||
}
|
||||
}
|
||||
|
||||
func TestBuildTrafficTrendPointsBucketsByHour(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
now := time.Date(2026, 6, 19, 17, 30, 0, 0, time.UTC)
|
||||
reports := []*model.OpenFlareRequestReport{
|
||||
{
|
||||
NodeID: "node-a",
|
||||
WindowStartedAt: now.Add(-3 * time.Hour),
|
||||
WindowEndedAt: now.Add(-3*time.Hour + time.Minute),
|
||||
RequestCount: 10,
|
||||
ErrorCount: 1,
|
||||
},
|
||||
{
|
||||
NodeID: "node-a",
|
||||
WindowStartedAt: now.Add(-30 * time.Minute),
|
||||
WindowEndedAt: now.Add(-29 * time.Minute),
|
||||
RequestCount: 6,
|
||||
ErrorCount: 0,
|
||||
},
|
||||
}
|
||||
|
||||
points := BuildTrafficTrendPoints(now, reports)
|
||||
if len(points) != observabilityTrendBuckets {
|
||||
t.Fatalf("BuildTrafficTrendPoints() len = %d, want %d", len(points), observabilityTrendBuckets)
|
||||
}
|
||||
|
||||
var totalRequests int64
|
||||
// Hourly UV must not be summed into trend points.
|
||||
for _, point := range points {
|
||||
totalRequests += point.RequestCount
|
||||
if point.UniqueVisitorCount != 0 {
|
||||
t.Fatalf("UniqueVisitorCount = %d, want 0 on hourly path", point.UniqueVisitorCount)
|
||||
}
|
||||
}
|
||||
if totalRequests != 16 {
|
||||
t.Fatalf("total request_count = %d, want 16", totalRequests)
|
||||
index, ok := trendBucketIndex(now.Add(-2*time.Hour).Truncate(time.Hour), trendWindowStart(now))
|
||||
if !ok {
|
||||
t.Fatal("expected valid bucket index")
|
||||
}
|
||||
|
||||
currentHour := points[len(points)-1]
|
||||
if currentHour.RequestCount != 6 {
|
||||
t.Fatalf("current hour request_count = %d, want 6", currentHour.RequestCount)
|
||||
if points[index].RequestCount != 12 {
|
||||
t.Fatalf("request_count = %d, want 12", points[index].RequestCount)
|
||||
}
|
||||
if currentHour.ErrorCount != 0 {
|
||||
t.Fatalf("current hour error_count = %d, want 0", currentHour.ErrorCount)
|
||||
if points[index].ErrorCount != 1 {
|
||||
t.Fatalf("error_count = %d, want 1", points[index].ErrorCount)
|
||||
}
|
||||
}
|
||||
|
||||
func TestBuildMetricSnapshotViewsMergesOpenrestyObservation(t *testing.T) {
|
||||
func TestBuildMetricSnapshotViewsMergesEdgeHealthConnections(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
capturedAt := time.Date(2026, 6, 19, 12, 0, 0, 0, time.UTC)
|
||||
@@ -82,54 +55,30 @@ func TestBuildMetricSnapshotViewsMergesOpenrestyObservation(t *testing.T) {
|
||||
CPUUsagePercent: 12.5,
|
||||
},
|
||||
}
|
||||
openrestyObs := []*model.OpenFlareNodeObservationOpenresty{
|
||||
edgeHealth := []*model.OpenFlareEdgeHealth{
|
||||
{
|
||||
NodeID: "node-a",
|
||||
CapturedAt: capturedAt.Add(5 * time.Second),
|
||||
OpenrestyRxBytes: 4096,
|
||||
OpenrestyTxBytes: 8192,
|
||||
OpenrestyConnections: 7,
|
||||
NodeID: "node-a",
|
||||
CapturedAt: capturedAt.Add(5 * time.Second),
|
||||
Status: "healthy",
|
||||
Connections: 7,
|
||||
},
|
||||
}
|
||||
|
||||
views := BuildMetricSnapshotViews(snapshots, openrestyObs)
|
||||
views := BuildMetricSnapshotViews(snapshots, edgeHealth)
|
||||
if len(views) != 1 {
|
||||
t.Fatalf("BuildMetricSnapshotViews() len = %d, want 1", len(views))
|
||||
}
|
||||
if views[0].OpenrestyRxBytes != 4096 {
|
||||
t.Fatalf("OpenrestyRxBytes = %d, want 4096", views[0].OpenrestyRxBytes)
|
||||
}
|
||||
if views[0].OpenrestyTxBytes != 8192 {
|
||||
t.Fatalf("OpenrestyTxBytes = %d, want 8192", views[0].OpenrestyTxBytes)
|
||||
}
|
||||
if views[0].OpenrestyConnections != 7 {
|
||||
t.Fatalf("OpenrestyConnections = %d, want 7", views[0].OpenrestyConnections)
|
||||
}
|
||||
}
|
||||
|
||||
func TestLatestTrafficReportUsesLatestWindowEndedAt(t *testing.T) {
|
||||
func TestBuildTrafficWindowSummaryFromAccessLogsNilWithoutData(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
older := &model.OpenFlareRequestReport{
|
||||
WindowEndedAt: time.Date(2026, 6, 19, 10, 0, 0, 0, time.UTC),
|
||||
RequestCount: 3,
|
||||
}
|
||||
newer := &model.OpenFlareRequestReport{
|
||||
WindowEndedAt: time.Date(2026, 6, 19, 11, 0, 0, 0, time.UTC),
|
||||
RequestCount: 9,
|
||||
}
|
||||
|
||||
latest := latestTrafficReport([]*model.OpenFlareRequestReport{older, newer})
|
||||
if latest == nil || latest.RequestCount != 9 {
|
||||
t.Fatalf("latestTrafficReport() = %#v, want newer report with request_count 9", latest)
|
||||
}
|
||||
}
|
||||
|
||||
func TestBuildTrafficWindowSummaryNilWithoutReport(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
if summary := buildTrafficWindowSummary(nil); summary != nil {
|
||||
t.Fatalf("buildTrafficWindowSummary(nil) = %#v, want nil", summary)
|
||||
// Without an access-log store / data, summary is nil.
|
||||
if summary := buildTrafficWindowSummaryFromAccessLogs(t.Context(), "missing", time.Now().Add(-time.Hour), time.Now()); summary != nil {
|
||||
t.Fatalf("buildTrafficWindowSummaryFromAccessLogs() = %#v, want nil", summary)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -173,12 +122,8 @@ func TestBuildNetworkTrendPointsUsesCounterDeltas(t *testing.T) {
|
||||
{NodeID: "n1", CapturedAt: base.Add(10 * time.Minute), NetworkRxBytes: 1000, NetworkTxBytes: 2000},
|
||||
{NodeID: "n1", CapturedAt: base.Add(20 * time.Minute), NetworkRxBytes: 1500, NetworkTxBytes: 2600},
|
||||
}
|
||||
openrestyObs := []*model.OpenFlareNodeObservationOpenresty{
|
||||
{NodeID: "n1", CapturedAt: base.Add(10 * time.Minute), OpenrestyRxBytes: 100, OpenrestyTxBytes: 200},
|
||||
{NodeID: "n1", CapturedAt: base.Add(20 * time.Minute), OpenrestyRxBytes: 180, OpenrestyTxBytes: 250},
|
||||
}
|
||||
|
||||
points := BuildNetworkTrendPoints(now, snapshots, openrestyObs)
|
||||
points := BuildNetworkTrendPoints(now, snapshots)
|
||||
current := points[len(points)-1]
|
||||
if current.NetworkRxBytes != 500 {
|
||||
t.Fatalf("network_rx_bytes = %d, want 500", current.NetworkRxBytes)
|
||||
@@ -186,11 +131,30 @@ func TestBuildNetworkTrendPointsUsesCounterDeltas(t *testing.T) {
|
||||
if current.NetworkTxBytes != 600 {
|
||||
t.Fatalf("network_tx_bytes = %d, want 600", current.NetworkTxBytes)
|
||||
}
|
||||
if current.OpenrestyRxBytes != 80 {
|
||||
t.Fatalf("openresty_rx_bytes = %d, want 80", current.OpenrestyRxBytes)
|
||||
if current.BytesReceived != 0 || current.BytesProvided != 0 {
|
||||
t.Fatalf("business bytes should be 0 without access logs overlay, got received=%d provided=%d",
|
||||
current.BytesReceived, current.BytesProvided)
|
||||
}
|
||||
if current.OpenrestyTxBytes != 50 {
|
||||
t.Fatalf("openresty_tx_bytes = %d, want 50", current.OpenrestyTxBytes)
|
||||
}
|
||||
|
||||
func TestBuildHealthSummaryUsesTrafficSummary(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
snapshot := &model.OpenFlareMetricSnapshot{
|
||||
CPUUsagePercent: 10,
|
||||
MemoryUsedBytes: 1,
|
||||
MemoryTotalBytes: 10,
|
||||
}
|
||||
traffic := &TrafficWindowSummary{
|
||||
RequestCount: 200,
|
||||
ErrorCount: 20, // 10% error rate
|
||||
}
|
||||
summary := buildHealthSummary(snapshot, traffic, nil)
|
||||
if !summary.HasTrafficRisk {
|
||||
t.Fatal("HasTrafficRisk = false, want true for 10% error rate with >=100 requests")
|
||||
}
|
||||
if summary.HasCapacityRisk {
|
||||
t.Fatal("HasCapacityRisk = true, want false")
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user