diff --git a/pkg/services/grpcserver/service.go b/pkg/services/grpcserver/service.go index b820662f5d1..456a26932df 100644 --- a/pkg/services/grpcserver/service.go +++ b/pkg/services/grpcserver/service.go @@ -5,12 +5,12 @@ import ( "fmt" "net" + "github.com/grafana/dskit/instrument" + "github.com/grafana/dskit/middleware" "github.com/grafana/grafana-plugin-sdk-go/backend" grpc_middleware "github.com/grpc-ecosystem/go-grpc-middleware" grpcAuth "github.com/grpc-ecosystem/go-grpc-middleware/auth" "github.com/prometheus/client_golang/prometheus" - "github.com/weaveworks/common/instrument" - "github.com/weaveworks/common/middleware" "google.golang.org/grpc" "google.golang.org/grpc/credentials" diff --git a/pkg/services/ngalert/metrics/historian.go b/pkg/services/ngalert/metrics/historian.go index 9d2febf9890..aba23d9816a 100644 --- a/pkg/services/ngalert/metrics/historian.go +++ b/pkg/services/ngalert/metrics/historian.go @@ -1,9 +1,9 @@ package metrics import ( + "github.com/grafana/dskit/instrument" "github.com/prometheus/client_golang/prometheus" "github.com/prometheus/client_golang/prometheus/promauto" - "github.com/weaveworks/common/instrument" ) type Historian struct { diff --git a/pkg/services/ngalert/state/historian/client.go b/pkg/services/ngalert/state/historian/client.go new file mode 100644 index 00000000000..3bbc4b713d0 --- /dev/null +++ b/pkg/services/ngalert/state/historian/client.go @@ -0,0 +1,67 @@ +package historian + +import ( + "context" + "fmt" + "net/http" + "strconv" + + "github.com/grafana/dskit/instrument" +) + +// Requester executes an HTTP request. +type Requester interface { + Do(req *http.Request) (*http.Response, error) +} + +// TimedClient instruments a request. It implements Requester. +type TimedClient struct { + client Requester + collector instrument.Collector +} + +type contextKey int + +// OperationNameContextKey specifies the operation name location within the context +// for instrumentation. +const OperationNameContextKey contextKey = 0 + +// NewTimedClient creates a Requester that instruments requests on `client`. +func NewTimedClient(client Requester, collector instrument.Collector) *TimedClient { + return &TimedClient{ + client: client, + collector: collector, + } +} + +// Do executes the request. +func (c TimedClient) Do(r *http.Request) (*http.Response, error) { + return TimeRequest(r.Context(), c.operationName(r), c.collector, c.client, r) +} + +func (c TimedClient) operationName(r *http.Request) string { + operation, _ := r.Context().Value(OperationNameContextKey).(string) + if operation == "" { + operation = r.URL.Path + } + return operation +} + +// TimeRequest performs an HTTP client request and records the duration in a histogram. +func TimeRequest(ctx context.Context, operation string, coll instrument.Collector, client Requester, request *http.Request) (*http.Response, error) { + var response *http.Response + doRequest := func(_ context.Context) error { + var err error + response, err = client.Do(request) // nolint:bodyclose + return err + } + toStatusCode := func(err error) string { + if err == nil { + return strconv.Itoa(response.StatusCode) + } + return "error" + } + err := instrument.CollectedRequest(ctx, fmt.Sprintf("%s %s", request.Method, operation), + coll, toStatusCode, doRequest) + return response, err +} diff --git a/pkg/services/ngalert/state/historian/client_test.go b/pkg/services/ngalert/state/historian/client_test.go new file mode 100644 index 00000000000..3538a6c1733 --- /dev/null +++ b/pkg/services/ngalert/state/historian/client_test.go @@ -0,0 +1,29 @@ +package historian + +import ( + "context" + "net/http" + "testing" + + "github.com/stretchr/testify/assert" +) + +func TestTimedClient_operationName(t *testing.T) { + r, err := http.NewRequest("GET", "https://weave.test", nil) + assert.NoError(t, err) + + r = r.WithContext(context.WithValue(context.Background(), OperationNameContextKey, "opp")) + c := NewTimedClient(http.DefaultClient, nil) + + assert.Equal(t, "opp", c.operationName(r)) +} + +func TestTimedClient_operationName_Default(t *testing.T) { + r, err := http.NewRequest("GET", "https://weave.test/you/know/me", nil) + assert.NoError(t, err) + + r = r.WithContext(context.Background()) + c := NewTimedClient(http.DefaultClient, nil) + + assert.Equal(t, "/you/know/me", c.operationName(r)) +} diff --git a/pkg/services/ngalert/state/historian/loki.go b/pkg/services/ngalert/state/historian/loki.go index 5275531e806..00556adfec5 100644 --- a/pkg/services/ngalert/state/historian/loki.go +++ b/pkg/services/ngalert/state/historian/loki.go @@ -10,7 +10,6 @@ import ( "github.com/benbjohnson/clock" "github.com/grafana/grafana-plugin-sdk-go/data" - "github.com/weaveworks/common/http/client" "go.opentelemetry.io/otel/trace" "github.com/grafana/grafana/pkg/components/simplejson" @@ -55,7 +54,7 @@ type RemoteLokiBackend struct { log log.Logger } -func NewRemoteLokiBackend(cfg LokiConfig, req client.Requester, metrics *metrics.Historian) *RemoteLokiBackend { +func NewRemoteLokiBackend(cfg LokiConfig, req Requester, metrics *metrics.Historian) *RemoteLokiBackend { logger := log.New("ngalert.state.historian", "backend", "loki") return &RemoteLokiBackend{ client: NewLokiClient(cfg, req, metrics, logger), diff --git a/pkg/services/ngalert/state/historian/loki_http.go b/pkg/services/ngalert/state/historian/loki_http.go index 003904e9871..8f51d315291 100644 --- a/pkg/services/ngalert/state/historian/loki_http.go +++ b/pkg/services/ngalert/state/historian/loki_http.go @@ -14,13 +14,12 @@ import ( "github.com/grafana/grafana/pkg/infra/log" "github.com/grafana/grafana/pkg/services/ngalert/metrics" "github.com/grafana/grafana/pkg/setting" - "github.com/weaveworks/common/http/client" ) const defaultPageSize = 1000 const maximumPageSize = 5000 -func NewRequester() client.Requester { +func NewRequester() Requester { return &http.Client{} } @@ -80,7 +79,7 @@ func NewLokiConfig(cfg setting.UnifiedAlertingStateHistorySettings) (LokiConfig, } type HttpLokiClient struct { - client client.Requester + client Requester encoder encoder cfg LokiConfig metrics *metrics.Historian @@ -101,8 +100,8 @@ const ( NeqRegEx Operator = "!~" ) -func NewLokiClient(cfg LokiConfig, req client.Requester, metrics *metrics.Historian, logger log.Logger) *HttpLokiClient { - tc := client.NewTimedClient(req, metrics.WriteDuration) +func NewLokiClient(cfg LokiConfig, req Requester, metrics *metrics.Historian, logger log.Logger) *HttpLokiClient { + tc := NewTimedClient(req, metrics.WriteDuration) return &HttpLokiClient{ client: tc, encoder: cfg.Encoder, diff --git a/pkg/services/ngalert/state/historian/loki_http_test.go b/pkg/services/ngalert/state/historian/loki_http_test.go index 764f9e61f82..2f7b7bc502f 100644 --- a/pkg/services/ngalert/state/historian/loki_http_test.go +++ b/pkg/services/ngalert/state/historian/loki_http_test.go @@ -15,7 +15,6 @@ import ( "github.com/grafana/grafana/pkg/setting" "github.com/prometheus/client_golang/prometheus" "github.com/stretchr/testify/require" - "github.com/weaveworks/common/http/client" "github.com/grafana/grafana/pkg/infra/log" ) @@ -338,7 +337,7 @@ func TestStream(t *testing.T) { }) } -func createTestLokiClient(req client.Requester) *HttpLokiClient { +func createTestLokiClient(req Requester) *HttpLokiClient { url, _ := url.Parse("http://some.url") cfg := LokiConfig{ WritePathURL: url, diff --git a/pkg/services/ngalert/state/historian/loki_test.go b/pkg/services/ngalert/state/historian/loki_test.go index 02971c8c0bb..25c29e0fb24 100644 --- a/pkg/services/ngalert/state/historian/loki_test.go +++ b/pkg/services/ngalert/state/historian/loki_test.go @@ -21,7 +21,6 @@ import ( "github.com/prometheus/client_golang/prometheus" "github.com/prometheus/client_golang/prometheus/testutil" "github.com/stretchr/testify/require" - "github.com/weaveworks/common/http/client" ) func TestRemoteLokiBackend(t *testing.T) { @@ -504,7 +503,7 @@ grafana_alerting_state_history_writes_total{backend="loki",org="1"} 2 }) } -func createTestLokiBackend(req client.Requester, met *metrics.Historian) *RemoteLokiBackend { +func createTestLokiBackend(req Requester, met *metrics.Historian) *RemoteLokiBackend { url, _ := url.Parse("http://some.url") cfg := LokiConfig{ WritePathURL: url,