Skip to content

Commit b7beb0f

Browse files
author
Eric Lee
authored
[Prometheus Remote Write Exporter for Cortex] Add Enhancements and Fixes (#326)
* Add default quantiles, update config tests, and add quantile tests * Change sendRequest test to use non-empty request and verify the payload * Refactor createLabelSet to use label.KeyValue instead of strings * Refactor ConvertToTimeSeries to add the correct labels for histogram and distribution timeseries * Change createTimeSeries to use specified NumberKind and update conversion functions * Remove validCheckpointSet test * Change mock time to milliseconds for conversion tests * Fix error where results in TestConvertToTimeSeries weren't being compared * Update convertFromSum, convertFromLastValue tests to use multiple values * Add tests for quantiles and distributions in utils module * Update docker-compose and reduce sleep time in main.go for example project * Fix docker-compose to pass CI test * Run make precommit * Update default Config quantiles * Update tests to match new quantile defaults * Run make precommit
1 parent 9a032d8 commit b7beb0f

12 files changed

+390
-148
lines changed

exporters/metric/cortex/config.go

+15
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,9 @@ var (
4141
// ErrNoBasicAuthPassword occurs when no password or password file was provided for
4242
// basic authentication.
4343
ErrNoBasicAuthPassword = fmt.Errorf("no password or password file provided for basic authentication")
44+
45+
// ErrInvalidQuantiles occurs when the supplied quantiles are not between 0 and 1.
46+
ErrInvalidQuantiles = fmt.Errorf("cannot have quantiles that are less than 0 or greater than 1")
4447
)
4548

4649
// Config contains properties the Exporter uses to export metrics data to Cortex.
@@ -86,6 +89,15 @@ func (c *Config) Validate() error {
8689
return ErrTwoBearerTokens
8790
}
8891

92+
// Verify that provided quantiles are between 0 and 1.
93+
if c.Quantiles != nil {
94+
for _, quantile := range c.Quantiles {
95+
if quantile < 0 || quantile > 1 {
96+
return ErrInvalidQuantiles
97+
}
98+
}
99+
}
100+
89101
// Add default values for missing properties.
90102
if c.Endpoint == "" {
91103
c.Endpoint = "/api/prom/push"
@@ -97,6 +109,9 @@ func (c *Config) Validate() error {
97109
if c.PushInterval == 0 {
98110
c.PushInterval = 10 * time.Second
99111
}
112+
if c.Quantiles == nil {
113+
c.Quantiles = []float64{0.5, 0.9, 0.95, 0.99}
114+
}
100115

101116
return nil
102117
}

exporters/metric/cortex/config_data_test.go

+32-2
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@ var validatedStandardConfig = cortex.Config{
2626
Name: "Config",
2727
RemoteTimeout: 30 * time.Second,
2828
PushInterval: 10 * time.Second,
29+
Quantiles: []float64{0.5, 0.9, 0.95, 0.99},
2930
}
3031

3132
// Config struct with default values other than the remote timeout. This is used to verify
@@ -35,6 +36,17 @@ var validatedCustomTimeoutConfig = cortex.Config{
3536
Name: "Config",
3637
RemoteTimeout: 10 * time.Second,
3738
PushInterval: 10 * time.Second,
39+
Quantiles: []float64{0.5, 0.9, 0.95, 0.99},
40+
}
41+
42+
// Config struct with default values other than the quantiles. This is used to verify
43+
// the output of Validate().
44+
var validatedQuantilesConfig = cortex.Config{
45+
Endpoint: "/api/prom/push",
46+
Name: "Config",
47+
RemoteTimeout: 30 * time.Second,
48+
PushInterval: 10 * time.Second,
49+
Quantiles: []float64{0, 0.5, 1},
3850
}
3951

4052
// Example Config struct with a custom remote timeout.
@@ -110,7 +122,7 @@ var exampleTwoAuthConfig = cortex.Config{
110122
BearerToken: "bearer_token",
111123
}
112124

113-
// Example Config struct with no password for basic authentication
125+
// Example Config struct with no password for basic authentication.
114126
var exampleNoPasswordConfig = cortex.Config{
115127
Endpoint: "/api/prom/push",
116128
Name: "Config",
@@ -121,7 +133,7 @@ var exampleNoPasswordConfig = cortex.Config{
121133
},
122134
}
123135

124-
// Example Config struct with no password for basic authentication
136+
// Example Config struct with no password for basic authentication.
125137
var exampleNoUsernameConfig = cortex.Config{
126138
Endpoint: "/api/prom/push",
127139
Name: "Config",
@@ -131,3 +143,21 @@ var exampleNoUsernameConfig = cortex.Config{
131143
"password": "password",
132144
},
133145
}
146+
147+
// Example Config struct with invalid quantiles.
148+
var exampleInvalidQuantilesConfig = cortex.Config{
149+
Endpoint: "/api/prom/push",
150+
Name: "Config",
151+
RemoteTimeout: 30 * time.Second,
152+
PushInterval: 10 * time.Second,
153+
Quantiles: []float64{0, 1, 2, 3},
154+
}
155+
156+
// Example Config struct with valid quantiles.
157+
var exampleValidQuantilesConfig = cortex.Config{
158+
Endpoint: "/api/prom/push",
159+
Name: "Config",
160+
RemoteTimeout: 30 * time.Second,
161+
PushInterval: 10 * time.Second,
162+
Quantiles: []float64{0, 0.5, 1},
163+
}

exporters/metric/cortex/config_test.go

+12
Original file line numberDiff line numberDiff line change
@@ -91,6 +91,18 @@ func TestValidate(t *testing.T) {
9191
expectedConfig: nil,
9292
expectedError: cortex.ErrConflictingAuthorization,
9393
},
94+
{
95+
testName: "Config with Invalid Quantiles",
96+
config: &exampleInvalidQuantilesConfig,
97+
expectedConfig: nil,
98+
expectedError: cortex.ErrInvalidQuantiles,
99+
},
100+
{
101+
testName: "Config with Valid Quantiles",
102+
config: &exampleValidQuantilesConfig,
103+
expectedConfig: &validatedQuantilesConfig,
104+
expectedError: nil,
105+
},
94106
}
95107
for _, test := range tests {
96108
t.Run(test.testName, func(t *testing.T) {

0 commit comments

Comments
 (0)