From 37ee2927697bf2393dec6efccfa93f124a6163b1 Mon Sep 17 00:00:00 2001 From: ulrik Date: Sat, 27 Sep 2014 18:21:07 +0200 Subject: [PATCH 01/21] Added gauges in addition to timers and counters --- lib/rstatsd/rstatsd.rb | 17 +++++++++++++---- 1 file changed, 13 insertions(+), 4 deletions(-) diff --git a/lib/rstatsd/rstatsd.rb b/lib/rstatsd/rstatsd.rb index 54d26e6..4ca03b6 100644 --- a/lib/rstatsd/rstatsd.rb +++ b/lib/rstatsd/rstatsd.rb @@ -30,7 +30,7 @@ def execute! trap(:INT) { logit("Caught SIGINT. Exiting"); Process.kill(:INT, pipe.pid) } trap(:TERM) { logit("Caught SIGTERM. Exiting"); Process.kill(:TERM, pipe.pid) } - timers, counters = {}, {} + timers, counters, gauges = {}, {}, {} logit("Starting thread for command #{@command}") pipe = IO.popen(@command) @@ -39,6 +39,8 @@ def execute! @regexes.each do |r| if r.statsd_type == RegExData::Timer timers = r.get_increments(l, timers) + elsif r.statsd_type == RegExData::Gauge + gauges = r.get_increments(l, gauges) else counters = r.get_increments(l, counters) end @@ -48,8 +50,9 @@ def execute! if (i % @every) == 0 logit("#{i} lines, sending to statsd", Logger::DEBUG) statsd_send(counters) + statsd_send(gauges, 'gauge') statsd_send(divide_hash(timers, @every), 'timer') - timers, counters = {}, {} + timers, counters, gauges = {}, {}, {} end # this is for debugging #sleep(rand/100) @@ -73,6 +76,9 @@ def statsd_send ( h, statsd_type = nil ) if statsd_type == 'timer' Statsd.timing(k,v) logit("Set timer value #{k} to #{v}",Logger::DEBUG) + elsif statsd_type == 'gauge' + Statsd.gauge(k,v) + logit("Set gauge value #{k} to #{v}",Logger::DEBUG) else Statsd.update_counter(k,v) logit("Incremented #{k} by #{v}",Logger::DEBUG) @@ -87,13 +93,14 @@ class RegExData attr_writer :logger attr_reader :regex, :statsd_type - Counter, Timer = 1, 2 + Counter, Timer, Gauge = 1, 2, 3 def initialize ( h ) @regex = which_regex h[:regex] @metrics = h[:metrics] || [] @statsd_type = case h[:statsd_type] when 'timer' then Timer + when 'gauge' then Gauge else Counter end @statsd = h[:statsd] || true @@ -132,7 +139,9 @@ def build_and_increment ( h, name = nil ) h[metric_name] ||= 0 if @statsd_type == Timer h[metric_name] += @matches[name.to_sym].to_f - else + elsif @statsd_type == Gauge + h[metric_name] = @matches[name.to_sym].to_f + else h[metric_name] += @matches[name.to_sym].to_i end else From 660462c575f8ae0c10accd19b6abb1a09d1993ba Mon Sep 17 00:00:00 2001 From: ulrik Date: Sat, 27 Sep 2014 18:41:36 +0200 Subject: [PATCH 02/21] Made the processctl work on ruby 1.9.x --- lib/rstatsd/processctl.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/rstatsd/processctl.rb b/lib/rstatsd/processctl.rb index 19345dd..2410aac 100644 --- a/lib/rstatsd/processctl.rb +++ b/lib/rstatsd/processctl.rb @@ -100,7 +100,7 @@ def get_running_pids end def get_allpids - @allpids = `ps -ef |sed 1d`.to_a.map { |x| a = x.strip.split(/\s+/); [a[1].to_i,a[2].to_i] } + @allpids = `ps -ef |sed 1d`.lines.to_a.map { |x| a = x.strip.split(/\s+/); [a[1].to_i,a[2].to_i] } end # thar be recursion ahead, matey From 8b3cfb8dbea094b9f06f52feea5b9d8b64cf51ac Mon Sep 17 00:00:00 2001 From: ulrik Date: Sat, 27 Sep 2014 19:15:14 +0200 Subject: [PATCH 03/21] Created a gemspec file --- rstatsd.gemspec | 14 ++++++++++++++ 1 file changed, 14 insertions(+) create mode 100644 rstatsd.gemspec diff --git a/rstatsd.gemspec b/rstatsd.gemspec new file mode 100644 index 0000000..6247451 --- /dev/null +++ b/rstatsd.gemspec @@ -0,0 +1,14 @@ +Gem::Specification.new do |s| + s.name = 'rstatsd' + s.version = '1.0.0' + s.date = '2014-09-27' + s.summary = "Tool to turn logs into statsd metrics." + s.description = "rstatsd is a daemon that takes the output of multiple commands and sends + the output to statsd based on a regular expressions with optional named capture + groups." + s.authors = ["Aaron Brown"] + s.email = '9minutesnooze@github.com' + s.files = ["lib/oniguruma.rb", "lib/rstatsd/rstatsd.rb", "lib/rstatsd/hash.rb", "lib/rstatsd/processctl.rb", "rstatsd.rb"] + s.homepage = 'https://github.com/ideeli/rstatsd' + s.license = 'MIT' +end From 23139fdbe8db23fe45a82f0c73bab179e38b83b1 Mon Sep 17 00:00:00 2001 From: ulrik Date: Sat, 27 Sep 2014 19:15:49 +0200 Subject: [PATCH 04/21] Added dynamically generated stuff to gitignore --- .gitignore | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/.gitignore b/.gitignore index 217d9f3..23b2db5 100644 --- a/.gitignore +++ b/.gitignore @@ -1,2 +1,11 @@ rstatsd.yaml rstatsd-cfg.rb +rstatsd-1.0.0.gem +rstatsd-1.0.0.tar.gz +rstatsd-1.0.0/ +ruby-rstatsd-1.0.0/ +ruby-rstatsd_1.0.0-1.debian.tar.gz +ruby-rstatsd_1.0.0-1.dsc +ruby-rstatsd_1.0.0-1_all.deb +ruby-rstatsd_1.0.0-1_amd64.changes +ruby-rstatsd_1.0.0.orig.tar.gz From 963eac2cc067e2007ea5aa30a45f814fe6764186 Mon Sep 17 00:00:00 2001 From: ulrik Date: Sat, 27 Sep 2014 20:05:42 +0200 Subject: [PATCH 05/21] Moved rstatsd.rb to bin/rstatsd --- rstatsd.rb => bin/rstatsd | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename rstatsd.rb => bin/rstatsd (100%) diff --git a/rstatsd.rb b/bin/rstatsd similarity index 100% rename from rstatsd.rb rename to bin/rstatsd From 5acd2c2240f3d9aa7484ef99cdd46ed332b542c9 Mon Sep 17 00:00:00 2001 From: ulrik Date: Sat, 27 Sep 2014 20:47:22 +0200 Subject: [PATCH 06/21] Created an upstart job for rstatsd --- config/rstatsd.upstart.conf | 13 +++++++++++++ 1 file changed, 13 insertions(+) create mode 100644 config/rstatsd.upstart.conf diff --git a/config/rstatsd.upstart.conf b/config/rstatsd.upstart.conf new file mode 100644 index 0000000..e1546e5 --- /dev/null +++ b/config/rstatsd.upstart.conf @@ -0,0 +1,13 @@ +description "Capture metrics from logs and send to statsd server" +start on runlevel [2345] +stop on runlevel [!2345] + +respawn +expect fork +kill timeout 2 + +pre-start exec /usr/bin/test -e /etc/rstatsd.yaml + +exec /usr/bin/rstatsd -c /etc/rstatsd.yaml -d -k start + +pre-stop exec /usr/bin/rstatsd -c /etc/rstatsd.yaml -d -k stop From 34b5c49754b95d977587283de20628a57de280eb Mon Sep 17 00:00:00 2001 From: ulrik Date: Sat, 27 Sep 2014 20:48:05 +0200 Subject: [PATCH 07/21] Made the gemspec use git ls-files to make sure all files got picked-up --- rstatsd.gemspec | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/rstatsd.gemspec b/rstatsd.gemspec index 6247451..874a51c 100644 --- a/rstatsd.gemspec +++ b/rstatsd.gemspec @@ -1,3 +1,5 @@ +$:.push File.expand_path("../lib", __FILE__) + Gem::Specification.new do |s| s.name = 'rstatsd' s.version = '1.0.0' @@ -8,7 +10,11 @@ Gem::Specification.new do |s| groups." s.authors = ["Aaron Brown"] s.email = '9minutesnooze@github.com' - s.files = ["lib/oniguruma.rb", "lib/rstatsd/rstatsd.rb", "lib/rstatsd/hash.rb", "lib/rstatsd/processctl.rb", "rstatsd.rb"] + s.files = `git ls-files`.split("\n") s.homepage = 'https://github.com/ideeli/rstatsd' s.license = 'MIT' + s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) } + s.require_paths = ["lib"] + s.default_executable = 'rstatsd' + s.add_dependency 'statsd-client' end From 51bf7f67b499c1f347c40b3d167fc274257d4d0d Mon Sep 17 00:00:00 2001 From: ulrik Date: Sat, 27 Sep 2014 20:48:43 +0200 Subject: [PATCH 08/21] Start use the gem provided rstatsd instead --- bin/rstatsd | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/bin/rstatsd b/bin/rstatsd index 1fa44c3..a614b54 100755 --- a/bin/rstatsd +++ b/bin/rstatsd @@ -10,7 +10,7 @@ require 'logger' require 'optparse' require 'rubygems' require 'statsd' -require File.dirname(__FILE__)+'/lib/rstatsd' +require 'rstatsd' def setup_logger ( logfile, loglevel = "INFO" ) From 662b96f0813c43d9ca4fa34bde0bf5929e0b0b69 Mon Sep 17 00:00:00 2001 From: ulrik Date: Sat, 27 Sep 2014 20:56:15 +0200 Subject: [PATCH 09/21] Removed the license, as no official license information could be found from ideeli --- rstatsd.gemspec | 1 - 1 file changed, 1 deletion(-) diff --git a/rstatsd.gemspec b/rstatsd.gemspec index 874a51c..2331e52 100644 --- a/rstatsd.gemspec +++ b/rstatsd.gemspec @@ -12,7 +12,6 @@ Gem::Specification.new do |s| s.email = '9minutesnooze@github.com' s.files = `git ls-files`.split("\n") s.homepage = 'https://github.com/ideeli/rstatsd' - s.license = 'MIT' s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) } s.require_paths = ["lib"] s.default_executable = 'rstatsd' From 96f52c517e6b452e27486a1073d7a7aebeb42be0 Mon Sep 17 00:00:00 2001 From: ulrik Date: Sat, 27 Sep 2014 21:30:08 +0200 Subject: [PATCH 10/21] Moved the example conf to config dir --- rstatsd-example.yaml => config/rstatsd-example.yaml | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename rstatsd-example.yaml => config/rstatsd-example.yaml (100%) diff --git a/rstatsd-example.yaml b/config/rstatsd-example.yaml similarity index 100% rename from rstatsd-example.yaml rename to config/rstatsd-example.yaml From 6f142ab2b22972baf4c6e98fbcec81250f3e7cfb Mon Sep 17 00:00:00 2001 From: ulrik Date: Sat, 27 Sep 2014 21:51:25 +0200 Subject: [PATCH 11/21] include only config, bin and lib dir from git ls-files --- rstatsd.gemspec | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/rstatsd.gemspec b/rstatsd.gemspec index 2331e52..1e3269d 100644 --- a/rstatsd.gemspec +++ b/rstatsd.gemspec @@ -10,7 +10,7 @@ Gem::Specification.new do |s| groups." s.authors = ["Aaron Brown"] s.email = '9minutesnooze@github.com' - s.files = `git ls-files`.split("\n") + s.files = `git ls-files -- bin lib config`.split("\n") s.homepage = 'https://github.com/ideeli/rstatsd' s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) } s.require_paths = ["lib"] From 2faddffe7ea23bd0fa9d1a9f5a8bff210d55fc87 Mon Sep 17 00:00:00 2001 From: ulrik Date: Sat, 27 Sep 2014 22:29:15 +0200 Subject: [PATCH 12/21] Added tool to assist in testing regexps for matching log messages --- config/test_regex.pl | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) create mode 100644 config/test_regex.pl diff --git a/config/test_regex.pl b/config/test_regex.pl new file mode 100644 index 0000000..1a1bcf3 --- /dev/null +++ b/config/test_regex.pl @@ -0,0 +1,21 @@ +#!/usr/bin/perl + +# example: +# perl test_regex.pl "Charlie has 9 girls in 12 cities" "Charlie\s+has\s+(?\d+)\s+girls\s+in\s+(?\d+)\s+cities" +# +# Should return: +# girls: 9 +# cities: 12 + +# Parse command line arguments +$input_string = $ARGV[0]; +$input_regexp = $ARGV[1]; + +# Perform regexp matching +$input_string =~ m/($input_regexp)/; + +# Print the resulting groups and values +while (($key, $value) = each(%+)){ + print $key.": ".$value."\n"; +} + From a301bcd8bd1fb2d044504ea25008ae5bc5cb3fc8 Mon Sep 17 00:00:00 2001 From: Ulrik Holmen Date: Wed, 22 Oct 2014 10:53:00 +0200 Subject: [PATCH 13/21] Added support for conf.d glob includes --- bin/rstatsd | 11 +++++++++++ rstatsd.gemspec | 4 ++-- 2 files changed, 13 insertions(+), 2 deletions(-) diff --git a/bin/rstatsd b/bin/rstatsd index a614b54..9bb6051 100755 --- a/bin/rstatsd +++ b/bin/rstatsd @@ -27,6 +27,7 @@ end options = { :cfg_file => File.dirname(__FILE__)+'/rstatsd.yaml', :pidfile => '/tmp/rstatsd.pid', :ctl_cmd => "start", + :cfg_dir => File.dirname(__FILE__)+'/conf.d', :daemonize => false } @@ -38,6 +39,9 @@ OptionParser.new do |opts| opts.on("-c", "--config FILE", String, "Configuration file (default #{options[:cfg_file]})") do |v| options[:cfg_file] = v end + opts.on("-g", "--glob-dir FILE", String, "Configuration include directory (default #{options[:cfg_dir]})") do |v| + options[:cfg_dir] = v + end opts.on("-p", "--pidfile FILE", String, "PID file (default #{options[:pidfile]})") do |v| options[:pidfile] = v end @@ -50,8 +54,15 @@ OptionParser.new do |opts| end end.parse! + cfg = YAML.load_file(options[:cfg_file]) +Dir[options[:cfg_dir]+'/*.yaml'].each do |file| + include_cfg = YAML.load_file(file) + puts "Loading " + file + cfg = cfg.merge include_cfg +end + Statsd.host = cfg[:statsd][:host] Statsd.port = cfg[:statsd][:port] diff --git a/rstatsd.gemspec b/rstatsd.gemspec index 1e3269d..c91fc0f 100644 --- a/rstatsd.gemspec +++ b/rstatsd.gemspec @@ -2,8 +2,8 @@ $:.push File.expand_path("../lib", __FILE__) Gem::Specification.new do |s| s.name = 'rstatsd' - s.version = '1.0.0' - s.date = '2014-09-27' + s.version = '1.0.1' + s.date = '2014-10-22' s.summary = "Tool to turn logs into statsd metrics." s.description = "rstatsd is a daemon that takes the output of multiple commands and sends the output to statsd based on a regular expressions with optional named capture From 9ec44fcca30dee7679d776c5a0cd8f14d88f0530 Mon Sep 17 00:00:00 2001 From: Ulrik Holmen Date: Wed, 22 Oct 2014 14:06:21 +0200 Subject: [PATCH 14/21] Updated the conf.d file globbing support to merge in a more sophisticated way --- bin/rstatsd | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/bin/rstatsd b/bin/rstatsd index 9bb6051..99023b9 100755 --- a/bin/rstatsd +++ b/bin/rstatsd @@ -54,13 +54,14 @@ OptionParser.new do |opts| end end.parse! - +puts "Loading config from " + options[:cfg_file] cfg = YAML.load_file(options[:cfg_file]) +cfg[:cmds] ||= [] -Dir[options[:cfg_dir]+'/*.yaml'].each do |file| - include_cfg = YAML.load_file(file) +Dir[options[:cfg_dir]+'/*.yaml'].each do |file| + include_cfg = YAML.load_file(file) puts "Loading " + file - cfg = cfg.merge include_cfg + cfg[:cmds] = cfg[:cmds].push(include_cfg[0]) end Statsd.host = cfg[:statsd][:host] From 90af59cba73ffb636dffcc714d82f6fc40156e65 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Stefan=20Bergstr=C3=B6m?= Date: Sat, 8 Nov 2014 16:29:38 +0100 Subject: [PATCH 15/21] glob include conf parse fix --- bin/rstatsd | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/bin/rstatsd b/bin/rstatsd index 9bb6051..dce8c02 100755 --- a/bin/rstatsd +++ b/bin/rstatsd @@ -56,11 +56,12 @@ end.parse! cfg = YAML.load_file(options[:cfg_file]) +cfg[:cmds] ||= [] Dir[options[:cfg_dir]+'/*.yaml'].each do |file| include_cfg = YAML.load_file(file) puts "Loading " + file - cfg = cfg.merge include_cfg + cfg[:cmds] = cfg[:cmds].push(include_cfg[0]) end Statsd.host = cfg[:statsd][:host] From eb75f4f209616f47cdb012b4484ee3919c7088a4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Stefan=20Bergstr=C3=B6m?= Date: Sat, 8 Nov 2014 16:30:06 +0100 Subject: [PATCH 16/21] Added time interval support New configuration parameter :interval. If :interval is set, stats are sent every :interval seconds, else if :every is set, stats are sent every :every row, else stats are sent once per second. --- bin/rstatsd | 1 + lib/rstatsd/rstatsd.rb | 40 ++++++++++++++++++++++++++++------------ 2 files changed, 29 insertions(+), 12 deletions(-) diff --git a/bin/rstatsd b/bin/rstatsd index dce8c02..81a762a 100755 --- a/bin/rstatsd +++ b/bin/rstatsd @@ -73,6 +73,7 @@ logger = setup_logger(cfg[:logfile] || STDOUT, cfg[:loglevel] || "INFO") cfg[:cmds].each do |cmd| params = { :every => cmd[:every], + :interval => cmd[:interval], :logger => logger, :prefix => cfg[:metric_prefix] } diff --git a/lib/rstatsd/rstatsd.rb b/lib/rstatsd/rstatsd.rb index 4ca03b6..019b728 100644 --- a/lib/rstatsd/rstatsd.rb +++ b/lib/rstatsd/rstatsd.rb @@ -1,4 +1,6 @@ module RStatsd + ENV['TZ'] = ":/etc/localtime" + module Helpers def prefix_metric_name ( pieces ) pieces.join(".") @@ -11,13 +13,15 @@ def logit ( msg, level = Logger::INFO ) class Command include Helpers - attr_accessor :command, :every + attr_accessor :command def initialize ( h = {}, &block ) - @command = nil - @logger = h[:logger] - @every = h[:every] || 1 - @prefix = h[:prefix] - @regexes = [] + @command = nil + @logger = h[:logger] + @every = h[:every] || 1 + @interval = h[:interval] || nil + @prefix = h[:prefix] + @regexes = [] + yield self end @@ -32,27 +36,39 @@ def execute! timers, counters, gauges = {}, {}, {} - logit("Starting thread for command #{@command}") + logit("Starting thread for command #{@command}; interval #{@interval}, every #{@every}") pipe = IO.popen(@command) begin + if @interval + next_update = Time.now.to_f + @interval + end + pipe.each_with_index do |l,i| @regexes.each do |r| if r.statsd_type == RegExData::Timer timers = r.get_increments(l, timers) elsif r.statsd_type == RegExData::Gauge - gauges = r.get_increments(l, gauges) + gauges = r.get_increments(l, gauges) else counters = r.get_increments(l, counters) end end - # only send to statsd every x lines - this is to avoid UDP floods - if (i % @every) == 0 - logit("#{i} lines, sending to statsd", Logger::DEBUG) + if @interval + do_update = Time.now.to_f >= next_update + else + do_update = (i % @every) == 0 + end + + if do_update + logit("#{@command}: #{i} lines, sending to statsd", Logger::DEBUG) statsd_send(counters) statsd_send(gauges, 'gauge') statsd_send(divide_hash(timers, @every), 'timer') timers, counters, gauges = {}, {}, {} + if @interval + next_update = Time.now.to_f + @interval + end end # this is for debugging #sleep(rand/100) @@ -141,7 +157,7 @@ def build_and_increment ( h, name = nil ) h[metric_name] += @matches[name.to_sym].to_f elsif @statsd_type == Gauge h[metric_name] = @matches[name.to_sym].to_f - else + else h[metric_name] += @matches[name.to_sym].to_i end else From dc138df43708cb9f6434cfc4e43e3805ac844e0e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Stefan=20Bergstr=C3=B6m?= Date: Sat, 8 Nov 2014 18:35:45 +0100 Subject: [PATCH 17/21] Added support for "unmetrics" A really bad name for non-matching rows. Instead of throwing away non- matching rows, the unmetrics feature let's the user count those as well with the metrics names given by a list of "unmetrics". --- lib/rstatsd/rstatsd.rb | 21 ++++++++++++++------- 1 file changed, 14 insertions(+), 7 deletions(-) diff --git a/lib/rstatsd/rstatsd.rb b/lib/rstatsd/rstatsd.rb index 019b728..cd17f40 100644 --- a/lib/rstatsd/rstatsd.rb +++ b/lib/rstatsd/rstatsd.rb @@ -114,6 +114,7 @@ class RegExData def initialize ( h ) @regex = which_regex h[:regex] @metrics = h[:metrics] || [] + @unmetrics = h[:unmetrics] || [] @statsd_type = case h[:statsd_type] when 'timer' then Timer when 'gauge' then Gauge @@ -133,13 +134,19 @@ def initialize ( h ) def get_increments ( line, h ) h ||= {} @matches = @regex.match(line) - return h unless @matches - if has_captures? - @matches.names.each do |name| - h = build_and_increment(h, name ) + if @matches + if has_captures? + @matches.names.each do |name| + h = build_and_increment(h, name ) + end + else + h = build_and_increment(h) + end + elsif @unmetrics + @unmetrics.each do |unmetric| + h[unmetric] ||= 0 + h[unmetric] += 1 end - else - h = build_and_increment(h) end h end @@ -161,7 +168,7 @@ def build_and_increment ( h, name = nil ) h[metric_name] += @matches[name.to_sym].to_i end else - # the value of the named capture will be used as a leaf node in the mtric name + # the value of the named capture will be used as a leaf node in the metric name metric_name = prefix_metric_name( [ metric_name, name, @matches[name.to_sym] ] ) if name h[metric_name] ||= 0 h[metric_name] += 1 From ed0fddcd74cd6c5289565e1c5e3bc0168bffed9c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Stefan=20Bergstr=C3=B6m?= Date: Sat, 8 Nov 2014 19:01:30 +0100 Subject: [PATCH 18/21] Fix for nested captures If we use nested captures, we can get a MatchData set where some members are nil (meaning that that capture did not match anything). Those should not be counted --- lib/rstatsd/rstatsd.rb | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/lib/rstatsd/rstatsd.rb b/lib/rstatsd/rstatsd.rb index cd17f40..66ceaa5 100644 --- a/lib/rstatsd/rstatsd.rb +++ b/lib/rstatsd/rstatsd.rb @@ -137,7 +137,11 @@ def get_increments ( line, h ) if @matches if has_captures? @matches.names.each do |name| - h = build_and_increment(h, name ) + # If we use nested captures, we can get empty MatchData members, + # we should skip those. + if !@matches[name.to_sym].nil? + h = build_and_increment(h, name ) + end end else h = build_and_increment(h) From 2cba4e937acfd18c5b2920f40080d47fd23f5c6c Mon Sep 17 00:00:00 2001 From: Ulrik Holmen Date: Sun, 9 Nov 2014 22:13:45 +0100 Subject: [PATCH 19/21] Added *.gem to avoid checking in the gem files --- .gitignore | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.gitignore b/.gitignore index 23b2db5..72ab018 100644 --- a/.gitignore +++ b/.gitignore @@ -1,6 +1,6 @@ rstatsd.yaml rstatsd-cfg.rb -rstatsd-1.0.0.gem +*.gem rstatsd-1.0.0.tar.gz rstatsd-1.0.0/ ruby-rstatsd-1.0.0/ From 2ad661259fc212098c94195395097e5e1a2f7eb7 Mon Sep 17 00:00:00 2001 From: Ulrik Holmen Date: Sun, 9 Nov 2014 22:14:18 +0100 Subject: [PATCH 20/21] Bumped the gemspec version --- rstatsd.gemspec | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/rstatsd.gemspec b/rstatsd.gemspec index c91fc0f..9c12ed1 100644 --- a/rstatsd.gemspec +++ b/rstatsd.gemspec @@ -2,7 +2,7 @@ $:.push File.expand_path("../lib", __FILE__) Gem::Specification.new do |s| s.name = 'rstatsd' - s.version = '1.0.1' + s.version = '1.0.2' s.date = '2014-10-22' s.summary = "Tool to turn logs into statsd metrics." s.description = "rstatsd is a daemon that takes the output of multiple commands and sends From 1e2ea94b0db50b7c7cb5f6be8316f7127e7824a2 Mon Sep 17 00:00:00 2001 From: Ulrik Holmen Date: Sun, 9 Nov 2014 22:18:49 +0100 Subject: [PATCH 21/21] Bumped the gem version --- rstatsd.gemspec | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/rstatsd.gemspec b/rstatsd.gemspec index 9c12ed1..58c2360 100644 --- a/rstatsd.gemspec +++ b/rstatsd.gemspec @@ -2,13 +2,13 @@ $:.push File.expand_path("../lib", __FILE__) Gem::Specification.new do |s| s.name = 'rstatsd' - s.version = '1.0.2' - s.date = '2014-10-22' + s.version = '1.0.3' + s.date = '2014-11-09' s.summary = "Tool to turn logs into statsd metrics." s.description = "rstatsd is a daemon that takes the output of multiple commands and sends the output to statsd based on a regular expressions with optional named capture groups." - s.authors = ["Aaron Brown"] + s.authors = ["Aaron Brown", "Ulrik Holmen", "Stefan Bergstrom"] s.email = '9minutesnooze@github.com' s.files = `git ls-files -- bin lib config`.split("\n") s.homepage = 'https://github.com/ideeli/rstatsd'