graphite-api 0.0.2.0 → 0.0.2.1

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 CHANGED
@@ -1,8 +1,8 @@
1
- # GraphiteAPI [Beta]
1
+ # GraphiteAPI ( [![Gem Version](https://fury-badge.herokuapp.com/rb/graphite-api.png)](http://badge.fury.io/rb/graphite-api) )
2
2
  A Ruby API toolkit for [Graphite](http://graphite.wikidot.com/).
3
3
 
4
4
  ## Description
5
- **GraphiteAPI** is a library written in Ruby that provides two ways for interacting with **Graphite's Carbon Daemon**, the first is for Ruby applications using the **GraphiteAPI::Client**, the second is through **GraphiteAPI-Middleware** daemon, both methods implements Graphite's [plaintext protocol](http://graphite.readthedocs.org/en/1.0/feeding-carbon.html).
5
+ **GraphiteAPI** provides two ways for interacting with **Graphite's Carbon Daemon**, the first is for Ruby applications using the **GraphiteAPI::Client**, the second is through **GraphiteAPI-Middleware** daemon, both methods implements Graphite's [plaintext protocol](http://graphite.readthedocs.org/en/1.0/feeding-carbon.html).
6
6
 
7
7
  ## Package Content
8
8
  * Includes a **simple** client for ruby.
@@ -129,11 +129,11 @@ example.middleware.value2 99 1334929231
129
129
  [root@graphite-middleware-node]
130
130
  ```
131
131
 
132
- * Send metrics via **GraphtieAPI client**
132
+ * Or via **GraphtieAPI client**
133
133
 
134
134
  ```ruby
135
135
  require 'graphite-api'
136
- client = GraphiteAPI::Client.new(:graphite => graphite-middleware-node)
136
+ client = GraphiteAPI::Client.new(:graphite => 'graphite-middleware-node:2005')
137
137
  client.example.middleware.value 10.2
138
138
  client.example.middleware.value2 27
139
139
  client.bla.bla.value2 27
@@ -16,25 +16,28 @@
16
16
  # ["mem.usage", 190.0, 1326842520]
17
17
  # ["shuki.tuki", 999.0, 1326842520]
18
18
  # -----------------------------------------------------
19
+ require 'set'
20
+
19
21
  module GraphiteAPI
20
22
  class Buffer
21
- include Utils
22
-
23
- attr_reader :options,:keys_to_send,:reanimation_mode, :streamer_buff
23
+ include Utils
24
+
25
+ CLOSING_STREAM = "\n" # end of message - when streaming to buffer obj
26
+ CHARS_TO_IGNORE = %w(\r) # skip these chars when parsing new message
27
+ FLOATS_ROUND_BY = 2 # round(x) after summing floats
24
28
 
25
- CLOSING_STREAM_CHAR = "\n" # end of message - when streaming to buffer obj
26
- CHARS_TO_IGNORE = ["\r"] # skip these chars when parsing new message
27
- FLOATS_ROUND_BY = 2 # round(x) after summing floats
28
- VALID_MESSAGE = /^[\w|\.]+ \d+(?:\.|\d)* \d+$/ # how a valid message should look like
29
+ VALID_MESSAGE = /^[\w|\.]+ \d+(?:\.|\d)* \d+$/
29
30
 
30
31
  def initialize options
31
32
  @options = options
32
- @keys_to_send = Hash.new {|h,k| h[k] = []}
33
+ @keys_to_sync = Hash.new { |h,k| h[k] = Set.new }
33
34
  @streamer_buff = Hash.new {|h,k| h[k] = ""}
34
35
  @reanimation_mode = !options[:reanimation_exp].nil?
35
36
  start_cleaner if reanimation_mode
36
37
  end
37
38
 
39
+ private_reader :options, :keys_to_sync, :reanimation_mode, :streamer_buff
40
+
38
41
  def push hash
39
42
  debug [:buffer,:add, hash]
40
43
  time = Utils.normalize_time(hash[:time],options[:slice])
@@ -44,7 +47,7 @@ module GraphiteAPI
44
47
  alias_method :<<, :push
45
48
 
46
49
  def stream message, client_id = nil
47
- message.each_char do |char|
50
+ message.gsub(/\t/,' ').each_char do |char|
48
51
  next if invalid_char? char
49
52
  streamer_buff[client_id] += char
50
53
 
@@ -59,7 +62,7 @@ module GraphiteAPI
59
62
 
60
63
  def pull as = nil
61
64
  Array.new.tap do |data|
62
- keys_to_send.each do |time,keys|
65
+ keys_to_sync.each do |time,keys|
63
66
  keys.each do |key|
64
67
  data.push cache_get(time, key, as)
65
68
  end
@@ -70,13 +73,13 @@ module GraphiteAPI
70
73
  end
71
74
 
72
75
  def new_records?
73
- !keys_to_send.empty?
76
+ !keys_to_sync.empty?
74
77
  end
75
78
 
76
79
  private
77
80
 
78
81
  def closed_stream? string
79
- string[-1,1] == CLOSING_STREAM_CHAR
82
+ string[-1,1] == CLOSING_STREAM
80
83
  end
81
84
 
82
85
  def invalid_char? char
@@ -85,24 +88,24 @@ module GraphiteAPI
85
88
 
86
89
  def cache_set time, key, value
87
90
  buffer_cache[time][key] = sum buffer_cache[time][key], value.to_f
88
- keys_to_send[time].push key unless keys_to_send[time].include? key
91
+ keys_to_sync[time].add key
89
92
  end
90
93
 
91
94
  def sum float1, float2
92
- ("%.#{FLOATS_ROUND_BY}f" % (float1 + float2)).to_f # can't use round on 1.8.X
95
+ ("%.#{FLOATS_ROUND_BY}f" % (float1 + float2)).to_f
93
96
  end
94
97
 
95
98
  def cache_get time, key, as
96
99
  metric = [prefix + key,buffer_cache[time][key],time]
97
100
  as == :string ? metric.join(" ") : metric
98
101
  end
99
-
102
+
100
103
  def build_metric key, value, time
101
104
  { :metric => { key => value },:time => Time.at(time.to_i) }
102
105
  end
103
106
 
104
107
  def clear
105
- keys_to_send.clear
108
+ keys_to_sync.clear
106
109
  buffer_cache.clear unless reanimation_mode
107
110
  end
108
111
 
@@ -123,7 +126,7 @@ module GraphiteAPI
123
126
  end
124
127
 
125
128
  def clean age
126
- [buffer_cache,keys_to_send].each {|o| o.delete_if {|t,k| Time.now.to_i - t > age}}
129
+ [buffer_cache,keys_to_sync].each {|o| o.delete_if {|t,k| Time.now.to_i - t > age}}
127
130
  end
128
131
 
129
132
  def start_cleaner
@@ -46,9 +46,7 @@ require File.expand_path '../utils', __FILE__
46
46
  module GraphiteAPI
47
47
  class Client
48
48
  include Utils
49
-
50
- extend Utils::ClassMethods
51
-
49
+
52
50
  def initialize opt
53
51
  @options = build_options validate opt.clone
54
52
  @buffer = GraphiteAPI::Buffer.new options
@@ -60,13 +58,13 @@ module GraphiteAPI
60
58
 
61
59
  end
62
60
 
63
- attr_private_reader :options, :buffer, :connectors
64
- delegate :loop, :stop, :to => :Reactor
61
+ private_reader :options, :buffer, :connectors
62
+
63
+ def_delegator :"GraphiteAPI::Reactor", :loop
64
+ def_delegator :"GraphiteAPI::Reactor", :stop
65
65
 
66
66
  def every interval, &block
67
- Reactor.every interval do
68
- block.call self
69
- end
67
+ Reactor.every( interval ) { block.call self }
70
68
  end
71
69
 
72
70
  def metrics metric, time = Time.now
@@ -84,24 +82,21 @@ module GraphiteAPI
84
82
  protected
85
83
 
86
84
  class Proxy
87
- extend Utils::ClassMethods
85
+ include Utils
88
86
 
89
87
  def initialize client
90
88
  @client = client
91
89
  @keys = []
92
90
  end
93
91
 
94
- attr_private_reader :client, :keys
92
+ private_reader :client, :keys
95
93
 
96
94
  def method_missing m, *args, &block
97
95
  keys.push m
98
96
  if keys.size > 10 # too deep
99
97
  super
100
- elsif !args.empty?
101
- client.metrics(
102
- Hash[keys.join("."),args.first],
103
- *args[1..-1]
104
- )
98
+ elsif args.any?
99
+ client.metrics(Hash[keys.join("."),args.first],*args[1..-1])
105
100
  else
106
101
  self
107
102
  end
@@ -12,14 +12,15 @@ require 'socket'
12
12
 
13
13
  module GraphiteAPI
14
14
  class Connector
15
-
16
- attr_reader :options, :host, :port
15
+ include Utils
17
16
 
18
17
  def initialize host, port
19
18
  @host = host
20
19
  @port = port
21
20
  end
22
21
 
22
+ private_reader :host, :port
23
+
23
24
  def puts message
24
25
  begin
25
26
  Logger.debug [:connector,:puts,[host,port].join(":"),message]
@@ -2,7 +2,7 @@ module GraphiteAPI
2
2
  class ConnectorGroup
3
3
  include Utils
4
4
 
5
- attr_reader :options, :connectors
5
+ private_reader :options, :connectors
6
6
 
7
7
  def initialize options
8
8
  @options = options
@@ -22,12 +22,12 @@ module GraphiteAPI
22
22
  # :std => out|err|file-name
23
23
  def init(options)
24
24
  self.logger = ::Logger.new(options[:std] || STDOUT)
25
- self.logger.level= eval "::Logger::#{options[:level].to_s.upcase}"
25
+ self.logger.level= ::Logger.const_get "#{options[:level].to_s.upcase}"
26
26
  end
27
27
 
28
28
  def method_missing(m,*args,&block)
29
- if logger.respond_to? m then logger.send(m,*args,&block) end
30
- end
29
+ logger.send m, *args, &block if logger.respond_to? m
30
+ end
31
31
  end
32
32
  end
33
- end
33
+ end
@@ -17,7 +17,6 @@
17
17
  # log_level info
18
18
  # -----------------------------------------------------
19
19
 
20
- require 'rubygems'
21
20
  require 'eventmachine'
22
21
  require 'socket'
23
22
  require File.expand_path '../utils', __FILE__
@@ -26,13 +25,12 @@ module GraphiteAPI
26
25
  class Middleware < EventMachine::Connection
27
26
 
28
27
  include Utils
29
- extend Utils::ClassMethods
30
28
 
31
29
  def initialize buffer
32
30
  @buffer = buffer and super
33
31
  end
34
32
 
35
- attr_private_reader :buffer,:client_id
33
+ private_reader :buffer, :client_id
36
34
 
37
35
  def post_init
38
36
  @client_id = peername
@@ -72,8 +70,8 @@ module GraphiteAPI
72
70
  GraphiteAPI::Reactor.every options[:interval], &block
73
71
  GraphiteAPI::Reactor.add_shutdown_hook &block
74
72
  end
75
- end
76
-
77
- end # start
73
+ end
74
+ end
75
+
78
76
  end # Middleware
79
77
  end # GraphiteAPI
@@ -1,4 +1,3 @@
1
- require 'rubygems'
2
1
  require 'eventmachine'
3
2
 
4
3
  module GraphiteAPI
@@ -16,6 +16,21 @@ module GraphiteAPI
16
16
 
17
17
  private
18
18
 
19
+ def daemonize pid
20
+ block_given? or raise ArgumentError.new "the block is missing..."
21
+
22
+ fork do
23
+ Process.setsid
24
+ exit if fork
25
+ Dir.chdir '/tmp'
26
+ STDIN.reopen('/dev/null')
27
+ STDOUT.reopen('/dev/null','a')
28
+ STDERR.reopen('/dev/null','a')
29
+ File.open(pid,'w') { |f| f.write(Process.pid) } rescue nil
30
+ yield
31
+ end
32
+ end
33
+
19
34
  def run!
20
35
  begin
21
36
  Middleware.start options
@@ -1,33 +1,29 @@
1
+ require 'forwardable'
2
+
1
3
  module GraphiteAPI
2
4
  module Utils
3
- module ClassMethods
4
- def attr_private_reader *args
5
- args.each { |o| attr_reader o or private o }
5
+
6
+ def self.included base
7
+ base.extend ClassUtils
8
+ base.extend Forwardable
9
+ base.__send__ :include, LoggerUtils
10
+ end
11
+
12
+ module LoggerUtils
13
+ [:info,:error,:warn,:debug].each do |m|
14
+ define_method m do |*args,&block|
15
+ Logger.send m, *args, &block
16
+ end
6
17
  end
18
+ end
7
19
 
8
- def delegate *sources, options
9
- instance_eval do
10
- options.fetch(:to).tap do |target|
11
- sources.each do |source|
12
- define_method source do |*args, &block|
13
- if target.is_a? Symbol
14
- eval String target
15
- else
16
- target
17
- end.send source,*args, &block
18
- end # define
19
- end # sources
20
- end # options
21
- end # instance_eval
22
- end # def delegate
23
- end # ClassMethods
24
-
25
- [:info,:error,:warn,:debug].each do |m|
26
- define_method(m) do |*args,&block|
27
- Logger.send(m,*args,&block)
20
+ module ClassUtils
21
+ def private_reader *args
22
+ attr_reader *args
23
+ private *args
28
24
  end
29
- end
30
-
25
+ end
26
+
31
27
  module_function
32
28
 
33
29
  def normalize_time time, slice = 60
@@ -54,21 +50,6 @@ module GraphiteAPI
54
50
  :pid => "/tmp/graphite-middleware.pid"
55
51
  }
56
52
  end
57
-
58
- def daemonize pid
59
- block_given? or raise ArgumentError.new "the block is missing..."
60
-
61
- fork do
62
- Process.setsid
63
- exit if fork
64
- Dir.chdir '/tmp'
65
- STDIN.reopen('/dev/null')
66
- STDOUT.reopen('/dev/null','a')
67
- STDERR.reopen('/dev/null','a')
68
- File.open(pid,'w') { |f| f.write(Process.pid) } rescue nil
69
- yield
70
- end
71
- end
72
53
 
73
54
  end
74
55
  end
@@ -1,5 +1,5 @@
1
1
  module GraphiteAPI
2
2
  class Version
3
- VERSION = "0.0.2.0"
3
+ VERSION = "0.0.2.1"
4
4
  end
5
5
  end
@@ -1,5 +1,7 @@
1
1
  require "rake/testtask"
2
2
 
3
+ task(:test) { ENV['with_coverage'] = "true" }
4
+
3
5
  Rake::TestTask.new(:test) do |t|
4
6
  t.libs << "tests"
5
7
  t.pattern = "tests/**/*_test.rb"
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.2.0
4
+ version: 0.0.2.1
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: 2012-11-25 00:00:00.000000000 Z
12
+ date: 2013-02-07 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: eventmachine