Skip to content

Commit

Permalink
added xgo and started using Trap to intercept function calls
Browse files Browse the repository at this point in the history
  • Loading branch information
kevkevinpal committed Dec 19, 2024
1 parent 7ac02f5 commit 51cb4c2
Show file tree
Hide file tree
Showing 10 changed files with 33 additions and 105 deletions.
2 changes: 1 addition & 1 deletion config/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,7 @@ func InitConfig() {
V2BotUrl = os.Getenv("V2_BOT_URL")
V2BotToken = os.Getenv("V2_BOT_TOKEN")
FfWebsocket = os.Getenv("FF_WEBSOCKET") == "true"
LogLevel = os.Getenv("LOG_LEVEL")
LogLevel = strings.ToUpper(os.Getenv("LOG_LEVEL"))

// Add to super admins
SuperAdmins = StripSuperAdmins(AdminStrings)
Expand Down
1 change: 1 addition & 0 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,7 @@ require (
github.com/onsi/gomega v1.26.0 // indirect
github.com/robfig/cron v1.2.0
github.com/urfave/negroni v1.0.0 // indirect
github.com/xhd2015/xgo/runtime v1.0.52 // indirect
golang.org/x/exp v0.0.0-20230315142452-642cacee5cc0 // indirect
gopkg.in/go-playground/assert.v1 v1.2.1 // indirect
)
2 changes: 2 additions & 0 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -2168,6 +2168,8 @@ github.com/urfave/cli v1.22.5/go.mod h1:Gos4lmkARVdJ6EkW0WaNv/tZAAMe9V7XWyB60NtX
github.com/urfave/cli v1.22.9/go.mod h1:Gos4lmkARVdJ6EkW0WaNv/tZAAMe9V7XWyB60NtXRu0=
github.com/urfave/negroni v1.0.0 h1:kIimOitoypq34K7TG7DUaJ9kq/N4Ofuwi1sjz0KipXc=
github.com/urfave/negroni v1.0.0/go.mod h1:Meg73S6kFm/4PpbYdq35yYWoCZ9mS/YSx+lKnmiohz4=
github.com/xhd2015/xgo/runtime v1.0.52 h1:njcRzY3Xo2AFu/qQSC4ak9+JN7xFmaI3iEUyJxoErWM=
github.com/xhd2015/xgo/runtime v1.0.52/go.mod h1:9GBQ2SzJCzpD3T+HRN+2C0TUOGv7qIz4s0mad1xJ8Jo=
github.com/xi2/xz v0.0.0-20171230120015-48954b6210f8 h1:nIPpBwaJSVYIxUFsDv3M8ofmx9yWTog9BfvIu0q41lo=
github.com/xi2/xz v0.0.0-20171230120015-48954b6210f8/go.mod h1:HUYIGzjTL3rfEspMxjDjgmT5uz5wzYJKVo23qUhYTos=
github.com/xiang90/probing v0.0.0-20190116061207-43a291ad63a2 h1:eY9dn8+vbi4tKz5Qo6v2eYzo7kUS51QINcR5jNpbZS8=
Expand Down
1 change: 1 addition & 0 deletions main.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ import (
"gopkg.in/go-playground/validator.v9"
)


func main() {
if err := godotenv.Load(); err != nil {
fmt.Println("no .env file")
Expand Down
8 changes: 4 additions & 4 deletions routes/people.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,10 +15,10 @@ func PeopleRoutes() chi.Router {

peopleHandler := handlers.NewPeopleHandler(db.DB)
r.Group(func(r chi.Router) {
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("/", utils.AutoLog(peopleHandler.GetListedPeople))
r.Get("/search", utils.AutoLog(peopleHandler.GetPeopleBySearch))
r.Get("/posts", utils.AutoLog(handlers.GetListedPosts))
r.Get("/wanteds/assigned/{uuid}", utils.AutoLog(bountyHandler.GetPersonAssignedBounties))
r.Get("/wanteds/created/{uuid}", bountyHandler.GetPersonCreatedBounties)
r.Get("/wanteds/header", handlers.GetWantedsHeader)
r.Get("/short", handlers.GetPeopleShortList)
Expand Down
2 changes: 1 addition & 1 deletion routes/person.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,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}", utils.TraceWithLogging(peopleHandler.GetPersonByUuid))
r.Get("/uuid/{uuid}", utils.AutoLog(peopleHandler.GetPersonByUuid))
r.Get("/uuid/{uuid}/assets", handlers.GetPersonAssetsByUuid)
r.Get("/githubname/{github}", handlers.GetPersonByGithubName)
})
Expand Down
23 changes: 1 addition & 22 deletions routes/test_routes.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,35 +2,14 @@ package routes

import (
"net/http"
"runtime/trace"
"log"
// "os"
"bytes"

"github.com/go-chi/chi"
)

func TestRoutes() chi.Router {
r := chi.NewRouter()

r.Get("/internal-server-error", func(w http.ResponseWriter, r *http.Request) {
// 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")
panic("Forced internal server error")
})

return r
Expand Down
Binary file added trace.out
Binary file not shown.
14 changes: 6 additions & 8 deletions utils/logger.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ package utils
import (
"log"
"os"
"strings"
"github.com/stakwork/sphinx-tribes/config"
)

type Logger struct {
Expand All @@ -12,7 +12,6 @@ type Logger struct {
errorLogger *log.Logger
debugLogger *log.Logger
machineLogger *log.Logger
logLevel string
}

var Log = Logger{
Expand All @@ -21,35 +20,34 @@ var Log = Logger{
errorLogger: log.New(os.Stderr, "ERROR: ", log.Ldate|log.Ltime|log.Lshortfile),
debugLogger: log.New(os.Stdout, "DEBUG: ", log.Ldate|log.Ltime|log.Lshortfile),
machineLogger: log.New(os.Stdout, "MACHINE: ", log.Ldate|log.Ltime|log.Lshortfile),
logLevel: strings.ToUpper(os.Getenv("LOG_LEVEL")),
}

func (l *Logger) Machine(format string, v ...interface{}) {
if l.logLevel == "MACHINE" {
if config.LogLevel == "MACHINE" {
l.machineLogger.Printf(format, v...)
}
}

func (l *Logger) Debug(format string, v ...interface{}) {
if l.logLevel == "MACHINE" || l.logLevel == "DEBUG" {
if config.LogLevel == "MACHINE" || config.LogLevel == "DEBUG" {
l.debugLogger.Printf(format, v...)
}
}

func (l *Logger) Info(format string, v ...interface{}) {
if l.logLevel == "MACHINE" || l.logLevel == "DEBUG" || l.logLevel == "INFO" {
if config.LogLevel == "MACHINE" || config.LogLevel == "DEBUG" || config.LogLevel == "INFO" {
l.infoLogger.Printf(format, v...)
}
}

func (l *Logger) Warning(format string, v ...interface{}) {
if l.logLevel == "MACHINE" || l.logLevel == "DEBUG" || l.logLevel == "INFO" || l.logLevel == "WARNING" {
if config.LogLevel == "MACHINE" || config.LogLevel == "DEBUG" || config.LogLevel == "INFO" || config.LogLevel == "WARNING" {
l.warningLogger.Printf(format, v...)
}
}

func (l *Logger) Error(format string, v ...interface{}) {
if l.logLevel == "MACHINE" || l.logLevel == "DEBUG" || l.logLevel == "INFO" || l.logLevel == "WARNING" || l.logLevel == "ERROR" {
if config.LogLevel == "MACHINE" || config.LogLevel == "DEBUG" || config.LogLevel == "INFO" || config.LogLevel == "WARNING" || config.LogLevel == "ERROR" {
l.errorLogger.Printf(format, v...)
}
}
85 changes: 16 additions & 69 deletions utils/trace.go
Original file line number Diff line number Diff line change
@@ -1,81 +1,28 @@
package utils

import (
"bytes"
"log"
"context"
"net/http"
"regexp"
"runtime/trace"
"fmt"
"strings"
"github.com/xhd2015/xgo/runtime/core"
"github.com/xhd2015/xgo/runtime/trap"
)

func TraceWithLogging(next http.HandlerFunc) http.HandlerFunc {
func AutoLog(fn 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
trap.AddInterceptor(&trap.Interceptor{
Pre: func(ctx context.Context, f *core.FuncInfo, args core.Object, results core.Object) (interface{}, error) {
index := strings.Index(f.File, "sphinx-tribes")
trimmed := f.File
if index != -1 {
trimmed = f.File[index:]
}
fmt.Printf("%s:%d %s\n", trimmed, f.Line, f.Name)

if line != "" {
traceFormatted := formatTrace(line)
for j, formattedLine := range traceFormatted {
log.Printf("%03d %s", j+1, formattedLine)
}
}
}
}()

next(w, r)
return nil, nil
},
})
fn(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)
}


0 comments on commit 51cb4c2

Please sign in to comment.