-
Notifications
You must be signed in to change notification settings - Fork 4.3k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Prometheus support on v1/sys/metrics endpoint (#5308)
* initial commit for prometheus and sys/metrics support * Throw an error if prometheusRetentionTime is 0,add prometheus in devmode * return when format=prometheus is used and prom is disable * parse prometheus_retention_time from string instead of int * Initialize config.Telemetry if nil * address PR issues * add sys/metrics framework.Path in a factory * Apply requiredMountTable entries's MountConfig to existing core table * address pr comments * enable prometheus sink by default * Move Metric-related code in a separate metricsutil helper
- Loading branch information
1 parent
9408c3b
commit 5dd50ef
Showing
14 changed files
with
1,529 additions
and
17 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,104 @@ | ||
package metricsutil | ||
|
||
import ( | ||
"bytes" | ||
"encoding/json" | ||
"fmt" | ||
"github.com/armon/go-metrics" | ||
"github.com/hashicorp/vault/logical" | ||
"github.com/prometheus/client_golang/prometheus" | ||
"github.com/prometheus/common/expfmt" | ||
"strings" | ||
) | ||
|
||
const ( | ||
OpenMetricsMIMEType = "application/openmetrics-text" | ||
) | ||
|
||
const ( | ||
PrometheusMetricFormat = "prometheus" | ||
) | ||
|
||
type MetricsHelper struct { | ||
inMemSink *metrics.InmemSink | ||
PrometheusEnabled bool | ||
} | ||
|
||
func NewMetricsHelper(inMem *metrics.InmemSink, enablePrometheus bool) *MetricsHelper{ | ||
return &MetricsHelper{inMem, enablePrometheus} | ||
} | ||
|
||
func FormatFromRequest(req *logical.Request) (string) { | ||
acceptHeaders := req.Headers["Accept"] | ||
if len(acceptHeaders) > 0 { | ||
acceptHeader := acceptHeaders[0] | ||
if strings.HasPrefix(acceptHeader, OpenMetricsMIMEType) { | ||
return "prometheus" | ||
} | ||
} | ||
return "" | ||
} | ||
|
||
func (m *MetricsHelper) ResponseForFormat(format string) (*logical.Response, error) { | ||
switch format { | ||
case PrometheusMetricFormat: | ||
return m.PrometheusResponse() | ||
case "": | ||
return m.GenericResponse() | ||
default: | ||
return nil, fmt.Errorf("metric response format \"%s\" unknown", format) | ||
} | ||
} | ||
|
||
func (m *MetricsHelper) PrometheusResponse() (*logical.Response, error) { | ||
if !m.PrometheusEnabled { | ||
return &logical.Response{ | ||
Data: map[string]interface{}{ | ||
logical.HTTPContentType: "text/plain", | ||
logical.HTTPRawBody: "prometheus is not enabled", | ||
logical.HTTPStatusCode: 400, | ||
}, | ||
}, nil | ||
} | ||
metricsFamilies, err := prometheus.DefaultGatherer.Gather() | ||
if err != nil && len(metricsFamilies) == 0 { | ||
return nil, fmt.Errorf("no prometheus metrics could be decoded: %s", err) | ||
} | ||
|
||
// Initialize a byte buffer. | ||
buf := &bytes.Buffer{} | ||
defer buf.Reset() | ||
|
||
e := expfmt.NewEncoder(buf, expfmt.FmtText) | ||
for _, mf := range metricsFamilies { | ||
err := e.Encode(mf) | ||
if err != nil { | ||
return nil, fmt.Errorf("error during the encoding of metrics: %s", err) | ||
} | ||
} | ||
return &logical.Response{ | ||
Data: map[string]interface{}{ | ||
logical.HTTPContentType: string(expfmt.FmtText), | ||
logical.HTTPRawBody: buf.Bytes(), | ||
logical.HTTPStatusCode: 200, | ||
}, | ||
}, nil | ||
} | ||
|
||
func (m *MetricsHelper) GenericResponse() (*logical.Response, error) { | ||
summary, err := m.inMemSink.DisplayMetrics(nil,nil) | ||
if err != nil { | ||
return nil, fmt.Errorf("error while fetching the in-memory metrics: %s", err) | ||
} | ||
content, err := json.Marshal(summary) | ||
if err != nil { | ||
return nil, fmt.Errorf("error while marshalling the in-memory metrics: %s", err) | ||
} | ||
return &logical.Response{ | ||
Data: map[string]interface{}{ | ||
logical.HTTPContentType: "application/json", | ||
logical.HTTPRawBody: content, | ||
logical.HTTPStatusCode: 200, | ||
}, | ||
}, nil | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.