graphite-api 0.0.6 → 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
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", # not optional
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
- cache: 4 * 60 * 60 # set the max age in seconds for records reanimation
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, "#{ROOT}/graphite-api/version"
5
- autoload :Client, "#{ROOT}/graphite-api/client"
6
- autoload :Cache, "#{ROOT}/graphite-api/cache"
7
- autoload :SafeBuffer, "#{ROOT}/graphite-api/safe_buffer"
8
- autoload :Reactor, "#{ROOT}/graphite-api/reactor"
9
- autoload :Connector, "#{ROOT}/graphite-api/connector"
10
- autoload :Middleware, "#{ROOT}/graphite-api/middleware"
11
- autoload :Runner, "#{ROOT}/graphite-api/runner"
12
- autoload :Utils, "#{ROOT}/graphite-api/utils"
13
- autoload :CLI, "#{ROOT}/graphite-api/cli"
14
- autoload :Buffer, "#{ROOT}/graphite-api/buffer"
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::Version::VERSION
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::SafeBuffer.new(GraphiteAPI::Utils.default_options)
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 SafeBuffer
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::SafeBuffer:%s @quque#size=%s @streamer=%s>" %
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
- Reactor.every(120) { clean(options[:cache]) }
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
@@ -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::SafeBuffer.new options
50
- @connectors = GraphiteAPI::ConnectorGroup.new options
51
-
52
- every options.fetch :interval do
53
- connectors.publish buffer.pull :string if buffer.new_records?
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
- private_reader :options, :buffer, :connectors
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
- Reactor.every( interval ) { block.call self }
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 m, *args, &block
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
- class Numeric
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::SafeBuffer.new options
61
- group = GraphiteAPI::ConnectorGroup.new options
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
- proc { group.publish buffer.pull :string if buffer.new_records? }.tap do |block|
70
- GraphiteAPI::Reactor.every options[:interval], &block
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
@@ -36,12 +36,12 @@ module GraphiteAPI
36
36
  Middleware.start options
37
37
  rescue Interrupt
38
38
  Logger.info "Shutting down..."
39
- Reactor.stop
39
+ Zscheduler.shutdown
40
40
  end
41
41
  end
42
42
 
43
43
  def options
44
- @options ||= Utils.default_options
44
+ @options ||= Utils.default_middleware_options
45
45
  end
46
46
 
47
47
  def validate_options
@@ -56,11 +56,15 @@ module GraphiteAPI
56
56
  :cache => nil,
57
57
  :host => "localhost",
58
58
  :prefix => [],
59
- :interval => 60,
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
@@ -1,5 +1,3 @@
1
1
  module GraphiteAPI
2
- class Version
3
- VERSION = "0.0.6"
4
- end
2
+ VERSION = "0.1.0"
5
3
  end
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.6
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-03-21 00:00:00.000000000 Z
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
@@ -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