statsd-metrics 0.0.1

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.
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 9bfc3544d39cfdd911ded83379e372a0d855aebd
4
+ data.tar.gz: ff6354c12b1873bdbe16a79d4e76aa43ea8f2e75
5
+ SHA512:
6
+ metadata.gz: 8ec2b4ca1fe254bc20fc34d48fcfa5fe10cace43d617f50520539c8a3ca49157af5294597b48ff7fc8c41281516c509f0f6fd926c631289a9a5c55def002fff8
7
+ data.tar.gz: 78c90ad5cf52879a33c45d56b59aeea810fee97288d8c67bf953a303c189f3be55617802ab0a1e0f63341985d595015329a389c2e9207b74baa143cc567b9ae9
data/.document ADDED
@@ -0,0 +1,5 @@
1
+ lib/**/*.rb
2
+ bin/*
3
+ -
4
+ features/**/*.feature
5
+ LICENSE.txt
data/.gitignore ADDED
@@ -0,0 +1,14 @@
1
+ /.bundle/
2
+ /.yardoc
3
+ /Gemfile.lock
4
+ /_yardoc/
5
+ /coverage/
6
+ /doc/
7
+ /pkg/
8
+ /spec/reports/
9
+ /tmp/
10
+ *.bundle
11
+ *.so
12
+ *.o
13
+ *.a
14
+ mkmf.log
data/.travis.yml ADDED
@@ -0,0 +1,6 @@
1
+ ---
2
+ language: ruby
3
+ rvm:
4
+ - 1.8.7
5
+ - 1.9.3
6
+ - jruby-19mode
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source 'https://rubygems.org'
2
+
3
+ # Specify your gem's dependencies in statsd_metrics.gemspec
4
+ gemspec
data/LICENSE.txt ADDED
@@ -0,0 +1,22 @@
1
+ Copyright (c) 2014 hindenbug
2
+
3
+ MIT License
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining
6
+ a copy of this software and associated documentation files (the
7
+ "Software"), to deal in the Software without restriction, including
8
+ without limitation the rights to use, copy, modify, merge, publish,
9
+ distribute, sublicense, and/or sell copies of the Software, and to
10
+ permit persons to whom the Software is furnished to do so, subject to
11
+ the following conditions:
12
+
13
+ The above copyright notice and this permission notice shall be
14
+ included in all copies or substantial portions of the Software.
15
+
16
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
20
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
21
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
22
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,43 @@
1
+ # StatsdMetrics
2
+
3
+ TODO: Write a gem description
4
+
5
+ ## Installation
6
+
7
+ Add this line to your application's Gemfile:
8
+
9
+ ```ruby
10
+ gem 'statsd-metrics'
11
+ ```
12
+
13
+ And then execute:
14
+
15
+ $ bundle
16
+
17
+ Or install it yourself as:
18
+
19
+ $ gem install statsd-metrics
20
+
21
+ ## Usage
22
+
23
+ ```ruby
24
+ #default host="127.0.0.1" and port=8125
25
+ $statsd = Statsd::Base.new
26
+ $statsd.increment("somestats")
27
+
28
+ # using batching with queues
29
+ # takes 2 params; A statsd instance and batch_size (defaults to 100)
30
+ $batchd = Statsd::Batch.new($statsd, 100)
31
+
32
+ #Makes use of ruby Queues internally
33
+ $batchd.increment("somestats")
34
+ ```
35
+
36
+
37
+ ## Contributing
38
+
39
+ 1. Fork it ( https://github.com/[my-github-username]/statsd-metrics/fork )
40
+ 2. Create your feature branch (`git checkout -b my-new-feature`)
41
+ 3. Commit your changes (`git commit -am 'Add some feature'`)
42
+ 4. Push to the branch (`git push origin my-new-feature`)
43
+ 5. Create a new Pull Request
data/Rakefile ADDED
@@ -0,0 +1 @@
1
+ require "bundler/gem_tasks"
data/lib/statsd.rb ADDED
@@ -0,0 +1,142 @@
1
+ require "statsd/version"
2
+ require "statsd/reporter"
3
+ require "socket"
4
+ require "logger"
5
+
6
+ module Statsd
7
+
8
+ class Base
9
+
10
+ attr_accessor :namespace, :counter
11
+
12
+ # StatsD host. Defaults to 127.0.0.1.
13
+ attr_accessor :host
14
+
15
+ # StatsD port. Defaults to 8125.
16
+ attr_accessor :port
17
+
18
+ class << self
19
+ # Set to a standard logger instance to enable debug logging.
20
+ attr_accessor :logger
21
+ end
22
+
23
+ def initialize(host='127.0.0.1', port=8125)
24
+ @socket = UDPSocket.new
25
+ @host = host
26
+ @port = port
27
+ @counter = 1
28
+ end
29
+
30
+ def increment(stat, sample_rate=1)
31
+ count stat, 1, sample_rate
32
+ end
33
+
34
+ def decrement(stat, sample_rate=1)
35
+ count stat, -1, sample_rate
36
+ end
37
+
38
+ def count(stat, count, sample_rate=1)
39
+ send_stat(stat, count, :c, sample_rate)
40
+ end
41
+
42
+ # Sends an arbitary gauge value for the given stat to the statsd server.
43
+ #
44
+ # This is useful for recording things like available disk space,
45
+ # memory usage, and the like, which have different semantics than
46
+ # counters.
47
+ #
48
+ # @param [String] stat stat name.
49
+ # @param [Numeric] gauge value.
50
+ # @param [Numeric] sample_rate sample rate, 1 for always
51
+ # @example Report the current user count:
52
+ # $statsd.gauge('user.count', User.count)
53
+ def gauge(stat, value, sample_rate=1)
54
+ send_stat(stat, value, :g, sample_rate)
55
+ end
56
+
57
+ # Sends a timing (in ms) for the given stat to the statsd server. The
58
+ # sample_rate determines what percentage of the time this report is sent. The
59
+ # statsd server then uses the sample_rate to correctly track the average
60
+ # timing for the stat.
61
+ #
62
+ # @param [String] stat stat name
63
+ # @param [Integer] ms timing in milliseconds
64
+ # @param [Numeric] sample_rate sample rate, 1 for always
65
+ def timing(stat, ms, sample_rate=1)
66
+ send_stat(stat, ms, :ms, sample_rate)
67
+ end
68
+
69
+ # Reports execution time of the provided block using {#timing}.
70
+ #
71
+ # @param [String] stat stat name
72
+ # @param [Numeric] sample_rate sample rate, 1 for always
73
+ # @yield The operation to be timed
74
+ # @see #timing
75
+ # @example Report the time (in ms) taken to activate an account
76
+ # $statsd.time('account.activate') { @account.activate! }
77
+ def time(stat, sample_rate=1)
78
+ start = Time.now
79
+ result = yield
80
+ timing(stat, ((Time.now - start) * 1000).round, sample_rate)
81
+ result
82
+ end
83
+
84
+ def send_to_socket(message)
85
+ self.class.logger.debug { "Statsd: #{message}" } if self.class.logger
86
+ @socket.send(message, 0, @host, @port)
87
+ rescue => boom
88
+ self.class.logger.error { "Statsd: #{boom.class} #{boom}" } if self.class.logger
89
+ nil
90
+ end
91
+
92
+ protected
93
+
94
+ def send_stat(stat, delta, type, sample_rate=1)
95
+ if sample_rate == 1 or rand < sample_rate
96
+ stat = stat.to_s.gsub('::', '.').tr(':|@', '_')
97
+ prefix = "#{@namespace}." unless @namespace.nil?
98
+ rate = "|@#{sample_rate}" unless sample_rate == 1
99
+ send_to_socket("#{prefix}#{stat}:#{delta}|#{type}#{rate}")
100
+ end
101
+ end
102
+ end
103
+
104
+ class Batch < Base
105
+
106
+ attr_accessor :batch_size, :wait_time
107
+
108
+ def initialize(statsd, batch_size)
109
+ @statsd = statsd
110
+ @batch_size = batch_size
111
+ @counter = statsd.counter
112
+ @namespace = statsd.namespace
113
+ @reporter = Statsd::Reporter.new(@statsd, batch_size)
114
+ end
115
+
116
+ protected
117
+
118
+ def send_stat(stat, delta, type, sample_rate=1)
119
+ if sample_rate == 1 or rand < sample_rate
120
+ stat = stat.to_s.gsub('::', '.').tr(':|@', '_')
121
+ prefix = "#{@namespace}." unless @namespace.nil?
122
+ rate = "|@#{sample_rate}" unless sample_rate == 1
123
+ msg = "#{prefix}#{stat}:#{delta}|#{type}#{rate}"
124
+ check_and_enqueue(msg)
125
+ end
126
+ end
127
+
128
+ def check_and_enqueue(msg)
129
+ if @reporter.queue.size == @reporter.batch_size
130
+ logger = Logger.new('queue.log')
131
+ logger.warn "Queue at Max Capacity !"
132
+ #@wait_time = @counter * @counter
133
+ #@counter += 1
134
+ else
135
+ @reporter.enqueue(msg)
136
+ #@counter = 1
137
+ end
138
+ end
139
+
140
+ end
141
+
142
+ end
@@ -0,0 +1,49 @@
1
+ require "thread"
2
+
3
+ module Statsd
4
+ class Reporter
5
+
6
+ attr_accessor :queue, :workers, :running, :messages
7
+ attr_reader :statsd_host, :batch_size
8
+
9
+ def initialize(host, batch_size)
10
+ @queue = Queue.new
11
+ @workers = []
12
+ @messages = []
13
+ @statsd_host = host
14
+ @batch_size = batch_size
15
+ end
16
+
17
+ def enqueue(metric)
18
+ workers << Thread.new do
19
+ queue << metric
20
+ flush if queue.size >= batch_size
21
+ end
22
+ finish
23
+ end
24
+
25
+ private
26
+
27
+ def flush
28
+ begin
29
+ while messages << queue.pop(true)
30
+ unless messages.empty?
31
+ statsd_host.send_to_socket messages.join("\n")
32
+ messages.clear
33
+ end
34
+ end
35
+ rescue ThreadError
36
+ end
37
+ end
38
+
39
+ def finish
40
+ workers.each(&:join)
41
+ end
42
+
43
+ def kill
44
+ workers.each(&:kill)
45
+ puts "========> Killed!"
46
+ end
47
+
48
+ end
49
+ end
@@ -0,0 +1,3 @@
1
+ module Statsd
2
+ VERSION = "0.0.1"
3
+ end
data/sample.rb ADDED
@@ -0,0 +1,15 @@
1
+ #require "statsd-ruby"
2
+ require "statsd"
3
+ require "pry"
4
+ require "benchmark"
5
+
6
+
7
+ $statsd = Statsd::Base.new("127.0.0.1", 8125)
8
+ $batch = Statsd::Batch.new($statsd, 10)
9
+ #$statsd = Statsd.new("127.0.0.1", 8125)
10
+
11
+ Benchmark.bm do |bm|
12
+ bm.report do
13
+ 1000000.times { $statsd.increment("qwewqeq.count") }
14
+ end
15
+ end
@@ -0,0 +1,24 @@
1
+ # -*- encoding: utf-8 -*-
2
+ $:.push File.expand_path("../lib", __FILE__)
3
+ require 'statsd/version'
4
+
5
+ Gem::Specification.new do |spec|
6
+ spec.name = "statsd-metrics"
7
+ spec.version = Statsd::VERSION
8
+ spec.authors = ["hindenbug"]
9
+ spec.email = ["manoj.mk27@gmail.com"]
10
+ spec.summary = "A small gem to enqueue statsd metrics and send them to the statsd/grpahite server over UDP"
11
+ spec.description = ""
12
+ spec.homepage = ""
13
+ spec.license = "MIT"
14
+
15
+ spec.files = `git ls-files -z`.split("\x0")
16
+ spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
17
+ spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
18
+ spec.require_paths = ["lib"]
19
+
20
+ spec.add_development_dependency "bundler", "~> 1.7"
21
+ spec.add_development_dependency "rake", "~> 10.0"
22
+ spec.add_development_dependency "rspec", "~> 3.1"
23
+ spec.add_development_dependency 'pry', '~> 0.10.1'
24
+ end
metadata ADDED
@@ -0,0 +1,113 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: statsd-metrics
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.1
5
+ platform: ruby
6
+ authors:
7
+ - hindenbug
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2014-12-26 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: bundler
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - "~>"
18
+ - !ruby/object:Gem::Version
19
+ version: '1.7'
20
+ type: :development
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - "~>"
25
+ - !ruby/object:Gem::Version
26
+ version: '1.7'
27
+ - !ruby/object:Gem::Dependency
28
+ name: rake
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - "~>"
32
+ - !ruby/object:Gem::Version
33
+ version: '10.0'
34
+ type: :development
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - "~>"
39
+ - !ruby/object:Gem::Version
40
+ version: '10.0'
41
+ - !ruby/object:Gem::Dependency
42
+ name: rspec
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - "~>"
46
+ - !ruby/object:Gem::Version
47
+ version: '3.1'
48
+ type: :development
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - "~>"
53
+ - !ruby/object:Gem::Version
54
+ version: '3.1'
55
+ - !ruby/object:Gem::Dependency
56
+ name: pry
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - "~>"
60
+ - !ruby/object:Gem::Version
61
+ version: 0.10.1
62
+ type: :development
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - "~>"
67
+ - !ruby/object:Gem::Version
68
+ version: 0.10.1
69
+ description: ''
70
+ email:
71
+ - manoj.mk27@gmail.com
72
+ executables: []
73
+ extensions: []
74
+ extra_rdoc_files: []
75
+ files:
76
+ - ".document"
77
+ - ".gitignore"
78
+ - ".travis.yml"
79
+ - Gemfile
80
+ - LICENSE.txt
81
+ - README.md
82
+ - Rakefile
83
+ - lib/statsd.rb
84
+ - lib/statsd/reporter.rb
85
+ - lib/statsd/version.rb
86
+ - sample.rb
87
+ - statsd-metrics.gemspec
88
+ homepage: ''
89
+ licenses:
90
+ - MIT
91
+ metadata: {}
92
+ post_install_message:
93
+ rdoc_options: []
94
+ require_paths:
95
+ - lib
96
+ required_ruby_version: !ruby/object:Gem::Requirement
97
+ requirements:
98
+ - - ">="
99
+ - !ruby/object:Gem::Version
100
+ version: '0'
101
+ required_rubygems_version: !ruby/object:Gem::Requirement
102
+ requirements:
103
+ - - ">="
104
+ - !ruby/object:Gem::Version
105
+ version: '0'
106
+ requirements: []
107
+ rubyforge_project:
108
+ rubygems_version: 2.4.5
109
+ signing_key:
110
+ specification_version: 4
111
+ summary: A small gem to enqueue statsd metrics and send them to the statsd/grpahite
112
+ server over UDP
113
+ test_files: []