librato-logreporter 0.1.0
Sign up to get free protection for your applications and to get access to all the features.
- 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
|
+
[![Build Status](https://secure.travis-ci.org/librato/librato-logreporter.png?branch=master)](http://travis-ci.org/librato/librato-logreporter) [![Code Climate](https://codeclimate.com/github/librato/librato-logreporter.png)](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
|