logging
This commit is contained in:
parent
0e7d284f09
commit
8b615def81
1
go.mod
1
go.mod
|
|
@ -4,6 +4,7 @@ go 1.25
|
|||
|
||||
require (
|
||||
github.com/gin-gonic/gin v1.11.0
|
||||
github.com/sirupsen/logrus v1.9.3
|
||||
gopkg.in/yaml.v3 v3.0.1
|
||||
)
|
||||
|
||||
|
|
|
|||
4
go.sum
4
go.sum
|
|
@ -48,10 +48,13 @@ github.com/quic-go/qpack v0.5.1 h1:giqksBPnT/HDtZ6VhtFKgoLOWmlyo9Ei6u9PqzIMbhI=
|
|||
github.com/quic-go/qpack v0.5.1/go.mod h1:+PC4XFrEskIVkcLzpEkbLqq1uCoxPhQuvK5rH1ZgaEg=
|
||||
github.com/quic-go/quic-go v0.54.0 h1:6s1YB9QotYI6Ospeiguknbp2Znb/jZYjZLRXn9kMQBg=
|
||||
github.com/quic-go/quic-go v0.54.0/go.mod h1:e68ZEaCdyviluZmy44P6Iey98v/Wfz6HCjQEm+l8zTY=
|
||||
github.com/sirupsen/logrus v1.9.3 h1:dueUQJ1C2q9oE3F7wvmSGAaVtTmUizReu6fjN8uqzbQ=
|
||||
github.com/sirupsen/logrus v1.9.3/go.mod h1:naHLuLoDiP4jHNo9R0sCBMtWGeIprob74mVsIT4qYEQ=
|
||||
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
|
||||
github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw=
|
||||
github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo=
|
||||
github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
|
||||
github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
|
||||
github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
|
||||
github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU=
|
||||
github.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4=
|
||||
|
|
@ -73,6 +76,7 @@ golang.org/x/net v0.42.0 h1:jzkYrhi3YQWD6MLBJcsklgQsoAcw89EcZbJw8Z614hs=
|
|||
golang.org/x/net v0.42.0/go.mod h1:FF1RA5d3u7nAYA4z2TkclSCKh68eSXtiFwcWQpPXdt8=
|
||||
golang.org/x/sync v0.16.0 h1:ycBJEhp9p4vXvUZNszeOq0kGTPghopOL8q0fq3vstxw=
|
||||
golang.org/x/sync v0.16.0/go.mod h1:1dzgHSNfp02xaA81J2MS99Qcpr2w7fw1gpm99rleRqA=
|
||||
golang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.35.0 h1:vz1N37gP5bs89s7He8XuIYXpyY0+QlsKmzipCbUtyxI=
|
||||
golang.org/x/sys v0.35.0/go.mod h1:BJP2sWEmIv4KK5OTEluFJCKSidICx8ciO85XgH3Ak8k=
|
||||
|
|
|
|||
54
main.go
54
main.go
|
|
@ -7,13 +7,12 @@ import (
|
|||
"fmt"
|
||||
"html/template"
|
||||
"io/ioutil"
|
||||
"log"
|
||||
"net/http"
|
||||
"os"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"github.com/gin-gonic/gin"
|
||||
"github.com/sirupsen/logrus"
|
||||
"gopkg.in/yaml.v3"
|
||||
)
|
||||
|
||||
|
|
@ -85,12 +84,12 @@ func loadConfig(path string) error {
|
|||
func (llm *LLMClient) ExtractKeywords(ctx context.Context, message string) ([]string, error) {
|
||||
prompt, err := renderPrompt(appConfig.LLM.ExtractKeywordsPrompt, map[string]string{"Message": message})
|
||||
if err != nil {
|
||||
log.Printf("[CONFIG] Failed to render ExtractKeywords prompt: %v", err)
|
||||
logrus.WithError(err).Error("[CONFIG] Failed to render ExtractKeywords prompt")
|
||||
return nil, err
|
||||
}
|
||||
log.Printf("[LLM] ExtractKeywords prompt: %q", prompt)
|
||||
logrus.WithField("prompt", prompt).Info("[LLM] ExtractKeywords prompt")
|
||||
resp, err := llm.openAICompletion(ctx, prompt)
|
||||
log.Printf("[LLM] ExtractKeywords response: %q, err: %v", resp, err)
|
||||
logrus.WithFields(logrus.Fields{"response": resp, "err": err}).Info("[LLM] ExtractKeywords response")
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
|
@ -113,12 +112,12 @@ func (llm *LLMClient) DisambiguateBestMatch(ctx context.Context, message string,
|
|||
entries, _ := json.Marshal(candidates)
|
||||
prompt, err := renderPrompt(appConfig.LLM.DisambiguatePrompt, map[string]string{"Entries": string(entries), "Message": message})
|
||||
if err != nil {
|
||||
log.Printf("[CONFIG] Failed to render Disambiguate prompt: %v", err)
|
||||
logrus.WithError(err).Error("[CONFIG] Failed to render Disambiguate prompt")
|
||||
return "", err
|
||||
}
|
||||
log.Printf("[LLM] DisambiguateBestMatch prompt: %q", prompt)
|
||||
logrus.WithField("prompt", prompt).Info("[LLM] DisambiguateBestMatch prompt")
|
||||
resp, err := llm.openAICompletion(ctx, prompt)
|
||||
log.Printf("[LLM] DisambiguateBestMatch response: %q, err: %v", resp, err)
|
||||
logrus.WithFields(logrus.Fields{"response": resp, "err": err}).Info("[LLM] DisambiguateBestMatch response")
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
|
@ -135,7 +134,7 @@ func (llm *LLMClient) openAICompletion(ctx context.Context, prompt string) (stri
|
|||
if apiURL == "" {
|
||||
apiURL = "https://api.openai.com/v1/completions"
|
||||
}
|
||||
log.Printf("[LLM] openAICompletion POST %s | prompt: %q", apiURL, prompt)
|
||||
logrus.WithFields(logrus.Fields{"api_url": apiURL, "prompt": prompt}).Info("[LLM] openAICompletion POST")
|
||||
body := map[string]interface{}{
|
||||
"model": "text-davinci-003",
|
||||
"prompt": prompt,
|
||||
|
|
@ -151,7 +150,7 @@ func (llm *LLMClient) openAICompletion(ctx context.Context, prompt string) (stri
|
|||
client := &http.Client{}
|
||||
resp, err := client.Do(req)
|
||||
if err != nil {
|
||||
log.Printf("[LLM] openAICompletion error: %v", err)
|
||||
logrus.WithError(err).Error("[LLM] openAICompletion error")
|
||||
return "", err
|
||||
}
|
||||
defer resp.Body.Close()
|
||||
|
|
@ -161,14 +160,14 @@ func (llm *LLMClient) openAICompletion(ctx context.Context, prompt string) (stri
|
|||
} `json:"choices"`
|
||||
}
|
||||
if err := json.NewDecoder(resp.Body).Decode(&result); err != nil {
|
||||
log.Printf("[LLM] openAICompletion decode error: %v", err)
|
||||
logrus.WithError(err).Error("[LLM] openAICompletion decode error")
|
||||
return "", err
|
||||
}
|
||||
if len(result.Choices) == 0 {
|
||||
log.Printf("[LLM] openAICompletion: no choices returned")
|
||||
logrus.Warn("[LLM] openAICompletion: no choices returned")
|
||||
return "", nil
|
||||
}
|
||||
log.Printf("[LLM] openAICompletion: got text: %q", result.Choices[0].Text)
|
||||
logrus.WithField("text", result.Choices[0].Text).Info("[LLM] openAICompletion: got text")
|
||||
return result.Choices[0].Text, nil
|
||||
}
|
||||
|
||||
|
|
@ -242,16 +241,19 @@ func loadUITemplate(path string) error {
|
|||
}
|
||||
|
||||
func main() {
|
||||
logrus.SetFormatter(&logrus.TextFormatter{FullTimestamp: true})
|
||||
logrus.SetLevel(logrus.InfoLevel)
|
||||
|
||||
if err := loadConfig("config.yaml"); err != nil {
|
||||
log.Fatalf("Failed to load config.yaml: %v", err)
|
||||
logrus.Fatalf("Failed to load config.yaml: %v", err)
|
||||
}
|
||||
log.Printf("Loaded config: %+v", appConfig)
|
||||
logrus.Infof("Loaded config: %+v", appConfig)
|
||||
if err := loadYAMLDB("db.yaml"); err != nil {
|
||||
log.Fatalf("Failed to load db.yaml: %v", err)
|
||||
logrus.Fatalf("Failed to load db.yaml: %v", err)
|
||||
}
|
||||
fmt.Printf("Loaded %d reasons from db.yaml\n", len(reasonsDB))
|
||||
if err := loadUITemplate("ui.html"); err != nil {
|
||||
log.Fatalf("Failed to load ui.html: %v", err)
|
||||
logrus.Fatalf("Failed to load ui.html: %v", err)
|
||||
}
|
||||
llm := &LLMClient{
|
||||
APIKey: os.Getenv("OPENAI_API_KEY"),
|
||||
|
|
@ -265,7 +267,7 @@ func main() {
|
|||
r.POST("/chat", func(c *gin.Context) {
|
||||
var req ChatRequest
|
||||
if err := c.ShouldBindJSON(&req); err != nil {
|
||||
log.Printf("[ERROR] Invalid request: %v", err)
|
||||
logrus.WithError(err).Error("Invalid request")
|
||||
c.JSON(http.StatusBadRequest, gin.H{"error": "Invalid request"})
|
||||
return
|
||||
}
|
||||
|
|
@ -293,7 +295,12 @@ func main() {
|
|||
return
|
||||
}
|
||||
totalPrice, totalDuration := sumProcedures(best.Procedures)
|
||||
log.Printf("[TRACE] Responding with match: %q, totalPrice: %d, totalDuration: %d, notes: %q", best.ID, totalPrice, totalDuration, best.Notes)
|
||||
logrus.WithFields(logrus.Fields{
|
||||
"match": best.ID,
|
||||
"total_price": totalPrice,
|
||||
"total_duration": totalDuration,
|
||||
"notes": best.Notes,
|
||||
}).Info("Responding with match")
|
||||
c.JSON(http.StatusOK, ChatResponse{
|
||||
Match: &best.ID,
|
||||
Procedures: best.Procedures,
|
||||
|
|
@ -308,8 +315,13 @@ func main() {
|
|||
|
||||
// logRequest logs incoming chat requests and extracted info
|
||||
func logRequest(req ChatRequest, keywords []string, candidates []Reason, bestID string, err error) {
|
||||
log.Printf("[TRACE] %s | message: %q | keywords: %v | candidates: %v | bestID: %q | err: %v",
|
||||
time.Now().Format(time.RFC3339), req.Message, keywords, getCandidateIDs(candidates), bestID, err)
|
||||
logrus.WithFields(logrus.Fields{
|
||||
"message": req.Message,
|
||||
"keywords": keywords,
|
||||
"candidates": getCandidateIDs(candidates),
|
||||
"bestID": bestID,
|
||||
"err": err,
|
||||
}).Info("Chat request trace")
|
||||
}
|
||||
|
||||
func getCandidateIDs(candidates []Reason) []string {
|
||||
|
|
|
|||
Loading…
Reference in New Issue