Skip to content

Commit 8664205

Browse files
author
mlinde201
committed
adding tomcat plugin
1 parent 83c003e commit 8664205

File tree

3 files changed

+344
-0
lines changed

3 files changed

+344
-0
lines changed

plugins/inputs/tomcat/README.md

Lines changed: 73 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,73 @@
1+
# Tomcat Input Plugin
2+
3+
The Tomcat plugin collects statistics available from the tomcat manager status page from the `http://<host>/manager/status/all?XML=true URL.`
4+
(`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.
5+
6+
### Configuration:
7+
8+
```toml
9+
# A Telegraf plugin to collect tomcat metrics.
10+
[[inputs.tomcat]]
11+
# A Tomcat status URI to gather stats.
12+
# Default is "http://127.0.0.1:8080/manager/status/all?XML=true".
13+
url = "http://127.0.0.1:8080/manager/status/all?XML=true"
14+
# Credentials for status URI.
15+
# Default is tomcat/s3cret.
16+
username = "tomcat"
17+
password = "s3cret"
18+
```
19+
20+
### Measurements & Fields:
21+
22+
- tomcat\_jvm\_memory
23+
- free
24+
- total
25+
- max
26+
- tomcat\_jvm\_memorypool
27+
- max\_threads
28+
- current\_thread\_count
29+
- current\_threads\_busy
30+
- max\_time
31+
- processing\_time
32+
- request\_count
33+
- error\_count
34+
- bytes\_received
35+
- bytes\_sent
36+
- tomcat\_connector
37+
- max\_threads
38+
- current\_thread\_count
39+
- current\_thread\_busy
40+
- max\_time
41+
- processing\_time
42+
- request\_count
43+
- error\_count
44+
- bytes\_received
45+
- bytes\_sent
46+
47+
### Tags:
48+
49+
- tomcat\_jvm\_memorypool has the following tags:
50+
- name
51+
- type
52+
- tomcat\_connector
53+
- name
54+
55+
### Sample Queries:
56+
57+
TODO
58+
59+
### Example Output:
60+
61+
```
62+
$ ./telegraf -config telegraf.conf -input-filter tomcat -test
63+
* Plugin: tomcat, Collection 1
64+
> tomcat_jvm_memory,host=N8-MBP free=20014352i,max=127729664i,total=41459712i 1474663361000000000
65+
> tomcat_jvm_memorypool,host=N8-MBP,name=Eden\ Space,type=Heap\ memory committed=11534336i,init=2228224i,max=35258368i,used=1941200i 1474663361000000000
66+
> tomcat_jvm_memorypool,host=N8-MBP,name=Survivor\ Space,type=Heap\ memory committed=1376256i,init=262144i,max=4390912i,used=1376248i 1474663361000000000
67+
> tomcat_jvm_memorypool,host=N8-MBP,name=Tenured\ Gen,type=Heap\ memory committed=28549120i,init=5636096i,max=88080384i,used=18127912i 1474663361000000000
68+
> tomcat_jvm_memorypool,host=N8-MBP,name=Code\ Cache,type=Non-heap\ memory committed=6946816i,init=2555904i,max=251658240i,used=6406528i 1474663361000000000
69+
> tomcat_jvm_memorypool,host=N8-MBP,name=Compressed\ Class\ Space,type=Non-heap\ memory committed=1966080i,init=0i,max=1073741824i,used=1816120i 1474663361000000000
70+
> tomcat_jvm_memorypool,host=N8-MBP,name=Metaspace,type=Non-heap\ memory committed=18219008i,init=0i,max=-1i,used=17559376i 1474663361000000000
71+
> 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
72+
> 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
73+
```

plugins/inputs/tomcat/tomcat.go

Lines changed: 176 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,176 @@
1+
package tomcat
2+
3+
import (
4+
"encoding/xml"
5+
"fmt"
6+
"io/ioutil"
7+
"net/http"
8+
"net/url"
9+
"strconv"
10+
11+
"github.com/influxdata/telegraf"
12+
"github.com/influxdata/telegraf/plugins/inputs"
13+
)
14+
15+
type TomcatStatus struct {
16+
TomcatJvm TomcatJvm `xml:"jvm"`
17+
TomcatConnectors []TomcatConnector `xml:"connector"`
18+
}
19+
20+
type TomcatJvm struct {
21+
JvmMemory JvmMemoryStat `xml:"memory"`
22+
JvmMemoryPools []JvmMemoryPoolStat `xml:"memorypool"`
23+
}
24+
25+
type JvmMemoryStat struct {
26+
Free int64 `xml:"free,attr"`
27+
Total int64 `xml:"total,attr"`
28+
Max int64 `xml:"max,attr"`
29+
}
30+
31+
type JvmMemoryPoolStat struct {
32+
Name string `xml:"name,attr"`
33+
Type string `xml:"type,attr"`
34+
UsageInit int64 `xml:"usageInit,attr"`
35+
UsageCommitted int64 `xml:"usageCommitted,attr"`
36+
UsageMax int64 `xml:"usageMax,attr"`
37+
UsageUsed int64 `xml:"usageUsed,attr"`
38+
}
39+
40+
type TomcatConnector struct {
41+
Name string `xml:"name,attr"`
42+
ThreadInfo ThreadInfo `xml:"threadInfo"`
43+
RequestInfo RequestInfo `xml:"requestInfo"`
44+
}
45+
46+
type ThreadInfo struct {
47+
MaxThreads int64 `xml:"maxThreads,attr"`
48+
CurrentThreadCount int64 `xml:"currentThreadCount,attr"`
49+
CurrentThreadsBusy int64 `xml:"currentThreadsBusy,attr"`
50+
}
51+
type RequestInfo struct {
52+
MaxTime int `xml:"maxTime,attr"`
53+
ProcessingTime int `xml:"processingTime,attr"`
54+
RequestCount int `xml:"requestCount,attr"`
55+
ErrorCount int `xml:"errorCount,attr"`
56+
BytesReceived int64 `xml:"bytesReceived,attr"`
57+
BytesSent int64 `xml:"bytesSent,attr"`
58+
}
59+
60+
type Tomcat struct {
61+
URL string
62+
Username string
63+
Password string
64+
}
65+
66+
var sampleconfig = `
67+
## A Tomcat status URI to gather stats.
68+
## Default is "http://127.0.0.1:8080/manager/status/all?XML=true".
69+
url = "http://127.0.0.1:8080/manager/status/all?XML=true"
70+
## Credentials for status URI.
71+
## Default is tomcat/s3cret.
72+
username = "tomcat"
73+
password = "s3cret"
74+
`
75+
76+
func (s *Tomcat) Description() string {
77+
return "A Telegraf plugin to collect tomcat metrics."
78+
}
79+
80+
func (s *Tomcat) SampleConfig() string {
81+
return sampleconfig
82+
}
83+
84+
func (s *Tomcat) Gather(acc telegraf.Accumulator) error {
85+
86+
if s.URL == "" {
87+
s.URL = "http://127.0.0.1:8080/manager/status/all?XML=true"
88+
}
89+
90+
if s.Username == "" {
91+
s.Username = "tomcat"
92+
}
93+
94+
if s.Password == "" {
95+
s.Password = "s3cret"
96+
}
97+
98+
_, err := url.Parse(s.URL)
99+
if err != nil {
100+
return fmt.Errorf("Unable to parse address '%s': %s", s.URL, err)
101+
}
102+
103+
req, err := http.NewRequest("GET", s.URL, nil)
104+
req.SetBasicAuth(s.Username, s.Password)
105+
cli := &http.Client{}
106+
resp, err := cli.Do(req)
107+
if err != nil {
108+
return fmt.Errorf("Unable to call URL '%s': %s", s.URL, err)
109+
}
110+
defer resp.Body.Close()
111+
body, err := ioutil.ReadAll(resp.Body)
112+
113+
var status TomcatStatus
114+
xml.Unmarshal(body, &status)
115+
116+
// add tomcat_jvm_memory measurements
117+
tcm := map[string]interface{}{
118+
"free": status.TomcatJvm.JvmMemory.Free,
119+
"total": status.TomcatJvm.JvmMemory.Total,
120+
"max": status.TomcatJvm.JvmMemory.Max,
121+
}
122+
acc.AddFields("tomcat_jvm_memory", tcm, nil)
123+
124+
// add tomcat_jvm_memorypool measurements
125+
for _, mp := range status.TomcatJvm.JvmMemoryPools {
126+
127+
tcmpTags := map[string]string{
128+
"name": mp.Name,
129+
"type": mp.Type,
130+
}
131+
132+
tcmpFields := map[string]interface{}{
133+
"init": mp.UsageInit,
134+
"committed": mp.UsageCommitted,
135+
"max": mp.UsageMax,
136+
"used": mp.UsageUsed,
137+
}
138+
139+
acc.AddFields("tomcat_jvm_memorypool", tcmpFields, tcmpTags)
140+
141+
}
142+
143+
// add tomcat_connector measurements
144+
for _, c := range status.TomcatConnectors {
145+
146+
name, err := strconv.Unquote(c.Name)
147+
if err != nil {
148+
return fmt.Errorf("Unable to unquote name '%s': %s", c.Name, err)
149+
}
150+
151+
tccTags := map[string]string{
152+
"name": name,
153+
}
154+
155+
tccFields := map[string]interface{}{
156+
"max_threads": c.ThreadInfo.MaxThreads,
157+
"current_thread_count": c.ThreadInfo.CurrentThreadCount,
158+
"current_threads_busy": c.ThreadInfo.CurrentThreadsBusy,
159+
"max_time": c.RequestInfo.MaxTime,
160+
"processing_time": c.RequestInfo.ProcessingTime,
161+
"request_count": c.RequestInfo.RequestCount,
162+
"error_count": c.RequestInfo.ErrorCount,
163+
"bytes_received": c.RequestInfo.BytesReceived,
164+
"bytes_sent": c.RequestInfo.BytesSent,
165+
}
166+
167+
acc.AddFields("tomcat_connector", tccFields, tccTags)
168+
169+
}
170+
171+
return nil
172+
}
173+
174+
func init() {
175+
inputs.Add("tomcat", func() telegraf.Input { return &Tomcat{} })
176+
}
Lines changed: 95 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,95 @@
1+
package tomcat
2+
3+
import (
4+
"fmt"
5+
"net/http"
6+
"net/http/httptest"
7+
"testing"
8+
9+
"github.com/influxdata/telegraf/testutil"
10+
11+
"github.com/stretchr/testify/require"
12+
)
13+
14+
var tomcatStatus = `<?xml version="1.0" encoding="UTF-8"?>
15+
<?xml-stylesheet type="text/xsl" href="/manager/xform.xsl" ?>
16+
<status>
17+
<jvm>
18+
<memory free='17909336' total='58195968' max='620756992'/>
19+
<memorypool name='PS Eden Space' type='Heap memory' usageInit='8912896' usageCommitted='35651584' usageMax='230686720' usageUsed='25591384'/>
20+
<memorypool name='PS Old Gen' type='Heap memory' usageInit='21495808' usageCommitted='21495808' usageMax='465567744' usageUsed='13663040'/>
21+
<memorypool name='PS Survivor Space' type='Heap memory' usageInit='1048576' usageCommitted='1048576' usageMax='1048576' usageUsed='1032208'/>
22+
<memorypool name='Code Cache' type='Non-heap memory' usageInit='2555904' usageCommitted='2555904' usageMax='50331648' usageUsed='1220096'/>
23+
<memorypool name='PS Perm Gen' type='Non-heap memory' usageInit='22020096' usageCommitted='22020096' usageMax='174063616' usageUsed='17533952'/>
24+
</jvm>
25+
<connector name='"ajp-apr-8009"'>
26+
<threadInfo maxThreads="200" currentThreadCount="0" currentThreadsBusy="0"/>
27+
<requestInfo maxTime="0" processingTime="0" requestCount="0" errorCount="0" bytesReceived="0" bytesSent="0"/>
28+
<workers>
29+
</workers>
30+
</connector>
31+
<connector name='"http-apr-8080"'>
32+
<threadInfo maxThreads="200" currentThreadCount="5" currentThreadsBusy="1"/>
33+
<requestInfo maxTime="68" processingTime="88" requestCount="2" errorCount="1" bytesReceived="0" bytesSent="9286"/>
34+
<workers>
35+
<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"/>
36+
</workers>
37+
</connector>
38+
</status>`
39+
40+
func TestHTTPTomcat(t *testing.T) {
41+
ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
42+
w.WriteHeader(http.StatusOK)
43+
fmt.Fprintln(w, tomcatStatus)
44+
}))
45+
defer ts.Close()
46+
47+
tc := Tomcat{
48+
URL: ts.URL,
49+
Username: "tomcat",
50+
Password: "s3cret",
51+
}
52+
53+
var acc testutil.Accumulator
54+
err := tc.Gather(&acc)
55+
require.NoError(t, err)
56+
57+
// tomcat_jvm_memory
58+
jvmMemoryFields := map[string]interface{}{
59+
"free": int64(17909336),
60+
"total": int64(58195968),
61+
"max": int64(620756992),
62+
}
63+
acc.AssertContainsFields(t, "tomcat_jvm_memory", jvmMemoryFields)
64+
65+
// tomcat_jvm_memorypool
66+
jvmMemoryPoolFields := map[string]interface{}{
67+
"init": int64(22020096),
68+
"committed": int64(22020096),
69+
"max": int64(174063616),
70+
"used": int64(17533952),
71+
}
72+
jvmMemoryPoolTags := map[string]string{
73+
"name": "PS Perm Gen",
74+
"type": "Non-heap memory",
75+
}
76+
acc.AssertContainsTaggedFields(t, "tomcat_jvm_memorypool", jvmMemoryPoolFields, jvmMemoryPoolTags)
77+
78+
// tomcat_connector
79+
connectorFields := map[string]interface{}{
80+
"max_threads": int64(200),
81+
"current_thread_count": int64(5),
82+
"current_threads_busy": int64(1),
83+
"max_time": int(68),
84+
"processing_time": int(88),
85+
"request_count": int(2),
86+
"error_count": int(1),
87+
"bytes_received": int64(0),
88+
"bytes_sent": int64(9286),
89+
}
90+
connectorTags := map[string]string{
91+
"name": "http-apr-8080",
92+
}
93+
acc.AssertContainsTaggedFields(t, "tomcat_connector", connectorFields, connectorTags)
94+
95+
}

0 commit comments

Comments
 (0)