nutcracker-graphite 0.0.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/README.md +102 -0
- data/Rakefile +18 -0
- data/lib/nutcracker/graphite.rb +98 -0
- data/lib/nutcracker/graphite/version.rb +5 -0
- data/tests/fixtures/expected_metrics_wo_redis_info.ruby_hash +1 -0
- data/tests/fixtures/expected_redis_info.json +1 -0
- data/tests/fixtures/expected_stats.ruby_hash +1 -0
- data/tests/fixtures/redis_info.json +1 -0
- data/tests/fixtures/stats.json +1 -0
- data/tests/minitest_helper.rb +31 -0
- data/tests/unit/agent_test.rb +51 -0
- metadata +123 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: 2ac51b5f953ef068101cc9c5b2f4aac6b0370eb2
|
4
|
+
data.tar.gz: 7f2d673e8982941ae96c2d65bb92f89e6ea116db
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 39344998867494f870f0c473533f13dbee63013ac3f8a0793ea9b4b8567390166603d4d411ab9a6d6dd2889ddded9b2c80ec13a997d65041e1d8d9883b9a93d1
|
7
|
+
data.tar.gz: aec3d483bbeaaeb8f8ac4514e7283a6ff33a1493d63c668e97fe93b38047ba4d200ccfd8def4b4f26403d256443f52465020d55ce853ddc9851e5a198c375718
|
data/README.md
ADDED
@@ -0,0 +1,102 @@
|
|
1
|
+
Nutcracker Graphite
|
2
|
+
==================
|
3
|
+
<a href="https://rubygems.org/gems/nutcracker-graphite"><img src=https://fury-badge.herokuapp.com/rb/nutcracker-graphite.png></a>
|
4
|
+
|
5
|
+
[Nutcracker](https://github.com/kontera-technologies/nutcracker) plugin for sending cluster data to Graphite
|
6
|
+
|
7
|
+
### DISCLAIMER
|
8
|
+
this is still a work in progress...
|
9
|
+
|
10
|
+
## Dependencies
|
11
|
+
- ruby 1.9+
|
12
|
+
- [Graphite](http://graphite.wikidot.com/)
|
13
|
+
|
14
|
+
## Installation
|
15
|
+
Add this line to your application's Gemfile:
|
16
|
+
```
|
17
|
+
gem 'nutcracker-graphite'
|
18
|
+
```
|
19
|
+
|
20
|
+
And then execute:
|
21
|
+
```
|
22
|
+
$ bundle install
|
23
|
+
```
|
24
|
+
|
25
|
+
or just by
|
26
|
+
```
|
27
|
+
$ gem install nutcracker-graphite
|
28
|
+
```
|
29
|
+
|
30
|
+
## Usage
|
31
|
+
example app
|
32
|
+
```ruby
|
33
|
+
require 'nutcracker'
|
34
|
+
require 'nutcracker/graphite'
|
35
|
+
|
36
|
+
# Start nutcracker
|
37
|
+
nutcracker = Nutcracker.start(cluster: 'cluster.conf')
|
38
|
+
|
39
|
+
# Start Graphite stats agent
|
40
|
+
nutcracker.use(:graphite, graphite: 'graphite.example.com')
|
41
|
+
# will send aggregated stats to graphite.example.com every 1 minute
|
42
|
+
|
43
|
+
# Waiting....
|
44
|
+
nutcracker.join
|
45
|
+
```
|
46
|
+
|
47
|
+
example output for two nodes cluster ( will be send every 1 minute )
|
48
|
+
```
|
49
|
+
nutcracker.<cluster-name>.<nutcracker-hostname>.client_eof 0.0 1369569180
|
50
|
+
nutcracker.<cluster-name>.<nutcracker-hostname>.client_err 0.0 1369569180
|
51
|
+
nutcracker.<cluster-name>.<nutcracker-hostname>.client_connections 0.0 1369569180
|
52
|
+
nutcracker.<cluster-name>.<nutcracker-hostname>.server_ejects 0.0 1369569180
|
53
|
+
nutcracker.<cluster-name>.<nutcracker-hostname>.forward_error 0.0 1369569180
|
54
|
+
nutcracker.<cluster-name>.<nutcracker-hostname>.fragments 0.0 1369569180
|
55
|
+
nutcracker.<cluster-name>.<nutcracker-hostname>.<node1>.cluster_server_eof 0.0 1369569180
|
56
|
+
nutcracker.<cluster-name>.<nutcracker-hostname>.<node1>.cluster_server_err 0.0 1369569180
|
57
|
+
nutcracker.<cluster-name>.<nutcracker-hostname>.<node1>.cluster_server_timedout 0.0 1369569180
|
58
|
+
nutcracker.<cluster-name>.<nutcracker-hostname>.<node1>.cluster_server_connections 0.0 1369569180
|
59
|
+
nutcracker.<cluster-name>.<nutcracker-hostname>.<node1>.cluster_requests 0.0 1369569180
|
60
|
+
nutcracker.<cluster-name>.<nutcracker-hostname>.<node1>.cluster_request_bytes 0.0 1369569180
|
61
|
+
nutcracker.<cluster-name>.<nutcracker-hostname>.<node1>.cluster_responses 0.0 1369569180
|
62
|
+
nutcracker.<cluster-name>.<nutcracker-hostname>.<node1>.cluster_response_bytes 0.0 1369569180
|
63
|
+
nutcracker.<cluster-name>.<nutcracker-hostname>.<node1>.cluster_in_queue 0.0 1369569180
|
64
|
+
nutcracker.<cluster-name>.<nutcracker-hostname>.<node1>.cluster_in_queue_bytes 0.0 1369569180
|
65
|
+
nutcracker.<cluster-name>.<nutcracker-hostname>.<node1>.cluster_out_queue 0.0 1369569180
|
66
|
+
nutcracker.<cluster-name>.<nutcracker-hostname>.<node1>.cluster_out_queue_bytes 0.0 1369569180
|
67
|
+
nutcracker.<cluster-name>.<nutcracker-hostname>.<node1>.connections 95.0 1369569180
|
68
|
+
nutcracker.<cluster-name>.<nutcracker-hostname>.<node1>.used_memory 20173789840.0 1369569180
|
69
|
+
nutcracker.<cluster-name>.<nutcracker-hostname>.<node1>.used_memory_rss 20932427776.0 1369569180
|
70
|
+
nutcracker.<cluster-name>.<nutcracker-hostname>.<node1>.fragmentation 1.04 1369569180
|
71
|
+
nutcracker.<cluster-name>.<nutcracker-hostname>.<node1>.expired_keys 36732182.0 1369569180
|
72
|
+
nutcracker.<cluster-name>.<nutcracker-hostname>.<node1>.evicted_keys 12284.0 1369569180
|
73
|
+
nutcracker.<cluster-name>.<nutcracker-hostname>.<node1>.hits 1372163466.0 1369569180
|
74
|
+
nutcracker.<cluster-name>.<nutcracker-hostname>.<node1>.misses 58928722.0 1369569180
|
75
|
+
nutcracker.<cluster-name>.<nutcracker-hostname>.<node1>.keys 24347281.0 1369569180
|
76
|
+
nutcracker.<cluster-name>.<nutcracker-hostname>.<node1>.max_memory 21474836480.0 1369569180
|
77
|
+
nutcracker.<cluster-name>.<nutcracker-hostname>.<node1>.hit_ratio 0.96 1369569180
|
78
|
+
nutcracker.<cluster-name>.<nutcracker-hostname>.<node2>.cluster_server_eof 0.0 1369569180
|
79
|
+
nutcracker.<cluster-name>.<nutcracker-hostname>.<node2>.cluster_server_err 0.0 1369569180
|
80
|
+
nutcracker.<cluster-name>.<nutcracker-hostname>.<node2>.cluster_server_timedout 0.0 1369569180
|
81
|
+
nutcracker.<cluster-name>.<nutcracker-hostname>.<node2>.cluster_server_connections 0.0 1369569180
|
82
|
+
nutcracker.<cluster-name>.<nutcracker-hostname>.<node2>.cluster_requests 0.0 1369569180
|
83
|
+
nutcracker.<cluster-name>.<nutcracker-hostname>.<node2>.cluster_request_bytes 0.0 1369569180
|
84
|
+
nutcracker.<cluster-name>.<nutcracker-hostname>.<node2>.cluster_responses 0.0 1369569180
|
85
|
+
nutcracker.<cluster-name>.<nutcracker-hostname>.<node2>.cluster_response_bytes 0.0 1369569180
|
86
|
+
nutcracker.<cluster-name>.<nutcracker-hostname>.<node2>.cluster_in_queue 0.0 1369569180
|
87
|
+
nutcracker.<cluster-name>.<nutcracker-hostname>.<node2>.cluster_in_queue_bytes 0.0 1369569180
|
88
|
+
nutcracker.<cluster-name>.<nutcracker-hostname>.<node2>.cluster_out_queue 0.0 1369569180
|
89
|
+
nutcracker.<cluster-name>.<nutcracker-hostname>.<node2>.cluster_out_queue_bytes 0.0 1369569180
|
90
|
+
nutcracker.<cluster-name>.<nutcracker-hostname>.<node2>.connections 95.0 1369569180
|
91
|
+
nutcracker.<cluster-name>.<nutcracker-hostname>.<node2>.used_memory 20173789840.0 1369569180
|
92
|
+
nutcracker.<cluster-name>.<nutcracker-hostname>.<node2>.used_memory_rss 20932427776.0 1369569180
|
93
|
+
nutcracker.<cluster-name>.<nutcracker-hostname>.<node2>.fragmentation 1.04 1369569180
|
94
|
+
nutcracker.<cluster-name>.<nutcracker-hostname>.<node2>.expired_keys 36732182.0 1369569180
|
95
|
+
nutcracker.<cluster-name>.<nutcracker-hostname>.<node2>.evicted_keys 12284.0 1369569180
|
96
|
+
nutcracker.<cluster-name>.<nutcracker-hostname>.<node2>.hits 1372163466.0 1369569180
|
97
|
+
nutcracker.<cluster-name>.<nutcracker-hostname>.<node2>.misses 58928722.0 1369569180
|
98
|
+
nutcracker.<cluster-name>.<nutcracker-hostname>.<node2>.keys 24347281.0 1369569180
|
99
|
+
nutcracker.<cluster-name>.<nutcracker-hostname>.<node2>.max_memory 21474836480.0 1369569180
|
100
|
+
nutcracker.<cluster-name>.<nutcracker-hostname>.<node2>.hit_ratio 0.96 1369569180
|
101
|
+
```
|
102
|
+
|
data/Rakefile
ADDED
@@ -0,0 +1,18 @@
|
|
1
|
+
$:.unshift File.expand_path '../lib', __FILE__
|
2
|
+
require 'nutcracker/graphite'
|
3
|
+
require 'rubygems/package_task'
|
4
|
+
require 'rake/testtask'
|
5
|
+
|
6
|
+
Nutcracker::GemSpec = eval File.read 'nutcracker-graphite.gemspec'
|
7
|
+
|
8
|
+
Gem::PackageTask.new Nutcracker::GemSpec do |p|
|
9
|
+
p.gem_spec = Nutcracker::GemSpec
|
10
|
+
end
|
11
|
+
|
12
|
+
## Tests stuff
|
13
|
+
task :default => :test
|
14
|
+
|
15
|
+
Rake::TestTask.new(:test) do |t|
|
16
|
+
t.libs.push 'tests'
|
17
|
+
t.pattern = 'tests/**/*_test.rb'
|
18
|
+
end
|
@@ -0,0 +1,98 @@
|
|
1
|
+
require 'nutcracker/graphite/version'
|
2
|
+
require 'graphite-api'
|
3
|
+
require 'redis'
|
4
|
+
|
5
|
+
module Nutcracker
|
6
|
+
module Graphite
|
7
|
+
|
8
|
+
def self.start nutcracker, options
|
9
|
+
Agent.new(nutcracker, options).start
|
10
|
+
end
|
11
|
+
|
12
|
+
class Agent
|
13
|
+
INTERVAL=60
|
14
|
+
|
15
|
+
attr_reader :nutcracker, :graphite
|
16
|
+
|
17
|
+
def initialize nutcracker, options
|
18
|
+
@nutcracker = nutcracker
|
19
|
+
@graphite = GraphiteAPI.new options.merge(:interval => INTERVAL)
|
20
|
+
end
|
21
|
+
|
22
|
+
def start
|
23
|
+
@task ||= graphite.every INTERVAL do |client|
|
24
|
+
client.metrics metrics parse nutcracker.stats
|
25
|
+
end
|
26
|
+
self
|
27
|
+
end
|
28
|
+
|
29
|
+
def stop
|
30
|
+
@task and @task.cancel
|
31
|
+
end
|
32
|
+
|
33
|
+
private
|
34
|
+
|
35
|
+
def metrics parsed_stats
|
36
|
+
data = parsed_stats.clone
|
37
|
+
escape = ->(s) { s.gsub(/\.|\:/,'_') }
|
38
|
+
hash = {}
|
39
|
+
data[:clusters].each do |cluster, cluster_data|
|
40
|
+
next unless ( nutcracker.config[cluster]["redis"] rescue false ) # skip memcached
|
41
|
+
cluster_key = ['nutcracker',cluster,data['source']].map(&escape).join('.')
|
42
|
+
cluster_data.each do |key, value|
|
43
|
+
hash[[cluster_key,key].join('.')] = value if value.is_a? Fixnum or value.is_a? Float
|
44
|
+
end
|
45
|
+
|
46
|
+
cluster_data[:nodes].each do |node, node_data|
|
47
|
+
node_key = "#{cluster_key}.#{escape.(node)}"
|
48
|
+
node_data.each do |key, value|
|
49
|
+
hash["#{node_key}.cluster_#{key}"] = value if value.is_a? Fixnum or value.is_a? Float
|
50
|
+
end
|
51
|
+
redis_info(node).each {|k,v| hash["#{node_key}.#{k}"] = v }
|
52
|
+
end
|
53
|
+
|
54
|
+
end
|
55
|
+
hash
|
56
|
+
end
|
57
|
+
|
58
|
+
def redis_info url
|
59
|
+
url = "redis://#{url}" unless url =~ /redis\:\/\//
|
60
|
+
redis = Redis.connect url: url
|
61
|
+
server_info = redis.info
|
62
|
+
db_size = redis.dbsize
|
63
|
+
max_memory = redis.config(:get, 'maxmemory')['maxmemory'].to_i
|
64
|
+
redis.quit
|
65
|
+
{
|
66
|
+
'connections' => server_info['connected_clients'].to_i,
|
67
|
+
'used_memory' => server_info['used_memory'].to_f,
|
68
|
+
'used_memory_rss' => server_info['used_memory_rss'].to_f,
|
69
|
+
'fragmentation' => server_info['mem_fragmentation_ratio'].to_f,
|
70
|
+
'expired_keys' => server_info['expired_keys'].to_i,
|
71
|
+
'evicted_keys' => server_info['evicted_keys'].to_i,
|
72
|
+
'hits' => server_info['keyspace_hits'].to_i,
|
73
|
+
'misses' => server_info['keyspace_misses'].to_i,
|
74
|
+
'keys' => db_size,
|
75
|
+
'max_memory' => max_memory,
|
76
|
+
'hit_ratio' => 0
|
77
|
+
}.tap {|d| d['hit_ratio'] = d['hits'].to_f / (d['hits']+d['misses']).to_f if d['hits'] > 0 }
|
78
|
+
end
|
79
|
+
|
80
|
+
|
81
|
+
def parse stats
|
82
|
+
{ :clusters => {} }.tap do |data|
|
83
|
+
(stats.dup).each do |key, value|
|
84
|
+
(data[key] = value and next) if !value.is_a? Hash
|
85
|
+
data[:clusters][key] = value
|
86
|
+
data[:clusters][key][:nodes] = {}
|
87
|
+
data[:clusters][key].each do |key2,value2|
|
88
|
+
if value2.kind_of? Hash and key2.is_a? String
|
89
|
+
data[:clusters][key][:nodes][key2] = data[:clusters][key].delete(key2)
|
90
|
+
end
|
91
|
+
end
|
92
|
+
end
|
93
|
+
end
|
94
|
+
end
|
95
|
+
|
96
|
+
end
|
97
|
+
end
|
98
|
+
end
|
@@ -0,0 +1 @@
|
|
1
|
+
{"nutcracker.page_data_cluster.Eran-Levis-MacBook-Pro_local.client_eof"=>0, "nutcracker.page_data_cluster.Eran-Levis-MacBook-Pro_local.client_err"=>0, "nutcracker.page_data_cluster.Eran-Levis-MacBook-Pro_local.client_connections"=>0, "nutcracker.page_data_cluster.Eran-Levis-MacBook-Pro_local.server_ejects"=>0, "nutcracker.page_data_cluster.Eran-Levis-MacBook-Pro_local.forward_error"=>0, "nutcracker.page_data_cluster.Eran-Levis-MacBook-Pro_local.fragments"=>0, "nutcracker.page_data_cluster.Eran-Levis-MacBook-Pro_local.node1_6379.cluster_server_eof"=>0, "nutcracker.page_data_cluster.Eran-Levis-MacBook-Pro_local.node1_6379.cluster_server_err"=>0, "nutcracker.page_data_cluster.Eran-Levis-MacBook-Pro_local.node1_6379.cluster_server_timedout"=>0, "nutcracker.page_data_cluster.Eran-Levis-MacBook-Pro_local.node1_6379.cluster_server_connections"=>0, "nutcracker.page_data_cluster.Eran-Levis-MacBook-Pro_local.node1_6379.cluster_requests"=>0, "nutcracker.page_data_cluster.Eran-Levis-MacBook-Pro_local.node1_6379.cluster_request_bytes"=>0, "nutcracker.page_data_cluster.Eran-Levis-MacBook-Pro_local.node1_6379.cluster_responses"=>0, "nutcracker.page_data_cluster.Eran-Levis-MacBook-Pro_local.node1_6379.cluster_response_bytes"=>0, "nutcracker.page_data_cluster.Eran-Levis-MacBook-Pro_local.node1_6379.cluster_in_queue"=>0, "nutcracker.page_data_cluster.Eran-Levis-MacBook-Pro_local.node1_6379.cluster_in_queue_bytes"=>0, "nutcracker.page_data_cluster.Eran-Levis-MacBook-Pro_local.node1_6379.cluster_out_queue"=>0, "nutcracker.page_data_cluster.Eran-Levis-MacBook-Pro_local.node1_6379.cluster_out_queue_bytes"=>0}
|
@@ -0,0 +1 @@
|
|
1
|
+
{"connections":96,"used_memory":20042110520.0,"used_memory_rss":20905414656.0,"fragmentation":1.04,"expired_keys":36705179,"evicted_keys":12284,"hits":1370531418,"misses":58886159,"keys":24296159,"max_memory":21474836480,"hit_ratio":0.9588040891986317}
|
@@ -0,0 +1 @@
|
|
1
|
+
{:clusters=>{"page_data_cluster"=>{"client_eof"=>0, "client_err"=>0, "client_connections"=>0, "server_ejects"=>0, "forward_error"=>0, "fragments"=>0, :nodes=>{"node1:6379"=>{"server_eof"=>0, "server_err"=>0, "server_timedout"=>0, "server_connections"=>0, "requests"=>0, "request_bytes"=>0, "responses"=>0, "response_bytes"=>0, "in_queue"=>0, "in_queue_bytes"=>0, "out_queue"=>0, "out_queue_bytes"=>0}}}}, "service"=>"nutcracker", "source"=>"Eran-Levis-MacBook-Pro.local", "version"=>"0.2.4", "uptime"=>53, "timestamp"=>1369558826}
|
@@ -0,0 +1 @@
|
|
1
|
+
{"info":{"redis_version":"2.4.10","redis_git_sha1":"00000000","redis_git_dirty":"0","arch_bits":"64","multiplexing_api":"epoll","gcc_version":"4.1.2","process_id":"15264","uptime_in_seconds":"5247213","uptime_in_days":"60","lru_clock":"641250","used_cpu_sys":"40451.50","used_cpu_user":"172259.69","used_cpu_sys_children":"0.00","used_cpu_user_children":"0.00","connected_clients":"96","connected_slaves":"0","client_longest_output_list":"0","client_biggest_input_buf":"0","blocked_clients":"0","used_memory":"20042110520","used_memory_human":"18.67G","used_memory_rss":"20905414656","used_memory_peak":"21474896448","used_memory_peak_human":"20.00G","mem_fragmentation_ratio":"1.04","mem_allocator":"jemalloc-2.2.5","loading":"0","aof_enabled":"0","changes_since_last_save":"8316280672","bgsave_in_progress":"0","last_save_time":"1364314088","bgrewriteaof_in_progress":"0","total_connections_received":"64618","total_commands_processed":"18247026966","expired_keys":"36705179","evicted_keys":"12284","keyspace_hits":"1370531418","keyspace_misses":"58886159","pubsub_channels":"0","pubsub_patterns":"0","latest_fork_usec":"0","vm_enabled":"0","role":"master","db0":"keys=24296116,expires=739455","db2":"keys=14178,expires=0"},"dbsize":24296159,"memory":{"maxmemory":"21474836480"}}
|
@@ -0,0 +1 @@
|
|
1
|
+
{"service":"nutcracker","source":"Eran-Levis-MacBook-Pro.local","version":"0.2.4","uptime":53,"timestamp":1369558826,"page_data_cluster":{"client_eof":0,"client_err":0,"client_connections":0,"server_ejects":0,"forward_error":0,"fragments":0,"node1:6379":{"server_eof":0,"server_err":0,"server_timedout":0,"server_connections":0,"requests":0,"request_bytes":0,"responses":0,"response_bytes":0,"in_queue":0,"in_queue_bytes":0,"out_queue":0,"out_queue_bytes":0}}}
|
@@ -0,0 +1,31 @@
|
|
1
|
+
$:.unshift File.expand_path '../../lib', __FILE__
|
2
|
+
gem 'minitest'
|
3
|
+
|
4
|
+
require 'minitest/autorun'
|
5
|
+
require 'mocha/setup'
|
6
|
+
require 'nutcracker/graphite'
|
7
|
+
require 'tempfile'
|
8
|
+
require 'fileutils'
|
9
|
+
require 'json'
|
10
|
+
|
11
|
+
module Nutcracker
|
12
|
+
module Graphite
|
13
|
+
class Test < ::Minitest::Test
|
14
|
+
def fixture name
|
15
|
+
File.expand_path("../fixtures/#{name}", __FILE__)
|
16
|
+
end
|
17
|
+
|
18
|
+
def load_fixture name
|
19
|
+
raw = File.read fixture name
|
20
|
+
if name.end_with? '.json'
|
21
|
+
JSON.parse raw
|
22
|
+
elsif name.end_with? '.ruby_hash'
|
23
|
+
eval raw
|
24
|
+
else
|
25
|
+
raw
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
@@ -0,0 +1,51 @@
|
|
1
|
+
require_relative '../minitest_helper'
|
2
|
+
|
3
|
+
module Nutcracker
|
4
|
+
module Graphite
|
5
|
+
class AgentTester < Test
|
6
|
+
|
7
|
+
def setup
|
8
|
+
@nutcracker = mock
|
9
|
+
@options = {:graphite => 'shuki'}
|
10
|
+
@agent = Agent.new( @nutcracker, @options )
|
11
|
+
end
|
12
|
+
|
13
|
+
attr_reader :agent, :options, :nutcracker
|
14
|
+
|
15
|
+
def test_stats_parser
|
16
|
+
assert_equal load_fixture('expected_stats.ruby_hash'),
|
17
|
+
agent.send(:parse,load_fixture('stats.json'))
|
18
|
+
end
|
19
|
+
|
20
|
+
def test_metrics_generator
|
21
|
+
nutcracker.expects(:config).returns({'page_data_cluster' => {'redis' => true}})
|
22
|
+
agent.expects(:redis_info).with('node1:6379').returns({})
|
23
|
+
|
24
|
+
assert_equal load_fixture('expected_metrics_wo_redis_info.ruby_hash') ,
|
25
|
+
agent.send(:metrics,load_fixture('expected_stats.ruby_hash'))
|
26
|
+
|
27
|
+
nutcracker.expects(:config).returns({'page_data_cluster' => {'redis' => true}})
|
28
|
+
agent.expects(:redis_info).with('node1:6379').returns({'blabla' => 20})
|
29
|
+
|
30
|
+
expected = load_fixture('expected_metrics_wo_redis_info.ruby_hash').merge(
|
31
|
+
"nutcracker.page_data_cluster.Eran-Levis-MacBook-Pro_local.node1_6379.blabla"=>20
|
32
|
+
)
|
33
|
+
|
34
|
+
assert_equal expected, agent.send(:metrics,load_fixture('expected_stats.ruby_hash'))
|
35
|
+
end
|
36
|
+
|
37
|
+
def test_redis_info
|
38
|
+
data = load_fixture 'redis_info.json'
|
39
|
+
redis = mock
|
40
|
+
Redis.expects(:connect).with(url: 'redis://node1:6379').returns(redis)
|
41
|
+
redis.expects(:info).returns(data['info'])
|
42
|
+
redis.expects(:dbsize).returns(data['dbsize'])
|
43
|
+
redis.expects('config').with(:get,'maxmemory').returns(data['memory'])
|
44
|
+
redis.expects(:quit)
|
45
|
+
assert_equal load_fixture('expected_redis_info.json'),
|
46
|
+
agent.send(:redis_info,'node1:6379')
|
47
|
+
end
|
48
|
+
|
49
|
+
end
|
50
|
+
end
|
51
|
+
end
|
metadata
ADDED
@@ -0,0 +1,123 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: nutcracker-graphite
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.0.1
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Eran Barak Levi
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
date: 2013-05-26 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: graphite-api
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - ~>
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: 0.1.1
|
20
|
+
type: :runtime
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - ~>
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: 0.1.1
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: nutcracker
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - '='
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: 0.2.4.beta3
|
34
|
+
type: :runtime
|
35
|
+
prerelease: false
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - '='
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: 0.2.4.beta3
|
41
|
+
- !ruby/object:Gem::Dependency
|
42
|
+
name: redis
|
43
|
+
requirement: !ruby/object:Gem::Requirement
|
44
|
+
requirements:
|
45
|
+
- - '>='
|
46
|
+
- !ruby/object:Gem::Version
|
47
|
+
version: '0'
|
48
|
+
type: :runtime
|
49
|
+
prerelease: false
|
50
|
+
version_requirements: !ruby/object:Gem::Requirement
|
51
|
+
requirements:
|
52
|
+
- - '>='
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: '0'
|
55
|
+
- !ruby/object:Gem::Dependency
|
56
|
+
name: minitest
|
57
|
+
requirement: !ruby/object:Gem::Requirement
|
58
|
+
requirements:
|
59
|
+
- - ~>
|
60
|
+
- !ruby/object:Gem::Version
|
61
|
+
version: 5.0.0
|
62
|
+
type: :development
|
63
|
+
prerelease: false
|
64
|
+
version_requirements: !ruby/object:Gem::Requirement
|
65
|
+
requirements:
|
66
|
+
- - ~>
|
67
|
+
- !ruby/object:Gem::Version
|
68
|
+
version: 5.0.0
|
69
|
+
- !ruby/object:Gem::Dependency
|
70
|
+
name: mocha
|
71
|
+
requirement: !ruby/object:Gem::Requirement
|
72
|
+
requirements:
|
73
|
+
- - ~>
|
74
|
+
- !ruby/object:Gem::Version
|
75
|
+
version: 0.14.0
|
76
|
+
type: :development
|
77
|
+
prerelease: false
|
78
|
+
version_requirements: !ruby/object:Gem::Requirement
|
79
|
+
requirements:
|
80
|
+
- - ~>
|
81
|
+
- !ruby/object:Gem::Version
|
82
|
+
version: 0.14.0
|
83
|
+
description: Nutcracker plugin for sending cluster statistics to Graphite
|
84
|
+
email: eran@kontera.com
|
85
|
+
executables: []
|
86
|
+
extensions: []
|
87
|
+
extra_rdoc_files: []
|
88
|
+
files:
|
89
|
+
- README.md
|
90
|
+
- Rakefile
|
91
|
+
- lib/nutcracker/graphite/version.rb
|
92
|
+
- lib/nutcracker/graphite.rb
|
93
|
+
- tests/fixtures/expected_metrics_wo_redis_info.ruby_hash
|
94
|
+
- tests/fixtures/expected_redis_info.json
|
95
|
+
- tests/fixtures/expected_stats.ruby_hash
|
96
|
+
- tests/fixtures/redis_info.json
|
97
|
+
- tests/fixtures/stats.json
|
98
|
+
- tests/minitest_helper.rb
|
99
|
+
- tests/unit/agent_test.rb
|
100
|
+
homepage: http://www.kontera.com
|
101
|
+
licenses: []
|
102
|
+
metadata: {}
|
103
|
+
post_install_message:
|
104
|
+
rdoc_options: []
|
105
|
+
require_paths:
|
106
|
+
- lib
|
107
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
108
|
+
requirements:
|
109
|
+
- - '>='
|
110
|
+
- !ruby/object:Gem::Version
|
111
|
+
version: 1.8.5
|
112
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
113
|
+
requirements:
|
114
|
+
- - '>='
|
115
|
+
- !ruby/object:Gem::Version
|
116
|
+
version: '0'
|
117
|
+
requirements: []
|
118
|
+
rubyforge_project: ruby-nutcracker-graphite
|
119
|
+
rubygems_version: 2.0.3
|
120
|
+
signing_key:
|
121
|
+
specification_version: 4
|
122
|
+
summary: Send Twemproxy/nutcracker statistics to Graphite
|
123
|
+
test_files: []
|