-
Notifications
You must be signed in to change notification settings - Fork 5.6k
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
adding tomcat plugin #3112
Merged
Merged
adding tomcat plugin #3112
Changes from all commits
Commits
File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,73 @@ | ||
# Tomcat Input Plugin | ||
|
||
The Tomcat plugin collects statistics available from the tomcat manager status page from the `http://<host>/manager/status/all?XML=true URL.` | ||
(`XML=true` will return only xml data). See the [Tomcat documentation](https://tomcat.apache.org/tomcat-9.0-doc/manager-howto.html#Server_Status) for details of these statistics. | ||
|
||
### Configuration: | ||
|
||
```toml | ||
# A Telegraf plugin to collect tomcat metrics. | ||
[[inputs.tomcat]] | ||
# A Tomcat status URI to gather stats. | ||
# Default is "http://127.0.0.1:8080/manager/status/all?XML=true". | ||
url = "http://127.0.0.1:8080/manager/status/all?XML=true" | ||
# Credentials for status URI. | ||
# Default is tomcat/s3cret. | ||
username = "tomcat" | ||
password = "s3cret" | ||
``` | ||
|
||
### Measurements & Fields: | ||
|
||
- tomcat\_jvm\_memory | ||
- free | ||
- total | ||
- max | ||
- tomcat\_jvm\_memorypool | ||
- max\_threads | ||
- current\_thread\_count | ||
- current\_threads\_busy | ||
- max\_time | ||
- processing\_time | ||
- request\_count | ||
- error\_count | ||
- bytes\_received | ||
- bytes\_sent | ||
- tomcat\_connector | ||
- max\_threads | ||
- current\_thread\_count | ||
- current\_thread\_busy | ||
- max\_time | ||
- processing\_time | ||
- request\_count | ||
- error\_count | ||
- bytes\_received | ||
- bytes\_sent | ||
|
||
### Tags: | ||
|
||
- tomcat\_jvm\_memorypool has the following tags: | ||
- name | ||
- type | ||
- tomcat\_connector | ||
- name | ||
|
||
### Sample Queries: | ||
|
||
TODO | ||
|
||
### Example Output: | ||
|
||
``` | ||
$ ./telegraf -config telegraf.conf -input-filter tomcat -test | ||
* Plugin: tomcat, Collection 1 | ||
> tomcat_jvm_memory,host=N8-MBP free=20014352i,max=127729664i,total=41459712i 1474663361000000000 | ||
> tomcat_jvm_memorypool,host=N8-MBP,name=Eden\ Space,type=Heap\ memory committed=11534336i,init=2228224i,max=35258368i,used=1941200i 1474663361000000000 | ||
> tomcat_jvm_memorypool,host=N8-MBP,name=Survivor\ Space,type=Heap\ memory committed=1376256i,init=262144i,max=4390912i,used=1376248i 1474663361000000000 | ||
> tomcat_jvm_memorypool,host=N8-MBP,name=Tenured\ Gen,type=Heap\ memory committed=28549120i,init=5636096i,max=88080384i,used=18127912i 1474663361000000000 | ||
> tomcat_jvm_memorypool,host=N8-MBP,name=Code\ Cache,type=Non-heap\ memory committed=6946816i,init=2555904i,max=251658240i,used=6406528i 1474663361000000000 | ||
> tomcat_jvm_memorypool,host=N8-MBP,name=Compressed\ Class\ Space,type=Non-heap\ memory committed=1966080i,init=0i,max=1073741824i,used=1816120i 1474663361000000000 | ||
> tomcat_jvm_memorypool,host=N8-MBP,name=Metaspace,type=Non-heap\ memory committed=18219008i,init=0i,max=-1i,used=17559376i 1474663361000000000 | ||
> tomcat_connector,host=N8-MBP,name=ajp-bio-8009 bytes_received=0i,bytes_sent=0i,current_thread_count=0i,current_threads_busy=0i,error_count=0i,max_threads=200i,max_time=0i,processing_time=0i,request_count=0i 1474663361000000000 | ||
> tomcat_connector,host=N8-MBP,name=http-bio-8080 bytes_received=0i,bytes_sent=86435i,current_thread_count=10i,current_threads_busy=1i,error_count=2i,max_threads=200i,max_time=167i,processing_time=245i,request_count=15i 1474663361000000000 | ||
``` |
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,176 @@ | ||
package tomcat | ||
|
||
import ( | ||
"encoding/xml" | ||
"fmt" | ||
"io/ioutil" | ||
"net/http" | ||
"net/url" | ||
"strconv" | ||
|
||
"github.com/influxdata/telegraf" | ||
"github.com/influxdata/telegraf/plugins/inputs" | ||
) | ||
|
||
type TomcatStatus struct { | ||
TomcatJvm TomcatJvm `xml:"jvm"` | ||
TomcatConnectors []TomcatConnector `xml:"connector"` | ||
} | ||
|
||
type TomcatJvm struct { | ||
JvmMemory JvmMemoryStat `xml:"memory"` | ||
JvmMemoryPools []JvmMemoryPoolStat `xml:"memorypool"` | ||
} | ||
|
||
type JvmMemoryStat struct { | ||
Free int64 `xml:"free,attr"` | ||
Total int64 `xml:"total,attr"` | ||
Max int64 `xml:"max,attr"` | ||
} | ||
|
||
type JvmMemoryPoolStat struct { | ||
Name string `xml:"name,attr"` | ||
Type string `xml:"type,attr"` | ||
UsageInit int64 `xml:"usageInit,attr"` | ||
UsageCommitted int64 `xml:"usageCommitted,attr"` | ||
UsageMax int64 `xml:"usageMax,attr"` | ||
UsageUsed int64 `xml:"usageUsed,attr"` | ||
} | ||
|
||
type TomcatConnector struct { | ||
Name string `xml:"name,attr"` | ||
ThreadInfo ThreadInfo `xml:"threadInfo"` | ||
RequestInfo RequestInfo `xml:"requestInfo"` | ||
} | ||
|
||
type ThreadInfo struct { | ||
MaxThreads int64 `xml:"maxThreads,attr"` | ||
CurrentThreadCount int64 `xml:"currentThreadCount,attr"` | ||
CurrentThreadsBusy int64 `xml:"currentThreadsBusy,attr"` | ||
} | ||
type RequestInfo struct { | ||
MaxTime int `xml:"maxTime,attr"` | ||
ProcessingTime int `xml:"processingTime,attr"` | ||
RequestCount int `xml:"requestCount,attr"` | ||
ErrorCount int `xml:"errorCount,attr"` | ||
BytesReceived int64 `xml:"bytesReceived,attr"` | ||
BytesSent int64 `xml:"bytesSent,attr"` | ||
} | ||
|
||
type Tomcat struct { | ||
URL string | ||
Username string | ||
Password string | ||
} | ||
|
||
var sampleconfig = ` | ||
## A Tomcat status URI to gather stats. | ||
## Default is "http://127.0.0.1:8080/manager/status/all?XML=true". | ||
url = "http://127.0.0.1:8080/manager/status/all?XML=true" | ||
## Credentials for status URI. | ||
## Default is tomcat/s3cret. | ||
username = "tomcat" | ||
password = "s3cret" | ||
` | ||
|
||
func (s *Tomcat) Description() string { | ||
return "A Telegraf plugin to collect tomcat metrics." | ||
} | ||
|
||
func (s *Tomcat) SampleConfig() string { | ||
return sampleconfig | ||
} | ||
|
||
func (s *Tomcat) Gather(acc telegraf.Accumulator) error { | ||
|
||
if s.URL == "" { | ||
s.URL = "http://127.0.0.1:8080/manager/status/all?XML=true" | ||
} | ||
|
||
if s.Username == "" { | ||
s.Username = "tomcat" | ||
} | ||
|
||
if s.Password == "" { | ||
s.Password = "s3cret" | ||
} | ||
|
||
_, err := url.Parse(s.URL) | ||
if err != nil { | ||
return fmt.Errorf("Unable to parse address '%s': %s", s.URL, err) | ||
} | ||
|
||
req, err := http.NewRequest("GET", s.URL, nil) | ||
req.SetBasicAuth(s.Username, s.Password) | ||
cli := &http.Client{} | ||
resp, err := cli.Do(req) | ||
if err != nil { | ||
return fmt.Errorf("Unable to call URL '%s': %s", s.URL, err) | ||
} | ||
defer resp.Body.Close() | ||
body, err := ioutil.ReadAll(resp.Body) | ||
|
||
var status TomcatStatus | ||
xml.Unmarshal(body, &status) | ||
|
||
// add tomcat_jvm_memory measurements | ||
tcm := map[string]interface{}{ | ||
"free": status.TomcatJvm.JvmMemory.Free, | ||
"total": status.TomcatJvm.JvmMemory.Total, | ||
"max": status.TomcatJvm.JvmMemory.Max, | ||
} | ||
acc.AddFields("tomcat_jvm_memory", tcm, nil) | ||
|
||
// add tomcat_jvm_memorypool measurements | ||
for _, mp := range status.TomcatJvm.JvmMemoryPools { | ||
|
||
tcmpTags := map[string]string{ | ||
"name": mp.Name, | ||
"type": mp.Type, | ||
} | ||
|
||
tcmpFields := map[string]interface{}{ | ||
"init": mp.UsageInit, | ||
"committed": mp.UsageCommitted, | ||
"max": mp.UsageMax, | ||
"used": mp.UsageUsed, | ||
} | ||
|
||
acc.AddFields("tomcat_jvm_memorypool", tcmpFields, tcmpTags) | ||
|
||
} | ||
|
||
// add tomcat_connector measurements | ||
for _, c := range status.TomcatConnectors { | ||
|
||
name, err := strconv.Unquote(c.Name) | ||
if err != nil { | ||
return fmt.Errorf("Unable to unquote name '%s': %s", c.Name, err) | ||
} | ||
|
||
tccTags := map[string]string{ | ||
"name": name, | ||
} | ||
|
||
tccFields := map[string]interface{}{ | ||
"max_threads": c.ThreadInfo.MaxThreads, | ||
"current_thread_count": c.ThreadInfo.CurrentThreadCount, | ||
"current_threads_busy": c.ThreadInfo.CurrentThreadsBusy, | ||
"max_time": c.RequestInfo.MaxTime, | ||
"processing_time": c.RequestInfo.ProcessingTime, | ||
"request_count": c.RequestInfo.RequestCount, | ||
"error_count": c.RequestInfo.ErrorCount, | ||
"bytes_received": c.RequestInfo.BytesReceived, | ||
"bytes_sent": c.RequestInfo.BytesSent, | ||
} | ||
|
||
acc.AddFields("tomcat_connector", tccFields, tccTags) | ||
|
||
} | ||
|
||
return nil | ||
} | ||
|
||
func init() { | ||
inputs.Add("tomcat", func() telegraf.Input { return &Tomcat{} }) | ||
} |
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,95 @@ | ||
package tomcat | ||
|
||
import ( | ||
"fmt" | ||
"net/http" | ||
"net/http/httptest" | ||
"testing" | ||
|
||
"github.com/influxdata/telegraf/testutil" | ||
|
||
"github.com/stretchr/testify/require" | ||
) | ||
|
||
var tomcatStatus = `<?xml version="1.0" encoding="UTF-8"?> | ||
<?xml-stylesheet type="text/xsl" href="/manager/xform.xsl" ?> | ||
<status> | ||
<jvm> | ||
<memory free='17909336' total='58195968' max='620756992'/> | ||
<memorypool name='PS Eden Space' type='Heap memory' usageInit='8912896' usageCommitted='35651584' usageMax='230686720' usageUsed='25591384'/> | ||
<memorypool name='PS Old Gen' type='Heap memory' usageInit='21495808' usageCommitted='21495808' usageMax='465567744' usageUsed='13663040'/> | ||
<memorypool name='PS Survivor Space' type='Heap memory' usageInit='1048576' usageCommitted='1048576' usageMax='1048576' usageUsed='1032208'/> | ||
<memorypool name='Code Cache' type='Non-heap memory' usageInit='2555904' usageCommitted='2555904' usageMax='50331648' usageUsed='1220096'/> | ||
<memorypool name='PS Perm Gen' type='Non-heap memory' usageInit='22020096' usageCommitted='22020096' usageMax='174063616' usageUsed='17533952'/> | ||
</jvm> | ||
<connector name='"ajp-apr-8009"'> | ||
<threadInfo maxThreads="200" currentThreadCount="0" currentThreadsBusy="0"/> | ||
<requestInfo maxTime="0" processingTime="0" requestCount="0" errorCount="0" bytesReceived="0" bytesSent="0"/> | ||
<workers> | ||
</workers> | ||
</connector> | ||
<connector name='"http-apr-8080"'> | ||
<threadInfo maxThreads="200" currentThreadCount="5" currentThreadsBusy="1"/> | ||
<requestInfo maxTime="68" processingTime="88" requestCount="2" errorCount="1" bytesReceived="0" bytesSent="9286"/> | ||
<workers> | ||
<worker stage="S" requestProcessingTime="4" requestBytesSent="0" requestBytesReceived="0" remoteAddr="127.0.0.1" virtualHost="127.0.0.1" method="GET" currentUri="/manager/status/all" currentQueryString="XML=true" protocol="HTTP/1.1"/> | ||
</workers> | ||
</connector> | ||
</status>` | ||
|
||
func TestHTTPTomcat(t *testing.T) { | ||
ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { | ||
w.WriteHeader(http.StatusOK) | ||
fmt.Fprintln(w, tomcatStatus) | ||
})) | ||
defer ts.Close() | ||
|
||
tc := Tomcat{ | ||
URL: ts.URL, | ||
Username: "tomcat", | ||
Password: "s3cret", | ||
} | ||
|
||
var acc testutil.Accumulator | ||
err := tc.Gather(&acc) | ||
require.NoError(t, err) | ||
|
||
// tomcat_jvm_memory | ||
jvmMemoryFields := map[string]interface{}{ | ||
"free": int64(17909336), | ||
"total": int64(58195968), | ||
"max": int64(620756992), | ||
} | ||
acc.AssertContainsFields(t, "tomcat_jvm_memory", jvmMemoryFields) | ||
|
||
// tomcat_jvm_memorypool | ||
jvmMemoryPoolFields := map[string]interface{}{ | ||
"init": int64(22020096), | ||
"committed": int64(22020096), | ||
"max": int64(174063616), | ||
"used": int64(17533952), | ||
} | ||
jvmMemoryPoolTags := map[string]string{ | ||
"name": "PS Perm Gen", | ||
"type": "Non-heap memory", | ||
} | ||
acc.AssertContainsTaggedFields(t, "tomcat_jvm_memorypool", jvmMemoryPoolFields, jvmMemoryPoolTags) | ||
|
||
// tomcat_connector | ||
connectorFields := map[string]interface{}{ | ||
"max_threads": int64(200), | ||
"current_thread_count": int64(5), | ||
"current_threads_busy": int64(1), | ||
"max_time": int(68), | ||
"processing_time": int(88), | ||
"request_count": int(2), | ||
"error_count": int(1), | ||
"bytes_received": int64(0), | ||
"bytes_sent": int64(9286), | ||
} | ||
connectorTags := map[string]string{ | ||
"name": "http-apr-8080", | ||
} | ||
acc.AssertContainsTaggedFields(t, "tomcat_connector", connectorFields, connectorTags) | ||
|
||
} |
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
After checking for errors, we should make sure the response code was a 200 status and if not return an error.