From 52e9144ee03d01b688cd8f8d519e8992281fc18d Mon Sep 17 00:00:00 2001 From: druanoor <51286702+druanoor@users.noreply.github.com> Date: Mon, 10 Jul 2023 15:26:18 +0200 Subject: [PATCH] feat: Allow to get Probe logs by target (#1063) * feat: Allow to get Probe logs by target Signed-off-by: Daniel Ruano * Commit for signing Signed-off-by: Daniel Ruano * Use net/http constants instead of hardcoded ints as http codes Signed-off-by: Daniel Ruano * Add unit testing for GetByTarget and GetById methods Signed-off-by: Daniel Ruano * Update main.go Co-authored-by: Suraj Nath <9503187+electron0zero@users.noreply.github.com> Signed-off-by: druanoor <51286702+druanoor@users.noreply.github.com> * Update main.go Co-authored-by: Suraj Nath <9503187+electron0zero@users.noreply.github.com> Signed-off-by: druanoor <51286702+druanoor@users.noreply.github.com> * Update main.go Co-authored-by: Suraj Nath <9503187+electron0zero@users.noreply.github.com> Signed-off-by: druanoor <51286702+druanoor@users.noreply.github.com> * Update main.go Co-authored-by: Suraj Nath <9503187+electron0zero@users.noreply.github.com> Signed-off-by: druanoor <51286702+druanoor@users.noreply.github.com> * Update main.go Co-authored-by: Suraj Nath <9503187+electron0zero@users.noreply.github.com> Signed-off-by: druanoor <51286702+druanoor@users.noreply.github.com> * Fix format Signed-off-by: Daniel Ruano --------- Signed-off-by: Daniel Ruano Signed-off-by: druanoor <51286702+druanoor@users.noreply.github.com> Co-authored-by: Suraj Nath <9503187+electron0zero@users.noreply.github.com> --- main.go | 28 +++++++++++++++---- prober/history.go | 23 ++++++++++++++-- prober/history_test.go | 62 ++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 106 insertions(+), 7 deletions(-) diff --git a/main.go b/main.go index 8f87d2f5..2699b6f8 100644 --- a/main.go +++ b/main.go @@ -216,14 +216,32 @@ func run() int { http.HandleFunc(path.Join(*routePrefix, "/logs"), func(w http.ResponseWriter, r *http.Request) { id, err := strconv.ParseInt(r.URL.Query().Get("id"), 10, 64) if err != nil { - http.Error(w, "Invalid probe id", 500) + id = -1 + } + target := r.URL.Query().Get("target") + if err == nil && target != "" { + http.Error(w, "Probe id and target can't be defined at the same time", http.StatusBadRequest) return } - result := rh.Get(id) - if result == nil { - http.Error(w, "Probe id not found", 404) + if id == -1 && target == "" { + http.Error(w, "Probe id or target must be defined as http query parameters", http.StatusBadRequest) return } + result := new(prober.Result) + if target != "" { + result = rh.GetByTarget(target) + if result == nil { + http.Error(w, "Probe target not found", http.StatusNotFound) + return + } + } else { + result = rh.GetById(id) + if result == nil { + http.Error(w, "Probe id not found", http.StatusNotFound) + return + } + } + w.Header().Set("Content-Type", "text/plain") w.Write([]byte(result.DebugOutput)) }) @@ -234,7 +252,7 @@ func run() int { sc.RUnlock() if err != nil { level.Warn(logger).Log("msg", "Error marshalling configuration", "err", err) - http.Error(w, err.Error(), 500) + http.Error(w, err.Error(), http.StatusInternalServerError) return } w.Header().Set("Content-Type", "text/plain") diff --git a/prober/history.go b/prober/history.go index 306eb419..c5009c2f 100644 --- a/prober/history.go +++ b/prober/history.go @@ -78,8 +78,8 @@ func (rh *ResultHistory) List() []*Result { return append(rh.preservedFailedResults[:], rh.results...) } -// Get returns a given result. -func (rh *ResultHistory) Get(id int64) *Result { +// Get returns a given result by id. +func (rh *ResultHistory) GetById(id int64) *Result { rh.mu.Lock() defer rh.mu.Unlock() @@ -96,3 +96,22 @@ func (rh *ResultHistory) Get(id int64) *Result { return nil } + +// Get returns a given result by url. +func (rh *ResultHistory) GetByTarget(target string) *Result { + rh.mu.Lock() + defer rh.mu.Unlock() + + for _, r := range rh.preservedFailedResults { + if r.Target == target { + return r + } + } + for _, r := range rh.results { + if r.Target == target { + return r + } + } + + return nil +} diff --git a/prober/history_test.go b/prober/history_test.go index b964c537..6ab9cdc1 100644 --- a/prober/history_test.go +++ b/prober/history_test.go @@ -79,3 +79,65 @@ func TestHistoryPreservesExpiredFailedResults(t *testing.T) { } } } + +func TestHistoryGetById(t *testing.T) { + history := &ResultHistory{MaxResults: 2} + + history.Add("module", "target-0", fmt.Sprintf("result %d", history.nextId), true) + history.Add("module", "target-1", fmt.Sprintf("result %d", history.nextId), false) + + // Get a Result object for a target that exists + resultTrue := history.GetById(0) + if resultTrue == nil { + t.Errorf("Error finding the result in history by id for id: 1") + } else { + if resultTrue.Id != 0 { + t.Errorf("Error finding the result in history by id: expected \"%d\" and got \"%d\"", 0, resultTrue.Id) + } + } + + resultFalse := history.GetById(1) + if resultFalse == nil { + t.Errorf("Error finding the result in history by id for id: 1") + } else { + if resultFalse.Id != 1 { + t.Errorf("Error finding the result in history by id: expected \"%d\" and got \"%d\"", 1, resultFalse.Id) + } + } + + // Get a Result object for a target that doesn't exist + if history.GetById(5) != nil { + t.Errorf("Error finding the result in history by id for id: 5") + } +} + +func TestHistoryGetByTarget(t *testing.T) { + history := &ResultHistory{MaxResults: 2} + + history.Add("module", "target-0", fmt.Sprintf("result %d", history.nextId), true) + history.Add("module", "target-1", fmt.Sprintf("result %d", history.nextId), false) + + // Get a Result object for a target that exists + resultTrue := history.GetByTarget("target-0") + if resultTrue == nil { + t.Errorf("Error finding the result in history by target for target-0") + } else { + if resultTrue.Target != "target-0" { + t.Errorf("Error finding the result in history by target for target: expected \"%s\" and got \"%s\"", "target-0", resultTrue.Target) + } + } + + resultFalse := history.GetByTarget("target-1") + if resultFalse == nil { + t.Errorf("Error finding the result in history by target for target-1") + } else { + if resultFalse.Target != "target-1" { + t.Errorf("Error finding the result in history by target for target: expected \"%s\" and got \"%s\"", "target-1", resultFalse.Target) + } + } + + // Get a Result object for a target that doesn't exist + if history.GetByTarget("target-5") != nil { + t.Errorf("Error finding the result in history by target for target-5") + } +}