I have a function called LokiLogs which sends logs to the Loki server. I want to add a traceId to the logs that gets passed as a header X-Trace-ID in every API call. Here's the code I have so far:
type StdoutLogger struct {
io.Writer
}
func (l *StdoutLogger) Print(v ...interface{}) {
vv := LogFormatter(v...) //This function is just beautify the log string, it will not affect the functionality
log.Println(vv)
if len(vv.Message) > 0 {
slice := vv.Message[0]
LokiLogs(slice.Sql + " " + slice.SqlMessage)
}
}
func main() {
router := gin.Default()
.
.
db.LogMode(true)
db.SetLogger(&StdoutLogger{os.Stdout})
}
func LokiLogs(msg string) {
v := strconv.FormatInt(time.Now().UnixNano(), 10)
msg = msg + " " + "traceId="
Lokijson := map[string]interface{}{
"streams": []interface{}{
map[string]interface{}{
"stream": map[string]interface{}{
"message": msg,
"client_ip": GetOutboundIP(),
"level": "info",
"job": "Test",
},
"values": []interface{}{
[]interface{}{
string(v),
msg,
},
},
},
},
}
jsonValue, _ := json.Marshal(Lokijson)
url := os.Getenv("LOKI_URL")
resp, err := http.Post(url, "application/json", bytes.NewBuffer(jsonValue))
fmt.Println(resp, err)
}
I have set a traceId header for every API call like this c.Request.Header.Set("X-Trace-ID", traceID) using a log middleware. How can I pass this traceId value to the LokiLogs function so that it can be concatenated to the msg string like this traceId=Some UUID?
It looks like your db.SetLogger is probably from jinzhu/gorm. The Logger interface there doesn't really allow you to pass additional details except through the logger instance, so I think you'd need something a bit like:
type StdoutLogger struct {
io.Writer
TraceID string
}
Then your gin HandlerFunc would need to extract the header from gin.Context using GetHeader, and use that to construct a logger instance specific to that request, something like:
func (s *mystruct) MyHandler(c *gin.Context) {
thisTraceID := c.GetHeader("X-Trace-ID")
...
db.SetLogger(&StdoutLogger{Writer: os.Stdout, TraceID: thisTraceID})
// db.Find/Exec/Save/...
}
and then
func (l *StdoutLogger) Print(v ...interface{}) {
vv := LogFormatter(v...) //This function is just beautify the log string, it will not affect the functionality
log.Println(vv)
if len(vv.Message) > 0 {
slice := vv.Message[0]
LokiLogs(l.TraceID, slice.Sql + " " + slice.SqlMessage)
}
}
func LokiLogs(traceID, msg string) {
...
}
```
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With