Skip to content

Commit

Permalink
GT-127 Add support for Metrics. Deprecate statistics (#440)
Browse files Browse the repository at this point in the history
  • Loading branch information
jwierzbo authored Sep 29, 2022
1 parent e2fe7cb commit c0551eb
Show file tree
Hide file tree
Showing 5 changed files with 123 additions and 0 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
- Add tests to check support for Enterprise Graphs
- Search View v2 (`search-alias`)
- Add Rename View support
- Add support for `Metrics`

## [1.3.3](https://github.com/arangodb/go-driver/tree/v1.3.3) (2022-07-27)
- Fix `lastValue` field type
Expand Down
20 changes: 20 additions & 0 deletions client_server_admin.go
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,26 @@ type ClientServerAdmin interface {
// Shutdown a specific server, optionally removing it from its cluster.
Shutdown(ctx context.Context, removeFromCluster bool) error

// Metrics returns the metrics of the server in Prometheus format.
// List of metrics: https://www.arangodb.com/docs/devel/http/administration-and-monitoring-metrics.html
// You can parse it using Prometheus client:
/*
var parser expfmt.TextParser
metricsProm, err := parser.TextToMetricFamilies(strings.NewReader(string(metrics)))
*/
Metrics(ctx context.Context) ([]byte, error)

// MetricsForSingleServer returns the metrics of the specific server in Prometheus format.
// This parameter 'serverID' is only meaningful on Coordinators.
// List of metrics: https://www.arangodb.com/docs/devel/http/administration-and-monitoring-metrics.html
// You can parse it using Prometheus client:
/*
var parser expfmt.TextParser
metricsProm, err := parser.TextToMetricFamilies(strings.NewReader(string(metrics)))
*/
MetricsForSingleServer(ctx context.Context, serverID string) ([]byte, error)

// Deprecated: Use Metrics instead.
// Statistics queries statistics from a specific server
Statistics(ctx context.Context) (ServerStatistics, error)

Expand Down
35 changes: 35 additions & 0 deletions client_server_admin_impl.go
Original file line number Diff line number Diff line change
Expand Up @@ -142,6 +142,41 @@ func (c *client) Shutdown(ctx context.Context, removeFromCluster bool) error {
return nil
}

// Metrics returns the metrics of the server in Prometheus format.
func (c *client) Metrics(ctx context.Context) ([]byte, error) {
return c.getMetrics(ctx, "")
}

// MetricsForSingleServer returns the metrics of the specific server in Prometheus format.
// This parameter 'serverID' is only meaningful on Coordinators.
func (c *client) MetricsForSingleServer(ctx context.Context, serverID string) ([]byte, error) {
return c.getMetrics(ctx, serverID)
}

// Metrics returns the metrics of the server in Prometheus format.
func (c *client) getMetrics(ctx context.Context, serverID string) ([]byte, error) {
var rawResponse []byte
ctx = WithRawResponse(ctx, &rawResponse)

req, err := c.conn.NewRequest("GET", "_admin/metrics/v2")
if err != nil {
return rawResponse, WithStack(err)
}

if serverID != "" {
req.SetQuery("serverId", serverID)
}

resp, err := c.conn.Do(ctx, req)
if err != nil {
return rawResponse, WithStack(err)
}
if err := resp.CheckStatus(200); err != nil {
return rawResponse, WithStack(err)
}
return rawResponse, nil
}

// Statistics queries statistics from a specific server.
func (c *client) Statistics(ctx context.Context) (ServerStatistics, error) {
req, err := c.conn.NewRequest("GET", "_admin/statistics")
Expand Down
4 changes: 4 additions & 0 deletions http/connection.go
Original file line number Diff line number Diff line change
Expand Up @@ -270,8 +270,10 @@ func (c *httpConnection) Do(ctx context.Context, req driver.Request) (driver.Res
return nil, driver.WithStack(err)
}
var rawResponse *[]byte
useRawResponse := false
if ctx != nil {
if v := ctx.Value(keyRawResponse); v != nil {
useRawResponse = true
if buf, ok := v.(*[]byte); ok {
rawResponse = buf
}
Expand Down Expand Up @@ -310,6 +312,8 @@ func (c *httpConnection) Do(ctx context.Context, req driver.Request) (driver.Res
*rawResponse = body
}
httpResp = &httpJSONResponse{resp: resp, rawResponse: body}
} else if useRawResponse {
httpResp = &httpJSONResponse{resp: resp, rawResponse: body}
} else {
return nil, driver.WithStack(fmt.Errorf("Unsupported content type '%s' with status %d and content '%s'", ct, resp.StatusCode, string(body)))
}
Expand Down
63 changes: 63 additions & 0 deletions test/server_metrics_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
//
// DISCLAIMER
//
// Copyright 2018 ArangoDB GmbH, Cologne, Germany
//
// 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.
//
// Copyright holder is ArangoDB GmbH, Cologne, Germany

package test

import (
"context"
"testing"

"github.com/arangodb/go-driver"

"github.com/stretchr/testify/require"
)

// TestGetServerMetrics tests if Client.Metrics works at all
func TestGetServerMetrics(t *testing.T) {
c := createClientFromEnv(t, true)
ctx := context.Background()
skipBelowVersion(c, "3.8", t)

metrics, err := c.Metrics(ctx)
require.NoError(t, err)
require.Contains(t, string(metrics), "arangodb_client_connection_statistics_total_time")
}

// TestGetServerMetricsForSingleServer tests if Client.MetricsForSingleServer works at all
func TestGetServerMetricsForSingleServer(t *testing.T) {
c := createClientFromEnv(t, true)
ctx := context.Background()
skipBelowVersion(c, "3.8", t)
skipNoCluster(c, t)

cl, err := c.Cluster(ctx)
require.NoError(t, err)

h, err := cl.Health(ctx)
require.NoError(t, err)

for id, sh := range h.Health {
if sh.Role == driver.ServerRoleDBServer || sh.Role == driver.ServerRoleCoordinator {
metrics, err := c.MetricsForSingleServer(ctx, string(id))
require.NoError(t, err)
require.Contains(t, string(metrics), "arangodb_client_connection_statistics_total_time")
require.Contains(t, string(metrics), sh.ShortName)
}
}
}

0 comments on commit c0551eb

Please sign in to comment.