Add SDK version to cookie banner logs via middleware
Extract X-SDK-Version from request headers in a dedicated middleware and store it in context. All ErrorCtx calls in the cookie banner handler now include the sdk_version field. Signed-off-by: Émile Ré <emile@getprobo.com>
This commit is contained in:
@@ -54,6 +54,7 @@ func NewMux(
|
|||||||
|
|
||||||
r := chi.NewMux()
|
r := chi.NewMux()
|
||||||
r.Route("/{bannerID}", func(r chi.Router) {
|
r.Route("/{bannerID}", func(r chi.Router) {
|
||||||
|
r.Use(newSDKVersionMiddleware())
|
||||||
r.Use(newCORSMiddleware(logger, cookieBannerSvc))
|
r.Use(newCORSMiddleware(logger, cookieBannerSvc))
|
||||||
r.Get("/config", h.handleGetConfig)
|
r.Get("/config", h.handleGetConfig)
|
||||||
r.Get("/consents/{visitorID}", h.handleGetConsent)
|
r.Get("/consents/{visitorID}", h.handleGetConsent)
|
||||||
@@ -73,7 +74,7 @@ func (h *Handler) handleGetConfig(w http.ResponseWriter, r *http.Request) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
lang := r.URL.Query().Get("lang")
|
lang := r.URL.Query().Get("lang")
|
||||||
sdkVersion := r.Header.Get("X-SDK-Version")
|
sdkVersion := sdkVersionFromContext(r.Context())
|
||||||
cc := h.resolveCountryCode(r)
|
cc := h.resolveCountryCode(r)
|
||||||
|
|
||||||
var regulation cookiebanner.Regulation
|
var regulation cookiebanner.Regulation
|
||||||
@@ -91,7 +92,7 @@ func (h *Handler) handleGetConfig(w http.ResponseWriter, r *http.Request) {
|
|||||||
jsonutil.RenderNotFound(w, fmt.Errorf("no published version"))
|
jsonutil.RenderNotFound(w, fmt.Errorf("no published version"))
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
h.logger.ErrorCtx(r.Context(), "cannot get banner config", log.Error(err))
|
h.logger.ErrorCtx(r.Context(), "cannot get banner config", log.Error(err), log.String("sdk_version", sdkVersion))
|
||||||
jsonutil.RenderInternalServerError(w)
|
jsonutil.RenderInternalServerError(w)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
@@ -104,7 +105,12 @@ func (h *Handler) resolveCountryCode(r *http.Request) *coredata.CountryCode {
|
|||||||
|
|
||||||
cc, err := h.geolocSvc.LookupCountry(r.Context(), ip)
|
cc, err := h.geolocSvc.LookupCountry(r.Context(), ip)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
h.logger.ErrorCtx(r.Context(), "cannot resolve country for IP", log.Error(err))
|
h.logger.ErrorCtx(
|
||||||
|
r.Context(),
|
||||||
|
"cannot resolve country for IP",
|
||||||
|
log.Error(err),
|
||||||
|
log.String("sdk_version", sdkVersionFromContext(r.Context())),
|
||||||
|
)
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -138,7 +144,12 @@ func (h *Handler) handleGetConsent(w http.ResponseWriter, r *http.Request) {
|
|||||||
jsonutil.RenderNotFound(w, fmt.Errorf("consent not found"))
|
jsonutil.RenderNotFound(w, fmt.Errorf("consent not found"))
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
h.logger.ErrorCtx(r.Context(), "cannot get visitor consent", log.Error(err))
|
h.logger.ErrorCtx(
|
||||||
|
r.Context(),
|
||||||
|
"cannot get visitor consent",
|
||||||
|
log.Error(err),
|
||||||
|
log.String("sdk_version", sdkVersionFromContext(r.Context())),
|
||||||
|
)
|
||||||
jsonutil.RenderInternalServerError(w)
|
jsonutil.RenderInternalServerError(w)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
@@ -177,7 +188,7 @@ func (h *Handler) handlePostConsent(w http.ResponseWriter, r *http.Request) {
|
|||||||
|
|
||||||
ip := clientip.Extract(r)
|
ip := clientip.Extract(r)
|
||||||
ua := r.UserAgent()
|
ua := r.UserAgent()
|
||||||
sdkVersion := r.Header.Get("X-SDK-Version")
|
sdkVersion := sdkVersionFromContext(r.Context())
|
||||||
cc := h.resolveCountryCode(r)
|
cc := h.resolveCountryCode(r)
|
||||||
|
|
||||||
var (
|
var (
|
||||||
@@ -214,7 +225,7 @@ func (h *Handler) handlePostConsent(w http.ResponseWriter, r *http.Request) {
|
|||||||
jsonutil.RenderBadRequest(w, fmt.Errorf("invalid version"))
|
jsonutil.RenderBadRequest(w, fmt.Errorf("invalid version"))
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
h.logger.ErrorCtx(r.Context(), "cannot record consent", log.Error(err))
|
h.logger.ErrorCtx(r.Context(), "cannot record consent", log.Error(err), log.String("sdk_version", sdkVersion))
|
||||||
jsonutil.RenderInternalServerError(w)
|
jsonutil.RenderInternalServerError(w)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
@@ -338,7 +349,12 @@ func (h *Handler) handleReportDetectedCookies(w http.ResponseWriter, r *http.Req
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
h.logger.ErrorCtx(r.Context(), "cannot report detected cookies", log.Error(err))
|
h.logger.ErrorCtx(
|
||||||
|
r.Context(),
|
||||||
|
"cannot report detected cookies",
|
||||||
|
log.Error(err),
|
||||||
|
log.String("sdk_version", sdkVersionFromContext(r.Context())),
|
||||||
|
)
|
||||||
jsonutil.RenderInternalServerError(w)
|
jsonutil.RenderInternalServerError(w)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
@@ -503,7 +519,7 @@ func (h *Handler) handleReportDetectedTrackers(w http.ResponseWriter, r *http.Re
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
h.logger.ErrorCtx(r.Context(), "cannot report detected trackers", log.Error(err))
|
h.logger.ErrorCtx(r.Context(), "cannot report detected trackers", log.Error(err), log.String("sdk_version", sdkVersionFromContext(r.Context())))
|
||||||
jsonutil.RenderInternalServerError(w)
|
jsonutil.RenderInternalServerError(w)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|||||||
37
pkg/server/api/cookiebanner/v1/sdk_version_middleware.go
Normal file
37
pkg/server/api/cookiebanner/v1/sdk_version_middleware.go
Normal file
@@ -0,0 +1,37 @@
|
|||||||
|
// Copyright (c) 2026 Probo Inc <hello@getprobo.com>.
|
||||||
|
//
|
||||||
|
// Permission to use, copy, modify, and/or distribute this software for any
|
||||||
|
// purpose with or without fee is hereby granted, provided that the above
|
||||||
|
// copyright notice and this permission notice appear in all copies.
|
||||||
|
//
|
||||||
|
// THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
|
||||||
|
// REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
|
||||||
|
// AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
|
||||||
|
// INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
|
||||||
|
// LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
|
||||||
|
// OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
|
||||||
|
// PERFORMANCE OF THIS SOFTWARE.
|
||||||
|
|
||||||
|
package cookiebanner_v1
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
"net/http"
|
||||||
|
)
|
||||||
|
|
||||||
|
type sdkVersionCtxKey struct{}
|
||||||
|
|
||||||
|
func newSDKVersionMiddleware() func(http.Handler) http.Handler {
|
||||||
|
return func(next http.Handler) http.Handler {
|
||||||
|
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
||||||
|
sdkVersion := r.Header.Get("X-SDK-Version")
|
||||||
|
ctx := context.WithValue(r.Context(), sdkVersionCtxKey{}, sdkVersion)
|
||||||
|
next.ServeHTTP(w, r.WithContext(ctx))
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func sdkVersionFromContext(ctx context.Context) string {
|
||||||
|
v, _ := ctx.Value(sdkVersionCtxKey{}).(string)
|
||||||
|
return v
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user