├── AUTHORS ├── Gemfile ├── README.md ├── Rakefile ├── VERSION ├── fluent-plugin-statsd.gemspec ├── lib └── fluent │ └── plugin │ └── out_statsd.rb └── test └── plugin └── out_statsd.rb /AUTHORS: -------------------------------------------------------------------------------- 1 | Chris Song 2 | -------------------------------------------------------------------------------- /Gemfile: -------------------------------------------------------------------------------- 1 | source :rubygems 2 | 3 | gemspec 4 | 5 | gem "statsd-ruby" 6 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Fluent event to statsd plugin. 2 | 3 | # Installation 4 | 5 | ``` 6 | $ fluent-gem install fluent-plugin-statsd 7 | ``` 8 | 9 | [![Gem Version](https://badge.fury.io/rb/fluent-plugin-statsd.png)](http://badge.fury.io/rb/fluent-plugin-statsd) 10 | 11 | # Usage 12 | 13 | ``` 14 | 15 | type statsd 16 | host localhost # optional 17 | port 8125# optional 18 | 19 | ``` 20 | 21 | ```ruby 22 | fluent_logger.post('statsd', 23 | :statsd_type => 'timing', 24 | :statsd_key => 'org.foo.timing', 25 | :statsd_timing => 0.234 26 | ) 27 | 28 | fluent_logger.post('statsd', 29 | :statsd_type => 'gauge', 30 | :statsd_gauge => 10, 31 | :statsd_key => 'org.foo.gauge' 32 | ) 33 | 34 | fluent_logger.post('statsd', 35 | :statsd_type => 'count', 36 | :statsd_gauge => 10, 37 | :statsd_key => 'org.foo.gauge' 38 | ) 39 | 40 | fluent_logger.post('statsd', 41 | :statsd_type => 'set', 42 | :statsd_gauge => 10, 43 | :statsd_key => 'org.foo.gauge' 44 | ) 45 | 46 | fluent_logger.post('statsd', 47 | :statsd_type => 'increment', 48 | :statsd_key => 'org.foo.counter' 49 | ) 50 | 51 | 52 | fluent_logger.post('statsd', 53 | :statsd_type => 'decrement', 54 | :statsd_key => 'org.foo.counter' 55 | ) 56 | ``` 57 | 58 | # td-agent.conf demo 59 | 60 | worked with record_reformer to transform access log request_time into statsd 61 | 62 | ``` 63 | 64 | type copy 65 | 66 | type statsd 67 | host 127.0.0.1 68 | port 8125 69 | flush_interval 1s 70 | 71 | # other stores... 72 | 73 | 74 | type record_reformer 75 | output_tag ${tag}.reformer 76 | # transform /url1/url2/url3 --> url.urlNN.urlNN 77 | statsd_key ${"url"+request_uri.gsub(/((\/[^\/]+){2}).*/, '\1').gsub(/([^\?]*)\?.*/,'\1').gsub(/[0-9]+/, "NN").gsub(/\//, ".");} 78 | statsd_timing ${request_time} 79 | statsd_type ${"timing"} 80 | 81 | ``` 82 | 83 | 84 | # Copyright 85 | 86 | Copyright (c) 2014- Chris Song 87 | 88 | # License 89 | 90 | Apache License, Version 2.0 91 | -------------------------------------------------------------------------------- /Rakefile: -------------------------------------------------------------------------------- 1 | require 'bundler' 2 | Bundler::GemHelper.install_tasks 3 | 4 | require 'rake/testtask' 5 | 6 | Rake::TestTask.new(:test) do |test| 7 | test.libs << 'lib' << 'test' 8 | test.test_files = FileList['test/plugin/*.rb'] 9 | test.verbose = true 10 | end 11 | 12 | task :coverage do |t| 13 | ENV['SIMPLE_COV'] = '1' 14 | Rake::Task["test"].invoke 15 | end 16 | 17 | task :default => [:build] 18 | -------------------------------------------------------------------------------- /VERSION: -------------------------------------------------------------------------------- 1 | 1.0.2 2 | -------------------------------------------------------------------------------- /fluent-plugin-statsd.gemspec: -------------------------------------------------------------------------------- 1 | # encoding: utf-8 2 | $:.push File.expand_path('../lib', __FILE__) 3 | 4 | Gem::Specification.new do |gem| 5 | gem.name = "fluent-plugin-statsd" 6 | gem.description = "fluentd output filter plugin to send metrics to Esty StatsD" 7 | gem.homepage = "https://github.com/fakechris/fluent-plugin-statsd" 8 | gem.summary = gem.description 9 | gem.version = File.read("VERSION").strip 10 | gem.authors = ["Chris Song"] 11 | gem.email = "fakechris@gmail.com" 12 | gem.has_rdoc = false 13 | gem.files = `git ls-files`.split("\n") 14 | gem.test_files = `git ls-files -- {test,spec,features}/*`.split("\n") 15 | gem.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) } 16 | gem.require_paths = ['lib'] 17 | 18 | gem.add_dependency "fluentd", ">= 0.10.8" 19 | 20 | gem.add_development_dependency "rake", ">= 0.9.2" 21 | gem.add_development_dependency "test-unit", ">= 3.2.0" 22 | gem.add_development_dependency "statsd-ruby", ">=1.2.1" 23 | end 24 | -------------------------------------------------------------------------------- /lib/fluent/plugin/out_statsd.rb: -------------------------------------------------------------------------------- 1 | require 'statsd-ruby' 2 | require 'fluent/output' 3 | 4 | module Fluent 5 | class StatsdOutput < BufferedOutput 6 | Fluent::Plugin.register_output('statsd', self) 7 | 8 | config_param :flush_interval, :time, :default => 1 9 | config_param :host, :string, :default => 'localhost' 10 | config_param :port, :string, :default => '8125' 11 | 12 | attr_reader :statsd 13 | 14 | def initialize 15 | super 16 | end 17 | 18 | def configure(conf) 19 | super 20 | @statsd = Statsd.new(host, port) 21 | end 22 | 23 | def start 24 | super 25 | end 26 | 27 | def shutdown 28 | super 29 | end 30 | 31 | def format(tag, time, record) 32 | record.to_msgpack 33 | end 34 | 35 | def write(chunk) 36 | chunk.msgpack_each {|record| 37 | if statsd_type = record['statsd_type'] 38 | case statsd_type 39 | when 'timing' 40 | @statsd.timing record['statsd_key'], record['statsd_timing'].to_f 41 | when 'gauge' 42 | @statsd.gauge record['statsd_key'], record['statsd_gauge'].to_f 43 | when 'count' 44 | @statsd.count record['statsd_key'], record['statsd_count'].to_f 45 | when 'set' 46 | @statsd.set record['statsd_key'], record['statsd_set'] 47 | when 'increment' 48 | @statsd.increment record['statsd_key'] 49 | when 'decrement' 50 | @statsd.decrement record['statsd_key'] 51 | end 52 | end 53 | } 54 | end 55 | 56 | end 57 | end 58 | -------------------------------------------------------------------------------- /test/plugin/out_statsd.rb: -------------------------------------------------------------------------------- 1 | require 'fluent/plugin/out_statsd' 2 | require 'fluent/test' 3 | require 'statsd-ruby' 4 | 5 | class StatsdOutputTest < Test::Unit::TestCase 6 | def setup 7 | super 8 | Fluent::Test.setup 9 | @now = Time.now 10 | end 11 | 12 | def treedown 13 | end 14 | 15 | CONFIG = %[ 16 | type statsd 17 | ] 18 | 19 | def create_driver(conf = CONFIG) 20 | Fluent::Test::BufferedOutputTestDriver.new(Fluent::StatsdOutput) { 21 | }.configure(conf) 22 | end 23 | 24 | def test_write 25 | d = create_driver 26 | time = Time.at(@now.to_i).utc 27 | d.emit({ :stastd_type => 'timing', :statsd_key => 'test.statsd.t', :statsd_timing => 100 }, time) 28 | d.emit({ :stastd_type => 'guage', :statsd_key => 'test.statsd.g', :statsd_gauge => 102 }, time) 29 | d.emit({ :stastd_type => 'increment', :statsd_key => 'test.statsd.i'}, time) 30 | 31 | d.run 32 | end 33 | end 34 | --------------------------------------------------------------------------------