librato-logreporter 0.1.0
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.
- data/CHANGELOG.md +2 -0
- data/LICENSE +24 -0
- data/README.md +138 -0
- data/Rakefile +25 -0
- data/lib/librato-logreporter.rb +1 -0
- data/lib/librato/logreporter.rb +123 -0
- data/lib/librato/logreporter/configuration.rb +41 -0
- data/lib/librato/logreporter/group.rb +37 -0
- data/lib/librato/logreporter/version.rb +5 -0
- data/test/test_helper.rb +7 -0
- data/test/unit/logreporter/configuration_test.rb +41 -0
- data/test/unit/logreporter/group_test.rb +48 -0
- data/test/unit/logreporter_test.rb +102 -0
- metadata +85 -0
data/CHANGELOG.md
ADDED
data/LICENSE
ADDED
@@ -0,0 +1,24 @@
|
|
1
|
+
Copyright (c) 2011. Librato, Inc.
|
2
|
+
All rights reserved.
|
3
|
+
|
4
|
+
Redistribution and use in source and binary forms, with or without
|
5
|
+
modification, are permitted provided that the following conditions are met:
|
6
|
+
* Redistributions of source code must retain the above copyright
|
7
|
+
notice, this list of conditions and the following disclaimer.
|
8
|
+
* Redistributions in binary form must reproduce the above copyright
|
9
|
+
notice, this list of conditions and the following disclaimer in the
|
10
|
+
documentation and/or other materials provided with the distribution.
|
11
|
+
* Neither the name of Librato, Inc. nor the names of project contributors
|
12
|
+
may be used to endorse or promote products derived from this software
|
13
|
+
without specific prior written permission.
|
14
|
+
|
15
|
+
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
16
|
+
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
17
|
+
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
18
|
+
DISCLAIMED. IN NO EVENT SHALL LIBRATO, INC. BE LIABLE FOR ANY
|
19
|
+
DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
20
|
+
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
21
|
+
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
22
|
+
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
23
|
+
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
24
|
+
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
data/README.md
ADDED
@@ -0,0 +1,138 @@
|
|
1
|
+
librato-logreporter
|
2
|
+
=======
|
3
|
+
|
4
|
+
[](http://travis-ci.org/librato/librato-logreporter) [](https://codeclimate.com/github/librato/librato-logreporter)
|
5
|
+
|
6
|
+
NOTE: This library is in active development and is suggested for early-adopter use only.
|
7
|
+
|
8
|
+
`librato-logreporter` provides an easy interface to write metrics ultimately bound for [Librato Metrics](https://metrics.librato.com/) to your logs or another IO stream. It is fully format-compliant with [l2met](https://github.com/ryandotsmith/l2met). If you are running on Heroku it will allow you to easily insert metrics which can be retrieved via a [log drain](https://devcenter.heroku.com/articles/logging#syslog-drains).
|
9
|
+
|
10
|
+
This library is ideally suited for custom or short-lived processes where the overhead of in-process collection will be costly and external metric collectors are unavailable.
|
11
|
+
|
12
|
+
If you are considering using `librato-logreporter` for a rails or rack-based web app, first explore [librato-rails](https://github.com/librato/librato-rails) and/or [librato-rack](https://github.com/librato/librato-rack). In most cases one of these libraries will be a better solution for your web applications.
|
13
|
+
|
14
|
+
Currently Ruby 1.9.2+ is required.
|
15
|
+
|
16
|
+
## Quick Start
|
17
|
+
|
18
|
+
Install `librato-logreporter` in your application:
|
19
|
+
|
20
|
+
require 'librato/logreporter'
|
21
|
+
|
22
|
+
You can now track custom metrics by adding simple one-liners to your code:
|
23
|
+
|
24
|
+
# keep counts of key events
|
25
|
+
Librato.increment 'jobs.worked'
|
26
|
+
|
27
|
+
# benchmark sections of code to verify performance
|
28
|
+
Librato.timing 'my.complicated.work' do
|
29
|
+
# do work
|
30
|
+
end
|
31
|
+
|
32
|
+
# track averages across processes/jobs/requests
|
33
|
+
Librato.measure 'payload.size', payload.length_in_bytes
|
34
|
+
|
35
|
+
## Installation & Configuration
|
36
|
+
|
37
|
+
Install the gem:
|
38
|
+
|
39
|
+
$ gem install librato-logreporter
|
40
|
+
|
41
|
+
Or add to your Gemfile if using bundler:
|
42
|
+
|
43
|
+
gem "librato-logreporter"
|
44
|
+
|
45
|
+
Then require it:
|
46
|
+
|
47
|
+
require 'librato-reporter'
|
48
|
+
|
49
|
+
If you don't have a [Librato Metrics](https://metrics.librato.com/) account already, [sign up](https://metrics.librato.com/). In order to send measurements to Librato you will need to provide your account credentials to the processor for output from `librato-reporter`.
|
50
|
+
|
51
|
+
##### Environment variables
|
52
|
+
|
53
|
+
There are a few optional environment variables you may find useful:
|
54
|
+
|
55
|
+
* `LIBRATO_SOURCE` - the default source to use for submitted metrics. If not set your metrics will be submitted without a source.
|
56
|
+
* `LIBRATO_PREFIX` - a prefix which will be appended to all metric names
|
57
|
+
|
58
|
+
##### Running on Heroku
|
59
|
+
|
60
|
+
You should specify a custom source for your app to track properly. You can set the source in your environment:
|
61
|
+
|
62
|
+
heroku config:add LIBRATO_SOURCE=myappname
|
63
|
+
|
64
|
+
NOTE: if Heroku idles your process no measurements will be sent until it receives a request and is restarted. If you see intermittent gaps in your measurements during periods of low traffic this is the most likely cause.
|
65
|
+
|
66
|
+
##### Harvesting your metrics from your logs
|
67
|
+
|
68
|
+
There are few options for this which we will document further going forward. For the moment, [come ask us about it](http://chat.librato.com/).
|
69
|
+
|
70
|
+
## Custom Measurements
|
71
|
+
|
72
|
+
Tracking anything that interests you is easy with Librato. There are four primary helpers available:
|
73
|
+
|
74
|
+
#### increment
|
75
|
+
|
76
|
+
Use for tracking a running total of something _across_ jobs or requests, examples:
|
77
|
+
|
78
|
+
# increment the 'jobs.completed' metric by one
|
79
|
+
Librato.increment 'jobs.completed'
|
80
|
+
|
81
|
+
# increment by five
|
82
|
+
Librato.increment 'items.purchased', :by => 5
|
83
|
+
|
84
|
+
# increment with a custom source
|
85
|
+
Librato.increment 'user.purchases', :source => user.id
|
86
|
+
|
87
|
+
Other things you might track this way: user activity, requests of a certain type or to a certain route, total jobs queued or processed, emails sent or received
|
88
|
+
|
89
|
+
#### measure
|
90
|
+
|
91
|
+
Use when you want to track an average value _per_-measurement period. Examples:
|
92
|
+
|
93
|
+
Librato.measure 'payload.size', 212
|
94
|
+
|
95
|
+
# report from a custom source
|
96
|
+
Librato.measure 'jobs.by.user', 3, :source => job.requestor.id
|
97
|
+
|
98
|
+
#### timing
|
99
|
+
|
100
|
+
Like `Librato.measure` this is per-period, but specialized for timing information:
|
101
|
+
|
102
|
+
Librato.timing 'twitter.lookup.time', 21.2
|
103
|
+
|
104
|
+
The block form auto-submits the time it took for its contents to execute as the measurement value:
|
105
|
+
|
106
|
+
Librato.timing 'twitter.lookup.time' do
|
107
|
+
@twitter = Twitter.lookup(user)
|
108
|
+
end
|
109
|
+
|
110
|
+
#### group
|
111
|
+
|
112
|
+
There is also a grouping helper, to make managing nested metrics easier. So this:
|
113
|
+
|
114
|
+
Librato.measure 'memcached.gets', 20
|
115
|
+
Librato.measure 'memcached.sets', 2
|
116
|
+
Librato.measure 'memcached.hits', 18
|
117
|
+
|
118
|
+
Can also be written as:
|
119
|
+
|
120
|
+
Librato.group 'memcached' do |g|
|
121
|
+
g.measure 'gets', 20
|
122
|
+
g.measure 'sets', 2
|
123
|
+
g.measure 'hits', 18
|
124
|
+
end
|
125
|
+
|
126
|
+
Symbols can be used interchangeably with strings for metric names.
|
127
|
+
|
128
|
+
## Contribution
|
129
|
+
|
130
|
+
* Check out the latest master to make sure the feature hasn't been implemented or the bug hasn't been fixed yet.
|
131
|
+
* Check out the issue tracker to make sure someone already hasn't requested it and/or contributed it.
|
132
|
+
* Fork the project and submit a pull request from a feature or bugfix branch.
|
133
|
+
* Please include tests. This is important so we don't break your changes unintentionally in a future version.
|
134
|
+
* Please don't modify the gemspec, Rakefile, version, or changelog. If you do change these files, please isolate a separate commit so we can cherry-pick around it.
|
135
|
+
|
136
|
+
## Copyright
|
137
|
+
|
138
|
+
Copyright (c) 2013 [Librato Inc.](http://librato.com) See LICENSE for details.
|
data/Rakefile
ADDED
@@ -0,0 +1,25 @@
|
|
1
|
+
#!/usr/bin/env rake
|
2
|
+
begin
|
3
|
+
require 'bundler/setup'
|
4
|
+
rescue LoadError
|
5
|
+
puts 'You must `gem install bundler` and `bundle install` to run rake tasks'
|
6
|
+
end
|
7
|
+
|
8
|
+
# console
|
9
|
+
desc "Open an console session preloaded with this library"
|
10
|
+
task :console do
|
11
|
+
sh "pry -r ./lib/librato-logreporter.rb"
|
12
|
+
end
|
13
|
+
|
14
|
+
Bundler::GemHelper.install_tasks
|
15
|
+
|
16
|
+
require 'rake/testtask'
|
17
|
+
|
18
|
+
Rake::TestTask.new(:test) do |t|
|
19
|
+
t.libs << 'lib'
|
20
|
+
t.libs << 'test'
|
21
|
+
t.pattern = 'test/**/*_test.rb'
|
22
|
+
t.verbose = false
|
23
|
+
end
|
24
|
+
|
25
|
+
task :default => :test
|
@@ -0,0 +1 @@
|
|
1
|
+
require 'librato/logreporter'
|
@@ -0,0 +1,123 @@
|
|
1
|
+
require_relative 'logreporter/configuration'
|
2
|
+
require_relative 'logreporter/group'
|
3
|
+
require_relative 'logreporter/version'
|
4
|
+
|
5
|
+
module Librato
|
6
|
+
extend SingleForwardable
|
7
|
+
def_delegators :log_reporter, :increment, :measure, :timing, :group
|
8
|
+
|
9
|
+
def self.log_reporter
|
10
|
+
@log_reporter ||= LogReporter.new
|
11
|
+
end
|
12
|
+
|
13
|
+
# Provides a common interface to reporting metrics with methods
|
14
|
+
# like #increment, #measure, #timing, #group - all written
|
15
|
+
# to your preferred IO stream.
|
16
|
+
#
|
17
|
+
class LogReporter
|
18
|
+
include Configuration
|
19
|
+
|
20
|
+
# Group a set of metrics by common prefix
|
21
|
+
#
|
22
|
+
# @example
|
23
|
+
# # write a 'performance.hits' increment and
|
24
|
+
# # a 'performance.response.time' measure
|
25
|
+
# group(:performance) do |perf|
|
26
|
+
# perf.increment :hits
|
27
|
+
# perf.measure 'response.time', response_time
|
28
|
+
# end
|
29
|
+
#
|
30
|
+
def group(prefix)
|
31
|
+
yield Group.new(collector: self, prefix: prefix)
|
32
|
+
end
|
33
|
+
|
34
|
+
# Increment a given metric
|
35
|
+
#
|
36
|
+
# @example Increment metric 'foo' by 1
|
37
|
+
# increment :foo
|
38
|
+
#
|
39
|
+
# @example Increment metric 'bar' by 2
|
40
|
+
# increment :bar, :by => 2
|
41
|
+
#
|
42
|
+
# @example Increment metric 'foo' by 1 with a custom source
|
43
|
+
# increment :foo, :source => user.id
|
44
|
+
#
|
45
|
+
def increment(counter, options={})
|
46
|
+
by = options[:by] || 1
|
47
|
+
log_write(counter => by, :source => options[:source])
|
48
|
+
end
|
49
|
+
|
50
|
+
# @example Simple measurement
|
51
|
+
# measure 'sources_returned', sources.length
|
52
|
+
#
|
53
|
+
# @example Simple timing in milliseconds
|
54
|
+
# timing 'myservice.lookup', 2.31
|
55
|
+
#
|
56
|
+
# @example Block-based timing
|
57
|
+
# timing 'db.query' do
|
58
|
+
# do_my_query
|
59
|
+
# end
|
60
|
+
#
|
61
|
+
# @example Custom source
|
62
|
+
# measure 'user.all_orders', user.order_count, :source => user.id
|
63
|
+
#
|
64
|
+
def measure(*args, &block)
|
65
|
+
options = {}
|
66
|
+
event = args[0].to_s
|
67
|
+
returned = nil
|
68
|
+
|
69
|
+
# handle block or specified argument
|
70
|
+
if block_given?
|
71
|
+
start = Time.now
|
72
|
+
returned = yield
|
73
|
+
value = ((Time.now - start) * 1000.0).to_i
|
74
|
+
elsif args[1]
|
75
|
+
value = args[1]
|
76
|
+
else
|
77
|
+
raise "no value provided"
|
78
|
+
end
|
79
|
+
|
80
|
+
# detect options hash if present
|
81
|
+
if args.length > 1 and args[-1].respond_to?(:each)
|
82
|
+
options = args[-1]
|
83
|
+
end
|
84
|
+
|
85
|
+
log_write(event => value, :source => options[:source])
|
86
|
+
returned
|
87
|
+
end
|
88
|
+
alias :timing :measure
|
89
|
+
|
90
|
+
private
|
91
|
+
|
92
|
+
# take key/value pairs and return an array of measure strings
|
93
|
+
def add_prefixes(measures)
|
94
|
+
measure_prefix = 'measure.'
|
95
|
+
measure_prefix << "#{prefix}." if prefix
|
96
|
+
measures.map { |keyval|
|
97
|
+
joined = keyval.join('=')
|
98
|
+
if keyval[0].to_sym == :source
|
99
|
+
joined
|
100
|
+
else
|
101
|
+
measure_prefix + joined
|
102
|
+
end
|
103
|
+
}
|
104
|
+
end
|
105
|
+
|
106
|
+
# add default source as appropriate
|
107
|
+
def manage_source(measures)
|
108
|
+
if source && !measures[:source]
|
109
|
+
measures[:source] = source # set default source
|
110
|
+
end
|
111
|
+
if !source && measures.has_key?(:source) && !measures[:source]
|
112
|
+
measures.delete(:source) # remove empty source
|
113
|
+
end
|
114
|
+
measures
|
115
|
+
end
|
116
|
+
|
117
|
+
def log_write(measures)
|
118
|
+
measure_chunks = add_prefixes(manage_source(measures))
|
119
|
+
log.puts measure_chunks.join(' ')
|
120
|
+
end
|
121
|
+
|
122
|
+
end
|
123
|
+
end
|
@@ -0,0 +1,41 @@
|
|
1
|
+
module Librato
|
2
|
+
class LogReporter
|
3
|
+
|
4
|
+
# Handles configuration options and intelligent defaults
|
5
|
+
# for the LogReporter class.
|
6
|
+
#
|
7
|
+
module Configuration
|
8
|
+
|
9
|
+
# current IO to log to
|
10
|
+
def log
|
11
|
+
@log ||= $stdout
|
12
|
+
end
|
13
|
+
|
14
|
+
# set IO to log to
|
15
|
+
def log=(io)
|
16
|
+
@log = io
|
17
|
+
end
|
18
|
+
|
19
|
+
# current prefix
|
20
|
+
def prefix
|
21
|
+
@prefix ||= ENV['LIBRATO_PREFIX']
|
22
|
+
end
|
23
|
+
|
24
|
+
# set prefix
|
25
|
+
def prefix=(prefix)
|
26
|
+
@prefix = prefix
|
27
|
+
end
|
28
|
+
|
29
|
+
# current default source
|
30
|
+
def source
|
31
|
+
@source ||= ENV['LIBRATO_SOURCE']
|
32
|
+
end
|
33
|
+
|
34
|
+
# set default source
|
35
|
+
def source=(source)
|
36
|
+
@source = source
|
37
|
+
end
|
38
|
+
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|
@@ -0,0 +1,37 @@
|
|
1
|
+
module Librato
|
2
|
+
class LogReporter
|
3
|
+
|
4
|
+
# Encapsulates state for grouping operations
|
5
|
+
#
|
6
|
+
class Group
|
7
|
+
|
8
|
+
def initialize(options={})
|
9
|
+
@collector = options[:collector]
|
10
|
+
@prefix = "#{options[:prefix]}."
|
11
|
+
end
|
12
|
+
|
13
|
+
def group(prefix)
|
14
|
+
prefix = apply_prefix(prefix)
|
15
|
+
yield self.class.new(collector: @collector, prefix: prefix)
|
16
|
+
end
|
17
|
+
|
18
|
+
def increment(counter, options={})
|
19
|
+
counter = apply_prefix(counter)
|
20
|
+
@collector.increment counter, options
|
21
|
+
end
|
22
|
+
|
23
|
+
def measure(*args, &block)
|
24
|
+
args[0] = apply_prefix(args[0])
|
25
|
+
@collector.measure(*args, &block)
|
26
|
+
end
|
27
|
+
alias :timing :measure
|
28
|
+
|
29
|
+
private
|
30
|
+
|
31
|
+
def apply_prefix(str)
|
32
|
+
"#{@prefix}#{str}"
|
33
|
+
end
|
34
|
+
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
data/test/test_helper.rb
ADDED
@@ -0,0 +1,41 @@
|
|
1
|
+
require 'test_helper'
|
2
|
+
require 'stringio'
|
3
|
+
|
4
|
+
module Librato
|
5
|
+
class LogReporter
|
6
|
+
class ConfigurationTest < MiniTest::Test
|
7
|
+
|
8
|
+
def setup
|
9
|
+
@reporter = LogReporter.new
|
10
|
+
end
|
11
|
+
|
12
|
+
def test_default_log
|
13
|
+
assert_equal $stdout, @reporter.log
|
14
|
+
end
|
15
|
+
|
16
|
+
def test_setting_log
|
17
|
+
@reporter.log = $stderr
|
18
|
+
assert_equal $stderr, @reporter.log
|
19
|
+
end
|
20
|
+
|
21
|
+
def test_default_prefix
|
22
|
+
assert_equal nil, @reporter.prefix
|
23
|
+
end
|
24
|
+
|
25
|
+
def test_setting_prefix
|
26
|
+
@reporter.prefix = 'mypref'
|
27
|
+
assert_equal 'mypref', @reporter.prefix
|
28
|
+
end
|
29
|
+
|
30
|
+
def test_default_source
|
31
|
+
assert_equal nil, @reporter.source
|
32
|
+
end
|
33
|
+
|
34
|
+
def test_setting_source
|
35
|
+
@reporter.source = 'librato'
|
36
|
+
assert_equal 'librato', @reporter.source
|
37
|
+
end
|
38
|
+
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|
@@ -0,0 +1,48 @@
|
|
1
|
+
require 'test_helper'
|
2
|
+
|
3
|
+
module Librato
|
4
|
+
class LogReporter
|
5
|
+
class GroupTest < MiniTest::Test
|
6
|
+
|
7
|
+
def setup
|
8
|
+
@reporter = MiniTest::Mock.new
|
9
|
+
@group = Group.new(collector: @reporter, prefix: 'mypref')
|
10
|
+
end
|
11
|
+
|
12
|
+
def test_increment
|
13
|
+
@reporter.expect :increment, true, ['mypref.foo', {}]
|
14
|
+
@group.increment 'foo'
|
15
|
+
@reporter.verify
|
16
|
+
|
17
|
+
@reporter.expect :increment, true, ['mypref.bar', {:source => 'baz'}]
|
18
|
+
@group.increment 'bar', :source => 'baz'
|
19
|
+
@reporter.verify
|
20
|
+
end
|
21
|
+
|
22
|
+
def test_measure
|
23
|
+
@reporter.expect :measure, true, ['mypref.mpg', 52]
|
24
|
+
@group.measure 'mpg', 52
|
25
|
+
@reporter.verify
|
26
|
+
|
27
|
+
@reporter.expect :measure, true, ['mypref.mpg', 8, {:source => 'vette'}]
|
28
|
+
@group.measure 'mpg', 8, :source => 'vette'
|
29
|
+
@reporter.verify
|
30
|
+
end
|
31
|
+
|
32
|
+
def test_timing
|
33
|
+
@reporter.expect :measure, true, ['mypref.completion']
|
34
|
+
@group.timing('completion') { sleep 0.01 }
|
35
|
+
@reporter.verify
|
36
|
+
end
|
37
|
+
|
38
|
+
def test_nesting_group
|
39
|
+
@reporter.expect :increment, true, ['mypref.more.foo', {}]
|
40
|
+
@group.group :more do |m|
|
41
|
+
m.increment :foo
|
42
|
+
end
|
43
|
+
@reporter.verify
|
44
|
+
end
|
45
|
+
|
46
|
+
end
|
47
|
+
end
|
48
|
+
end
|
@@ -0,0 +1,102 @@
|
|
1
|
+
require 'test_helper'
|
2
|
+
require 'stringio'
|
3
|
+
|
4
|
+
module Librato
|
5
|
+
class LogReporterTest < MiniTest::Test
|
6
|
+
|
7
|
+
def setup
|
8
|
+
@buffer = StringIO.new
|
9
|
+
@reporter = LogReporter.new
|
10
|
+
@reporter.log = @buffer
|
11
|
+
end
|
12
|
+
|
13
|
+
def test_increment
|
14
|
+
@reporter.increment :foo
|
15
|
+
assert_last_logged 'measure.foo=1'
|
16
|
+
|
17
|
+
@reporter.increment 'foo.bar', :by => 2
|
18
|
+
assert_last_logged 'measure.foo.bar=2'
|
19
|
+
end
|
20
|
+
|
21
|
+
def test_increment_supports_source
|
22
|
+
@reporter.source = 'sf'
|
23
|
+
|
24
|
+
# default source
|
25
|
+
@reporter.increment 'days.foggy'
|
26
|
+
assert_last_logged 'measure.days.foggy=1 source=sf'
|
27
|
+
|
28
|
+
# custom source
|
29
|
+
@reporter.increment 'days.foggy', :source => 'seattle'
|
30
|
+
assert_last_logged 'measure.days.foggy=1 source=seattle'
|
31
|
+
end
|
32
|
+
|
33
|
+
def test_measure
|
34
|
+
@reporter.measure 'documents.rendered', 12
|
35
|
+
assert_last_logged 'measure.documents.rendered=12'
|
36
|
+
|
37
|
+
# custom source
|
38
|
+
@reporter.measure 'cycles.wasted', 23, :source => 'cpu_1'
|
39
|
+
assert_last_logged 'measure.cycles.wasted=23 source=cpu_1'
|
40
|
+
end
|
41
|
+
|
42
|
+
def test_timing
|
43
|
+
@reporter.timing('do.stuff') { sleep 0.1 }
|
44
|
+
last = last_logged
|
45
|
+
assert last =~ /\=/, 'should have a measure pair'
|
46
|
+
key, value = last.split('=')
|
47
|
+
assert_equal 'measure.do.stuff', key, 'should have timing key'
|
48
|
+
assert_in_delta 100, value.to_i, 10
|
49
|
+
|
50
|
+
# custom source
|
51
|
+
@reporter.timing('do.more', :source => 'worker') do
|
52
|
+
sleep 0.05
|
53
|
+
end
|
54
|
+
assert last_logged.index('source=worker'), 'should use custom source'
|
55
|
+
end
|
56
|
+
|
57
|
+
def test_basic_grouping
|
58
|
+
@reporter.group :pages do |p|
|
59
|
+
p.increment :total
|
60
|
+
p.timing :render_time, 63
|
61
|
+
# nested
|
62
|
+
p.group('public') { |pub| pub.increment 'views', :by => 2 }
|
63
|
+
end
|
64
|
+
|
65
|
+
@buffer.rewind
|
66
|
+
lines = @buffer.readlines
|
67
|
+
assert_equal 'measure.pages.total=1', lines[0].chomp
|
68
|
+
assert_equal 'measure.pages.render_time=63', lines[1].chomp
|
69
|
+
assert_equal 'measure.pages.public.views=2', lines[2].chomp
|
70
|
+
end
|
71
|
+
|
72
|
+
def test_custom_prefix
|
73
|
+
@reporter.prefix = 'librato'
|
74
|
+
|
75
|
+
# increment
|
76
|
+
@reporter.increment 'views'
|
77
|
+
assert_last_logged 'measure.librato.views=1'
|
78
|
+
|
79
|
+
# measure/timing
|
80
|
+
@reporter.measure 'sql.queries', 6
|
81
|
+
assert_last_logged 'measure.librato.sql.queries=6'
|
82
|
+
|
83
|
+
# group
|
84
|
+
@reporter.group :private do |priv|
|
85
|
+
priv.increment 'secret'
|
86
|
+
end
|
87
|
+
assert_last_logged 'measure.librato.private.secret=1'
|
88
|
+
end
|
89
|
+
|
90
|
+
private
|
91
|
+
|
92
|
+
def assert_last_logged(string)
|
93
|
+
assert_equal string, last_logged, "Last logged should be '#{string}'."
|
94
|
+
end
|
95
|
+
|
96
|
+
def last_logged
|
97
|
+
@buffer.rewind
|
98
|
+
@buffer.readlines[-1].to_s.chomp
|
99
|
+
end
|
100
|
+
|
101
|
+
end
|
102
|
+
end
|
metadata
ADDED
@@ -0,0 +1,85 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: librato-logreporter
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.1.0
|
5
|
+
prerelease:
|
6
|
+
platform: ruby
|
7
|
+
authors:
|
8
|
+
- Matt Sanders
|
9
|
+
autorequire:
|
10
|
+
bindir: bin
|
11
|
+
cert_chain: []
|
12
|
+
date: 2013-06-21 00:00:00.000000000 Z
|
13
|
+
dependencies:
|
14
|
+
- !ruby/object:Gem::Dependency
|
15
|
+
name: minitest
|
16
|
+
requirement: !ruby/object:Gem::Requirement
|
17
|
+
none: false
|
18
|
+
requirements:
|
19
|
+
- - ! '>='
|
20
|
+
- !ruby/object:Gem::Version
|
21
|
+
version: '0'
|
22
|
+
type: :development
|
23
|
+
prerelease: false
|
24
|
+
version_requirements: !ruby/object:Gem::Requirement
|
25
|
+
none: false
|
26
|
+
requirements:
|
27
|
+
- - ! '>='
|
28
|
+
- !ruby/object:Gem::Version
|
29
|
+
version: '0'
|
30
|
+
description: Provides a simple interface to log Librato metrics to your log files
|
31
|
+
in l2met format.
|
32
|
+
email:
|
33
|
+
- matt@librato.com
|
34
|
+
executables: []
|
35
|
+
extensions: []
|
36
|
+
extra_rdoc_files: []
|
37
|
+
files:
|
38
|
+
- lib/librato/logreporter/configuration.rb
|
39
|
+
- lib/librato/logreporter/group.rb
|
40
|
+
- lib/librato/logreporter/version.rb
|
41
|
+
- lib/librato/logreporter.rb
|
42
|
+
- lib/librato-logreporter.rb
|
43
|
+
- LICENSE
|
44
|
+
- Rakefile
|
45
|
+
- README.md
|
46
|
+
- CHANGELOG.md
|
47
|
+
- test/test_helper.rb
|
48
|
+
- test/unit/logreporter/configuration_test.rb
|
49
|
+
- test/unit/logreporter/group_test.rb
|
50
|
+
- test/unit/logreporter_test.rb
|
51
|
+
homepage: https://github.com/librato/librato-logreporter
|
52
|
+
licenses: []
|
53
|
+
post_install_message:
|
54
|
+
rdoc_options: []
|
55
|
+
require_paths:
|
56
|
+
- lib
|
57
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
58
|
+
none: false
|
59
|
+
requirements:
|
60
|
+
- - ! '>='
|
61
|
+
- !ruby/object:Gem::Version
|
62
|
+
version: '0'
|
63
|
+
segments:
|
64
|
+
- 0
|
65
|
+
hash: -2188963699629568403
|
66
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
67
|
+
none: false
|
68
|
+
requirements:
|
69
|
+
- - ! '>='
|
70
|
+
- !ruby/object:Gem::Version
|
71
|
+
version: '0'
|
72
|
+
segments:
|
73
|
+
- 0
|
74
|
+
hash: -2188963699629568403
|
75
|
+
requirements: []
|
76
|
+
rubyforge_project:
|
77
|
+
rubygems_version: 1.8.25
|
78
|
+
signing_key:
|
79
|
+
specification_version: 3
|
80
|
+
summary: Write Librato metrics to your logs with a convenient interface
|
81
|
+
test_files:
|
82
|
+
- test/test_helper.rb
|
83
|
+
- test/unit/logreporter/configuration_test.rb
|
84
|
+
- test/unit/logreporter/group_test.rb
|
85
|
+
- test/unit/logreporter_test.rb
|