mirror of
https://github.com/prometheus/prometheus.git
synced 2024-11-09 23:24:05 -08:00
Query Log: Add source IP from console queries (#6593)
* Query Log: Add source IP from console queries Signed-off-by: Julien Pivotto <roidelapluie@inuits.eu>
This commit is contained in:
parent
1e64d757f7
commit
e7f7b6a06f
50
util/httputil/context.go
Normal file
50
util/httputil/context.go
Normal file
|
@ -0,0 +1,50 @@
|
|||
// Copyright 2020 The Prometheus Authors
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
package httputil
|
||||
|
||||
import (
|
||||
"context"
|
||||
"net"
|
||||
"net/http"
|
||||
|
||||
"github.com/prometheus/prometheus/promql"
|
||||
)
|
||||
|
||||
type ctxParam int
|
||||
|
||||
var pathParam ctxParam
|
||||
|
||||
// ContextWithPath returns a new context with the given path to be used later
|
||||
// when logging the query.
|
||||
func ContextWithPath(ctx context.Context, path string) context.Context {
|
||||
return context.WithValue(ctx, pathParam, path)
|
||||
}
|
||||
|
||||
// ContextFromRequest returns a new context from a requests with identifiers of
|
||||
// the request to be used later when logging the query.
|
||||
func ContextFromRequest(ctx context.Context, r *http.Request) (context.Context, error) {
|
||||
ip, _, err := net.SplitHostPort(r.RemoteAddr)
|
||||
if err != nil {
|
||||
return ctx, err
|
||||
}
|
||||
var path string
|
||||
if v := ctx.Value(pathParam); v != nil {
|
||||
path = v.(string)
|
||||
}
|
||||
return promql.NewOriginContext(ctx, map[string]string{
|
||||
"clientIP": ip,
|
||||
"method": r.Method,
|
||||
"path": path,
|
||||
}), nil
|
||||
}
|
|
@ -18,7 +18,6 @@ import (
|
|||
"fmt"
|
||||
"math"
|
||||
"math/rand"
|
||||
"net"
|
||||
"net/http"
|
||||
"net/url"
|
||||
"os"
|
||||
|
@ -342,7 +341,7 @@ func (api *API) query(r *http.Request) apiFuncResult {
|
|||
return apiFuncResult{nil, &apiError{errorBadData, err}, nil, nil}
|
||||
}
|
||||
|
||||
ctx, err = contextFromRequest(ctx, r)
|
||||
ctx, err = httputil.ContextFromRequest(ctx, r)
|
||||
if err != nil {
|
||||
return apiFuncResult{nil, returnAPIError(err), nil, nil}
|
||||
}
|
||||
|
@ -417,7 +416,7 @@ func (api *API) queryRange(r *http.Request) apiFuncResult {
|
|||
return apiFuncResult{nil, &apiError{errorBadData, err}, nil, nil}
|
||||
}
|
||||
|
||||
ctx, err = contextFromRequest(ctx, r)
|
||||
ctx, err = httputil.ContextFromRequest(ctx, r)
|
||||
if err != nil {
|
||||
return apiFuncResult{nil, returnAPIError(err), nil, nil}
|
||||
}
|
||||
|
@ -1480,11 +1479,3 @@ func marshalPointJSON(ptr unsafe.Pointer, stream *jsoniter.Stream) {
|
|||
func marshalPointJSONIsEmpty(ptr unsafe.Pointer) bool {
|
||||
return false
|
||||
}
|
||||
|
||||
func contextFromRequest(ctx context.Context, r *http.Request) (context.Context, error) {
|
||||
ip, _, err := net.SplitHostPort(r.RemoteAddr)
|
||||
if err != nil {
|
||||
return ctx, err
|
||||
}
|
||||
return promql.NewOriginContext(ctx, map[string]string{"clientIP": ip}), nil
|
||||
}
|
||||
|
|
39
web/web.go
39
web/web.go
|
@ -253,7 +253,11 @@ func New(logger log.Logger, o *Options) *Handler {
|
|||
}
|
||||
|
||||
m := newMetrics(o.Registerer)
|
||||
router := route.New().WithInstrumentation(m.instrumentHandler)
|
||||
router := route.New().
|
||||
WithInstrumentation(combineInstrumentations(
|
||||
m.instrumentHandler,
|
||||
setPathWithPrefix(""),
|
||||
))
|
||||
|
||||
cwd, err := os.Getwd()
|
||||
if err != nil {
|
||||
|
@ -542,13 +546,17 @@ func (h *Handler) Run(ctx context.Context) error {
|
|||
mux := http.NewServeMux()
|
||||
mux.Handle("/", h.router)
|
||||
|
||||
av1 := route.New().WithInstrumentation(h.metrics.instrumentHandlerWithPrefix("/api/v1"))
|
||||
h.apiV1.Register(av1)
|
||||
apiPath := "/api"
|
||||
if h.options.RoutePrefix != "/" {
|
||||
apiPath = h.options.RoutePrefix + apiPath
|
||||
level.Info(h.logger).Log("msg", "router prefix", "prefix", h.options.RoutePrefix)
|
||||
}
|
||||
av1 := route.New().
|
||||
WithInstrumentation(combineInstrumentations(
|
||||
h.metrics.instrumentHandlerWithPrefix("/api/v1"),
|
||||
setPathWithPrefix(apiPath+"/v1"),
|
||||
))
|
||||
h.apiV1.Register(av1)
|
||||
|
||||
mux.Handle(apiPath+"/v1/", http.StripPrefix(apiPath+"/v1", av1))
|
||||
|
||||
|
@ -643,6 +651,12 @@ func (h *Handler) consoles(w http.ResponseWriter, r *http.Request) {
|
|||
return
|
||||
}
|
||||
|
||||
ctx, err = httputil.ContextFromRequest(ctx, r)
|
||||
if err != nil {
|
||||
http.Error(w, err.Error(), http.StatusInternalServerError)
|
||||
return
|
||||
}
|
||||
|
||||
// Provide URL parameters as a map for easy use. Advanced users may have need for
|
||||
// parameters beyond the first, so provide RawParams.
|
||||
rawParams, err := url.ParseQuery(r.URL.RawQuery)
|
||||
|
@ -685,7 +699,7 @@ func (h *Handler) consoles(w http.ResponseWriter, r *http.Request) {
|
|||
}
|
||||
|
||||
tmpl := template.NewTemplateExpander(
|
||||
h.context,
|
||||
ctx,
|
||||
strings.Join(append(defs, string(text)), ""),
|
||||
"__console_"+name,
|
||||
data,
|
||||
|
@ -1103,3 +1117,20 @@ type AlertByStateCount struct {
|
|||
Pending int32
|
||||
Firing int32
|
||||
}
|
||||
|
||||
func combineInstrumentations(fs ...func(handlerName string, handler http.HandlerFunc) http.HandlerFunc) func(string, http.HandlerFunc) http.HandlerFunc {
|
||||
return func(handlerName string, handler http.HandlerFunc) http.HandlerFunc {
|
||||
for _, f := range fs {
|
||||
handler = f(handlerName, handler)
|
||||
}
|
||||
return handler
|
||||
}
|
||||
}
|
||||
|
||||
func setPathWithPrefix(prefix string) func(handlerName string, handler http.HandlerFunc) http.HandlerFunc {
|
||||
return func(handlerName string, handler http.HandlerFunc) http.HandlerFunc {
|
||||
return func(w http.ResponseWriter, r *http.Request) {
|
||||
handler(w, r.WithContext(httputil.ContextWithPath(r.Context(), prefix+r.URL.Path)))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue