From 7bbd148d1cd4a5e06dd3d2bd3069ed2ff772bfcc Mon Sep 17 00:00:00 2001 From: kevkevinpal Date: Tue, 17 Dec 2024 16:11:12 -0500 Subject: [PATCH] feat: created util to print out trace from endpoint call --- routes/people.go | 7 ++-- routes/person.go | 3 +- routes/test_routes.go | 22 +++++++++++- utils/trace.go | 81 +++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 108 insertions(+), 5 deletions(-) create mode 100644 utils/trace.go diff --git a/routes/people.go b/routes/people.go index 59d6b0480..1f11e5735 100644 --- a/routes/people.go +++ b/routes/people.go @@ -6,6 +6,7 @@ import ( "github.com/go-chi/chi" "github.com/stakwork/sphinx-tribes/db" "github.com/stakwork/sphinx-tribes/handlers" + "github.com/stakwork/sphinx-tribes/utils" ) func PeopleRoutes() chi.Router { @@ -14,9 +15,9 @@ func PeopleRoutes() chi.Router { peopleHandler := handlers.NewPeopleHandler(db.DB) r.Group(func(r chi.Router) { - r.Get("/", peopleHandler.GetListedPeople) - r.Get("/search", peopleHandler.GetPeopleBySearch) - r.Get("/posts", handlers.GetListedPosts) + r.Get("/", utils.TraceWithLogging(peopleHandler.GetListedPeople)) + r.Get("/search", utils.TraceWithLogging(peopleHandler.GetPeopleBySearch)) + r.Get("/posts", utils.TraceWithLogging(handlers.GetListedPosts)) r.Get("/wanteds/assigned/{uuid}", bountyHandler.GetPersonAssignedBounties) r.Get("/wanteds/created/{uuid}", bountyHandler.GetPersonCreatedBounties) r.Get("/wanteds/header", handlers.GetWantedsHeader) diff --git a/routes/person.go b/routes/person.go index 1b4246563..1c98b4625 100644 --- a/routes/person.go +++ b/routes/person.go @@ -5,6 +5,7 @@ import ( "github.com/stakwork/sphinx-tribes/auth" "github.com/stakwork/sphinx-tribes/db" "github.com/stakwork/sphinx-tribes/handlers" + "github.com/stakwork/sphinx-tribes/utils" ) func PersonRoutes() chi.Router { @@ -13,7 +14,7 @@ func PersonRoutes() chi.Router { r.Group(func(r chi.Router) { r.Get("/{pubkey}", peopleHandler.GetPersonByPubkey) r.Get("/id/{id}", peopleHandler.GetPersonById) - r.Get("/uuid/{uuid}", peopleHandler.GetPersonByUuid) + r.Get("/uuid/{uuid}", utils.TraceWithLogging(peopleHandler.GetPersonByUuid)) r.Get("/uuid/{uuid}/assets", handlers.GetPersonAssetsByUuid) r.Get("/githubname/{github}", handlers.GetPersonByGithubName) }) diff --git a/routes/test_routes.go b/routes/test_routes.go index 92a82b872..5b944adf5 100644 --- a/routes/test_routes.go +++ b/routes/test_routes.go @@ -2,6 +2,10 @@ package routes import ( "net/http" + "runtime/trace" + "log" +// "os" + "bytes" "github.com/go-chi/chi" ) @@ -10,7 +14,23 @@ func TestRoutes() chi.Router { r := chi.NewRouter() r.Get("/internal-server-error", func(w http.ResponseWriter, r *http.Request) { - panic("Forced internal server error") + // Enable tracing + //f, err := os.Create("trace.out") + var buf bytes.Buffer + //if err != nil { + // log.Fatalf("Failed to create trace output file: %v", err) + //} + //defer f.Close() + + if err := trace.Start(&buf); err != nil { + log.Fatalf("Failed to start trace: %v", err) + } + defer func() { + trace.Stop() + log.Println("Trace Data:") + log.Println(buf.String()) + }() + //panic("Forced internal server error") }) return r diff --git a/utils/trace.go b/utils/trace.go new file mode 100644 index 000000000..d7570c89c --- /dev/null +++ b/utils/trace.go @@ -0,0 +1,81 @@ +package utils + +import ( + "bytes" + "log" + "net/http" + "regexp" + "runtime/trace" + "strings" +) + +func TraceWithLogging(next http.HandlerFunc) http.HandlerFunc { + return func(w http.ResponseWriter, r *http.Request) { + var buf bytes.Buffer + + // Start trace capturing + if err := trace.Start(&buf); err != nil { + http.Error(w, "Failed to start trace", http.StatusInternalServerError) + log.Fatalf("Failed to start trace: %v", err) + return + } + defer func() { + trace.Stop() + + // Extract and process trace output + traceOutput := buf.String() + //log.Println("Raw Trace Output (for debugging):", traceOutput) + // Split the trace output into lines + traceLines := strings.Split(traceOutput, "\n") + startedFormatting := false + + // Log each trace line with a line number and format + for _, line := range traceLines { + if !startedFormatting && strings.Contains(line, "start trace") { + startedFormatting = true + } else { + continue + } + + if line != "" { + traceFormatted := formatTrace(line) + for j, formattedLine := range traceFormatted { + log.Printf("%03d %s", j+1, formattedLine) + } + } + } + }() + + next(w, r) + } +} + +func splitTrace(traceString string) []string { + // Define the regex pattern for detecting file paths ending with .go + re := regexp.MustCompile(`/([^/\s]+\.go)`) + + // Replace each match with the file path followed by a newline + formattedTrace := re.ReplaceAllString(traceString, "$0\n") + + cleanRegex := regexp.MustCompile(`[^a-zA-Z0-9\s\./:_\-@()]`) + cleanedTrace := cleanRegex.ReplaceAllString(formattedTrace, "") + + + // Split the formatted trace into lines and return as a string array + return strings.Split(strings.TrimSpace(cleanedTrace), "\n") +} +func formatTrace(input string) []string { + // Find the position where "start trace" appears + startIdx := strings.Index(input, "start trace") + if startIdx == -1 { + return nil // "start trace" not found, return nil slice + } + + // Slice input string from "start trace" onwards + traceContent := input[startIdx:] + + // Use splitTrace to split and format the trace content + return splitTrace(traceContent) +} + +