very rudimentary impl
This commit is contained in:
105
llmproxymetrics.go
Normal file
105
llmproxymetrics.go
Normal file
@@ -0,0 +1,105 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"log"
|
||||
"net/http"
|
||||
"net/http/httptest"
|
||||
"net/http/httputil"
|
||||
"net/url"
|
||||
"strconv"
|
||||
"time"
|
||||
|
||||
"github.com/caarlos0/env/v11"
|
||||
)
|
||||
|
||||
var cfg config
|
||||
|
||||
type config struct {
|
||||
BaseURL string `env:"BASE_URL"`
|
||||
Port int `env:"PORT"`
|
||||
}
|
||||
|
||||
func createProxy(target *url.URL) func(http.ResponseWriter, *http.Request) {
|
||||
return func(w http.ResponseWriter, r *http.Request) {
|
||||
r.Host = target.Host
|
||||
r.URL.Scheme = target.Scheme
|
||||
r.URL.Host = target.Host
|
||||
|
||||
lrw := &LoggingResponseWriter{ResponseWriter: w, body: new(bytes.Buffer)}
|
||||
proxy := httputil.NewSingleHostReverseProxy(target)
|
||||
|
||||
startTime := time.Now()
|
||||
recorder := httptest.NewRecorder()
|
||||
proxy.ServeHTTP(recorder, r)
|
||||
|
||||
responseBody := recorder.Body.Bytes()
|
||||
|
||||
var jsonResponse map[string]interface{}
|
||||
err := json.Unmarshal(responseBody, &jsonResponse)
|
||||
if err != nil {
|
||||
log.Printf("Error unmarshalling JSON response: %v", err)
|
||||
lrw.Write(responseBody)
|
||||
return
|
||||
}
|
||||
|
||||
// Add your metrics metadata here
|
||||
jsonResponse["metrics"] = map[string]interface{}{
|
||||
"requestPath": r.URL.Path,
|
||||
"statusCode": recorder.Code,
|
||||
"responseTime": time.Since(startTime).Milliseconds(),
|
||||
// Add more metrics as needed
|
||||
}
|
||||
|
||||
modifiedResponseBody, err := json.Marshal(jsonResponse)
|
||||
if err != nil {
|
||||
log.Printf("Error marshalling modified JSON response: %v", err)
|
||||
lrw.Write(responseBody)
|
||||
return
|
||||
}
|
||||
|
||||
for name, values := range recorder.Header() {
|
||||
for _, value := range values {
|
||||
w.Header().Add(name, value)
|
||||
}
|
||||
}
|
||||
|
||||
w.WriteHeader(recorder.Code)
|
||||
lrw.Write(modifiedResponseBody)
|
||||
|
||||
log.Printf("Response with metrics: %s", lrw.Body())
|
||||
}
|
||||
}
|
||||
|
||||
type LoggingResponseWriter struct {
|
||||
http.ResponseWriter
|
||||
body *bytes.Buffer
|
||||
}
|
||||
|
||||
func (lrw *LoggingResponseWriter) Write(b []byte) (int, error) {
|
||||
lrw.body.Write(b)
|
||||
return lrw.ResponseWriter.Write(b)
|
||||
}
|
||||
|
||||
func (lrw *LoggingResponseWriter) Body() string {
|
||||
return lrw.body.String()
|
||||
}
|
||||
|
||||
func main() {
|
||||
env.Parse(&cfg)
|
||||
|
||||
targetURL, err := url.Parse(cfg.BaseURL)
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
|
||||
http.HandleFunc("/", createProxy(targetURL))
|
||||
|
||||
log.Printf("Starting proxy server on :%s", strconv.Itoa(cfg.Port))
|
||||
err = http.ListenAndServe(fmt.Sprintf(":%s", strconv.Itoa(cfg.Port)), nil)
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user