Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Httpmetricbeat #4092

Closed
Closed
Show file tree
Hide file tree
Changes from 6 commits
Commits
Show all changes
43 commits
Select commit Hold shift + click to select a range
e97377d
Warn Beats users not to do multiline handling in Logstash
dedemorton Apr 21, 2017
4f061e2
Initial commit http metricbeat module
christiangalsterer Apr 21, 2017
e750f90
Initial commit http metricbeat module
christiangalsterer Apr 21, 2017
1977b33
Add first fields information
christiangalsterer Apr 23, 2017
2242883
Add first fields information
christiangalsterer Apr 23, 2017
c442602
Updated config and docu files.
christiangalsterer Apr 23, 2017
621f763
Fix fmt findings
christiangalsterer Apr 23, 2017
282d81d
Update CONTRIBUTING.md to Golang 1.8.1 (#4094)
ruflin Apr 24, 2017
3efb9db
Allow to overwrite uri in http helper (#4084)
ruflin Apr 24, 2017
856e151
Skip empty events without error (#4087)
ruflin Apr 24, 2017
38e04b4
Fix race in go-metrics adapater (#4098)
Apr 24, 2017
fafe088
Set 10000 field limit also for ES v5 (#4079)
ruflin Apr 24, 2017
4aed040
Merge pull request #4086 from dedemorton/logstash_input_beats_issue#199
dedemorton Apr 24, 2017
2bc0a20
File restructure by providers for add_cloud_metadata (#4088)
athom Apr 25, 2017
de11679
Add perfmon raw counter values calculations (#3972)
martinscholz83 Apr 25, 2017
af60958
Add x-pack monitoring note to kibana/es docs (#4012)
ruflin Apr 25, 2017
5afda3d
Minor enhancements to kubernetes processor (#4068)
exekias Apr 25, 2017
354fdd6
Adding query APIs for metricsets and modules from metricbeat registry…
vjsamuel Apr 25, 2017
ca2e449
Suggest GOPATH in ~/go (#4110)
7AC Apr 25, 2017
aaee997
filebeat: expand double wildcards in prospector (#3980)
7AC Apr 26, 2017
dce6887
Disable default prospector and adjust short configs (#4105)
tsg Apr 26, 2017
a279b5d
Adding goimports support to make check and fmt (#4114)
vjsamuel Apr 26, 2017
7a8bc70
Add rsbeat to communitybeats doc (#4108)
rockybean Apr 26, 2017
7d15bf3
Fix link to the MacOSX SDK tarball (#4120)
tsg Apr 26, 2017
074add2
Fixing nil pointer on prometheus collector when http response is nil …
vjsamuel Apr 27, 2017
bee77ee
Remove duplicate code in glob_watcher_test.go (#4117)
athom Apr 27, 2017
24aed8c
Refactor harvester to send events directly to the spooler (#4070)
ruflin Apr 27, 2017
1344e4f
Support Alibaba Cloud provider for add_cloud_metadata proccessor (#4111)
athom Apr 27, 2017
b9f1b50
Add community beats topic to devguide
dedemorton Apr 28, 2017
6b01fa9
Heartbeat event format (#4091)
Apr 28, 2017
b845687
Add example dashboards using the time series visual builder (#4115)
monicasarbu Apr 28, 2017
ea763e2
Merge pull request #4134 from dedemorton/add_commbeats
dedemorton Apr 28, 2017
946bfd8
Initial commit http metricbeat module
christiangalsterer Apr 21, 2017
92ee85e
Initial commit http metricbeat module
christiangalsterer Apr 21, 2017
81da4f6
Add first fields information
christiangalsterer Apr 23, 2017
2c84adf
Add first fields information
christiangalsterer Apr 23, 2017
521c11c
Updated config and docu files.
christiangalsterer Apr 23, 2017
9d69fd6
Fix fmt findings
christiangalsterer Apr 23, 2017
47a046c
Fixed review findings
christiangalsterer Apr 29, 2017
a3bbadb
Added integration tess
christiangalsterer Apr 30, 2017
494b428
Merge remote-tracking branch 'origin/httpmetricbeat' into httpmetricbeat
christiangalsterer Apr 30, 2017
1fca1b0
Generated docucmentation
christiangalsterer Apr 30, 2017
8eb085f
Updated documentation and added entry to changelog
christiangalsterer May 1, 2017
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
83 changes: 83 additions & 0 deletions metricbeat/docs/fields.asciidoc
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ grouped in the following categories:
* <<exported-fields-elasticsearch>>
* <<exported-fields-golang>>
* <<exported-fields-haproxy>>
* <<exported-fields-http>>
* <<exported-fields-jolokia>>
* <<exported-fields-kafka>>
* <<exported-fields-kibana>>
Expand Down Expand Up @@ -3443,6 +3444,88 @@ type: integer
The average queue time in ms over the last 1024 requests.


[[exported-fields-http]]
== http Fields

http Module



[float]
== http Fields




[float]
== json Fields

json metricset



[float]
== request Fields

HTTP request information



[float]
=== http.json.request.header

type: nested

The HTTP headers sent


[float]
=== http.json.request.method

type: keyword

The HTTP method used


[float]
=== http.json.request.body

type: keyword

The HTTP payload sent


[float]
== response Fields

HTTP response information



[float]
=== http.json.response.header

type: nested

The HTTP headers received


[float]
=== http.json.response.status_code

type: keyword

The HTTP status code


[float]
=== http.json.response.body

type: keyword

The HTTP payload received


[[exported-fields-jolokia]]
== Jolokia Fields

Expand Down
37 changes: 37 additions & 0 deletions metricbeat/docs/modules/http.asciidoc
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
////
This file is generated! See scripts/docs_collector.py
////

[[metricbeat-module-http]]
== http Module

This is the http Module.



[float]
=== Example Configuration

The http module supports the standard configuration options that are described
in <<configuration-metricbeat>>. Here is an example configuration:

[source,yaml]
----
metricbeat.modules:
- module: http
metricsets: ["json"]
enabled: true
period: 10s
hosts: ["localhost"]

----

[float]
=== Metricsets

The following metricsets are available:

* <<metricbeat-metricset-http-json,json>>

include::http/json.asciidoc[]

19 changes: 19 additions & 0 deletions metricbeat/docs/modules/http/json.asciidoc
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
////
This file is generated! See scripts/docs_collector.py
////

[[metricbeat-metricset-http-json]]
include::../../../module/http/json/_meta/docs.asciidoc[]


==== Fields

For a description of each field in the metricset, see the
<<exported-fields-http,exported fields>> section.

Here is an example document generated by this metricset:

[source,json]
----
include::../../../module/http/json/_meta/data.json[]
----
2 changes: 2 additions & 0 deletions metricbeat/docs/modules_list.asciidoc
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ This file is generated! See scripts/docs_collector.py
* <<metricbeat-module-elasticsearch,elasticsearch>>
* <<metricbeat-module-golang,golang>>
* <<metricbeat-module-haproxy,HAProxy>>
* <<metricbeat-module-http,http>>
* <<metricbeat-module-jolokia,Jolokia>>
* <<metricbeat-module-kafka,kafka>>
* <<metricbeat-module-kibana,kibana>>
Expand Down Expand Up @@ -37,6 +38,7 @@ include::modules/dropwizard.asciidoc[]
include::modules/elasticsearch.asciidoc[]
include::modules/golang.asciidoc[]
include::modules/haproxy.asciidoc[]
include::modules/http.asciidoc[]
include::modules/jolokia.asciidoc[]
include::modules/kafka.asciidoc[]
include::modules/kibana.asciidoc[]
Expand Down
2 changes: 2 additions & 0 deletions metricbeat/include/list.go
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,8 @@ import (
_ "github.com/elastic/beats/metricbeat/module/haproxy"
_ "github.com/elastic/beats/metricbeat/module/haproxy/info"
_ "github.com/elastic/beats/metricbeat/module/haproxy/stat"
_ "github.com/elastic/beats/metricbeat/module/http"
_ "github.com/elastic/beats/metricbeat/module/http/json"
_ "github.com/elastic/beats/metricbeat/module/jolokia"
_ "github.com/elastic/beats/metricbeat/module/jolokia/jmx"
_ "github.com/elastic/beats/metricbeat/module/kafka"
Expand Down
8 changes: 8 additions & 0 deletions metricbeat/metricbeat.full.yml
Original file line number Diff line number Diff line change
Expand Up @@ -160,6 +160,14 @@ metricbeat.modules:
period: 10s
hosts: ["tcp://127.0.0.1:14567"]

#-------------------------------- http Module --------------------------------
- module: http
metricsets: ["json"]
enabled: true
period: 10s
hosts: ["localhost"]


#------------------------------- Jolokia Module ------------------------------
- module: jolokia
metricsets: ["jmx"]
Expand Down
6 changes: 6 additions & 0 deletions metricbeat/module/http/_meta/config.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
- module: http
metricsets: ["json"]
enabled: true
period: 10s
hosts: ["localhost"]

4 changes: 4 additions & 0 deletions metricbeat/module/http/_meta/docs.asciidoc
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
== http Module

This is the http Module.

9 changes: 9 additions & 0 deletions metricbeat/module/http/_meta/fields.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
- key: http
title: "http"
description: >
http Module
fields:
- name: http
type: group
description: >
fields:
4 changes: 4 additions & 0 deletions metricbeat/module/http/doc.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
/*
Package http is a Metricbeat module that contains MetricSets.
*/
package http
19 changes: 19 additions & 0 deletions metricbeat/module/http/json/_meta/data.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
{
"@timestamp":"2016-05-23T08:05:34.853Z",
"beat":{
"hostname":"beathost",
"name":"beathost"
},
"metricset":{
"host":"localhost",
"module":"http",
"name":"json",
"rtt":44269
},
"http":{
"json":{
"example": "json"
}
},
"type":"metricsets"
}
3 changes: 3 additions & 0 deletions metricbeat/module/http/json/_meta/docs.asciidoc
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
=== http json MetricSet

This is the json metricset of the module http.
39 changes: 39 additions & 0 deletions metricbeat/module/http/json/_meta/fields.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
- name: json
type: group
description: >
json metricset
fields:
- name: request
type: group
description: >
HTTP request information
fields:
- name: header
type: nested
description: >
The HTTP headers sent
- name: method
type: keyword
description: >
The HTTP method used
- name: body
type: keyword
description: >
The HTTP payload sent
- name: response
type: group
description: >
HTTP response information
fields:
- name: header
type: nested
description: >
The HTTP headers received
- name: status_code
type: keyword
description: >
The HTTP status code
- name: body
type: keyword
description: >
The HTTP payload received
108 changes: 108 additions & 0 deletions metricbeat/module/http/json/json.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,108 @@
package json

import (
"github.com/elastic/beats/libbeat/common"
"github.com/elastic/beats/metricbeat/helper"
"github.com/elastic/beats/metricbeat/mb"
"io/ioutil"
"net/http"
"strings"
)

// init registers the MetricSet with the central registry.
// The New method will be called after the setup of the module and before starting to fetch data
func init() {
if err := mb.Registry.AddMetricSet("http", "json", New); err != nil {
panic(err)
}
}

// MetricSet type defines all fields of the MetricSet
// As a minimum it must inherit the mb.BaseMetricSet fields, but can be extended with
// additional entries. These variables can be used to persist data or configuration between
// multiple fetch calls.
type MetricSet struct {
mb.BaseMetricSet
http *helper.HTTP
headers map[string]string
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In case we do not add these fields (see comment below) to the event, they are probably not needed in the object.

method string
body string
}

// New create a new instance of the MetricSet
// Part of new is also setting up the configuration by processing additional
// configuration entries if needed.
func New(base mb.BaseMetricSet) (mb.MetricSet, error) {

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could you add here a log message like logp.Beta("The http json metricset is in beta.").

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes will do.

config := struct {
Method string `config:"method"`
Body string `config:"body"`
Headers map[string]string `config:"headers"`
}{}

if err := base.Module().UnpackConfig(&config); err != nil {
return nil, err
}

http := helper.NewHTTP(base)
http.SetMethod(config.Method)
http.SetBody([]byte(config.Body))
for key, value := range config.Headers {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

True, saw that as well, but then forgot to change before committing.

http.SetHeader(key, value)
}

return &MetricSet{
BaseMetricSet: base,
http: http,
headers: config.Headers,
method: config.Method,
body: config.Body,
}, nil
}

// Fetch methods implements the data gathering and data conversion to the right format
// It returns the event which is then forward to the output. In case of an error, a
// descriptive error must be returned.
func (m *MetricSet) Fetch() (common.MapStr, error) {

response, err := m.http.FetchResponse()
if err != nil {
return nil, err
}
defer response.Body.Close()

responseBody, err := ioutil.ReadAll(response.Body)
if err != nil {
return nil, err
}

event := common.MapStr{}

event["request"] = common.MapStr{
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

As these are based on the configs set, not sure if we should really add the request to each document. What would be the use case here?

"headers": m.headers,
"method": m.method,
"body": m.body,
}

event["response"] = common.MapStr{
"status_code": response.StatusCode,
"headers": m.getHeaders(response.Header),
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

As status_code and response header will be the same for all http metricsets, I was thinking to add these on the module lever for example under a response namespace. How to do that for example see docker: https://github.com/elastic/beats/blob/master/metricbeat/module/docker/cpu/data.go#L18

That would mean these are always under http.response.*.

I'm not sure if we should enable the headers by default because in the case of json I assume in most use cases people are not too interested in the headers (happy to be convinced otherwise). So I would make it configurable with a config option. As we already have headers in the config file, we could make it response.headers.enabled.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There is definitely room for improvement to move some of the information to the module layer. Idea was to get something working and getting familiar with Metricbeat implementation.
W.r.t if we should add the header I don't see an issue here to always add them

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Happy to merge the PR rater soonish and do improvements on top of it.

For the headers, I probably miss the use case.

"body": responseBody,
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

As this is JSON, don't we need to decode it here?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes definitely.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

One more note on the body: I would probably put the decode json directly on the top level and not into a body namespace.

}

return event, nil
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The json metricset is a dynamic metricset. That means it can be used multiple times with different fields as output. To make sure these fields to not conflict, we need a namespace which can be configure. As an example see here the jmx metricset: https://github.com/elastic/beats/blob/master/metricbeat/module/jolokia/jmx/jmx.go#L93 So event are put into http.namespace.*.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

True, thanks for the hint. Is namespace here the correct concept, or is it to use different document_types?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Namespace is the one to use here. We don't use document type, especially as it will be removed in 6.0

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ok, will make the changes accordingly.

}

func (m *MetricSet) getHeaders(header http.Header) map[string]string {

headers := make(map[string]string)
for k, v := range header {
value := ""
for _, h := range v {
value += h + " ,"
}
value = strings.TrimRight(value, " ,")
headers[k] = value
}
return headers
}