more otel
This commit is contained in:
1 parent
9620e3bfa6
commit
21f04d696b
88 files changed
+23419
-192
No files matched your search
@@ -11,6 +11,7 @@ import (
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
"git.tornberg.me/go-otel/internal/issues"
|
||||
"git.tornberg.me/go-otel/internal/storage"
|
||||
"git.tornberg.me/go-otel/internal/websocket"
|
||||
"go.opentelemetry.io/collector/pdata/pcommon"
|
||||
@@ -242,6 +243,77 @@ func TestConsumeTracesRecordsIssue(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
func TestConsumeTracesHTTPErrorsAndNaming(t *testing.T) {
|
||||
coll := New(noopBroadcaster{}, 10, nil)
|
||||
|
||||
td := ptrace.NewTraces()
|
||||
|
||||
// 1. Nginx span with 404 and empty name (common for ingress/reverse proxy)
|
||||
rs1 := td.ResourceSpans().AppendEmpty()
|
||||
rs1.Resource().Attributes().PutStr("service.name", "nginx")
|
||||
s1 := rs1.ScopeSpans().AppendEmpty().Spans().AppendEmpty()
|
||||
s1.SetName("") // empty name
|
||||
s1.Attributes().PutInt("http.status_code", 404)
|
||||
s1.Attributes().PutStr("http.method", "GET")
|
||||
s1.Attributes().PutStr("http.target", "/missing-path")
|
||||
|
||||
// 2. e2e-verify span with 500 and service name in span attributes
|
||||
rs2 := td.ResourceSpans().AppendEmpty()
|
||||
// Resource has no service.name, fallback to app attribute on span
|
||||
s2 := rs2.ScopeSpans().AppendEmpty().Spans().AppendEmpty()
|
||||
s2.SetName("test-endpoint")
|
||||
s2.Attributes().PutStr("app.kubernetes.io/name", "e2e-verify")
|
||||
s2.Attributes().PutInt("http.response.status_code", 500)
|
||||
s2.Attributes().PutStr("http.request.method", "POST")
|
||||
s2.Attributes().PutStr("http.route", "/api/v1/test")
|
||||
|
||||
if err := coll.ConsumeTraces(context.Background(), td); err != nil {
|
||||
t.Fatalf("ConsumeTraces failed: %v", err)
|
||||
}
|
||||
|
||||
issuesList := coll.ListIssues(10)
|
||||
if len(issuesList) != 2 {
|
||||
t.Fatalf("expected 2 distinct issues (404 and 500), got %d: %+v", len(issuesList), issuesList)
|
||||
}
|
||||
|
||||
foundNginx := false
|
||||
foundE2E := false
|
||||
|
||||
for _, iss := range issuesList {
|
||||
if iss.Title == "(error)" {
|
||||
t.Errorf("issue title must not be '(error)', got %q", iss.Title)
|
||||
}
|
||||
if iss.Service == "unknown" {
|
||||
t.Errorf("service must not be 'unknown', got %s", iss.Service)
|
||||
}
|
||||
if iss.Service == "nginx" {
|
||||
foundNginx = true
|
||||
if !strings.Contains(iss.Title, "HTTP 404 (Not Found): GET /missing-path") {
|
||||
t.Errorf("expected nginx 404 title, got %q", iss.Title)
|
||||
}
|
||||
if iss.Samples[0].HTTPStatus != 404 {
|
||||
t.Errorf("expected sample HTTPStatus 404, got %d", iss.Samples[0].HTTPStatus)
|
||||
}
|
||||
}
|
||||
if iss.Service == "e2e-verify" {
|
||||
foundE2E = true
|
||||
if !strings.Contains(iss.Title, "HTTP 500 (Internal Server Error): POST /api/v1/test") {
|
||||
t.Errorf("expected e2e-verify 500 title, got %q", iss.Title)
|
||||
}
|
||||
if iss.Samples[0].HTTPStatus != 500 {
|
||||
t.Errorf("expected sample HTTPStatus 500, got %d", iss.Samples[0].HTTPStatus)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if !foundNginx {
|
||||
t.Errorf("expected to find nginx issue")
|
||||
}
|
||||
if !foundE2E {
|
||||
t.Errorf("expected to find e2e-verify issue")
|
||||
}
|
||||
}
|
||||
|
||||
func TestConsumeLogsRecordsIssue(t *testing.T) {
|
||||
coll := New(noopBroadcaster{}, 10, nil)
|
||||
|
||||
@@ -320,6 +392,41 @@ func TestHandleIssuesAndByID(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
func TestHandleIssuesFiltersAndPaginates(t *testing.T) {
|
||||
coll := New(noopBroadcaster{}, 10, nil)
|
||||
coll.issues.Record("span_error", "nginx", "GET /.env", issues.Sample{Timestamp: 300, SourceIP: "203.0.113.10", HTTPRoute: "/.env"})
|
||||
coll.issues.Record("span_error", "nginx", "GET /.git/HEAD", issues.Sample{Timestamp: 200, SourceIP: "203.0.113.11", HTTPRoute: "/.git/HEAD"})
|
||||
coll.issues.Record("log_error", "api", "database down", issues.Sample{Timestamp: 100})
|
||||
|
||||
req := httptest.NewRequest(http.MethodGet, "/api/issues?service=nginx&kind=span_error&limit=1", nil)
|
||||
rec := httptest.NewRecorder()
|
||||
coll.HandleIssues(rec, req)
|
||||
if rec.Code != http.StatusOK {
|
||||
t.Fatalf("expected 200, got %d: %s", rec.Code, rec.Body.String())
|
||||
}
|
||||
var page []issues.Issue
|
||||
if err := json.Unmarshal(rec.Body.Bytes(), &page); err != nil {
|
||||
t.Fatalf("failed to decode issues page: %v", err)
|
||||
}
|
||||
if len(page) != 1 || page[0].Service != "nginx" {
|
||||
t.Fatalf("unexpected filtered page: %+v", page)
|
||||
}
|
||||
cursor := rec.Header().Get("X-Next-Cursor")
|
||||
if cursor == "" {
|
||||
t.Fatal("expected next cursor header")
|
||||
}
|
||||
|
||||
req = httptest.NewRequest(http.MethodGet, "/api/issues?service=nginx&limit=1&cursor="+cursor, nil)
|
||||
rec = httptest.NewRecorder()
|
||||
coll.HandleIssues(rec, req)
|
||||
if err := json.Unmarshal(rec.Body.Bytes(), &page); err != nil {
|
||||
t.Fatalf("failed to decode cursor page: %v", err)
|
||||
}
|
||||
if len(page) != 1 || page[0].Title != "GET /.git/HEAD" {
|
||||
t.Fatalf("unexpected cursor page: %+v", page)
|
||||
}
|
||||
}
|
||||
|
||||
func TestHandleLogsIngestKey(t *testing.T) {
|
||||
coll := New(noopBroadcaster{}, 10, nil)
|
||||
coll.SetIngestKey("secret")
|
||||
|
||||
Reference in new issue
Block a user