package services import ( "strings" "testing" ) // 推送地址纠正:这是「采集器 running 但一条日志都进不去」的根因防护。 func TestHostPushEndpoint(t *testing.T) { const ip = "172.19.16.8" cases := []struct { name string endpoint string hostIP string dockerMode bool want string wantErr string }{ { name: "正常 IP 不动", endpoint: "http://172.19.16.8:3100", hostIP: ip, want: "http://172.19.16.8:3100", }, { name: "k8s svc 地址不动(命名空间短名照原样)", endpoint: "http://loki.log.svc.cluster.local:3100", hostIP: ip, want: "http://loki.log.svc.cluster.local:3100", }, { // 本会话实测踩到:listenIP 填 0.0.0.0 → endpoint 变成 0.0.0.0:3100 → 推送被拒 name: "通配地址 0.0.0.0 换成真实主机 IP(两种模式都要换)", endpoint: "http://0.0.0.0:3100", hostIP: ip, want: "http://172.19.16.8:3100", }, { name: "容器模式下 127.0.0.1 必须换成主机 IP(bridge 里指向容器自己)", endpoint: "http://127.0.0.1:3100", hostIP: ip, dockerMode: true, want: "http://172.19.16.8:3100", }, { name: "systemd 模式下 127.0.0.1 保持原样(同机部署是合法的)", endpoint: "http://127.0.0.1:3100", hostIP: ip, want: "http://127.0.0.1:3100", }, { name: "容器模式下 localhost 同样换掉", endpoint: "http://localhost:3100", hostIP: ip, dockerMode: true, want: "http://172.19.16.8:3100", }, { name: "缺端口时补 3100", endpoint: "http://0.0.0.0", hostIP: ip, want: "http://172.19.16.8:3100", }, { name: "空 endpoint 直接报错", endpoint: " ", hostIP: ip, wantErr: "缺少 Loki 推送地址", }, { name: "拿不到主机 IP 时明确报错,而不是返回必然失败的地址", endpoint: "http://0.0.0.0:3100", hostIP: "", wantErr: "取不到目标主机 IP", }, } for _, c := range cases { got, err := hostPushEndpoint(c.endpoint, c.hostIP, c.dockerMode) if c.wantErr != "" { if err == nil || !strings.Contains(err.Error(), c.wantErr) { t.Fatalf("%s: 期望报错含 %q,实际 got=%q err=%v", c.name, c.wantErr, got, err) } continue } if err != nil { t.Fatalf("%s: 不应报错: %v", c.name, err) } if got != c.want { t.Fatalf("%s: 期望 %q,实际 %q", c.name, c.want, got) } } } // 渲染出来的 promtail 配置里不能再出现 0.0.0.0 这类推不上去的地址。 func TestHostPromtailConfigUsesReachableEndpoint(t *testing.T) { fixed, err := hostPushEndpoint("http://0.0.0.0:3100", "172.19.16.8", true) if err != nil { t.Fatalf("纠正失败: %v", err) } cfg, err := PromtailConfigForHost(HostPromtailOptions{ Endpoint: fixed, Cluster: "host", Hostname: "h1", LogPath: "/var/log/a.log", }) if err != nil { t.Fatalf("渲染失败: %v", err) } if strings.Contains(cfg, "0.0.0.0") { t.Fatalf("配置里仍是通配地址:\n%s", cfg) } if !strings.Contains(cfg, "url: http://172.19.16.8:3100/loki/api/v1/push") { t.Fatalf("推送地址不是纠正后的地址:\n%s", cfg) } }