simple-graphite 1.1.1 → 2.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.
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: dd5755e6f33393cf4462556dae8ec9f73eddac24
4
+ data.tar.gz: 6a1c7f28c36e69386d19bfdd877259bc6067e2e4
5
+ SHA512:
6
+ metadata.gz: 6771d947538cd1f4fe0a933dee1e9ceae3c0fbfcb3a4a9b0cc0938f0883606199e2c2b118282113042696564705489b140d1b345295414be816bfa6c5c653254
7
+ data.tar.gz: 4371d070f53c70e13267ead0f77c14584cee8bef111ee71720d1d0bbf64382e693612bfda1775d616545f92aa26953d2d8cc29030558563d9222343b24a4dda3
@@ -1,6 +1,6 @@
1
1
  = simple-graphite
2
2
 
3
- A simple interface into [Graphite](http://graphite.wikidot.com).
3
+ A simple interface to {Graphite}[http://graphite.wikidot.com].
4
4
 
5
5
  = How-to
6
6
 
@@ -12,10 +12,16 @@ or
12
12
  g.port = 2003
13
13
 
14
14
  To push data to Graphite:
15
- g.push_to_graphite do |socket|
16
- socket.puts "your.metric.name 3.1415926 #{g.time_now}"
15
+ g.push_to_graphite do |graphite|
16
+ graphite.puts "your.metric.name 3.1415926 #{g.time_now}"
17
17
  end
18
18
 
19
+ Or:
20
+ g.send_metrics({
21
+ 'foo.bar1' => 250,
22
+ 'foo.bar2' => 114
23
+ })
24
+
19
25
  == Note on Patches/Pull Requests
20
26
 
21
27
  * Fork the project.
@@ -24,7 +30,7 @@ To push data to Graphite:
24
30
  future version unintentionally.
25
31
  * Commit, do not mess with rakefile, version, or history.
26
32
  (if you want to have your own version, that is fine but
27
- bump version in a commit by itself I can ignore when I pull)
33
+ bump version in a commit by itself I can ignore when I pull)
28
34
  * Send me a pull request. Bonus points for topic branches.
29
35
 
30
36
  == Copyright
@@ -0,0 +1,44 @@
1
+ require 'socket'
2
+
3
+ class Graphite
4
+ class Socket
5
+ attr_accessor :host, :port, :type, :socket
6
+
7
+ def initialize(host, port, socket_type)
8
+ @host = host
9
+ @port = port
10
+ @type = socket_type
11
+ @socket = nil
12
+ end
13
+
14
+ def puts(event)
15
+ socket.write(terminated_event(event.to_s))
16
+ close if @type == :udp
17
+ end
18
+
19
+ def close
20
+ @socket.close if @socket and !@socket.closed?
21
+ rescue => e
22
+ warn "#{self.class} - #{e.class} - #{e.message}"
23
+ end
24
+
25
+ def socket
26
+ return @socket if @socket && !@socket.closed?
27
+ @socket = case @type
28
+ when :udp then UDPSocket.new.tap {|s| s.connect(@host, @port)}
29
+ when :tcp then TCPSocket.new(@host, @port)
30
+ else
31
+ raise NameError, "#{@type} is invalid; must be udp or tcp"
32
+ end
33
+ end
34
+
35
+ def terminated_event(event)
36
+ event =~ /\n$/ ? event : event + "\n"
37
+ end
38
+
39
+ # Retained for compatibility
40
+ def connect
41
+ socket
42
+ end
43
+ end
44
+ end
@@ -1,21 +1,37 @@
1
1
  require 'socket'
2
+ require 'graphite/socket'
2
3
 
3
4
  class Graphite
4
- attr_accessor :host, :port, :time
5
+
6
+ attr_accessor :host, :type, :port, :time
7
+
5
8
  def initialize(options = {})
6
9
  @host = options[:host]
7
- @port = options[:port]
10
+ @type = options[:type] ||= :tcp
11
+ @port = options[:port] ||= @type.eql?(:tcp) ? 2003 : 8125
8
12
  @time = Time.now.to_i
9
13
  end
10
14
 
11
15
  def push_to_graphite
12
- socket = TCPSocket.new(@host, @port)
13
- yield socket
14
- socket.close
16
+ raise "You need to provide a hostname" if @host.nil?
17
+ begin
18
+ socket = Graphite::Socket.new @host, @port, @type
19
+ yield socket
20
+ ensure
21
+ socket.close
22
+ end
23
+ end
24
+
25
+ def send_metrics(metrics_hash)
26
+ current_time = time_now
27
+ push_to_graphite do |graphite|
28
+ graphite.puts((metrics_hash.map { |k,v| [k, v, current_time].join(' ') + "\n" }).join(''))
29
+ end
30
+ current_time
15
31
  end
16
32
 
17
33
  def hostname
18
- Socket.gethostname
34
+ ::Socket.gethostname
19
35
  end
20
36
 
21
37
  def self.time_now
@@ -0,0 +1,155 @@
1
+ require 'spec_helper'
2
+ require 'socket'
3
+ require 'simple-graphite'
4
+
5
+ describe Graphite do
6
+
7
+ it "uses TCP by default" do
8
+ a = Graphite.new
9
+ a.port.should == 2003 && a.type.should == :tcp
10
+ end
11
+
12
+ it "has a default TCP port" do
13
+ a = Graphite.new
14
+ a.port.should == 2003
15
+ end
16
+
17
+ it "has a default UDP port" do
18
+ a = Graphite.new :type => :udp
19
+ a.port.should == 8125
20
+ end
21
+
22
+ it "only accepts UDP or TCP as protocols" do
23
+ a = Graphite.new :host => 'localhost', :type => :fake
24
+ expect {a.push_to_graphite{|g| g.puts "hello world"}}.to raise_error(NameError, "fake is invalid; must be udp or tcp")
25
+ end
26
+
27
+ it "requires a hostname" do
28
+ a = Graphite.new
29
+ expect {a.push_to_graphite}.to raise_error(RuntimeError, "You need to provide a hostname")
30
+ end
31
+
32
+ it "returns time accurately" do
33
+ a = Graphite.new
34
+ a.time_now.should == Time.now.to_i
35
+ end
36
+
37
+ describe "over TCP" do
38
+ before do
39
+ @ftcp = FakeTCPSocket.new
40
+ end
41
+
42
+ after do
43
+ @ftcp.close
44
+ end
45
+
46
+ it "sends individual metrics to graphite" do
47
+ a = Graphite.new(:host => 'localhost', :type => :tcp, :port => 12003)
48
+ a.push_to_graphite do |graphite|
49
+ graphite.puts "hello world\n"
50
+ end
51
+
52
+ @ftcp.buffer.should == "hello world\n"
53
+ end
54
+
55
+ it "terminates individual metrics with newlines" do
56
+ a = Graphite.new(:host => 'localhost', :type => :tcp, :port => 12003)
57
+ a.push_to_graphite do |graphite|
58
+ graphite.puts "hello world"
59
+ end
60
+
61
+ @ftcp.buffer.should == "hello world\n"
62
+ end
63
+
64
+ it "sends multiple metrics to graphite" do
65
+ a = Graphite.new(:host => 'localhost', :type => :tcp, :port => 12003)
66
+ a.push_to_graphite do |graphite|
67
+ graphite.puts "hello\n"
68
+ graphite.puts "world\n"
69
+ end
70
+
71
+ @ftcp.buffer.should == "hello\nworld\n"
72
+ end
73
+
74
+ it "terminates multiple metrics with newlines" do
75
+ a = Graphite.new(:host => 'localhost', :type => :tcp, :port => 12003)
76
+ a.push_to_graphite do |graphite|
77
+ graphite.puts "hello"
78
+ graphite.puts "world"
79
+ end
80
+
81
+ @ftcp.buffer.should == "hello\nworld\n"
82
+ end
83
+
84
+ it "sends a hash of metrics to graphite" do
85
+ a = Graphite.new(:host => 'localhost', :type => :tcp, :port => 12003)
86
+
87
+ time = a.send_metrics({
88
+ 'foo.bar' => 200,
89
+ 'foo.test' => 10.2
90
+ })
91
+
92
+ @ftcp.buffer.should == "foo.bar 200 #{time}\nfoo.test 10.2 #{time}\n"
93
+ end
94
+ end
95
+
96
+ describe "over UDP" do
97
+ before do
98
+ @fudp = FakeUDPSocket.new
99
+ end
100
+
101
+ after do
102
+ @fudp.close
103
+ end
104
+
105
+ it "sends individual metrics to graphite" do
106
+ a = Graphite.new(:host => 'localhost', :type => :udp, :port => 18125)
107
+ a.push_to_graphite do |graphite|
108
+ graphite.puts "hello world\n"
109
+ end
110
+
111
+ @fudp.buffer.should == "hello world\n"
112
+ end
113
+
114
+ it "terminates individual metrics with newlines" do
115
+ a = Graphite.new(:host => 'localhost', :type => :udp, :port => 18125)
116
+ a.push_to_graphite do |graphite|
117
+ graphite.puts "hello world"
118
+ end
119
+
120
+ @fudp.buffer.should == "hello world\n"
121
+ end
122
+
123
+ it "sends multiple metrics to graphite" do
124
+ a = Graphite.new(:host => 'localhost', :type => :udp, :port => 18125)
125
+ a.push_to_graphite do |graphite|
126
+ graphite.puts "hello\n"
127
+ graphite.puts "world\n"
128
+ end
129
+
130
+ @fudp.buffer.should == "hello\nworld\n"
131
+ end
132
+
133
+ it "terminates multiple metrics with newlines" do
134
+ a = Graphite.new(:host => 'localhost', :type => :udp, :port => 18125)
135
+ a.push_to_graphite do |graphite|
136
+ graphite.puts "hello"
137
+ graphite.puts "world"
138
+ end
139
+
140
+ @fudp.buffer.should == "hello\nworld\n"
141
+ end
142
+
143
+ it "sends a hash of metrics to graphite" do
144
+ a = Graphite.new(:host => 'localhost', :type => :udp, :port => 18125)
145
+
146
+ time = a.send_metrics({
147
+ 'foo.bar' => 200,
148
+ 'foo.test' => 10.2
149
+ })
150
+
151
+ @fudp.buffer.should == "foo.bar 200 #{time}\nfoo.test 10.2 #{time}\n"
152
+ end
153
+ end
154
+
155
+ end
@@ -0,0 +1,52 @@
1
+ if ENV["COVERAGE"]
2
+ require 'simplecov'
3
+ SimpleCov.start
4
+ end
5
+
6
+ require 'socket'
7
+
8
+ RSpec.configure do |config|
9
+ config.treat_symbols_as_metadata_keys_with_true_values = true
10
+ config.run_all_when_everything_filtered = true
11
+ config.filter_run :focus
12
+ config.color_enabled = true
13
+ config.tty = true
14
+ config.formatter = :documentation # :progress, :html, :textmate
15
+ end
16
+
17
+ class FakeTCPSocket
18
+ def initialize
19
+ @sock = TCPServer.new(12003)
20
+ end
21
+
22
+ def buffer
23
+ buf = @sock.accept
24
+ buf.read_nonblock(65535)
25
+ end
26
+
27
+ def close
28
+ @sock.close
29
+ end
30
+ end
31
+
32
+ class FakeUDPSocket
33
+ def initialize
34
+ @sock = UDPSocket.new
35
+ @sock.bind(nil, 18125)
36
+ end
37
+
38
+ def buffer
39
+ buf = Array.new
40
+ begin
41
+ while pkt = @sock.recvfrom_nonblock(65535)
42
+ buf << pkt
43
+ end
44
+ rescue IO::WaitReadable
45
+ end
46
+ buf.map{|p| p.first}.join()
47
+ end
48
+
49
+ def close
50
+ @sock.close
51
+ end
52
+ end
metadata CHANGED
@@ -1,73 +1,82 @@
1
- --- !ruby/object:Gem::Specification
1
+ --- !ruby/object:Gem::Specification
2
2
  name: simple-graphite
3
- version: !ruby/object:Gem::Version
4
- hash: 17
5
- prerelease: false
6
- segments:
7
- - 1
8
- - 1
9
- - 1
10
- version: 1.1.1
3
+ version: !ruby/object:Gem::Version
4
+ version: 2.1.0
11
5
  platform: ruby
12
- authors:
6
+ authors:
13
7
  - Ian Meyer
14
8
  autorequire:
15
9
  bindir: bin
16
10
  cert_chain: []
17
-
18
- date: 2010-06-21 00:00:00 +00:00
19
- default_executable:
20
- dependencies: []
21
-
22
- description: Exposes methods to send data to graphite
11
+ date: 2013-05-30 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: rspec
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - '>='
18
+ - !ruby/object:Gem::Version
19
+ version: '0'
20
+ type: :development
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - '>='
25
+ - !ruby/object:Gem::Version
26
+ version: '0'
27
+ - !ruby/object:Gem::Dependency
28
+ name: rspec-mocks
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - '>='
32
+ - !ruby/object:Gem::Version
33
+ version: '0'
34
+ type: :development
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - '>='
39
+ - !ruby/object:Gem::Version
40
+ version: '0'
41
+ description: Simple methods for sending data to graphite over TCP or UDP
23
42
  email: ianmmeyer@gmail.com
24
43
  executables: []
25
-
26
44
  extensions: []
27
-
28
- extra_rdoc_files:
45
+ extra_rdoc_files:
29
46
  - LICENSE
30
47
  - README.rdoc
31
- files:
48
+ files:
49
+ - lib/graphite/socket.rb
32
50
  - lib/simple-graphite.rb
33
- - test/simple-graphite_test.rb
34
- - test/test_helper.rb
51
+ - spec/simple-graphite_spec.rb
52
+ - spec/spec_helper.rb
35
53
  - LICENSE
36
54
  - README.rdoc
37
- has_rdoc: true
38
55
  homepage: http://github.com/imeyer/simple-graphite
39
- licenses: []
40
-
56
+ licenses:
57
+ - MIT
58
+ metadata: {}
41
59
  post_install_message:
42
- rdoc_options:
60
+ rdoc_options:
43
61
  - --charset=UTF-8
44
- require_paths:
62
+ require_paths:
45
63
  - lib
46
- required_ruby_version: !ruby/object:Gem::Requirement
47
- none: false
48
- requirements:
49
- - - ">="
50
- - !ruby/object:Gem::Version
51
- hash: 3
52
- segments:
53
- - 0
54
- version: "0"
55
- required_rubygems_version: !ruby/object:Gem::Requirement
56
- none: false
57
- requirements:
58
- - - ">="
59
- - !ruby/object:Gem::Version
60
- hash: 3
61
- segments:
62
- - 0
63
- version: "0"
64
+ required_ruby_version: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - '>='
67
+ - !ruby/object:Gem::Version
68
+ version: '0'
69
+ required_rubygems_version: !ruby/object:Gem::Requirement
70
+ requirements:
71
+ - - '>='
72
+ - !ruby/object:Gem::Version
73
+ version: '0'
64
74
  requirements: []
65
-
66
75
  rubyforge_project:
67
- rubygems_version: 1.3.7
76
+ rubygems_version: 2.0.3
68
77
  signing_key:
69
- specification_version: 3
78
+ specification_version: 4
70
79
  summary: Simple hook into graphite
71
- test_files:
72
- - test/test_helper.rb
73
- - test/simple-graphite_test.rb
80
+ test_files:
81
+ - spec/simple-graphite_spec.rb
82
+ - spec/spec_helper.rb
@@ -1,7 +0,0 @@
1
- require 'test_helper'
2
-
3
- class EtsyGraphiteTest < Test::Unit::TestCase
4
- should "probably rename this file and start testing for real" do
5
- flunk "hey buddy, you should probably rename this file and start testing for real"
6
- end
7
- end
@@ -1,10 +0,0 @@
1
- require 'rubygems'
2
- require 'test/unit'
3
- require 'shoulda'
4
-
5
- $LOAD_PATH.unshift(File.join(File.dirname(__FILE__), '..', 'lib'))
6
- $LOAD_PATH.unshift(File.dirname(__FILE__))
7
- require 'simple-graphite'
8
-
9
- class Test::Unit::TestCase
10
- end