mirror of
https://github.com/k8sgpt-ai/k8sgpt.git
synced 2025-09-19 18:16:09 +00:00
feat: init logging middleware on server mode
Signed-off-by: Matthis Holleville <matthish29@gmail.com>
This commit is contained in:
77
pkg/server/log.go
Normal file
77
pkg/server/log.go
Normal file
@@ -0,0 +1,77 @@
|
|||||||
|
package server
|
||||||
|
|
||||||
|
import (
|
||||||
|
"bytes"
|
||||||
|
"net/http"
|
||||||
|
"time"
|
||||||
|
|
||||||
|
"go.uber.org/zap"
|
||||||
|
)
|
||||||
|
|
||||||
|
type loggingResponseWriter struct {
|
||||||
|
http.ResponseWriter
|
||||||
|
statusCode int
|
||||||
|
buf *bytes.Buffer
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewLoggingResponseWriter(w http.ResponseWriter) *loggingResponseWriter {
|
||||||
|
return &loggingResponseWriter{
|
||||||
|
w,
|
||||||
|
http.StatusOK,
|
||||||
|
&bytes.Buffer{},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (lrw *loggingResponseWriter) WriteHeader(code int) {
|
||||||
|
lrw.statusCode = code
|
||||||
|
lrw.ResponseWriter.WriteHeader(code)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (lrw *loggingResponseWriter) Write(b []byte) (int, error) {
|
||||||
|
return lrw.buf.Write(b)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (lrw *loggingResponseWriter) Flush() {
|
||||||
|
if f, ok := lrw.ResponseWriter.(http.Flusher); ok {
|
||||||
|
f.Flush()
|
||||||
|
}
|
||||||
|
lrw.ResponseWriter.Write(lrw.buf.Bytes())
|
||||||
|
}
|
||||||
|
|
||||||
|
func logRequest(logger *zap.Logger, fields []zap.Field, statusCode int, message string) {
|
||||||
|
if statusCode >= 400 {
|
||||||
|
logger.Error(message, fields...)
|
||||||
|
} else {
|
||||||
|
logger.Info("request completed", fields...)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func loggingMiddleware(next http.Handler) http.Handler {
|
||||||
|
config := zap.NewProductionConfig()
|
||||||
|
config.DisableCaller = true
|
||||||
|
logger, err := config.Build()
|
||||||
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
defer logger.Sync()
|
||||||
|
|
||||||
|
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
||||||
|
lrw := NewLoggingResponseWriter(w)
|
||||||
|
start := time.Now()
|
||||||
|
defer func() {
|
||||||
|
duration := time.Since(start).Milliseconds()
|
||||||
|
fields := []zap.Field{
|
||||||
|
zap.Int64("duration_ms", duration),
|
||||||
|
zap.String("method", r.Method),
|
||||||
|
zap.String("remote_addr", r.RemoteAddr),
|
||||||
|
zap.Int("status_code", lrw.statusCode),
|
||||||
|
zap.String("url", r.URL.Path),
|
||||||
|
}
|
||||||
|
logRequest(logger, fields, lrw.statusCode, lrw.buf.String())
|
||||||
|
}()
|
||||||
|
|
||||||
|
next.ServeHTTP(lrw, r)
|
||||||
|
|
||||||
|
lrw.Flush()
|
||||||
|
})
|
||||||
|
}
|
@@ -51,30 +51,32 @@ func (s *Config) analyzeHandler(w http.ResponseWriter, r *http.Request) {
|
|||||||
config, err := analysis.NewAnalysis(s.Backend, language, []string{}, namespace, nocache, explain)
|
config, err := analysis.NewAnalysis(s.Backend, language, []string{}, namespace, nocache, explain)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
health.Failure++
|
health.Failure++
|
||||||
fmt.Fprintf(w, err.Error())
|
http.Error(w, err.Error(), http.StatusInternalServerError)
|
||||||
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
err = config.RunAnalysis()
|
err = config.RunAnalysis()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
color.Red("Error: %v", err)
|
color.Red("Error: %v", err)
|
||||||
health.Failure++
|
health.Failure++
|
||||||
fmt.Fprintf(w, err.Error())
|
http.Error(w, err.Error(), http.StatusInternalServerError)
|
||||||
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
if explain {
|
if explain {
|
||||||
err := config.GetAIResults(s.Output, anonymize)
|
err := config.GetAIResults(s.Output, anonymize)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
color.Red("Error: %v", err)
|
|
||||||
health.Failure++
|
health.Failure++
|
||||||
fmt.Fprintf(w, err.Error())
|
http.Error(w, err.Error(), http.StatusInternalServerError)
|
||||||
|
return
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
out, err := config.PrintOutput(s.Output)
|
out, err := config.PrintOutput(s.Output)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
color.Red("Error: %v", err)
|
|
||||||
health.Failure++
|
health.Failure++
|
||||||
fmt.Fprintf(w, err.Error())
|
http.Error(w, err.Error(), http.StatusInternalServerError)
|
||||||
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
health.Success++
|
health.Success++
|
||||||
@@ -82,11 +84,12 @@ func (s *Config) analyzeHandler(w http.ResponseWriter, r *http.Request) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (s *Config) Serve() error {
|
func (s *Config) Serve() error {
|
||||||
|
handler := loggingMiddleware(http.DefaultServeMux)
|
||||||
http.Handle("/metrics", promhttp.Handler())
|
http.Handle("/metrics", promhttp.Handler())
|
||||||
http.HandleFunc("/analyze", s.analyzeHandler)
|
http.HandleFunc("/analyze", s.analyzeHandler)
|
||||||
http.HandleFunc("/healthz", s.healthzHandler)
|
http.HandleFunc("/healthz", s.healthzHandler)
|
||||||
color.Green("Starting server on port %s", s.Port)
|
color.Green("Starting server on port %s", s.Port)
|
||||||
err := http.ListenAndServe(":"+s.Port, nil)
|
err := http.ListenAndServe(":"+s.Port, handler)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
fmt.Printf("error starting server: %s\n", err)
|
fmt.Printf("error starting server: %s\n", err)
|
||||||
return err
|
return err
|
||||||
|
Reference in New Issue
Block a user