Add context to throughout the project and update logging (#2209)

propagate context from all the API calls and log request ID, account ID and peer ID

---------

Co-authored-by: Zoltan Papp <zoltan.pmail@gmail.com>
This commit is contained in:
pascal-fischer
2024-07-03 11:33:02 +02:00
committed by GitHub
co-authored by Zoltan Papp
parent 7cb81f1d70
commit 765aba2c1c
127 changed files with 2936 additions and 2642 deletions
+6 -6
View File
@@ -22,7 +22,7 @@ const defaultEndpoint = "/metrics"
type MockAppMetrics struct {
GetMeterFunc func() metric2.Meter
CloseFunc func() error
ExposeFunc func(port int, endpoint string) error
ExposeFunc func(ctx context.Context, port int, endpoint string) error
IDPMetricsFunc func() *IDPMetrics
HTTPMiddlewareFunc func() *HTTPMiddleware
GRPCMetricsFunc func() *GRPCMetrics
@@ -47,9 +47,9 @@ func (mock *MockAppMetrics) Close() error {
}
// Expose mocks the Expose function of the AppMetrics interface
func (mock *MockAppMetrics) Expose(port int, endpoint string) error {
func (mock *MockAppMetrics) Expose(ctx context.Context, port int, endpoint string) error {
if mock.ExposeFunc != nil {
return mock.ExposeFunc(port, endpoint)
return mock.ExposeFunc(ctx, port, endpoint)
}
return fmt.Errorf("unimplemented")
}
@@ -98,7 +98,7 @@ func (mock *MockAppMetrics) UpdateChannelMetrics() *UpdateChannelMetrics {
type AppMetrics interface {
GetMeter() metric2.Meter
Close() error
Expose(port int, endpoint string) error
Expose(ctx context.Context, port int, endpoint string) error
IDPMetrics() *IDPMetrics
HTTPMiddleware() *HTTPMiddleware
GRPCMetrics() *GRPCMetrics
@@ -154,7 +154,7 @@ func (appMetrics *defaultAppMetrics) Close() error {
// Expose metrics on a given port and endpoint. If endpoint is empty a defaultEndpoint one will be used.
// Exposes metrics in the Prometheus format https://prometheus.io/
func (appMetrics *defaultAppMetrics) Expose(port int, endpoint string) error {
func (appMetrics *defaultAppMetrics) Expose(ctx context.Context, port int, endpoint string) error {
if endpoint == "" {
endpoint = defaultEndpoint
}
@@ -174,7 +174,7 @@ func (appMetrics *defaultAppMetrics) Expose(port int, endpoint string) error {
}
}()
log.Infof("enabled application metrics and exposing on http://%s", listener.Addr().String())
log.WithContext(ctx).Infof("enabled application metrics and exposing on http://%s", listener.Addr().String())
return nil
}
+17 -16
View File
@@ -3,14 +3,17 @@ package telemetry
import (
"context"
"fmt"
"hash/fnv"
"net/http"
"strings"
"time"
"github.com/google/uuid"
log "github.com/sirupsen/logrus"
"go.opentelemetry.io/otel/attribute"
"go.opentelemetry.io/otel/metric"
"github.com/netbirdio/netbird/formatter"
nbContext "github.com/netbirdio/netbird/management/server/context"
)
const (
@@ -163,8 +166,15 @@ func getResponseCounterKey(endpoint, method string, status int) string {
func (m *HTTPMiddleware) Handler(h http.Handler) http.Handler {
fn := func(rw http.ResponseWriter, r *http.Request) {
reqStart := time.Now()
traceID := hash(fmt.Sprintf("%v", r))
log.Tracef("HTTP request %v: %v %v", traceID, r.Method, r.URL)
//nolint
ctx := context.WithValue(r.Context(), formatter.ExecutionContextKey, formatter.HTTPSource)
reqID := uuid.New().String()
//nolint
ctx = context.WithValue(ctx, nbContext.RequestIDKey, reqID)
log.WithContext(ctx).Tracef("HTTP request %v: %v %v", reqID, r.Method, r.URL)
metricKey := getRequestCounterKey(r.URL.Path, r.Method)
@@ -175,12 +185,12 @@ func (m *HTTPMiddleware) Handler(h http.Handler) http.Handler {
w := WrapResponseWriter(rw)
h.ServeHTTP(w, r)
h.ServeHTTP(w, r.WithContext(ctx))
if w.Status() > 399 {
log.Errorf("HTTP response %v: %v %v status %v", traceID, r.Method, r.URL, w.Status())
log.WithContext(ctx).Errorf("HTTP response %v: %v %v status %v", reqID, r.Method, r.URL, w.Status())
} else {
log.Tracef("HTTP response %v: %v %v status %v", traceID, r.Method, r.URL, w.Status())
log.WithContext(ctx).Tracef("HTTP response %v: %v %v status %v", reqID, r.Method, r.URL, w.Status())
}
metricKey = getResponseCounterKey(r.URL.Path, r.Method, w.Status())
@@ -198,7 +208,7 @@ func (m *HTTPMiddleware) Handler(h http.Handler) http.Handler {
if c, ok := m.httpRequestDurations[durationKey]; ok {
c.Record(m.ctx, reqTook.Milliseconds())
}
log.Debugf("request %s %s took %d ms and finished with status %d", r.Method, r.URL.Path, reqTook.Milliseconds(), w.Status())
log.WithContext(ctx).Debugf("request %s %s took %d ms and finished with status %d", r.Method, r.URL.Path, reqTook.Milliseconds(), w.Status())
if w.Status() == 200 && (r.Method == http.MethodPut || r.Method == http.MethodPost || r.Method == http.MethodDelete) {
opts := metric.WithAttributeSet(attribute.NewSet(attribute.String("type", "write")))
@@ -212,12 +222,3 @@ func (m *HTTPMiddleware) Handler(h http.Handler) http.Handler {
return http.HandlerFunc(fn)
}
func hash(s string) uint32 {
h := fnv.New32a()
_, err := h.Write([]byte(s))
if err != nil {
panic(err)
}
return h.Sum32()
}