simple_metrics 0.2.3 → 0.3.2
Sign up to get free protection for your applications and to get access to all the features.
- data/.travis.yml +3 -0
- data/README.markdown +16 -53
- data/Rakefile +17 -0
- data/bin/populate +26 -13
- data/bin/simple_metrics_server +4 -3
- data/bin/simple_metrics_web +11 -0
- data/config.ru +6 -0
- data/default_config.yml +34 -0
- data/lib/simple_metrics/app.rb +136 -0
- data/lib/simple_metrics/array_aggregation.rb +84 -0
- data/lib/simple_metrics/bucket.rb +74 -63
- data/lib/simple_metrics/configuration.rb +79 -0
- data/lib/simple_metrics/data_point/base.rb +59 -0
- data/lib/simple_metrics/data_point/counter.rb +13 -0
- data/lib/simple_metrics/data_point/event.rb +12 -0
- data/lib/simple_metrics/data_point/gauge.rb +13 -0
- data/lib/simple_metrics/data_point/timing.rb +12 -0
- data/lib/simple_metrics/data_point.rb +32 -136
- data/lib/simple_metrics/data_point_repository.rb +131 -0
- data/lib/simple_metrics/functions.rb +5 -5
- data/lib/simple_metrics/graph.rb +10 -14
- data/lib/simple_metrics/metric.rb +28 -0
- data/lib/simple_metrics/metric_repository.rb +54 -0
- data/lib/simple_metrics/public/css/bootstrap-responsive.min.css +12 -0
- data/lib/simple_metrics/public/css/bootstrap.min.css +689 -0
- data/lib/simple_metrics/public/css/graph.css +45 -0
- data/lib/simple_metrics/public/css/rickshaw.min.css +1 -0
- data/lib/simple_metrics/public/img/glyphicons-halflings-white.png +0 -0
- data/lib/simple_metrics/public/img/glyphicons-halflings.png +0 -0
- data/lib/simple_metrics/public/js/application.js +278 -0
- data/lib/simple_metrics/public/js/backbone-0.9.2.min.js +38 -0
- data/lib/simple_metrics/public/js/bootstrap.min.js +6 -0
- data/lib/simple_metrics/public/js/d3.v2.min.js +4 -0
- data/lib/simple_metrics/public/js/handlebars-1.0.0.beta.6.js +1550 -0
- data/lib/simple_metrics/public/js/jquery-1.7.1.min.js +4 -0
- data/lib/simple_metrics/public/js/rickshaw.min.js +1 -0
- data/lib/simple_metrics/public/js/underscore-1.3.1.min.js +31 -0
- data/lib/simple_metrics/repository.rb +34 -0
- data/lib/simple_metrics/udp_server.rb +81 -0
- data/lib/simple_metrics/update_aggregation.rb +62 -0
- data/lib/simple_metrics/value_aggregation.rb +63 -0
- data/lib/simple_metrics/version.rb +1 -1
- data/lib/simple_metrics/views/graph.erb +93 -0
- data/lib/simple_metrics/views/index.erb +0 -0
- data/lib/simple_metrics/views/layout.erb +119 -0
- data/lib/simple_metrics/views/show.erb +31 -0
- data/lib/simple_metrics.rb +19 -76
- data/simple_metrics.gemspec +6 -0
- data/spec/array_aggregation_spec.rb +51 -0
- data/spec/bucket_spec.rb +24 -62
- data/spec/data_point_repository_spec.rb +114 -0
- data/spec/data_point_spec.rb +1 -70
- data/spec/graph_spec.rb +2 -20
- data/spec/metric_repository_spec.rb +53 -0
- data/spec/spec_helper.rb +3 -3
- data/spec/value_aggregation_spec.rb +52 -0
- metadata +131 -24
- data/bin/simple_metrics_client +0 -64
- data/lib/simple_metrics/client.rb +0 -83
- data/lib/simple_metrics/mongo.rb +0 -48
- data/lib/simple_metrics/server.rb +0 -66
data/bin/simple_metrics_client
DELETED
@@ -1,64 +0,0 @@
|
|
1
|
-
#!/usr/bin/env ruby
|
2
|
-
|
3
|
-
require "rubygems"
|
4
|
-
require "bundler/setup"
|
5
|
-
|
6
|
-
require 'optparse'
|
7
|
-
require "simple_metrics"
|
8
|
-
|
9
|
-
options = {
|
10
|
-
:host => 'localhost',
|
11
|
-
:port => 8125,
|
12
|
-
:sample_rate => 1
|
13
|
-
}
|
14
|
-
|
15
|
-
parser ||= OptionParser.new do |opts|
|
16
|
-
opts.banner = "Usage Example: simple_metrics_send com.test.mymetric -c5"
|
17
|
-
|
18
|
-
opts.separator ""
|
19
|
-
opts.separator "Client options:"
|
20
|
-
|
21
|
-
opts.on("-c", "--counter VALUE", "Counter, a relative value") do |value|
|
22
|
-
options[:type] = 'c'
|
23
|
-
options[:stat] = value.to_i
|
24
|
-
end
|
25
|
-
opts.on("-g", "--gauge VALUE", "Gauge, an absolute value ") do |value|
|
26
|
-
options[:type] = 'g'
|
27
|
-
options[:stat] = value.to_i
|
28
|
-
end
|
29
|
-
opts.on("-t", "--timing VALUE", "A timing in ms") do |value|
|
30
|
-
options[:type] = 'ms'
|
31
|
-
options[:stat] = value.to_i
|
32
|
-
end
|
33
|
-
opts.on("-s", "--sample_rate VALUE", "An optional sample rate between 0 and 1 (example: 0.2)") do |value|
|
34
|
-
options[:sample_rate] = value.to_f || 1
|
35
|
-
end
|
36
|
-
|
37
|
-
opts.separator ""
|
38
|
-
|
39
|
-
opts.on("-a", "--address HOST", "bind to HOST address (default: #{options[:host]})") do |host|
|
40
|
-
options[:host] = host
|
41
|
-
end
|
42
|
-
|
43
|
-
opts.on("-p", "--port PORT", "use PORT (default: #{options[:port]})") do |port|
|
44
|
-
options[:port] = port.to_i
|
45
|
-
end
|
46
|
-
|
47
|
-
opts.separator ""
|
48
|
-
opts.on_tail("-h", "--help", "Show this message") { puts opts; exit }
|
49
|
-
opts.on_tail('-v', '--version', "Show version") { puts SimpleMetrics::VERSION; exit }
|
50
|
-
|
51
|
-
end.parse!(ARGV)
|
52
|
-
|
53
|
-
command = ARGV.shift
|
54
|
-
arguments = ARGV
|
55
|
-
client = SimpleMetrics::Client.new(options[:host])
|
56
|
-
|
57
|
-
case options[:type]
|
58
|
-
when'c'
|
59
|
-
client.count(command, options[:stat], options[:sample_rate])
|
60
|
-
when 'g'
|
61
|
-
client.gauge(command, options[:stat], options[:sample_rate])
|
62
|
-
when 'ms'
|
63
|
-
client.timing(command, options[:stat], options[:sample_rate])
|
64
|
-
end
|
@@ -1,83 +0,0 @@
|
|
1
|
-
# encoding: utf-8
|
2
|
-
require "socket"
|
3
|
-
|
4
|
-
module SimpleMetrics
|
5
|
-
|
6
|
-
class Client
|
7
|
-
VERSION = "0.0.1"
|
8
|
-
|
9
|
-
def initialize(host, port = 8125)
|
10
|
-
@host, @port = host, port
|
11
|
-
end
|
12
|
-
|
13
|
-
# send relative value
|
14
|
-
def increment(stat, sample_rate = 1)
|
15
|
-
count(stat, 1, sample_rate)
|
16
|
-
end
|
17
|
-
|
18
|
-
# send relative value
|
19
|
-
def decrement(stat, sample_rate = 1)
|
20
|
-
count(stat, -1, sample_rate)
|
21
|
-
end
|
22
|
-
|
23
|
-
# send relative value
|
24
|
-
def count(stat, count, sample_rate = 1)
|
25
|
-
send_data( stat, count, 'c', sample_rate)
|
26
|
-
end
|
27
|
-
|
28
|
-
# send absolute value
|
29
|
-
# TODO: check if this is actually supported by Statsd server
|
30
|
-
def gauge(stat, value)
|
31
|
-
send_data(stat, value, 'g')
|
32
|
-
end
|
33
|
-
|
34
|
-
# Sends a timing (in ms) (glork)
|
35
|
-
def timing(stat, ms, sample_rate = 1)
|
36
|
-
send_data(stat, ms, 'ms', sample_rate)
|
37
|
-
end
|
38
|
-
|
39
|
-
# Sends a timing (in ms) block based
|
40
|
-
def time(stat, sample_rate = 1, &block)
|
41
|
-
start = Time.now
|
42
|
-
result = block.call
|
43
|
-
timing(stat, ((Time.now - start) * 1000).round, sample_rate)
|
44
|
-
result
|
45
|
-
end
|
46
|
-
|
47
|
-
private
|
48
|
-
|
49
|
-
def sampled(sample_rate, &block)
|
50
|
-
if sample_rate < 1
|
51
|
-
block.call if rand <= sample_rate
|
52
|
-
else
|
53
|
-
block.call
|
54
|
-
end
|
55
|
-
end
|
56
|
-
|
57
|
-
def send_data(stat, delta, type, sample_rate = 1)
|
58
|
-
sampled(sample_rate) do
|
59
|
-
data = "#{stat}:#{delta}|#{type}" # TODO: check stat is valid
|
60
|
-
data << "|@#{sample_rate}" if sample_rate < 1
|
61
|
-
send_to_socket(data)
|
62
|
-
end
|
63
|
-
end
|
64
|
-
|
65
|
-
def send_to_socket(data)
|
66
|
-
logger.debug "SimpleMetrics Client send: #{data}"
|
67
|
-
socket.send(data, 0, @host, @port)
|
68
|
-
rescue Exception => e
|
69
|
-
puts e.backtrace
|
70
|
-
logger.error "SimpleMetrics Client error: #{e}"
|
71
|
-
end
|
72
|
-
|
73
|
-
def socket
|
74
|
-
@socket ||= UDPSocket.new
|
75
|
-
end
|
76
|
-
|
77
|
-
def logger
|
78
|
-
@logger ||= SimpleMetrics.logger
|
79
|
-
end
|
80
|
-
|
81
|
-
end
|
82
|
-
|
83
|
-
end
|
data/lib/simple_metrics/mongo.rb
DELETED
@@ -1,48 +0,0 @@
|
|
1
|
-
# encoding: utf-8
|
2
|
-
require "mongo"
|
3
|
-
|
4
|
-
module SimpleMetrics
|
5
|
-
module Mongo
|
6
|
-
extend self
|
7
|
-
|
8
|
-
def ensure_collections_exist
|
9
|
-
SimpleMetrics.logger.debug "SERVER: MongoDB - found following collections: #{db.collection_names.inspect}"
|
10
|
-
Bucket.all.each do |bucket|
|
11
|
-
unless db.collection_names.include?(bucket.name)
|
12
|
-
db.create_collection(bucket.name, :capped => bucket.capped, :size => bucket.size)
|
13
|
-
SimpleMetrics.logger.debug "SERVER: MongoDB - created collection #{bucket.name}, capped: #{bucket.capped}, size: #{bucket.size}"
|
14
|
-
end
|
15
|
-
|
16
|
-
db.collection(bucket.name).ensure_index([['ts', ::Mongo::ASCENDING]])
|
17
|
-
SimpleMetrics.logger.debug "SERVER: MongoDB - ensure index on column ts for collection #{bucket.name}"
|
18
|
-
end
|
19
|
-
end
|
20
|
-
|
21
|
-
def truncate_collections
|
22
|
-
Bucket.all.each do |bucket|
|
23
|
-
if db.collection_names.include?(bucket.name)
|
24
|
-
if bucket.capped?
|
25
|
-
collection(bucket.name).drop # capped collections can't remove elements, drop it instead
|
26
|
-
else
|
27
|
-
collection(bucket.name).remove
|
28
|
-
end
|
29
|
-
SimpleMetrics.logger.debug "SERVER: MongoDB - truncated collection #{bucket.name}"
|
30
|
-
end
|
31
|
-
end
|
32
|
-
end
|
33
|
-
|
34
|
-
@@collection = {}
|
35
|
-
def collection(name)
|
36
|
-
@@collection[name] ||= db.collection(name)
|
37
|
-
end
|
38
|
-
|
39
|
-
def connection
|
40
|
-
@@connection ||= ::Mongo::Connection.new(SimpleMetrics.db_config[:host], SimpleMetrics.db_config[:port])
|
41
|
-
end
|
42
|
-
|
43
|
-
def db
|
44
|
-
@@db ||= connection.db(SimpleMetrics.db_config[:db_name], SimpleMetrics.db_config[:options])
|
45
|
-
end
|
46
|
-
|
47
|
-
end
|
48
|
-
end
|
@@ -1,66 +0,0 @@
|
|
1
|
-
# encoding: utf-8
|
2
|
-
require "eventmachine"
|
3
|
-
|
4
|
-
module SimpleMetrics
|
5
|
-
|
6
|
-
module ClientHandler
|
7
|
-
|
8
|
-
@@data_points = []
|
9
|
-
|
10
|
-
class << self
|
11
|
-
def get_and_clear_data_points
|
12
|
-
data_points = @@data_points.dup
|
13
|
-
@@data_points = []
|
14
|
-
data_points
|
15
|
-
end
|
16
|
-
end
|
17
|
-
|
18
|
-
def data_points
|
19
|
-
@@data_points
|
20
|
-
end
|
21
|
-
|
22
|
-
def post_init
|
23
|
-
SimpleMetrics.logger.info "ClientHandler entering post_init"
|
24
|
-
end
|
25
|
-
|
26
|
-
def receive_data(data)
|
27
|
-
SimpleMetrics.logger.debug "received_data: #{data.inspect}"
|
28
|
-
|
29
|
-
@@data_points ||= []
|
30
|
-
@@data_points << DataPoint.parse(data)
|
31
|
-
rescue DataPoint::ParserError => e
|
32
|
-
SimpleMetrics.logger.debug "Invalid Data skipped: #{data}"
|
33
|
-
end
|
34
|
-
end
|
35
|
-
|
36
|
-
class Server
|
37
|
-
|
38
|
-
attr_reader :db, :connection
|
39
|
-
|
40
|
-
def start
|
41
|
-
SimpleMetrics.logger.info "SERVER: starting up on #{SimpleMetrics.config[:host]}:#{SimpleMetrics.config[:port]}..."
|
42
|
-
|
43
|
-
Mongo.ensure_collections_exist
|
44
|
-
|
45
|
-
EM.run do
|
46
|
-
EM.open_datagram_socket(SimpleMetrics.config[:host], SimpleMetrics.config[:port], SimpleMetrics::ClientHandler) do |con|
|
47
|
-
EventMachine::add_periodic_timer(SimpleMetrics.config[:flush_interval]) do
|
48
|
-
SimpleMetrics.logger.debug "SERVER: period timer triggered after #{SimpleMetrics.config[:flush_interval]} seconds"
|
49
|
-
|
50
|
-
EM.defer { Bucket.flush_data_points(ClientHandler.get_and_clear_data_points) }
|
51
|
-
end
|
52
|
-
end
|
53
|
-
end
|
54
|
-
end
|
55
|
-
|
56
|
-
def stop
|
57
|
-
SimpleMetrics.logger.info "EventMachine stop"
|
58
|
-
EM.stop
|
59
|
-
end
|
60
|
-
|
61
|
-
def to_s
|
62
|
-
"#{SimpleMetrics.config[:host]}:#{SimpleMetrics.config[:port]}"
|
63
|
-
end
|
64
|
-
|
65
|
-
end
|
66
|
-
end
|