1
+ /*
2
+ * Copyright 2012-2015 the original author or authors.
3
+ *
4
+ * Licensed under the Apache License, Version 2.0 (the "License");
5
+ * you may not use this file except in compliance with the License.
6
+ * You may obtain a copy of the License at
7
+ *
8
+ * http://www.apache.org/licenses/LICENSE-2.0
9
+ *
10
+ * Unless required by applicable law or agreed to in writing, software
11
+ * distributed under the License is distributed on an "AS IS" BASIS,
12
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13
+ * See the License for the specific language governing permissions and
14
+ * limitations under the License.
15
+ */
16
+
17
+ package org .springframework .boot .actuate .metrics .opentsdb ;
18
+
19
+ import java .util .ArrayList ;
20
+ import java .util .Arrays ;
21
+ import java .util .List ;
22
+ import java .util .Map ;
23
+
24
+ import org .apache .commons .logging .Log ;
25
+ import org .apache .commons .logging .LogFactory ;
26
+ import org .springframework .boot .actuate .metrics .Metric ;
27
+ import org .springframework .boot .actuate .metrics .writer .Delta ;
28
+ import org .springframework .boot .actuate .metrics .writer .MetricWriter ;
29
+ import org .springframework .http .HttpEntity ;
30
+ import org .springframework .http .HttpHeaders ;
31
+ import org .springframework .http .MediaType ;
32
+ import org .springframework .http .ResponseEntity ;
33
+ import org .springframework .scheduling .annotation .Scheduled ;
34
+ import org .springframework .web .client .RestTemplate ;
35
+
36
+ /**
37
+ * A {@link MetricWriter} for the Open TSDB database (version 2.0), writing metrics to the
38
+ * HTTP endpoint provided by the server. Data are buffered according to the
39
+ * {@link #setBufferSize(int) bufferSize} property, and only flushed automatically when
40
+ * the buffer size is reached. Users should either manually {@link #flush()} after writing
41
+ * a batch of data if that makes sense, or consider adding a {@link Scheduled
42
+ * <code>@Scheduled</code>} task to flush periodically.
43
+ *
44
+ * @author Dave Syer
45
+ */
46
+ public class OpenTsdbHttpMetricWriter implements MetricWriter {
47
+
48
+ private static final Log logger = LogFactory .getLog (OpenTsdbHttpMetricWriter .class );
49
+
50
+ private RestTemplate restTemplate = new RestTemplate ();
51
+
52
+ /**
53
+ * URL for POSTing data. Defaults to http://localhost:4242/api/put.
54
+ */
55
+ private String url = "http://localhost:4242/api/put" ;
56
+
57
+ /**
58
+ * Buffer size to fill before posting data to server.
59
+ */
60
+ private int bufferSize = 64 ;
61
+
62
+ /**
63
+ * The media type to use to serialize and accept responses from the server. Defaults
64
+ * to "application/json".
65
+ */
66
+ private MediaType mediaType = MediaType .APPLICATION_JSON ;
67
+
68
+ private List <OpenTsdbData > buffer = new ArrayList <OpenTsdbData >(this .bufferSize );
69
+
70
+ private OpenTsdbNamingStrategy namingStrategy = new DefaultOpenTsdbNamingStrategy ();
71
+
72
+ public RestTemplate getRestTemplate () {
73
+ return this .restTemplate ;
74
+ }
75
+
76
+ public void setRestTemplate (RestTemplate restTemplate ) {
77
+ this .restTemplate = restTemplate ;
78
+ }
79
+
80
+ public void setUrl (String url ) {
81
+ this .url = url ;
82
+ }
83
+
84
+ public void setBufferSize (int bufferSize ) {
85
+ this .bufferSize = bufferSize ;
86
+ }
87
+
88
+ public void setMediaType (MediaType mediaType ) {
89
+ this .mediaType = mediaType ;
90
+ }
91
+
92
+ public void setNamingStrategy (OpenTsdbNamingStrategy namingStrategy ) {
93
+ this .namingStrategy = namingStrategy ;
94
+ }
95
+
96
+ @ Override
97
+ public void increment (Delta <?> delta ) {
98
+ throw new UnsupportedOperationException ("Counters not supported via increment" );
99
+ }
100
+
101
+ @ Override
102
+ public void set (Metric <?> value ) {
103
+ OpenTsdbData data = new OpenTsdbData (
104
+ this .namingStrategy .getName (value .getName ()), value .getValue (), value
105
+ .getTimestamp ().getTime ());
106
+ this .buffer .add (data );
107
+ if (this .buffer .size () >= this .bufferSize ) {
108
+ flush ();
109
+ }
110
+ }
111
+
112
+ /**
113
+ * Flush the buffer without waiting for it to fill any further.
114
+ */
115
+ public void flush () {
116
+ if (this .buffer .isEmpty ()) {
117
+ return ;
118
+ }
119
+ List <OpenTsdbData > temp = new ArrayList <OpenTsdbData >();
120
+ synchronized (this .buffer ) {
121
+ temp .addAll (this .buffer );
122
+ this .buffer .clear ();
123
+ }
124
+ HttpHeaders headers = new HttpHeaders ();
125
+ headers .setAccept (Arrays .asList (this .mediaType ));
126
+ headers .setContentType (this .mediaType );
127
+ HttpEntity <List <OpenTsdbData >> request = new HttpEntity <List <OpenTsdbData >>(temp ,
128
+ headers );
129
+ @ SuppressWarnings ("rawtypes" )
130
+ ResponseEntity <Map > response = this .restTemplate .postForEntity (this .url , request ,
131
+ Map .class );
132
+ if (!response .getStatusCode ().is2xxSuccessful ()) {
133
+ logger .warn ("Cannot write metrics (discarded " + temp .size () + " values): "
134
+ + response .getBody ());
135
+ }
136
+ }
137
+
138
+ @ Override
139
+ public void reset (String metricName ) {
140
+ set (new Metric <Long >(metricName , 0L ));
141
+ }
142
+
143
+ }
0 commit comments