graphite-api 0.0.6 → 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/README.md +12 -11
- data/lib/graphite-api.rb +15 -14
- data/lib/graphite-api/{safe_buffer.rb → buffer.rb} +4 -4
- data/lib/graphite-api/cache/memory.rb +2 -2
- data/lib/graphite-api/client.rb +34 -27
- data/lib/graphite-api/connector.rb +17 -0
- data/lib/graphite-api/core_ext/numeric.rb +1 -20
- data/lib/graphite-api/middleware.rb +6 -6
- data/lib/graphite-api/runner.rb +2 -2
- data/lib/graphite-api/utils.rb +6 -2
- data/lib/graphite-api/version.rb +1 -3
- data/tasks/build.rake +2 -1
- metadata +19 -5
- data/lib/graphite-api/connector_group.rb +0 -18
- data/lib/graphite-api/reactor.rb +0 -59
data/README.md
CHANGED
@@ -51,11 +51,12 @@ Creating a new client instance
|
|
51
51
|
require 'graphite-api'
|
52
52
|
|
53
53
|
GraphiteAPI::Client.new(
|
54
|
-
graphite: "graphite.example.com:2003", #
|
55
|
-
prefix: ["example","prefix"],
|
56
|
-
slice: 60
|
57
|
-
interval: 60
|
58
|
-
|
54
|
+
graphite: "graphite.example.com:2003", # required argument
|
55
|
+
prefix: ["example","prefix"], # add example.prefix to each key
|
56
|
+
slice: 60, # results are aggregated in 60 seconds slices
|
57
|
+
interval: 60, # send to graphite every 60 seconds
|
58
|
+
# default is 0 ( direct send )
|
59
|
+
cache: 4 * 60 * 60 # set the max age in seconds for records reanimation
|
59
60
|
)
|
60
61
|
```
|
61
62
|
|
@@ -131,7 +132,7 @@ client = GraphiteAPI::Client.new( graphite: 'graphite:2003' )
|
|
131
132
|
|
132
133
|
# lets send the metric every 120 seconds
|
133
134
|
client.every(120) do |c|
|
134
|
-
c.webServer.web01.uptime `uptime`.split.first.to_i
|
135
|
+
c.metrics("webServer.web01.uptime" => `uptime`.split.first.to_i)
|
135
136
|
end
|
136
137
|
```
|
137
138
|
|
@@ -143,11 +144,11 @@ require 'graphite-api/core_ext/numeric'
|
|
143
144
|
client = GraphiteAPI::Client.new( graphite: 'graphite:2003' )
|
144
145
|
|
145
146
|
client.every 10.seconds do |c|
|
146
|
-
c.webServer.web01.uptime `uptime`.split.first.to_i
|
147
|
+
c.metrics("webServer.web01.uptime" => `uptime`.split.first.to_i)
|
147
148
|
end
|
148
149
|
|
149
150
|
client.every 52.minutes do |c|
|
150
|
-
c.just.fake 12
|
151
|
+
c.metrics("just.fake" => 12)
|
151
152
|
end
|
152
153
|
```
|
153
154
|
|
@@ -159,9 +160,9 @@ require 'graphite-api/core_ext/numeric'
|
|
159
160
|
client = GraphiteAPI::Client.new( graphite: 'graphite:2003' )
|
160
161
|
|
161
162
|
client.every 26.minutes do |c|
|
162
|
-
c.webServer.shuki.stats 10
|
163
|
-
c.webServer.shuki.x 97
|
164
|
-
c.webServer.shuki.y 121
|
163
|
+
c.metrics("webServer.shuki.stats" => 10)
|
164
|
+
c.metrics("webServer.shuki.x" => 97)
|
165
|
+
c.metrics("webServer.shuki.y" => 121)
|
165
166
|
end
|
166
167
|
|
167
168
|
client.join # wait for ever...
|
data/lib/graphite-api.rb
CHANGED
@@ -1,22 +1,23 @@
|
|
1
|
+
require 'zscheduler'
|
2
|
+
|
1
3
|
module GraphiteAPI
|
2
4
|
ROOT = File.expand_path(File.dirname(__FILE__))
|
5
|
+
require "#{ROOT}/graphite-api/version"
|
3
6
|
|
4
|
-
autoload :Version,
|
5
|
-
autoload :Client,
|
6
|
-
autoload :Cache,
|
7
|
-
autoload :
|
8
|
-
autoload :
|
9
|
-
autoload :
|
10
|
-
autoload :
|
11
|
-
autoload :
|
12
|
-
autoload :
|
13
|
-
autoload :
|
14
|
-
autoload :
|
15
|
-
autoload :Logger, "#{ROOT}/graphite-api/logger"
|
16
|
-
autoload :ConnectorGroup, "#{ROOT}/graphite-api/connector_group"
|
7
|
+
autoload :Version, "#{ROOT}/graphite-api/version"
|
8
|
+
autoload :Client, "#{ROOT}/graphite-api/client"
|
9
|
+
autoload :Cache, "#{ROOT}/graphite-api/cache"
|
10
|
+
autoload :Reactor, "#{ROOT}/graphite-api/reactor"
|
11
|
+
autoload :Connector, "#{ROOT}/graphite-api/connector"
|
12
|
+
autoload :Middleware, "#{ROOT}/graphite-api/middleware"
|
13
|
+
autoload :Runner, "#{ROOT}/graphite-api/runner"
|
14
|
+
autoload :Utils, "#{ROOT}/graphite-api/utils"
|
15
|
+
autoload :CLI, "#{ROOT}/graphite-api/cli"
|
16
|
+
autoload :Buffer, "#{ROOT}/graphite-api/buffer"
|
17
|
+
autoload :Logger, "#{ROOT}/graphite-api/logger"
|
17
18
|
|
18
19
|
def self.version
|
19
|
-
GraphiteAPI::
|
20
|
+
GraphiteAPI::VERSION
|
20
21
|
end
|
21
22
|
|
22
23
|
end
|
@@ -3,7 +3,7 @@
|
|
3
3
|
# Handle Socket & Client data streams
|
4
4
|
# -----------------------------------------------------
|
5
5
|
# Usage:
|
6
|
-
# buff = GraphiteAPI::
|
6
|
+
# buff = GraphiteAPI::Buffer.new(GraphiteAPI::Utils.default_options)
|
7
7
|
# buff << {:metric => {"load_avg" => 10},:time => Time.now}
|
8
8
|
# buff << {:metric => {"load_avg" => 30},:time => Time.now}
|
9
9
|
# buff.stream "mem.usage 1"
|
@@ -20,7 +20,7 @@ require 'thread'
|
|
20
20
|
require 'set'
|
21
21
|
|
22
22
|
module GraphiteAPI
|
23
|
-
class
|
23
|
+
class Buffer
|
24
24
|
include Utils
|
25
25
|
|
26
26
|
CHARS_TO_BE_IGNORED = ["\r"]
|
@@ -90,7 +90,7 @@ module GraphiteAPI
|
|
90
90
|
end
|
91
91
|
|
92
92
|
def inspect
|
93
|
-
"#<GraphiteAPI::
|
93
|
+
"#<GraphiteAPI::Buffer:%s @quque#size=%s @streamer=%s>" %
|
94
94
|
[object_id,queue.size,streamer]
|
95
95
|
end
|
96
96
|
|
@@ -122,4 +122,4 @@ module GraphiteAPI
|
|
122
122
|
end
|
123
123
|
|
124
124
|
end
|
125
|
-
end
|
125
|
+
end
|
@@ -4,7 +4,7 @@ module GraphiteAPI
|
|
4
4
|
include Utils
|
5
5
|
|
6
6
|
def initialize options
|
7
|
-
|
7
|
+
Zscheduler.every(120) { clean(options[:cache]) }
|
8
8
|
end
|
9
9
|
|
10
10
|
def get time, key
|
@@ -33,4 +33,4 @@ module GraphiteAPI
|
|
33
33
|
|
34
34
|
end
|
35
35
|
end
|
36
|
-
end
|
36
|
+
end
|
data/lib/graphite-api/client.rb
CHANGED
@@ -44,32 +44,36 @@ module GraphiteAPI
|
|
44
44
|
class Client
|
45
45
|
include Utils
|
46
46
|
|
47
|
+
private_reader :options, :buffer, :connectors, :direct_send
|
48
|
+
|
47
49
|
def initialize opt
|
48
50
|
@options = build_options validate opt.clone
|
49
|
-
@buffer = GraphiteAPI::
|
50
|
-
@connectors = GraphiteAPI::
|
51
|
-
|
52
|
-
|
53
|
-
|
51
|
+
@buffer = GraphiteAPI::Buffer.new options
|
52
|
+
@connectors = GraphiteAPI::Connector::Group.new options
|
53
|
+
@direct_send = @options[:interval] == 0
|
54
|
+
|
55
|
+
if direct_send
|
56
|
+
options[:slice] = 1
|
57
|
+
else
|
58
|
+
every(options.fetch(:interval),&method(:send_metrics))
|
54
59
|
end
|
55
|
-
|
60
|
+
|
56
61
|
end
|
57
62
|
|
58
|
-
|
63
|
+
def_delegator Zscheduler, :loop, :join
|
64
|
+
def_delegator Zscheduler, :stop
|
59
65
|
|
60
|
-
def_delegator :"GraphiteAPI::Reactor", :loop
|
61
|
-
def_delegator :"GraphiteAPI::Reactor", :stop
|
62
|
-
|
63
66
|
def every interval, &block
|
64
|
-
|
67
|
+
Zscheduler.every( interval ) { block.arity == 1 ? block.call(self) : block.call }
|
65
68
|
end
|
66
|
-
|
69
|
+
|
67
70
|
def metrics metric, time = Time.now
|
68
71
|
buffer.push :metric => metric, :time => time
|
72
|
+
send_metrics if direct_send
|
69
73
|
end
|
70
|
-
|
74
|
+
|
71
75
|
alias_method :add_metrics, :metrics
|
72
|
-
|
76
|
+
|
73
77
|
# increment keys
|
74
78
|
#
|
75
79
|
# increment("key1","key2")
|
@@ -88,27 +92,27 @@ module GraphiteAPI
|
|
88
92
|
metric = keys.inject({}) {|h,k| h.tap { h[k] = by}}
|
89
93
|
metrics(metric, time)
|
90
94
|
end
|
91
|
-
|
95
|
+
|
92
96
|
def join
|
93
97
|
sleep while buffer.new_records?
|
94
98
|
end
|
95
|
-
|
99
|
+
|
96
100
|
def method_missing m, *args, &block
|
97
|
-
Proxy.new( self ).send
|
101
|
+
Proxy.new( self ).send(m,*args,&block)
|
98
102
|
end
|
99
|
-
|
103
|
+
|
100
104
|
protected
|
101
|
-
|
105
|
+
|
102
106
|
class Proxy
|
103
107
|
include Utils
|
104
|
-
|
108
|
+
|
105
109
|
def initialize client
|
106
110
|
@client = client
|
107
111
|
@keys = []
|
108
112
|
end
|
109
|
-
|
113
|
+
|
110
114
|
private_reader :client, :keys
|
111
|
-
|
115
|
+
|
112
116
|
def method_missing m, *args, &block
|
113
117
|
keys.push m
|
114
118
|
if keys.size > 10 # too deep
|
@@ -119,22 +123,25 @@ module GraphiteAPI
|
|
119
123
|
self
|
120
124
|
end
|
121
125
|
end
|
122
|
-
|
126
|
+
|
123
127
|
end
|
124
|
-
|
128
|
+
|
125
129
|
def validate options
|
126
130
|
options.tap do |opt|
|
127
131
|
raise ArgumentError.new ":graphite must be specified" if opt[:graphite].nil?
|
128
132
|
end
|
129
133
|
end
|
130
|
-
|
134
|
+
|
131
135
|
def build_options opt
|
132
136
|
default_options.tap do |options_hash|
|
133
137
|
options_hash[:backends].push expand_host opt.delete :graphite
|
134
138
|
options_hash.merge! opt
|
135
|
-
options_hash.freeze
|
136
139
|
end
|
137
140
|
end
|
138
|
-
|
141
|
+
|
142
|
+
def send_metrics
|
143
|
+
connectors.publish buffer.pull :string if buffer.new_records?
|
144
|
+
end
|
145
|
+
|
139
146
|
end
|
140
147
|
end
|
@@ -12,6 +12,23 @@ require 'socket'
|
|
12
12
|
|
13
13
|
module GraphiteAPI
|
14
14
|
class Connector
|
15
|
+
class Group
|
16
|
+
include Utils
|
17
|
+
|
18
|
+
private_reader :options, :connectors
|
19
|
+
|
20
|
+
def initialize options
|
21
|
+
@options = options
|
22
|
+
@connectors = options[:backends].map { |o| Connector.new(*o) }
|
23
|
+
end
|
24
|
+
|
25
|
+
def publish messages
|
26
|
+
debug [:connector_group,:publish,messages.size, @connectors]
|
27
|
+
Array(messages).each { |msg| connectors.map {|c| c.puts msg} }
|
28
|
+
end
|
29
|
+
|
30
|
+
end
|
31
|
+
|
15
32
|
include Utils
|
16
33
|
|
17
34
|
def initialize host, port
|
@@ -1,20 +1 @@
|
|
1
|
-
|
2
|
-
{
|
3
|
-
:year => 365 * 24 * 3600,
|
4
|
-
:month => 30 * 24 * 3600,
|
5
|
-
:week => 7 * 24 * 3600,
|
6
|
-
:day => 24 * 3600,
|
7
|
-
:hour => 3600,
|
8
|
-
:minute => 60,
|
9
|
-
:second => 1
|
10
|
-
}.each do |m,val|
|
11
|
-
respond_to? m or define_method m do
|
12
|
-
self * val
|
13
|
-
end
|
14
|
-
|
15
|
-
"#{m}s".tap do |plural|
|
16
|
-
respond_to? plural or alias_method plural, m
|
17
|
-
end
|
18
|
-
|
19
|
-
end
|
20
|
-
end
|
1
|
+
require 'zscheduler/core_ext/numeric'
|
@@ -57,8 +57,8 @@ module GraphiteAPI
|
|
57
57
|
EventMachine.run do
|
58
58
|
GraphiteAPI::Logger.info "Server running on port #{options[:port]}"
|
59
59
|
|
60
|
-
buffer = GraphiteAPI::
|
61
|
-
group = GraphiteAPI::
|
60
|
+
buffer = GraphiteAPI::Buffer.new options
|
61
|
+
group = GraphiteAPI::Connector::Group.new options
|
62
62
|
|
63
63
|
# Starting server
|
64
64
|
[:start_server, :open_datagram_socket].each do |m|
|
@@ -66,12 +66,12 @@ module GraphiteAPI
|
|
66
66
|
end
|
67
67
|
|
68
68
|
# Send metrics to graphite every X seconds
|
69
|
-
|
70
|
-
|
71
|
-
GraphiteAPI::Reactor.add_shutdown_hook &block
|
69
|
+
Zscheduler.every(options[:interval],:on_shutdown => true) do
|
70
|
+
group.publish buffer.pull :string if buffer.new_records?
|
72
71
|
end
|
72
|
+
|
73
73
|
end
|
74
74
|
end
|
75
75
|
|
76
76
|
end # Middleware
|
77
|
-
end # GraphiteAPI
|
77
|
+
end # GraphiteAPI
|
data/lib/graphite-api/runner.rb
CHANGED
@@ -36,12 +36,12 @@ module GraphiteAPI
|
|
36
36
|
Middleware.start options
|
37
37
|
rescue Interrupt
|
38
38
|
Logger.info "Shutting down..."
|
39
|
-
|
39
|
+
Zscheduler.shutdown
|
40
40
|
end
|
41
41
|
end
|
42
42
|
|
43
43
|
def options
|
44
|
-
@options ||= Utils.
|
44
|
+
@options ||= Utils.default_middleware_options
|
45
45
|
end
|
46
46
|
|
47
47
|
def validate_options
|
data/lib/graphite-api/utils.rb
CHANGED
@@ -56,11 +56,15 @@ module GraphiteAPI
|
|
56
56
|
:cache => nil,
|
57
57
|
:host => "localhost",
|
58
58
|
:prefix => [],
|
59
|
-
:interval =>
|
59
|
+
:interval => 0,
|
60
60
|
:slice => 60,
|
61
61
|
:pid => "/tmp/graphite-middleware.pid"
|
62
62
|
}
|
63
63
|
end
|
64
64
|
|
65
|
+
def default_middleware_options
|
66
|
+
default_options.merge(:interval => 60)
|
67
|
+
end
|
68
|
+
|
65
69
|
end
|
66
|
-
end
|
70
|
+
end
|
data/lib/graphite-api/version.rb
CHANGED
data/tasks/build.rake
CHANGED
@@ -17,6 +17,7 @@ GraphiteAPI::GemSpec = Gem::Specification.new do |s|
|
|
17
17
|
s.bindir = "bin"
|
18
18
|
|
19
19
|
s.add_dependency 'eventmachine','>= 0.3.3'
|
20
|
+
s.add_dependency 'zscheduler', '>= 0.0.3'
|
20
21
|
end
|
21
22
|
|
22
23
|
task :gem => [:test,:clobber_package]
|
@@ -28,4 +29,4 @@ end
|
|
28
29
|
task :install => [:gem] do
|
29
30
|
sh "gem install pkg/graphite-api"
|
30
31
|
Rake::Task['clobber_package'].execute
|
31
|
-
end
|
32
|
+
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: graphite-api
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0
|
4
|
+
version: 0.1.0
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -9,7 +9,7 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date: 2013-
|
12
|
+
date: 2013-05-09 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: eventmachine
|
@@ -27,6 +27,22 @@ dependencies:
|
|
27
27
|
- - ! '>='
|
28
28
|
- !ruby/object:Gem::Version
|
29
29
|
version: 0.3.3
|
30
|
+
- !ruby/object:Gem::Dependency
|
31
|
+
name: zscheduler
|
32
|
+
requirement: !ruby/object:Gem::Requirement
|
33
|
+
none: false
|
34
|
+
requirements:
|
35
|
+
- - ! '>='
|
36
|
+
- !ruby/object:Gem::Version
|
37
|
+
version: 0.0.3
|
38
|
+
type: :runtime
|
39
|
+
prerelease: false
|
40
|
+
version_requirements: !ruby/object:Gem::Requirement
|
41
|
+
none: false
|
42
|
+
requirements:
|
43
|
+
- - ! '>='
|
44
|
+
- !ruby/object:Gem::Version
|
45
|
+
version: 0.0.3
|
30
46
|
description: Graphite API - A Simple ruby client, aggregator daemon and API tools
|
31
47
|
email: eran@kontera.com
|
32
48
|
executables:
|
@@ -37,18 +53,16 @@ files:
|
|
37
53
|
- README.md
|
38
54
|
- Rakefile
|
39
55
|
- bin/graphite-middleware
|
56
|
+
- lib/graphite-api/buffer.rb
|
40
57
|
- lib/graphite-api/cache/memory.rb
|
41
58
|
- lib/graphite-api/cache.rb
|
42
59
|
- lib/graphite-api/cli.rb
|
43
60
|
- lib/graphite-api/client.rb
|
44
61
|
- lib/graphite-api/connector.rb
|
45
|
-
- lib/graphite-api/connector_group.rb
|
46
62
|
- lib/graphite-api/core_ext/numeric.rb
|
47
63
|
- lib/graphite-api/logger.rb
|
48
64
|
- lib/graphite-api/middleware.rb
|
49
|
-
- lib/graphite-api/reactor.rb
|
50
65
|
- lib/graphite-api/runner.rb
|
51
|
-
- lib/graphite-api/safe_buffer.rb
|
52
66
|
- lib/graphite-api/utils.rb
|
53
67
|
- lib/graphite-api/version.rb
|
54
68
|
- lib/graphite-api.rb
|
@@ -1,18 +0,0 @@
|
|
1
|
-
module GraphiteAPI
|
2
|
-
class ConnectorGroup
|
3
|
-
include Utils
|
4
|
-
|
5
|
-
private_reader :options, :connectors
|
6
|
-
|
7
|
-
def initialize options
|
8
|
-
@options = options
|
9
|
-
@connectors = options[:backends].map { |o| Connector.new(*o) }
|
10
|
-
end
|
11
|
-
|
12
|
-
def publish messages
|
13
|
-
debug [:connector_group,:publish,messages.size, @connectors]
|
14
|
-
Array(messages).each { |msg| connectors.map {|c| c.puts msg} }
|
15
|
-
end
|
16
|
-
|
17
|
-
end
|
18
|
-
end
|
data/lib/graphite-api/reactor.rb
DELETED
@@ -1,59 +0,0 @@
|
|
1
|
-
require 'eventmachine'
|
2
|
-
|
3
|
-
module GraphiteAPI
|
4
|
-
class Reactor
|
5
|
-
@@wrapper = nil
|
6
|
-
|
7
|
-
class << self
|
8
|
-
def every(frequency,&block)
|
9
|
-
reactor_running? or start_reactor
|
10
|
-
timers << EventMachine::PeriodicTimer.new(frequency.to_i) { yield }
|
11
|
-
timers.last
|
12
|
-
end
|
13
|
-
|
14
|
-
def stop
|
15
|
-
timers.each(&:cancel)
|
16
|
-
shutdown_hooks.each(&:call)
|
17
|
-
wrapper and EventMachine.stop
|
18
|
-
end
|
19
|
-
|
20
|
-
def join
|
21
|
-
wrapper and wrapper.join
|
22
|
-
end
|
23
|
-
|
24
|
-
def add_shutdown_hook(&block)
|
25
|
-
shutdown_hooks << block
|
26
|
-
end
|
27
|
-
|
28
|
-
def loop
|
29
|
-
EventMachine.reactor_thread.join
|
30
|
-
end
|
31
|
-
|
32
|
-
private
|
33
|
-
|
34
|
-
def start_reactor
|
35
|
-
@@wrapper = Thread.new { EventMachine.run }
|
36
|
-
wrapper.abort_on_exception = true
|
37
|
-
Thread.pass until reactor_running?
|
38
|
-
end
|
39
|
-
|
40
|
-
def reactor_running?
|
41
|
-
EventMachine.reactor_running?
|
42
|
-
end
|
43
|
-
|
44
|
-
def wrapper
|
45
|
-
@@wrapper
|
46
|
-
end
|
47
|
-
|
48
|
-
def timers
|
49
|
-
@@timers ||= []
|
50
|
-
end
|
51
|
-
|
52
|
-
def shutdown_hooks
|
53
|
-
@@shutdown_hooks ||= []
|
54
|
-
end
|
55
|
-
|
56
|
-
end
|
57
|
-
|
58
|
-
end
|
59
|
-
end
|