Merge 529a894c55
into 869483617b
This commit is contained in:
commit
33d4f56d9c
|
@ -0,0 +1,69 @@
|
||||||
|
# HTTP JSON Plugin
|
||||||
|
|
||||||
|
The httpjson plugin can collect data from remote URLs which respond with JSON. Then it flattens JSON and finds all numeric values, treating them as floats.
|
||||||
|
|
||||||
|
For example, if you have a service called _mycollector_, which has HTTP endpoint for gathering stats http://my.service.com/_stats:
|
||||||
|
|
||||||
|
```
|
||||||
|
[[httpjson.services]]
|
||||||
|
name = "mycollector"
|
||||||
|
|
||||||
|
servers = [
|
||||||
|
"http://my.service.com/_stats"
|
||||||
|
]
|
||||||
|
|
||||||
|
# HTTP method to use (case-sensitive)
|
||||||
|
method = "GET"
|
||||||
|
```
|
||||||
|
|
||||||
|
The name is used as a prefix for the measurements.
|
||||||
|
|
||||||
|
The `method` specifies HTTP method to use for requests.
|
||||||
|
|
||||||
|
You can specify which keys from server response should be considered as tags:
|
||||||
|
|
||||||
|
```
|
||||||
|
[[httpjson.services]]
|
||||||
|
...
|
||||||
|
|
||||||
|
tagKeys = [
|
||||||
|
"role",
|
||||||
|
"version"
|
||||||
|
]
|
||||||
|
```
|
||||||
|
|
||||||
|
**NOTE**: tag values should be strings.
|
||||||
|
|
||||||
|
You can also specify additional request parameters for the service:
|
||||||
|
|
||||||
|
```
|
||||||
|
[[httpjson.services]]
|
||||||
|
...
|
||||||
|
|
||||||
|
[httpjson.services.parameters]
|
||||||
|
event_type = "cpu_spike"
|
||||||
|
threshold = "0.75"
|
||||||
|
|
||||||
|
```
|
||||||
|
|
||||||
|
|
||||||
|
# Sample
|
||||||
|
|
||||||
|
Let's say that we have a service named "mycollector", which responds with:
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"a": 0.5,
|
||||||
|
"b": {
|
||||||
|
"c": "some text",
|
||||||
|
"d": 0.1,
|
||||||
|
"e": 5
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
The collected metrics will be:
|
||||||
|
```
|
||||||
|
httpjson_mycollector_a value=0.5
|
||||||
|
httpjson_mycollector_b_d value=0.1
|
||||||
|
httpjson_mycollector_b_e value=5
|
||||||
|
```
|
|
@ -22,6 +22,7 @@ type Service struct {
|
||||||
Name string
|
Name string
|
||||||
Servers []string
|
Servers []string
|
||||||
Method string
|
Method string
|
||||||
|
TagKeys []string
|
||||||
Parameters map[string]string
|
Parameters map[string]string
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -61,6 +62,12 @@ var sampleConfig = `
|
||||||
# HTTP method to use (case-sensitive)
|
# HTTP method to use (case-sensitive)
|
||||||
method = "GET"
|
method = "GET"
|
||||||
|
|
||||||
|
# List of tag names to extract from server response
|
||||||
|
# tagKeys = [
|
||||||
|
# "my_tag_1",
|
||||||
|
# "my_tag_2"
|
||||||
|
# ]
|
||||||
|
|
||||||
# HTTP parameters (all values must be strings)
|
# HTTP parameters (all values must be strings)
|
||||||
[httpjson.services.parameters]
|
[httpjson.services.parameters]
|
||||||
event_type = "cpu_spike"
|
event_type = "cpu_spike"
|
||||||
|
@ -126,7 +133,7 @@ func (h *HttpJson) gatherServer(acc plugins.Accumulator, service Service, server
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
var jsonOut interface{}
|
var jsonOut map[string]interface{}
|
||||||
if err = json.Unmarshal([]byte(resp), &jsonOut); err != nil {
|
if err = json.Unmarshal([]byte(resp), &jsonOut); err != nil {
|
||||||
return errors.New("Error decoding JSON response")
|
return errors.New("Error decoding JSON response")
|
||||||
}
|
}
|
||||||
|
@ -135,6 +142,14 @@ func (h *HttpJson) gatherServer(acc plugins.Accumulator, service Service, server
|
||||||
"server": serverURL,
|
"server": serverURL,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
for _, tag := range service.TagKeys {
|
||||||
|
switch v := jsonOut[tag].(type) {
|
||||||
|
case string:
|
||||||
|
tags[tag] = v
|
||||||
|
}
|
||||||
|
delete(jsonOut, tag)
|
||||||
|
}
|
||||||
|
|
||||||
processResponse(acc, service.Name, tags, jsonOut)
|
processResponse(acc, service.Name, tags, jsonOut)
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
|
@ -28,6 +28,13 @@ const validJSON = `
|
||||||
}
|
}
|
||||||
}`
|
}`
|
||||||
|
|
||||||
|
const validJSONTags = `
|
||||||
|
{
|
||||||
|
"value": 15,
|
||||||
|
"role": "master",
|
||||||
|
"build": "123"
|
||||||
|
}`
|
||||||
|
|
||||||
const invalidJSON = "I don't think this is JSON"
|
const invalidJSON = "I don't think this is JSON"
|
||||||
|
|
||||||
const empty = ""
|
const empty = ""
|
||||||
|
@ -87,8 +94,8 @@ func genMockHttpJson(response string, statusCode int) *HttpJson {
|
||||||
},
|
},
|
||||||
Service{
|
Service{
|
||||||
Servers: []string{
|
Servers: []string{
|
||||||
"http://server1.example.com/metrics/",
|
"http://server3.example.com/metrics/",
|
||||||
"http://server2.example.com/metrics/",
|
"http://server4.example.com/metrics/",
|
||||||
},
|
},
|
||||||
Name: "other_webapp",
|
Name: "other_webapp",
|
||||||
Method: "POST",
|
Method: "POST",
|
||||||
|
@ -96,6 +103,10 @@ func genMockHttpJson(response string, statusCode int) *HttpJson {
|
||||||
"httpParam1": "12",
|
"httpParam1": "12",
|
||||||
"httpParam2": "the second parameter",
|
"httpParam2": "the second parameter",
|
||||||
},
|
},
|
||||||
|
TagKeys: []string{
|
||||||
|
"role",
|
||||||
|
"build",
|
||||||
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
@ -185,3 +196,28 @@ func TestHttpJsonEmptyResponse(t *testing.T) {
|
||||||
assert.Equal(t, len(strings.Split(err.Error(), "\n")), 4)
|
assert.Equal(t, len(strings.Split(err.Error(), "\n")), 4)
|
||||||
assert.Equal(t, 0, len(acc.Points))
|
assert.Equal(t, 0, len(acc.Points))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Test that the proper values are ignored or collected
|
||||||
|
func TestHttpJson200Tags(t *testing.T) {
|
||||||
|
httpjson := genMockHttpJson(validJSONTags, 200)
|
||||||
|
|
||||||
|
var acc testutil.Accumulator
|
||||||
|
err := httpjson.Gather(&acc)
|
||||||
|
require.NoError(t, err)
|
||||||
|
|
||||||
|
assert.Equal(t, 4, len(acc.Points))
|
||||||
|
|
||||||
|
for _, service := range httpjson.Services {
|
||||||
|
if service.Name == "other_webapp" {
|
||||||
|
for _, srv := range service.Servers {
|
||||||
|
require.NoError(t,
|
||||||
|
acc.ValidateTaggedValue(
|
||||||
|
fmt.Sprintf("%s_value", service.Name),
|
||||||
|
15.0,
|
||||||
|
map[string]string{"server": srv, "role": "master", "build": "123"},
|
||||||
|
),
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
Loading…
Reference in New Issue