Remove Needle; stop paging on nginx 4xx
Needle scored ~chance on the golden set and never gated alerts, so drop the sidecar, proxy handlers, UI buttons, k8s container and build step. The labelled eval sets move to cmd/triage-eval/data. nginx 4xx (registry 401 challenges, /oauth2/auth, scanner 405s) is now dropped in FilterActionable instead of only being discounted, so it cannot ride along with a real 5xx. nginx 5xx still alerts. Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
This commit is contained in:
1 parent
e046bd86d1
commit
51a8412ae1
22 files changed
+29
-1162
No files matched your search
@@ -13,7 +13,6 @@ import (
|
||||
"io"
|
||||
"log"
|
||||
"net/http"
|
||||
"os"
|
||||
"strconv"
|
||||
"strings"
|
||||
"time"
|
||||
@@ -1007,110 +1006,6 @@ func (c *Collector) HandleStatsEndpoints(w http.ResponseWriter, r *http.Request)
|
||||
})
|
||||
}
|
||||
|
||||
// needleAddr returns the configured or default address for the Needle 3 sidecar.
|
||||
func needleAddr() string {
|
||||
addr := os.Getenv("OTEL_NEEDLE_ADDR")
|
||||
if addr == "" {
|
||||
addr = "http://127.0.0.1:5005"
|
||||
}
|
||||
return strings.TrimRight(addr, "/")
|
||||
}
|
||||
|
||||
// HandleNeedleStatus checks if the Needle 3 sidecar is reachable and reports its health.
|
||||
func (c *Collector) HandleNeedleStatus(w http.ResponseWriter, r *http.Request) {
|
||||
if r.Method != http.MethodGet {
|
||||
http.Error(w, "method not allowed", http.StatusMethodNotAllowed)
|
||||
return
|
||||
}
|
||||
|
||||
target := needleAddr() + "/health"
|
||||
client := &http.Client{Timeout: 2 * time.Second}
|
||||
resp, err := client.Get(target)
|
||||
w.Header().Set("Content-Type", "application/json")
|
||||
if err != nil {
|
||||
w.WriteHeader(http.StatusServiceUnavailable)
|
||||
_ = json.NewEncoder(w).Encode(map[string]interface{}{
|
||||
"available": false,
|
||||
"error": fmt.Sprintf("Needle sidecar unreachable at %s: %v", target, err),
|
||||
})
|
||||
return
|
||||
}
|
||||
defer resp.Body.Close()
|
||||
w.WriteHeader(resp.StatusCode)
|
||||
_, _ = io.Copy(w, resp.Body)
|
||||
}
|
||||
|
||||
// HandleNeedleClassify proxies telemetry triage requests to the Needle 3 sidecar.
|
||||
func (c *Collector) HandleNeedleClassify(w http.ResponseWriter, r *http.Request) {
|
||||
if r.Method != http.MethodPost {
|
||||
http.Error(w, "method not allowed", http.StatusMethodNotAllowed)
|
||||
return
|
||||
}
|
||||
|
||||
body, err := io.ReadAll(r.Body)
|
||||
if err != nil {
|
||||
http.Error(w, "failed to read request body", http.StatusBadRequest)
|
||||
return
|
||||
}
|
||||
|
||||
// If the payload specifies an issue_id and no text, look up the issue
|
||||
var reqMap map[string]interface{}
|
||||
if err := json.Unmarshal(body, &reqMap); err == nil {
|
||||
if issueID, ok := reqMap["issue_id"].(string); ok && issueID != "" {
|
||||
if issue, ok := c.GetIssue(issueID); ok {
|
||||
var promptParts []string
|
||||
promptParts = append(promptParts, fmt.Sprintf("Service: %s", issue.Service))
|
||||
promptParts = append(promptParts, fmt.Sprintf("Title: %s", issue.Title))
|
||||
promptParts = append(promptParts, fmt.Sprintf("Kind: %s", issue.Kind))
|
||||
if len(issue.Samples) > 0 {
|
||||
latest := issue.Samples[len(issue.Samples)-1]
|
||||
if latest.Message != "" {
|
||||
promptParts = append(promptParts, fmt.Sprintf("Message: %s", latest.Message))
|
||||
}
|
||||
if latest.URL != "" {
|
||||
promptParts = append(promptParts, fmt.Sprintf("URL: %s", latest.URL))
|
||||
}
|
||||
if latest.HTTPStatus > 0 {
|
||||
promptParts = append(promptParts, fmt.Sprintf("Status: %d", latest.HTTPStatus))
|
||||
}
|
||||
if latest.HTTPRoute != "" {
|
||||
promptParts = append(promptParts, fmt.Sprintf("Route: %s", latest.HTTPRoute))
|
||||
}
|
||||
}
|
||||
reqMap["text"] = strings.Join(promptParts, " | ")
|
||||
reqMap["service"] = issue.Service
|
||||
reqMap["title"] = issue.Title
|
||||
body, _ = json.Marshal(reqMap)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
target := needleAddr() + "/classify"
|
||||
client := &http.Client{Timeout: 60 * time.Second}
|
||||
proxyReq, err := http.NewRequestWithContext(r.Context(), http.MethodPost, target, strings.NewReader(string(body)))
|
||||
if err != nil {
|
||||
http.Error(w, "failed to create proxy request", http.StatusInternalServerError)
|
||||
return
|
||||
}
|
||||
proxyReq.Header.Set("Content-Type", "application/json")
|
||||
|
||||
resp, err := client.Do(proxyReq)
|
||||
if err != nil {
|
||||
w.Header().Set("Content-Type", "application/json")
|
||||
w.WriteHeader(http.StatusServiceUnavailable)
|
||||
_ = json.NewEncoder(w).Encode(map[string]interface{}{
|
||||
"success": false,
|
||||
"error": fmt.Sprintf("Needle sidecar unreachable at %s: %v", target, err),
|
||||
})
|
||||
return
|
||||
}
|
||||
defer resp.Body.Close()
|
||||
|
||||
w.Header().Set("Content-Type", "application/json")
|
||||
w.WriteHeader(resp.StatusCode)
|
||||
_, _ = io.Copy(w, resp.Body)
|
||||
}
|
||||
|
||||
// stampFrontendClient fills in client.address and user_agent.original on
|
||||
// browser-originated log records (source=frontend) from the ingest request,
|
||||
// since the browser cannot know its own public IP. Values the SDK already
|
||||
|
||||
Reference in new issue
Block a user