graphite-api 0.4.0 → 1.0.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/README.md +4 -81
- data/Rakefile +17 -35
- data/lib/graphite-api.rb +2 -3
- data/lib/graphite-api/client.rb +1 -2
- data/lib/graphite-api/connector.rb +1 -0
- data/lib/graphite-api/version.rb +1 -1
- metadata +5 -9
- data/bin/graphite-middleware +0 -78
- data/lib/graphite-api/middleware.rb +0 -73
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 0f81b82a2dff25c88b118c8734da6711683cd3dbe4befa2d5faea3172d3c752b
|
4
|
+
data.tar.gz: f0c6278c05daba7691b3a854953b2a6f5d8abb0338298fddc76afa2ae8892d24
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: ea462f77942592a9b31067f091b417b3e6bc13a945f68e11c5d283744e7d585a3ee4136400175c5cd9778ccb012ccfca3bd3a9ed569eba3c7e83d861736dee89
|
7
|
+
data.tar.gz: 951db12f2528aeff81202121809c09d96394e25c65a2ca14a79297c0f3789c3f8109f931c28575303ae05d875b0edc0b24d9d5d2851d87f1735dec7cf4322e01
|
data/README.md
CHANGED
@@ -1,14 +1,12 @@
|
|
1
1
|
# Description
|
2
|
-
**GraphiteAPI** provides
|
2
|
+
**GraphiteAPI** provides a way for interacting with **Graphite's Carbon Daemon** using the **GraphiteAPI::Client**, that implements Graphite's [plaintext protocol](http://graphite.readthedocs.org/en/1.0/feeding-carbon.html).
|
3
3
|
|
4
4
|
## Package Content
|
5
5
|
* Includes a **simple** client for ruby.
|
6
|
-
* Ships with a **GraphiteAPI-Middleware**, which is a lightweight, event-driven, aggregator daemon.
|
7
6
|
* Utilities like scheduling and caching.
|
8
7
|
|
9
8
|
## Key Features
|
10
|
-
* **
|
11
|
-
* **Reanimation mode** - support cases which the same keys (same timestamps as well) can be received simultaneously and asynchronously from multiple input sources, in these cases GraphiteAPI-Middleware will "reanimate" old records (records that were already sent to Graphite server), and will send the sum of the reanimated record value + the value of the record that was just received to the graphite server; this new summed record should override the key with the new value on Graphite database.
|
9
|
+
* **Reanimation mode** - support cases which the same keys (same timestamps as well) can be received simultaneously and asynchronously from multiple input sources, in these cases GraphiteAPI will "reanimate" old records (records that were already sent to Graphite server), and will send the sum of the reanimated record value + the value of the record that was just received to the graphite server; this new summed record should override the key with the new value on Graphite database.
|
12
10
|
* **non-blocking I/O** ( EventMachine aware ).
|
13
11
|
* **Thread-Safe** client.
|
14
12
|
|
@@ -47,7 +45,7 @@ options = {
|
|
47
45
|
# Optional: set the max age in seconds for records reanimation ( default is 12 hours )
|
48
46
|
cache: 4 * 60 * 60,
|
49
47
|
|
50
|
-
# Optional: The default aggregation method for multiple reports in the same slice (default is :
|
48
|
+
# Optional: The default aggregation method for multiple reports in the same slice (default is :sum).
|
51
49
|
# Possible options: :sum, :avg, :replace
|
52
50
|
default_aggregation_method: :avg
|
53
51
|
}
|
@@ -126,19 +124,7 @@ require 'graphite-api'
|
|
126
124
|
client = GraphiteAPI.new graphite: 'udp://UNKNOWN-HOST:1234'
|
127
125
|
client.check!
|
128
126
|
|
129
|
-
SocketError: udp://UNKNOWN-HOST:1234: getaddrinfo: nodename nor servname provided, or not known
|
130
|
-
from graphite-api/lib/graphite-api/connector.rb:71:in `connect'
|
131
|
-
from graphite-api/lib/graphite-api/connector.rb:71:in `block in init_udp'
|
132
|
-
from graphite-api/lib/graphite-api/connector.rb:71:in `tap'
|
133
|
-
from graphite-api/lib/graphite-api/connector.rb:71:in `init_udp'
|
134
|
-
from graphite-api/lib/graphite-api/connector.rb:37:in `socket'
|
135
|
-
from graphite-api/lib/graphite-api/connector.rb:30:in `check!'
|
136
|
-
from graphite-api/lib/graphite-api/connector.rb:88:in `block in check!'
|
137
|
-
from graphite-api/lib/graphite-api/connector.rb:86:in `each'
|
138
|
-
from github/graphite-api/lib/graphite-api/connector.rb:86:in `check!'
|
139
|
-
from graphite-api/lib/graphite-api/client.rb:22:in `check!'
|
140
|
-
from (irb):4
|
141
|
-
from ~/.rvm/rubies/ruby-2.3.3/bin/irb:11:in `<main>'
|
127
|
+
# SocketError: udp://UNKNOWN-HOST:1234: getaddrinfo: nodename nor servname provided, or not known
|
142
128
|
```
|
143
129
|
|
144
130
|
Increment records
|
@@ -218,69 +204,6 @@ GraphiteAPI::Logger.logger.level = ::Logger::DEBUG
|
|
218
204
|
GraphiteAPI::Logger.init level: :debug, dev: 'logger.out' # or STDOUT | STDERR
|
219
205
|
```
|
220
206
|
|
221
|
-
## GraphiteAPI-Middleware Usage
|
222
|
-
* After installing GraphiteAPI gem, the `graphite-middleware` command should be available.
|
223
|
-
|
224
|
-
```
|
225
|
-
[root@graphite-middleware-node]# graphite-middleware --help
|
226
|
-
|
227
|
-
GraphiteAPI Middleware Server
|
228
|
-
|
229
|
-
Usage: graphite-middleware [options]
|
230
|
-
-g, --graphite HOST:PORT graphite host, in HOST:PORT format (can be specified multiple times)
|
231
|
-
-p, --port PORT listening port (default 2003)
|
232
|
-
-l, --log-file FILE log file
|
233
|
-
-L, --log-level LEVEL log level (default warn)
|
234
|
-
-P, --pid-file FILE pid file (default /var/run/graphite-middleware.pid)
|
235
|
-
-d, --daemonize run in background
|
236
|
-
-i, --interval INT report every X seconds (default 60)
|
237
|
-
-s, --slice SECONDS send to graphite in X seconds slices (default 60)
|
238
|
-
-r, --reanimation HOURS reanimate records that are younger than X hours, please see README
|
239
|
-
-m, --aggregation-method method The aggregation method (sum, avg or replace) for multiple reports in the same time slice (default sum)
|
240
|
-
|
241
|
-
More Info @ https://github.com/kontera-technologies/graphite-api
|
242
|
-
```
|
243
|
-
|
244
|
-
* launch **GraphiteAPI-Middleware** daemon
|
245
|
-
|
246
|
-
```
|
247
|
-
[root@graphite-middleware-node]# graphite-middleware \
|
248
|
-
--port 2005 \
|
249
|
-
--interval 60 \
|
250
|
-
--log-level debug \
|
251
|
-
--log-file /tmp/graphite-middleware.out \
|
252
|
-
--daemonize \
|
253
|
-
--graphite graphite-server:2003 \
|
254
|
-
--graphite graphite-backup-server:2003
|
255
|
-
```
|
256
|
-
|
257
|
-
* Send metrics via **UDP/TCP sockets**
|
258
|
-
|
259
|
-
```
|
260
|
-
[root@graphite-middleware-node] telnet localhost 2005
|
261
|
-
Trying 127.0.0.1...
|
262
|
-
Connected to localhost.
|
263
|
-
Escape character is '^]'.
|
264
|
-
example.middleware.value 10.2 1335008343
|
265
|
-
example.middleware.value2 99 1334929231
|
266
|
-
^C
|
267
|
-
[root@graphite-middleware-node]
|
268
|
-
```
|
269
|
-
|
270
|
-
* Or via **GraphtieAPI client**
|
271
|
-
|
272
|
-
```ruby
|
273
|
-
require 'graphite-api'
|
274
|
-
client = GraphiteAPI.new(:graphite => 'tcp://graphite-middleware-node:2005')
|
275
|
-
client.example.middleware.value 10.2
|
276
|
-
client.example.middleware.value2 27
|
277
|
-
client.bla.bla.value2 27
|
278
|
-
```
|
279
|
-
|
280
|
-
## Example Setup
|
281
|
-
<br/>
|
282
|
-
<img src="https://raw.github.com/kontera-technologies/graphite-api/master/examples/middleware_t1.png" align="center">
|
283
|
-
|
284
207
|
## Bugs
|
285
208
|
|
286
209
|
If you find a bug, feel free to report it @ our [issues tracker](https://github.com/kontera-technologies/graphite-api/issues) on github.
|
data/Rakefile
CHANGED
@@ -2,54 +2,36 @@ $:.unshift File.join(File.dirname(__FILE__), 'lib')
|
|
2
2
|
Dir.chdir File.dirname __FILE__
|
3
3
|
|
4
4
|
require 'graphite-api'
|
5
|
+
require "bundler/gem_tasks"
|
5
6
|
require "rake/testtask"
|
6
7
|
require 'rubygems/package_task'
|
7
8
|
|
8
|
-
|
9
|
-
|
9
|
+
Rake::TestTask.new(:prepare) do |t|
|
10
|
+
t.libs << "tests"
|
10
11
|
end
|
11
12
|
|
12
|
-
|
13
|
+
Rake::TestTask.new(:unit => :prepare) do |t|
|
14
|
+
t.pattern = "tests/unit/*_test.rb"
|
15
|
+
end
|
13
16
|
|
14
|
-
Rake::TestTask.new do |t|
|
15
|
-
t.
|
17
|
+
Rake::TestTask.new(:functional => :prepare) do |t|
|
18
|
+
t.pattern = "tests/functional/*_test.rb"
|
19
|
+
end
|
20
|
+
|
21
|
+
Rake::TestTask.new(:all => :prepare) do |t|
|
16
22
|
t.pattern = "tests/**/*_test.rb"
|
17
23
|
end
|
18
24
|
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
unless RUBY_COPYRIGHT.end_with?("Matsumoto")
|
25
|
-
puts("Functional tests are enabled only on MRI...")
|
26
|
-
next
|
27
|
-
end
|
28
|
-
|
29
|
-
message "Executing GraphiteAPI Functional Tests"
|
30
|
-
message "( You can skip them by passing SKIP_FUNC=true )"
|
31
|
-
|
32
|
-
Dir[File.expand_path("../tests/functional/*",__FILE__)].each do |file|
|
33
|
-
next unless file.end_with?(".rb")
|
34
|
-
now = Time.now.to_i
|
35
|
-
name = File.basename(file)
|
36
|
-
message "Executing #{name}"
|
37
|
-
Process.waitpid(Process.spawn("ruby", File.expand_path(file)))
|
38
|
-
took = "took #{Time.now.to_i - now} seconds"
|
39
|
-
if $?.success?
|
40
|
-
message "[PASS] #{name}, #{took}"
|
41
|
-
else
|
42
|
-
message "[FAIL] #{name}, #{took}"
|
43
|
-
some_failed = true
|
44
|
-
end
|
45
|
-
end
|
46
|
-
message "Done Executing GraphiteAPI Functional Tests"
|
47
|
-
abort "Some functional tests failed..." if some_failed
|
25
|
+
# Disable functional tests on JRuby
|
26
|
+
if RUBY_PLATFORM == "java"
|
27
|
+
task(:test => :unit)
|
28
|
+
else
|
29
|
+
task(:test => :all)
|
48
30
|
end
|
49
31
|
|
50
32
|
task :default => :test
|
51
33
|
|
52
|
-
task :gem => [:test
|
34
|
+
task :gem => [:test, :clobber_package]
|
53
35
|
|
54
36
|
GraphiteAPI::GemSpec = eval File.read 'graphite-api.gemspec'
|
55
37
|
|
data/lib/graphite-api.rb
CHANGED
@@ -3,7 +3,6 @@ require 'graphite-api/version'
|
|
3
3
|
require 'graphite-api/client'
|
4
4
|
require 'graphite-api/cache'
|
5
5
|
require 'graphite-api/connector'
|
6
|
-
require 'graphite-api/middleware'
|
7
6
|
require 'graphite-api/buffer'
|
8
7
|
require 'graphite-api/logger'
|
9
8
|
|
@@ -12,9 +11,9 @@ module GraphiteAPI
|
|
12
11
|
def self.version
|
13
12
|
GraphiteAPI::VERSION
|
14
13
|
end
|
15
|
-
|
14
|
+
|
16
15
|
def self.new options
|
17
16
|
Client.new options
|
18
17
|
end
|
19
|
-
|
18
|
+
|
20
19
|
end
|
data/lib/graphite-api/client.rb
CHANGED
@@ -5,8 +5,7 @@ module GraphiteAPI
|
|
5
5
|
class Client
|
6
6
|
extend Forwardable
|
7
7
|
|
8
|
-
def_delegator Zscheduler, :loop, :
|
9
|
-
def_delegator Zscheduler, :stop
|
8
|
+
def_delegator Zscheduler, :loop, :stop
|
10
9
|
|
11
10
|
attr_reader :options, :buffer, :connectors, :mu
|
12
11
|
private :options, :buffer, :connectors, :mu
|
data/lib/graphite-api/version.rb
CHANGED
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: graphite-api
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 1.0.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Eran Barak Levi
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2019-
|
11
|
+
date: 2019-03-19 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: eventmachine
|
@@ -40,15 +40,13 @@ dependencies:
|
|
40
40
|
version: 0.0.7
|
41
41
|
description: Graphite API - A Simple ruby client, aggregator daemon and API tools
|
42
42
|
email: eran@kontera.com
|
43
|
-
executables:
|
44
|
-
- graphite-middleware
|
43
|
+
executables: []
|
45
44
|
extensions: []
|
46
45
|
extra_rdoc_files: []
|
47
46
|
files:
|
48
47
|
- LICENSE
|
49
48
|
- README.md
|
50
49
|
- Rakefile
|
51
|
-
- bin/graphite-middleware
|
52
50
|
- lib/graphite-api.rb
|
53
51
|
- lib/graphite-api/buffer.rb
|
54
52
|
- lib/graphite-api/cache.rb
|
@@ -56,7 +54,6 @@ files:
|
|
56
54
|
- lib/graphite-api/connector.rb
|
57
55
|
- lib/graphite-api/core_ext/numeric.rb
|
58
56
|
- lib/graphite-api/logger.rb
|
59
|
-
- lib/graphite-api/middleware.rb
|
60
57
|
- lib/graphite-api/version.rb
|
61
58
|
homepage: http://www.kontera.com
|
62
59
|
licenses:
|
@@ -70,15 +67,14 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
70
67
|
requirements:
|
71
68
|
- - ">="
|
72
69
|
- !ruby/object:Gem::Version
|
73
|
-
version:
|
70
|
+
version: '2.3'
|
74
71
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
75
72
|
requirements:
|
76
73
|
- - ">="
|
77
74
|
- !ruby/object:Gem::Version
|
78
75
|
version: '0'
|
79
76
|
requirements: []
|
80
|
-
|
81
|
-
rubygems_version: 2.7.8
|
77
|
+
rubygems_version: 3.0.3
|
82
78
|
signing_key:
|
83
79
|
specification_version: 4
|
84
80
|
summary: Graphite Ruby Client
|
data/bin/graphite-middleware
DELETED
@@ -1,78 +0,0 @@
|
|
1
|
-
#!/usr/bin/env ruby
|
2
|
-
$:.unshift File.expand_path('../../lib',__FILE__)
|
3
|
-
|
4
|
-
require 'graphite-api'
|
5
|
-
require 'optparse'
|
6
|
-
|
7
|
-
options = GraphiteAPI::Client.default_options.merge interval: 60
|
8
|
-
|
9
|
-
OptionParser.new do |opts|
|
10
|
-
opts.banner = "GraphiteAPI Middleware Server"
|
11
|
-
opts.define_head "Usage: graphite-middleware [options]"
|
12
|
-
opts.define_head ""
|
13
|
-
|
14
|
-
opts.on("-g", "--graphite [udp,tcp]://host:port", "can be specified multiple times") do |graphite|
|
15
|
-
options[:backends].push graphite
|
16
|
-
end
|
17
|
-
|
18
|
-
opts.on("-p", "--port PORT","listening port (default #{options[:port]})") do |port|
|
19
|
-
options[:port] = port
|
20
|
-
end
|
21
|
-
|
22
|
-
opts.on("-l", "--log-file FILE","log file") do |file|
|
23
|
-
options[:log_file] = File::expand_path(file)
|
24
|
-
end
|
25
|
-
|
26
|
-
opts.on("-L", "--log-level LEVEL","log level (default warn)") do |level|
|
27
|
-
options[:log_level] = level
|
28
|
-
end
|
29
|
-
|
30
|
-
opts.on("-P", "--pid-file FILE","pid file (default #{options[:pid]})") do |pid_file|
|
31
|
-
options[:pid] = pid_file
|
32
|
-
end
|
33
|
-
|
34
|
-
opts.on("-d", "--daemonize","run in background") do
|
35
|
-
options[:daemonize] = true
|
36
|
-
end
|
37
|
-
|
38
|
-
opts.on("-i", "--interval INT","report every X seconds (default #{options[:interval]})") do |x_seconds|
|
39
|
-
options[:interval] = x_seconds.to_i if x_seconds.to_i > 0
|
40
|
-
end
|
41
|
-
|
42
|
-
opts.on("-s", "--slice SECONDS","send to graphite in X seconds slices (default #{options[:slice]})") do |slice|
|
43
|
-
options[:slice] = slice.to_i if slice.to_i >= 0
|
44
|
-
end
|
45
|
-
|
46
|
-
opts.on("-r", "--reanimation HOURS","reanimate records that are younger than X hours, please see README") do |exp|
|
47
|
-
(options[:cache] = exp.to_i * 3600) if exp.to_i > 0
|
48
|
-
end
|
49
|
-
|
50
|
-
opts.on("-m", "--aggregation-method method","The aggregation method (sum, avg or replace) for multiple reports in the same time slice (default sum)") do |exp|
|
51
|
-
raise "Invalid aggregation method. Valid values are sum, avg or replace." unless ["sum", "avg", "replace"].include? exp
|
52
|
-
options[:default_aggregation_method] = exp.to_sym
|
53
|
-
end
|
54
|
-
|
55
|
-
opts.on("-v", "--version","Show version and exit") do |exp|
|
56
|
-
puts "Version #{GraphiteAPI.version}"
|
57
|
-
exit
|
58
|
-
end
|
59
|
-
|
60
|
-
opts.separator ""
|
61
|
-
opts.separator "More Info @ https://github.com/kontera-technologies/graphite-api"
|
62
|
-
opts.separator ""
|
63
|
-
|
64
|
-
opts.define_tail ""
|
65
|
-
opts.define_tail ""
|
66
|
-
end.parse! ARGV
|
67
|
-
|
68
|
-
abort "You must specify at least one graphite host" if options[:backends].empty?
|
69
|
-
|
70
|
-
GraphiteAPI::Logger.init Hash[[:dev,:level].zip options.values_at(:log_file, :log_level) ]
|
71
|
-
|
72
|
-
begin
|
73
|
-
Process.daemon if options[:daemonize]
|
74
|
-
GraphiteAPI::Middleware.start options
|
75
|
-
rescue Interrupt
|
76
|
-
GraphiteAPI::Logger.info "Shutting down..."
|
77
|
-
Zscheduler.stop
|
78
|
-
end
|
@@ -1,73 +0,0 @@
|
|
1
|
-
# -----------------------------------------------------
|
2
|
-
# Graphite Middleware Server
|
3
|
-
# Should be placed between graphite server and graphite clients
|
4
|
-
# - Data Aggregator
|
5
|
-
# - Caching
|
6
|
-
# - Data Manipulation
|
7
|
-
# -----------------------------------------------------
|
8
|
-
# Usage:
|
9
|
-
# GraphiteAPI::Middleware.start(options)
|
10
|
-
#
|
11
|
-
# Options:
|
12
|
-
# graphite target graphite hostname
|
13
|
-
# reanimation_exp cache lifetime in seconds (default is 43200 seconds)
|
14
|
-
# prefix add prefix to each key
|
15
|
-
# interval report to graphite every X seconds (default is 60)
|
16
|
-
# slice send to graphite in X seconds slices (default is 60)
|
17
|
-
# log_level info
|
18
|
-
# -----------------------------------------------------
|
19
|
-
require 'eventmachine'
|
20
|
-
require 'socket'
|
21
|
-
|
22
|
-
module GraphiteAPI
|
23
|
-
class Middleware < EventMachine::Connection
|
24
|
-
|
25
|
-
def initialize buffer
|
26
|
-
@buffer = buffer and super
|
27
|
-
end
|
28
|
-
|
29
|
-
attr_reader :buffer, :client_id
|
30
|
-
|
31
|
-
def post_init
|
32
|
-
@client_id = peername
|
33
|
-
Logger.debug [:middleware, :connecting, client_id]
|
34
|
-
end
|
35
|
-
|
36
|
-
def receive_data data
|
37
|
-
Logger.debug [:middleware, :message, client_id, data]
|
38
|
-
buffer.stream data, client_id
|
39
|
-
end
|
40
|
-
|
41
|
-
def unbind
|
42
|
-
Logger.debug [:middleware, :disconnecting, client_id]
|
43
|
-
end
|
44
|
-
|
45
|
-
def peername
|
46
|
-
port, *ip = get_peername[2,6].unpack "nC4"
|
47
|
-
[ip.join("."),port].join ":"
|
48
|
-
end
|
49
|
-
|
50
|
-
private :peername
|
51
|
-
|
52
|
-
def self.start options
|
53
|
-
EventMachine.run do
|
54
|
-
GraphiteAPI::Logger.info "Server running on port #{options[:port]}"
|
55
|
-
|
56
|
-
buffer = GraphiteAPI::Buffer.new options
|
57
|
-
group = GraphiteAPI::Connector::Group.new options
|
58
|
-
|
59
|
-
# Starting server
|
60
|
-
[:start_server, :open_datagram_socket].each do |m|
|
61
|
-
EventMachine.send(m,'0.0.0.0',options[:port],self,buffer)
|
62
|
-
end
|
63
|
-
|
64
|
-
# Send metrics to graphite every X seconds
|
65
|
-
Zscheduler.every(options[:interval], :on_shutdown => true) do
|
66
|
-
group.publish buffer.pull :string if buffer.new_records?
|
67
|
-
end
|
68
|
-
|
69
|
-
end
|
70
|
-
end
|
71
|
-
|
72
|
-
end
|
73
|
-
end
|