echo_cli 0.6.25 → 0.6.28
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/README.md +13 -57
- data/lib/echo_cli/cli.rb +110 -382
- data/lib/echo_cli/version.rb +1 -1
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: c3b600a594c6f6f3219bb052d8ca7f7705bc866c
|
4
|
+
data.tar.gz: 1d3ff7b2815f508e24f327d304dd873dc8dc8c68
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: aeac419f4164aabe7752a991c4ced877e8319fad765b188b06bc97a8e648fa8068b839124067fc11bdffd5bafe4adc90994d82a7a678972016a7ebec12894966
|
7
|
+
data.tar.gz: 5623cf94125413f9ab875a4609882ee2918a03d29fdf3a5ef56adecf09d46be4db4f7b028ca376f98ed7d2b89c0845b73aa127a1949bc1da1064c1147974d703
|
data/README.md
CHANGED
@@ -110,26 +110,6 @@ $ echo_cli convert 2017-05-11T15:05:23-07:00
|
|
110
110
|
```
|
111
111
|
This example will convert from a human-readable timestamp to an epoch timestamp.
|
112
112
|
|
113
|
-
#### cpost
|
114
|
-
```bash
|
115
|
-
$ echo_cli cpost '<metric>' {frequency} {-v} {-z}
|
116
|
-
```
|
117
|
-
Parameters:
|
118
|
-
|
119
|
-
`'<metric>'`: (required) the application name, as well as any tags, and data value and data type to be posted to StatsD
|
120
|
-
|
121
|
-
`{frequency}`: (optional) the rate at which the metric will be continuously posted to Echo's server. If left unspecified, this value will default to 10 seconds.
|
122
|
-
|
123
|
-
`{-v}`: (optional) continuously output a 'successfully posted' message, with updated start and end times, to the command line.
|
124
|
-
|
125
|
-
`{-z}`: (optional) spawn the continuous post process in the background. Additionally, this option will return a PID (Process ID) that can be used in the future to kill the command. Use `kill -9 <PID>` to kill the process.
|
126
|
-
|
127
|
-
Example:
|
128
|
-
```bash
|
129
|
-
$ echo_cli cpost 'example.post:1|c' 5 -z
|
130
|
-
```
|
131
|
-
The previous example will post the metric 'example' with tag 'post' to Echo's StatsD server instance once every 5 seconds. The specified '-z' option will spawn the process in the background, and return the newly spawned process ID in the command line.
|
132
|
-
|
133
113
|
#### help
|
134
114
|
```bash
|
135
115
|
$ echo_cli help [COMMAND]
|
@@ -154,67 +134,43 @@ $ echo_cli now
|
|
154
134
|
|
155
135
|
#### post
|
156
136
|
```bash
|
157
|
-
$ echo_cli post '<metric>' {number} {-
|
137
|
+
$ echo_cli post '<metric>' {number} {-z}
|
158
138
|
```
|
159
139
|
Parameters:
|
160
140
|
|
161
|
-
`'<metric>'`: (required) the application name, as well as any tags, and data value and data type to be posted to StatsD
|
141
|
+
`'<metric>'`: (required) the application name, as well as any tags, and data value and data type to be posted to StatsD. Note the single-quotes surrounding the metric, these are required as well.
|
162
142
|
|
163
143
|
`{number}`: (optional) the number of posts to occur, e.g. a number value of '10' would post the metric 10 times to the StatsD server
|
164
144
|
|
165
|
-
`{-
|
166
|
-
|
167
|
-
`{-v}`: (optional) continuously output a 'successfully posted' message, with updated start and end times, to the command line.
|
145
|
+
`{-z}`: (optional) spawn the continuous post process in the background. Additionally, this option will return a PID (Process ID) that can be used in the future to kill the command. Use `kill -9 <PID>` to kill the process.
|
168
146
|
|
169
147
|
Example:
|
170
148
|
```bash
|
171
|
-
$ echo_cli 'sample.post.here:1|c' 10
|
149
|
+
$ echo_cli 'sample.post.here:1|c' 10
|
172
150
|
```
|
173
|
-
The previous example would post the application name 'sample' with tags 'post' and 'here' with data value '1' and with data type 'c' (for count). This information would be posted to the instance of StatsD, and it would be posted 10 times.
|
151
|
+
The previous example would post the application name 'sample' with tags 'post' and 'here' with data value '1' and with data type 'c' (for count). This information would be posted to the instance of StatsD, and it would be posted 10 times.
|
174
152
|
|
175
153
|
#### query
|
176
154
|
```bash
|
177
|
-
$ echo_cli query '<metric>' <time_start> <time_end>
|
155
|
+
$ echo_cli query '<metric>' <time_start> <time_end>
|
178
156
|
```
|
179
157
|
Parameters:
|
180
158
|
|
181
|
-
`'<metric>'`: (required) the application name, including any tags, with which the query for
|
182
|
-
|
183
|
-
`<time_start>`: (required) the start of the range you are attempting to query in seconds from January 1, 1970 (epoch time)
|
184
|
-
|
185
|
-
`<time_end>`: (required) the end of the range you are attempting to query in seconds from January 1, 1970 (epoch time)
|
186
|
-
|
187
|
-
`{-v}`: (optional) verbosely prints the status code and response body of the query
|
188
|
-
|
189
|
-
`{-e}`: (optional) formats the response datapoints such that their timestamps are in the epoch format, must have '-v' option selected for changes to appear
|
190
|
-
|
191
|
-
`{-s}`: (optional) formats the response datapoints to be usable as SQL statements for insertions into SQL-esque databases, must have '-v' option selected for changes to appear
|
192
|
-
|
193
|
-
Example:
|
194
|
-
```bash
|
195
|
-
$ echo_cli query 'sample.query.here' 1492464745 1492465045 -v
|
196
|
-
```
|
197
|
-
The previous example will query OpenTSDB with the application name 'sample' and tags 'query' and 'here' between the times of '1492464745' and '1492465045'. Additionally, the '-v' specified option will also return the response code and response body upon completion.
|
198
|
-
|
199
|
-
#### fquery
|
200
|
-
```bash
|
201
|
-
$ echo_cli fquery '<metric>' <range> {-e} {-s}
|
202
|
-
```
|
203
|
-
Parameters:
|
159
|
+
`'<metric>'`: (required) the application name, including any tags, with which the query for Graphite will be constructed
|
204
160
|
|
205
|
-
`
|
161
|
+
`{time_start}`: (optional) the start of the range you are attempting to query in seconds from January 1, 1970 (epoch time)
|
206
162
|
|
207
|
-
|
163
|
+
`{time_end}`: (optional) the end of the range you are attempting to query in seconds from January 1, 1970 (epoch time)
|
208
164
|
|
209
|
-
|
165
|
+
See: https://graphite-api.readthedocs.io/en/latest/api.html#from-until for possible time_start and time_end formats.
|
210
166
|
|
211
|
-
|
167
|
+
The default timestamp query range begins 15 minutes prior to the current time, to now.
|
212
168
|
|
213
169
|
Example:
|
214
170
|
```bash
|
215
|
-
$ echo_cli
|
171
|
+
$ echo_cli query 'sample.query.here:1|c' 1492464745 1492465045
|
216
172
|
```
|
217
|
-
The previous example will query
|
173
|
+
The previous example will query Graphite with the application name 'sample' and tags 'query' and 'here' between the times of '1492464745' and '1492465045'.
|
218
174
|
|
219
175
|
## Development
|
220
176
|
|
data/lib/echo_cli/cli.rb
CHANGED
@@ -2,19 +2,22 @@ require 'thor'
|
|
2
2
|
require 'json'
|
3
3
|
require 'time'
|
4
4
|
require 'colorize'
|
5
|
+
require 'socket'
|
5
6
|
require 'net/http'
|
6
7
|
require 'net/https'
|
7
8
|
require 'uri'
|
8
9
|
require 'openssl'
|
10
|
+
require 'timeout'
|
9
11
|
|
10
12
|
module Echo_cli
|
11
13
|
class Echo < Thor
|
12
|
-
desc "post", "Post metrics to Echo. Use \"echo_cli post '<metric>' {number} {-
|
14
|
+
desc "post", "Post metrics to Echo. Use \"echo_cli post '<metric>' {number} {-z}\""
|
13
15
|
|
14
|
-
option :
|
15
|
-
option :v
|
16
|
+
option :z
|
16
17
|
|
17
18
|
long_desc <<-LONGDESC
|
19
|
+
Post metrics to Echo. Use \"echo_cli post '<metric>' {number} {-z}\"
|
20
|
+
|
18
21
|
`echo_cli post` will post a metric directly to Echo's StatsD server.
|
19
22
|
|
20
23
|
You can optionally specify a third integer parameter, which will post the same metric an integer number of times equal to the number specified.
|
@@ -23,365 +26,98 @@ module Echo_cli
|
|
23
26
|
|
24
27
|
Ensure the environment variable 'ECHO_CLI_HOST' is set to the correct IP.
|
25
28
|
|
26
|
-
With -
|
29
|
+
With the -z (zombie) option, post will continuously send the metric to Echo once every second in the background, and return its PID for future removal. Use "$ kill -9 <PID>" to kill the zombie process.
|
27
30
|
|
28
|
-
|
31
|
+
The -z option will override the {number} parameter, should both be included in an execution of the command.
|
29
32
|
|
30
|
-
> $ echo_cli post 'example.post:1|c' {10} {-
|
33
|
+
> $ echo_cli post 'example.post:1|c' {10} {-z}
|
31
34
|
LONGDESC
|
32
35
|
|
33
|
-
def post(metric, num =
|
34
|
-
Helper.new
|
35
|
-
|
36
|
-
|
37
|
-
Helper.new.set_envs()
|
38
|
-
|
39
|
-
uri = URI.parse(statsd_uri)
|
40
|
-
request = Net::HTTP::Post.new(uri)
|
41
|
-
request["Token"] = "mySecretToken"
|
42
|
-
request.body = metric.gsub(/'/,"")
|
43
|
-
|
44
|
-
req_options = {
|
45
|
-
use_ssl: uri.scheme == "https",
|
46
|
-
verify_mode: OpenSSL::SSL::VERIFY_NONE,
|
47
|
-
}
|
48
|
-
|
49
|
-
if(num.to_i > 0)
|
50
|
-
begin
|
51
|
-
time_start = Time.new.to_i.to_s
|
52
|
-
|
53
|
-
for i in 1..num.to_i
|
54
|
-
time_temp_start = Time.new.to_i.to_s
|
55
|
-
|
56
|
-
response = Net::HTTP.start(uri.hostname, uri.port, req_options) do |http|
|
57
|
-
http.request(request)
|
58
|
-
end
|
59
|
-
|
60
|
-
time_temp_end = Time.new.to_i.to_s
|
61
|
-
|
62
|
-
if response.code != '200'
|
63
|
-
puts "Final run at: " + i + " of " + num
|
64
|
-
raise
|
65
|
-
end
|
66
|
-
if(options[:v] && response.code == '200')
|
67
|
-
puts "\nSuccessfully posted ".green + request.body.yellow + " to ".green + statsd_uri.blue + "\nTime start: ".green + time_temp_start.yellow + ", Time end: ".green + time_temp_end.yellow + "\n"
|
68
|
-
end
|
69
|
-
end
|
70
|
-
|
71
|
-
if options[:q]
|
72
|
-
sleep 15 # ensure data reception and replication
|
73
|
-
end
|
74
|
-
time_end = Time.new.to_i.to_s
|
75
|
-
|
76
|
-
puts "\nSuccessfully posted ".green + request.body.yellow + " to ".green + statsd_uri.blue + " " + num.to_s.green + " time(s)".green + "\nTime start: ".green + time_start.yellow + ", Time end: ".green + time_end.yellow
|
77
|
-
|
78
|
-
if options[:q]
|
79
|
-
opentsdb_uri = statsd_uri[0..statsd_uri.index(':8125')-1] + ":4242/api/query"
|
80
|
-
query(request.body[0..request.body.index(":")-1], time_start, time_end)
|
81
|
-
end
|
82
|
-
|
83
|
-
rescue
|
84
|
-
puts "\nFailed to post ".red + request.body.yellow + " to ".red + statsd_uri.blue + " " + num.to_s.red + " time(s)".red
|
85
|
-
end
|
86
|
-
|
87
|
-
else
|
88
|
-
begin
|
89
|
-
time_start = Time.new.to_i.to_s
|
90
|
-
|
91
|
-
response = Net::HTTP.start(uri.hostname, uri.port, req_options) do |http|
|
92
|
-
http.request(request)
|
93
|
-
end
|
94
|
-
|
95
|
-
if options[:q]
|
96
|
-
sleep 15 # ensure data reception and replication
|
97
|
-
end
|
98
|
-
|
99
|
-
time_end = Time.new.to_i.to_s
|
100
|
-
|
101
|
-
if response.code == '200'
|
102
|
-
puts "\nSuccessfully posted ".green + request.body.yellow + " to ".green + statsd_uri.blue + "\nTime start: ".green + time_start.yellow + ", Time end: ".green + time_end.yellow
|
103
|
-
|
104
|
-
if options[:q]
|
105
|
-
opentsdb_uri = statsd_uri[0..statsd_uri.index(':8125')-1] + ":4242/api/query"
|
106
|
-
query(request.body[0..request.body.index(":")-1], time_start, time_end)
|
107
|
-
end
|
108
|
-
end
|
109
|
-
rescue
|
110
|
-
puts "\nFailed to post ".red + request.body.yellow + " to ".red + statsd_uri.blue
|
111
|
-
end
|
112
|
-
end
|
113
|
-
return response
|
114
|
-
|
115
|
-
Helper.new.unset_envs()
|
116
|
-
end
|
117
|
-
|
118
|
-
desc "cpost", "Continuously post metrics to Echo. Use \"echo_cli cpost '<metric>' {frequency} {-v} {-z}\""
|
119
|
-
|
120
|
-
option :z
|
121
|
-
option :v
|
122
|
-
|
123
|
-
long_desc <<-LONGDESC
|
124
|
-
`echo_cli cpost` will continuously post a metric directly to Echo's StatsD server. This process can be killed with "CTRL-c".
|
36
|
+
def post(metric, num = 1)
|
37
|
+
helper = Helper.new
|
38
|
+
helper.set_envs()
|
39
|
+
helper.check_for_IP()
|
125
40
|
|
126
|
-
|
127
|
-
|
128
|
-
Ensure single-quotes surround the metric.
|
129
|
-
|
130
|
-
Ensure the environment variable 'ECHO_CLI_HOST' is set to the correct IP.
|
131
|
-
|
132
|
-
With -v (verbose) option, cpost will continuously output a 'successfully posted' message, with updated times, to the command line.
|
133
|
-
|
134
|
-
With -z (zombie) option, cpost will continuously send posts to Echo in the background, and return its PID for future removal. Use "$ kill -9 <PID>" to kill the zombie process. Specifying this option will override the '-v' option.
|
135
|
-
|
136
|
-
> $ echo_cli cpost 'example.post:1|c' {1} {-v} {-z}
|
137
|
-
LONGDESC
|
138
|
-
|
139
|
-
def cpost(metric, num = 0)
|
140
|
-
Helper.new.check_for_IP()
|
141
|
-
|
142
|
-
statsd_uri = "https://" + ENV["ECHO_CLI_HOST"] + ":8125/metrix"
|
143
|
-
|
144
|
-
Helper.new.set_envs()
|
145
|
-
|
146
|
-
uri = URI.parse(statsd_uri)
|
147
|
-
request = Net::HTTP::Post.new(uri)
|
148
|
-
request["Token"] = "mySecretToken"
|
149
|
-
request.body = metric.gsub(/'/,"")
|
41
|
+
metric = metric.gsub(/'/,"")
|
42
|
+
exit if !helper.check_metric_format(metric)
|
150
43
|
|
151
|
-
|
152
|
-
|
153
|
-
verify_mode: OpenSSL::SSL::VERIFY_NONE,
|
154
|
-
}
|
44
|
+
if options[:z]
|
45
|
+
time_start = Time.new.to_i.to_s
|
155
46
|
|
156
|
-
|
157
|
-
|
158
|
-
|
159
|
-
s = 10
|
160
|
-
end
|
161
|
-
|
162
|
-
if(options[:z])
|
47
|
+
# sort of a mini-smoketest to ensure the posts will work before creating a background process
|
48
|
+
helper.do_post_tcp(ENV["ECHO_CLI_HOST"], "8125", metric)
|
49
|
+
|
163
50
|
pid = Process.fork do
|
164
51
|
while true do
|
165
|
-
|
166
|
-
|
167
|
-
end
|
168
|
-
sleep s
|
52
|
+
helper.do_post_tcp(ENV["ECHO_CLI_HOST"], "8125", metric)
|
53
|
+
sleep 1
|
169
54
|
end
|
170
55
|
end
|
171
|
-
puts "\nProcess ID: ".green + pid.to_s.yellow + "\nUse ".green + "kill
|
56
|
+
puts "\nProcess ID: ".green + pid.to_s.yellow + "\nUse ".green + "$ kill ".yellow + pid.to_s.yellow + " to kill the zombie process.".green
|
57
|
+
puts "Process began posting at ".green + time_start.yellow
|
172
58
|
else
|
173
|
-
|
174
|
-
|
175
|
-
|
176
|
-
|
177
|
-
|
178
|
-
http.request(request)
|
179
|
-
end
|
180
|
-
|
181
|
-
sleep s
|
182
|
-
|
183
|
-
time_end = Time.new.to_i.to_s
|
59
|
+
num = num.to_i
|
60
|
+
if num <= 0
|
61
|
+
puts "\nThe number of posts specified is an incorrect expression, or is less than or equal to zero!".red
|
62
|
+
exit
|
63
|
+
end
|
184
64
|
|
185
|
-
|
186
|
-
|
187
|
-
|
65
|
+
while num > 0
|
66
|
+
helper.do_post_tcp(ENV["ECHO_CLI_HOST"], "8125", metric)
|
67
|
+
puts "\nPosted ".green + metric.yellow + " to ".green + "http://".yellow + ENV["ECHO_CLI_HOST"].yellow + ":".yellow + "8125".yellow + " at ".green + Time.new.to_i.to_s.yellow
|
68
|
+
num -= 1
|
188
69
|
end
|
189
70
|
end
|
190
71
|
|
191
|
-
|
192
|
-
|
72
|
+
helper.unset_envs()
|
193
73
|
end
|
194
74
|
|
195
|
-
desc "query", "Query metrics on Echo. Use \"echo_cli query '<metric>'
|
196
|
-
|
197
|
-
option :v
|
198
|
-
option :e
|
199
|
-
option :s
|
75
|
+
desc "query", "Query metrics on Echo. Use \"echo_cli query '<metric>' {time_start} {time_end}\""
|
200
76
|
|
201
77
|
long_desc <<-LONGDESC
|
202
|
-
|
203
|
-
|
204
|
-
Timestamps are given in epoch time, in seconds.
|
205
|
-
|
206
|
-
If timestamps are unknown, echo_cli's post command provides time_start and time_end values for future querying.
|
207
|
-
|
208
|
-
Ensure single-quotes surround the metric.
|
209
|
-
|
210
|
-
Ensure the environment variable 'ECHO_CLI_HOST' is set to the correct IP.
|
211
|
-
|
212
|
-
Unlike the echo_cli post command, query does not require the data value nor the data type (e.g. remove ':1|c' from 'example.post:1|c' and your query will still work).
|
213
|
-
|
214
|
-
With -v (verbose) option, query will print the status code and response body upon completion of the request.
|
215
|
-
|
216
|
-
With -e (epoch) option, echo_cli will format the response datapoints, with the verbose ('-v') option selected, such that their timestamps will be in epoch format.
|
217
|
-
|
218
|
-
With -s (sql) option, echo_cli will format the response data, with the verbose ('-v') option selected, to be usable within a sql database.
|
219
|
-
|
220
|
-
> $ echo_cli query 'example.post' 1492186212 1492186214 {-v}
|
221
|
-
LONGDESC
|
78
|
+
Query metrics on Echo. Use \"echo_cli query '<metric>' {time_start} {time_end}\"
|
222
79
|
|
223
|
-
|
224
|
-
Helper.new.check_for_IP()
|
80
|
+
`echo_cli query` will query a metric directly from Echo's Graphite server instance.
|
225
81
|
|
226
|
-
|
82
|
+
The default timestamp query range begins 15 minutes prior to the current time, to now.
|
227
83
|
|
228
|
-
|
229
|
-
metric_name = Helper.new.get_metric_name(metric)
|
230
|
-
tags = Helper.new.check_get_tags(metric)
|
231
|
-
opentsdb_query = Helper.new.get_query(time_start, time_end, metric_name, tags)
|
84
|
+
See: https://graphite-api.readthedocs.io/en/latest/api.html#from-until for possible time_start and time_end formats.
|
232
85
|
|
233
|
-
|
234
|
-
|
235
|
-
uri = URI.parse(opentsdb_uri)
|
236
|
-
https = Net::HTTP.new(uri.host, uri.port)
|
237
|
-
https.use_ssl = false
|
238
|
-
https.verify_mode = OpenSSL::SSL::VERIFY_NONE if https.use_ssl?
|
239
|
-
req = Net::HTTP::Post.new(uri.request_uri, initheader = {'Content-Type' => 'text/plain'}, )
|
240
|
-
req.body = opentsdb_query
|
241
|
-
|
242
|
-
if options[:v]
|
243
|
-
begin
|
244
|
-
res = https.request(req)
|
245
|
-
if res.code == '200'
|
246
|
-
|
247
|
-
json = JSON.parse(res.body)[0]
|
248
|
-
|
249
|
-
if !options[:e]
|
250
|
-
json["dps"] = {}
|
251
|
-
for i in JSON.parse(res.body)[0]["dps"].keys do
|
252
|
-
Helper.new.stfu do
|
253
|
-
json["dps"][convert(i)] = JSON.parse(res.body)[0]["dps"][i]
|
254
|
-
end
|
255
|
-
end
|
256
|
-
end
|
257
|
-
|
258
|
-
if options[:s]
|
259
|
-
sql = "CREATE TABLE " + metric + "(\n sep VARCHAR(24) NOT NULL PRIMARY KEY\n ,FIELD2 VARCHAR(21) NOT NULL\n);"
|
260
|
-
for i in json["dps"].keys do
|
261
|
-
Helper.new.stfu do
|
262
|
-
sql = sql + "\nINSERT INTO " + metric + "(sep,FIELD2) VALUES ('" + i.to_s + "','" + json["dps"][i].to_s + "');"
|
263
|
-
end
|
264
|
-
end
|
265
|
-
|
266
|
-
puts "\nSuccessfully retrieved ".green + metric_name.yellow + " from ".green + opentsdb_uri.blue + " in timestamp range: ".green + time_start.yellow + " to ".green + time_end.yellow + "\nSQL-ized data points:\n\n".green + sql.green
|
267
|
-
else
|
268
|
-
puts "\nSuccessfully retrieved ".green + metric_name.yellow + " from ".green + opentsdb_uri.blue + " in timestamp range: ".green + time_start.yellow + " to ".green + time_end.yellow + "\nData points:\n\n".green + JSON.pretty_generate(json).green
|
269
|
-
end
|
270
|
-
else
|
271
|
-
puts "\nFailed to retrieve ".red + metric_name.yellow + " from ".red + opentsdb_uri.blue + " in timestamp range: ".red + time_start.yellow + " to ".red + time_end.yellow + "\nStatus Code: ".red + res.code.yellow + "\nResponse Body: ".red + JSON.pretty_generate(JSON.parse(res.body)).red
|
272
|
-
end
|
273
|
-
rescue
|
274
|
-
puts "\nYour request returned an error. Are you sure your query was correct?"
|
275
|
-
end
|
276
|
-
else
|
277
|
-
begin
|
278
|
-
res = https.request(req)
|
279
|
-
if res.code == '200'
|
280
|
-
puts "\nSuccessfully retrieved ".green + metric_name.yellow + " from ".green + opentsdb_uri.blue + " in timestamp range: ".green + time_start.yellow + " to ".green + time_end.yellow
|
281
|
-
else
|
282
|
-
puts "\nFailed to retrieve ".red + metric_name.yellow + " from ".red + opentsdb_uri.blue + " in timestamp range: ".red + time_start.yellow + " to ".red + time_end.yellow
|
283
|
-
end
|
284
|
-
rescue
|
285
|
-
puts "\nYour request returned an error. Are you sure your query was correct?"
|
286
|
-
end
|
287
|
-
end
|
288
|
-
|
289
|
-
Helper.new.unset_envs()
|
290
|
-
|
291
|
-
return res.code
|
292
|
-
end
|
293
|
-
|
294
|
-
desc "fquery", "Query metrics on Echo from the current time. Use \"echo_cli fquery '<metric>' <range> {-e} {-s}\""
|
295
|
-
|
296
|
-
option :e
|
297
|
-
option :s
|
298
|
-
|
299
|
-
long_desc <<-LONGDESC
|
300
|
-
`echo_cli fquery` (fast query) will query a metric directly from Echo's OpenTSDB server instance for a given time range beginning in the present.
|
86
|
+
The metric-value number (following the ':' in the <metric> string parameter) can be random. The query command does not require this information, it is merely left in place for consistency across commands and ease-of-use.
|
301
87
|
|
302
88
|
Ensure single-quotes surround the metric.
|
303
89
|
|
304
90
|
Ensure the environment variable 'ECHO_CLI_HOST' is set to the correct IP.
|
305
91
|
|
306
|
-
|
307
|
-
|
308
|
-
The <range> parameter is defined in seconds, and is used to query the metric from the current time.
|
309
|
-
|
310
|
-
With -e (epoch) option, echo_cli will format the response datapoints such that their timestamps will be in epoch format.
|
311
|
-
|
312
|
-
With -s (sql) option, echo_cli will format the response data to be usable within a sql database.
|
313
|
-
|
314
|
-
> $ echo_cli fquery 'example' 30
|
315
|
-
|
316
|
-
The previous example would find all data points with metric name 'example' on Echo's OpenTSDB instance at 'localhost' in the last 30 seconds.
|
92
|
+
> $ echo_cli query 'example.query:1|c' {1492186212} {-5min}
|
317
93
|
LONGDESC
|
318
94
|
|
319
|
-
def
|
320
|
-
Helper.new
|
321
|
-
|
322
|
-
|
323
|
-
|
324
|
-
|
325
|
-
time_start = time_end - range.to_i
|
326
|
-
time_start = time_start.to_s
|
327
|
-
time_end = time_end.to_s
|
328
|
-
|
329
|
-
metric = Helper.new.get_metric(metric)
|
330
|
-
metric_name = Helper.new.get_metric_name(metric)
|
331
|
-
tags = Helper.new.check_get_tags(metric)
|
332
|
-
opentsdb_query = Helper.new.get_query(time_start, time_end, metric_name, tags)
|
333
|
-
|
334
|
-
Helper.new.set_envs()
|
335
|
-
|
336
|
-
uri = URI.parse(opentsdb_uri)
|
337
|
-
https = Net::HTTP.new(uri.host, uri.port)
|
338
|
-
https.use_ssl = false
|
339
|
-
https.verify_mode = OpenSSL::SSL::VERIFY_NONE if https.use_ssl?
|
340
|
-
req = Net::HTTP::Post.new(uri.request_uri, initheader = {'Content-Type' => 'text/plain'}, )
|
341
|
-
req.body = opentsdb_query
|
95
|
+
def query(metric, time_start = '-15min', time_end = 'now')
|
96
|
+
helper = Helper.new
|
97
|
+
helper.set_envs()
|
98
|
+
helper.check_for_IP()
|
99
|
+
metric = metric.gsub(/'/,"")
|
100
|
+
exit if !helper.check_metric_format(metric)
|
342
101
|
|
343
|
-
|
344
|
-
res = https.request(req)
|
345
|
-
if res.code == '200'
|
346
|
-
|
347
|
-
json = JSON.parse(res.body)[0]
|
348
|
-
|
349
|
-
if !options[:e]
|
350
|
-
json["dps"] = {}
|
351
|
-
for i in JSON.parse(res.body)[0]["dps"].keys do
|
352
|
-
Helper.new.stfu do
|
353
|
-
json["dps"][convert(i)] = JSON.parse(res.body)[0]["dps"][i]
|
354
|
-
end
|
355
|
-
end
|
356
|
-
end
|
102
|
+
query_url = 'http://' + ENV["ECHO_CLI_HOST"] + ':8080/render?target=' + helper.get_metric_string(metric) + '&from=' + time_start + '&until=' + time_end + '&format=json'
|
357
103
|
|
358
|
-
|
359
|
-
|
360
|
-
|
361
|
-
|
362
|
-
|
363
|
-
|
364
|
-
|
365
|
-
|
366
|
-
puts "\nSuccessfully retrieved ".green + metric_name.yellow + " from ".green + opentsdb_uri.blue + " in timestamp range: ".green + time_start.yellow + " to ".green + time_end.yellow + "\nSQL-ized data points in the last ".green + range.yellow + " seconds:\n\n".green + sql.green
|
367
|
-
else
|
368
|
-
puts "\nSuccessfully retrieved ".green + metric_name.yellow + " from ".green + opentsdb_uri.blue + " in timestamp range: ".green + time_start.yellow + " to ".green + time_end.yellow + "\nData points in the last ".green + range.yellow + " seconds:\n\n".green + JSON.pretty_generate(json).green
|
369
|
-
end
|
370
|
-
else
|
371
|
-
puts "\nFailed to retrieve ".red + metric_name.yellow + " from ".red + opentsdb_uri.blue + " in timestamp range: ".red + time_start.yellow + " to ".red + time_end.yellow + "\nStatus Code: ".red + res.code.yellow + "\nResponse Body: ".red + JSON.pretty_generate(JSON.parse(res.body)).red
|
372
|
-
end
|
373
|
-
rescue
|
374
|
-
puts "\nYour request returned an error. Are you sure your query was correct?"
|
104
|
+
response = helper.query_graphite(query_url)
|
105
|
+
if(response.code != '200')
|
106
|
+
puts "\nThe query returned a status code of ".red + response.code.yellow + ". If the query has start or end times, ensure they are formatted correctly.".red
|
107
|
+
puts "Otherwise, check your metric query formatting and the 'ECHO_CLI_HOST' environment variable value.".red
|
108
|
+
puts "\nResponse Body:\n".red
|
109
|
+
puts response.body
|
110
|
+
else
|
111
|
+
puts "\nSuccessful Query:\n\n".green + JSON.parse(response.body).to_s.green
|
375
112
|
end
|
376
|
-
|
377
|
-
Helper.new.unset_envs()
|
378
|
-
|
379
|
-
return res.code
|
113
|
+
helper.unset_envs()
|
380
114
|
end
|
381
115
|
|
382
116
|
desc "convert", "Convert timestamp formats. Use \"echo_cli convert <timestamp>\""
|
383
117
|
|
384
118
|
long_desc <<-LONGDESC
|
119
|
+
Convert timestamp formats. Use \"echo_cli convert <timestamp>\"
|
120
|
+
|
385
121
|
`echo_cli convert` will convert a given timestamp from epoch to a human-readable format, or vice-versa. Useful for determining locations of data on grafana. Ensure that an epoch timestamp has no punctation, and a human-readable timestamp follows the format 'YYYY-MM-DDTHH:MM:SS.SSS-Z' exactly.
|
386
122
|
|
387
123
|
Epoch timestamp example: 1492186214
|
@@ -406,14 +142,15 @@ module Echo_cli
|
|
406
142
|
desc "now", "The current time, in epoch and human-readable formats. Use \"echo_cli now\""
|
407
143
|
|
408
144
|
long_desc <<-LONGDESC
|
409
|
-
|
145
|
+
The current time, in epoch and human-readable formats. Use \"echo_cli now\"
|
410
146
|
|
411
|
-
|
147
|
+
`echo_cli now` will present the current timestamp (based on your computer's local time) to more easily utilize the rest of the Echo CLI commands.
|
412
148
|
|
413
|
-
|
149
|
+
Epoch timestamp example: 1492186214
|
414
150
|
|
415
|
-
|
151
|
+
Human-readable date/time timestamp example: 2011-10-18T21:01:52-07:00
|
416
152
|
|
153
|
+
> $ echo_cli now
|
417
154
|
LONGDESC
|
418
155
|
|
419
156
|
def now
|
@@ -423,6 +160,7 @@ module Echo_cli
|
|
423
160
|
end
|
424
161
|
|
425
162
|
class Helper
|
163
|
+
# useful silencing function, plz leave here
|
426
164
|
def stfu
|
427
165
|
begin
|
428
166
|
orig_stderr = $stderr.clone
|
@@ -441,61 +179,6 @@ module Echo_cli
|
|
441
179
|
retval
|
442
180
|
end
|
443
181
|
|
444
|
-
def check_get_tags(metric)
|
445
|
-
tags = ""
|
446
|
-
|
447
|
-
if metric.include? "."
|
448
|
-
tags = metric[metric.index(".")+1..-1] + "."
|
449
|
-
metric = metric[0..metric.index(".")-1]
|
450
|
-
|
451
|
-
toReturn = ""
|
452
|
-
count = 1
|
453
|
-
while tags.include?(".") do
|
454
|
-
toReturn = toReturn + "\"tag" + count.to_s + "\": \"" + tags[0..tags.index(".")-1] + "\""
|
455
|
-
count = count + 1
|
456
|
-
tags = tags[tags.index(".")+1..-1]
|
457
|
-
if tags.include?(".")
|
458
|
-
toReturn = toReturn + ",\n"
|
459
|
-
end
|
460
|
-
end
|
461
|
-
|
462
|
-
tags = toReturn
|
463
|
-
end
|
464
|
-
return tags
|
465
|
-
end
|
466
|
-
|
467
|
-
def get_metric(metric)
|
468
|
-
metric = metric.gsub(/'/,"")
|
469
|
-
if metric.include? ":"
|
470
|
-
metric = metric[0..metric.index(":")-1]
|
471
|
-
end
|
472
|
-
return metric
|
473
|
-
end
|
474
|
-
|
475
|
-
def get_metric_name(metric)
|
476
|
-
if metric.include?(".")
|
477
|
-
metric = metric[0..metric.index(".")-1]
|
478
|
-
end
|
479
|
-
return metric
|
480
|
-
end
|
481
|
-
|
482
|
-
def get_query(time_start, time_end, metric, tags)
|
483
|
-
opentsdb_query =
|
484
|
-
"{
|
485
|
-
\"start\": " + time_start + ",
|
486
|
-
\"end\": " + time_end + ",
|
487
|
-
\"queries\": [
|
488
|
-
{
|
489
|
-
\"aggregator\": \"sum\",
|
490
|
-
\"metric\": \"" + metric + "\",
|
491
|
-
\"tags\": {" + tags +
|
492
|
-
"}
|
493
|
-
}
|
494
|
-
]
|
495
|
-
}"
|
496
|
-
return opentsdb_query
|
497
|
-
end
|
498
|
-
|
499
182
|
def set_envs
|
500
183
|
ENV["http_proxy"] = ENV["HTTP_PROXY"]
|
501
184
|
ENV["https_proxy"] = ENV["HTTPS_PROXY"]
|
@@ -512,5 +195,50 @@ module Echo_cli
|
|
512
195
|
exit
|
513
196
|
end
|
514
197
|
end
|
198
|
+
|
199
|
+
def get_metric_string(metric)
|
200
|
+
type = metric[metric.index('|') + 1 .. metric.length]
|
201
|
+
case type
|
202
|
+
when 'c'
|
203
|
+
return "stats.counters." + metric[0..metric.index(':')-1] + ".count"
|
204
|
+
when 'ms'
|
205
|
+
return "stats.timers." + metric[0..metric.index(':')-1]
|
206
|
+
when 's'
|
207
|
+
return "stats.sets." + metric[0..metric.index(':')-1]
|
208
|
+
when 'g'
|
209
|
+
return "stats.gauges." + metric[0..metric.index(':')-1]
|
210
|
+
end
|
211
|
+
end
|
212
|
+
|
213
|
+
def check_metric_format(metric)
|
214
|
+
if /.*(:\d*\.?\d*)\|(ms|c|g|s)/.match(metric).to_s != metric
|
215
|
+
puts "\nThe posted metric was not of the correct form.\nMetrics must be of the form <metric>.<tag1>.<tag2>...<tagN>:<value>|<type>".red
|
216
|
+
puts "Where <value> is a number, and <type> is any of the following: 'ms', 'c', 's', 'g'.".red
|
217
|
+
return false
|
218
|
+
end
|
219
|
+
return true
|
220
|
+
end
|
221
|
+
|
222
|
+
def do_post_tcp(statsd_uri, port, request_body)
|
223
|
+
begin
|
224
|
+
timeout(10) do
|
225
|
+
socket = TCPSocket.new(statsd_uri, port)
|
226
|
+
socket.puts(request_body)
|
227
|
+
end
|
228
|
+
rescue Timeout::Error
|
229
|
+
puts "\nOperation timed out! Ensure the 'ECHO_CLI_HOST' environment variable is correct.".red
|
230
|
+
exit
|
231
|
+
end
|
232
|
+
end
|
233
|
+
|
234
|
+
def query_graphite(graphite_uri)
|
235
|
+
uri = URI.parse(graphite_uri)
|
236
|
+
https = Net::HTTP.new(uri.host, uri.port)
|
237
|
+
https.use_ssl = false
|
238
|
+
https.verify_mode = OpenSSL::SSL::VERIFY_NONE if https.use_ssl?
|
239
|
+
req = Net::HTTP::Get.new(uri.request_uri, initheader = {'Content-Type' => 'text/plain'}, )
|
240
|
+
res = https.request(req)
|
241
|
+
return res
|
242
|
+
end
|
515
243
|
end
|
516
244
|
end
|
data/lib/echo_cli/version.rb
CHANGED
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: echo_cli
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.6.
|
4
|
+
version: 0.6.28
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Brandon Raphael
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2017-
|
11
|
+
date: 2017-06-13 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: thor
|