cabin 0.3.8 → 0.4.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.
- data/examples/metrics.rb +41 -0
- data/lib/cabin/channel.rb +3 -0
- data/lib/cabin/inspectable.rb +1 -1
- data/lib/cabin/metric.rb +22 -0
- data/lib/cabin/metrics.rb +18 -4
- data/lib/cabin/metrics/counter.rb +4 -2
- data/lib/cabin/metrics/gauge.rb +2 -2
- data/lib/cabin/metrics/histogram.rb +11 -6
- data/lib/cabin/metrics/meter.rb +3 -2
- data/lib/cabin/metrics/timer.rb +0 -2
- data/lib/cabin/namespace.rb +1 -0
- data/lib/cabin/publisher.rb +20 -0
- data/test/test_metrics.rb +7 -0
- metadata +7 -4
data/examples/metrics.rb
ADDED
@@ -0,0 +1,41 @@
|
|
1
|
+
require "rubygems"
|
2
|
+
require "cabin"
|
3
|
+
require "logger"
|
4
|
+
|
5
|
+
# Logging::... is something I'm implemented and experimenting with.
|
6
|
+
@logger = Cabin::Channel.new
|
7
|
+
|
8
|
+
# Metrics can be subscribed-to as well.
|
9
|
+
@logger.subscribe(Logger.new(STDOUT))
|
10
|
+
|
11
|
+
counter = @logger.metrics.counter("mycounter")
|
12
|
+
counter.incr
|
13
|
+
counter.incr
|
14
|
+
counter.incr
|
15
|
+
counter.decr
|
16
|
+
|
17
|
+
meter = @logger.metrics.meter("something", "hello-world")
|
18
|
+
meter.mark
|
19
|
+
meter.mark
|
20
|
+
meter.mark
|
21
|
+
|
22
|
+
# If nil is passed as the 'instance' then the metric class name will be
|
23
|
+
# used instead.
|
24
|
+
timer = @logger.metrics.timer("ticktock")
|
25
|
+
5.times do
|
26
|
+
timer.time do
|
27
|
+
sleep rand * 2
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
3.times do
|
32
|
+
# Another way to do timing.
|
33
|
+
clock = timer.time
|
34
|
+
sleep rand * 2
|
35
|
+
clock.stop
|
36
|
+
end
|
37
|
+
|
38
|
+
# Loop through all metrics:
|
39
|
+
@logger.metrics.each do |metric|
|
40
|
+
@logger.info(metric.inspect)
|
41
|
+
end
|
data/lib/cabin/channel.rb
CHANGED
@@ -45,6 +45,8 @@ require "logger"
|
|
45
45
|
#
|
46
46
|
class Cabin::Channel
|
47
47
|
include Cabin::Mixins::Logger
|
48
|
+
|
49
|
+
# All channels come with a metrics provider.
|
48
50
|
attr_accessor :metrics
|
49
51
|
|
50
52
|
# Get a channel for a given identifier. If this identifier has never been
|
@@ -67,6 +69,7 @@ class Cabin::Channel
|
|
67
69
|
@data = {}
|
68
70
|
@level = :info
|
69
71
|
@metrics = Cabin::Metrics.new
|
72
|
+
@metrics.channel = self
|
70
73
|
end # def initialize
|
71
74
|
|
72
75
|
# Subscribe a new input
|
data/lib/cabin/inspectable.rb
CHANGED
@@ -22,7 +22,7 @@ module Cabin
|
|
22
22
|
# foo = Foo.new
|
23
23
|
# foo.inspect == '<Foo(1) @foo=123 @bar="hello" >'
|
24
24
|
def inspect
|
25
|
-
if instance_variable_defined?(
|
25
|
+
if instance_variable_defined?(:@inspectables)
|
26
26
|
ivars = @inspectables
|
27
27
|
else
|
28
28
|
ivars = instance_variables
|
data/lib/cabin/metric.rb
ADDED
@@ -0,0 +1,22 @@
|
|
1
|
+
require "cabin/namespace"
|
2
|
+
require "cabin/publisher"
|
3
|
+
require "cabin/inspectable"
|
4
|
+
|
5
|
+
module Cabin::Metric
|
6
|
+
include Cabin::Inspectable
|
7
|
+
include Cabin::Publisher
|
8
|
+
|
9
|
+
def instance=(instance)
|
10
|
+
@instance = instance
|
11
|
+
end # def instance=
|
12
|
+
|
13
|
+
def instance
|
14
|
+
return @instance
|
15
|
+
end # def instance
|
16
|
+
|
17
|
+
def emit
|
18
|
+
if !@channel.nil?
|
19
|
+
@channel.publish({ :metric => instance }.merge(to_hash))
|
20
|
+
end
|
21
|
+
end # def emit
|
22
|
+
end # module Cabin::Metric
|
data/lib/cabin/metrics.rb
CHANGED
@@ -4,6 +4,8 @@ require "cabin/metrics/meter"
|
|
4
4
|
require "cabin/metrics/counter"
|
5
5
|
require "cabin/metrics/timer"
|
6
6
|
require "cabin/metrics/histogram"
|
7
|
+
require "cabin/publisher"
|
8
|
+
require "cabin/channel"
|
7
9
|
|
8
10
|
# What type of metrics do we want?
|
9
11
|
#
|
@@ -44,13 +46,14 @@ require "cabin/metrics/histogram"
|
|
44
46
|
# and management tools.
|
45
47
|
class Cabin::Metrics
|
46
48
|
include Enumerable
|
49
|
+
include Cabin::Publisher
|
47
50
|
|
48
51
|
# Get us a new metrics container.
|
49
52
|
public
|
50
53
|
def initialize
|
51
54
|
@metrics = {}
|
52
55
|
end # def initialize
|
53
|
-
|
56
|
+
|
54
57
|
private
|
55
58
|
def create(instance, name, metric_object)
|
56
59
|
if !instance.is_a?(String)
|
@@ -58,11 +61,22 @@ class Cabin::Metrics
|
|
58
61
|
end
|
59
62
|
|
60
63
|
if name.nil?
|
61
|
-
|
64
|
+
# If no name is given, use the class name of the metric.
|
65
|
+
# For example, if we invoke Metrics#timer("foo"), the metric
|
66
|
+
# name will be "foo/timer"
|
67
|
+
metric_name = "#{instance}/#{metric_object.class.name.split("::").last.downcase}"
|
62
68
|
else
|
63
|
-
|
69
|
+
# Otherwise, use "instance/name" as the name.
|
70
|
+
metric_name = "#{instance}/#{name}"
|
71
|
+
end
|
72
|
+
|
73
|
+
metric_object.channel = @channel
|
74
|
+
metric_object.instance = metric_name
|
75
|
+
|
76
|
+
if @channel
|
77
|
+
@channel.debug("Created metric", :instance => instance, :type => metric_object.class)
|
64
78
|
end
|
65
|
-
return @metrics[
|
79
|
+
return @metrics[metric_name] = metric_object
|
66
80
|
end # def create
|
67
81
|
|
68
82
|
# Create a new Counter metric
|
@@ -1,9 +1,9 @@
|
|
1
1
|
require "cabin/namespace"
|
2
|
-
require "cabin/
|
2
|
+
require "cabin/metric"
|
3
3
|
require "thread"
|
4
4
|
|
5
5
|
class Cabin::Metrics::Counter
|
6
|
-
include Cabin::
|
6
|
+
include Cabin::Metric
|
7
7
|
|
8
8
|
# A new Counter.
|
9
9
|
#
|
@@ -18,11 +18,13 @@ class Cabin::Metrics::Counter
|
|
18
18
|
# increment this counter
|
19
19
|
def incr
|
20
20
|
@lock.synchronize { @value += 1 }
|
21
|
+
emit
|
21
22
|
end # def incr
|
22
23
|
|
23
24
|
# decrement this counter
|
24
25
|
def decr
|
25
26
|
@lock.synchronize { @value -= 1 }
|
27
|
+
emit
|
26
28
|
end # def decr
|
27
29
|
|
28
30
|
# Get the value of this metric.
|
data/lib/cabin/metrics/gauge.rb
CHANGED
@@ -1,9 +1,9 @@
|
|
1
1
|
require "cabin/namespace"
|
2
|
-
require "cabin/
|
2
|
+
require "cabin/metric"
|
3
3
|
require "thread"
|
4
4
|
|
5
5
|
class Cabin::Metrics::Histogram
|
6
|
-
include Cabin::
|
6
|
+
include Cabin::Metric
|
7
7
|
|
8
8
|
# A new Histogram.
|
9
9
|
public
|
@@ -20,8 +20,8 @@ class Cabin::Metrics::Histogram
|
|
20
20
|
#
|
21
21
|
# Sliding values of all of these?
|
22
22
|
@total = 0
|
23
|
-
@min =
|
24
|
-
@max =
|
23
|
+
@min = nil
|
24
|
+
@max = nil
|
25
25
|
@count = 0
|
26
26
|
@mean = 0.0
|
27
27
|
end # def initialize
|
@@ -31,12 +31,17 @@ class Cabin::Metrics::Histogram
|
|
31
31
|
@lock.synchronize do
|
32
32
|
@count += 1
|
33
33
|
@total += value
|
34
|
-
@min
|
35
|
-
|
34
|
+
if @min.nil? or value < @min
|
35
|
+
@min = value
|
36
|
+
end
|
37
|
+
if @max.nil? or value > @max
|
38
|
+
@max = value
|
39
|
+
end
|
36
40
|
@mean = @total / @count
|
37
41
|
# TODO(sissel): median
|
38
42
|
# TODO(sissel): percentiles
|
39
43
|
end
|
44
|
+
emit
|
40
45
|
end # def record
|
41
46
|
|
42
47
|
# This is a very poor way to access the metric data.
|
data/lib/cabin/metrics/meter.rb
CHANGED
@@ -1,9 +1,9 @@
|
|
1
1
|
require "cabin/namespace"
|
2
|
-
require "cabin/
|
2
|
+
require "cabin/metric"
|
3
3
|
require "thread"
|
4
4
|
|
5
5
|
class Cabin::Metrics::Meter
|
6
|
-
include Cabin::
|
6
|
+
include Cabin::Metric
|
7
7
|
|
8
8
|
# A new Meter
|
9
9
|
#
|
@@ -21,6 +21,7 @@ class Cabin::Metrics::Meter
|
|
21
21
|
@value += 1
|
22
22
|
# TODO(sissel): Keep some moving averages?
|
23
23
|
end
|
24
|
+
emit
|
24
25
|
end # def mark
|
25
26
|
|
26
27
|
# Get the value of this metric.
|
data/lib/cabin/metrics/timer.rb
CHANGED
data/lib/cabin/namespace.rb
CHANGED
@@ -0,0 +1,20 @@
|
|
1
|
+
require "cabin/namespace"
|
2
|
+
|
3
|
+
# This mixin allows you to easily give channel and publish features
|
4
|
+
# to a class.
|
5
|
+
module Cabin::Publisher
|
6
|
+
# Set the channel
|
7
|
+
def channel=(channel)
|
8
|
+
@channel = channel
|
9
|
+
end # def channel=
|
10
|
+
|
11
|
+
# Get the channel
|
12
|
+
def channel
|
13
|
+
return @channel
|
14
|
+
end # def channel
|
15
|
+
|
16
|
+
# Publish to the channel
|
17
|
+
def publish(object)
|
18
|
+
@channel << object
|
19
|
+
end # def publish
|
20
|
+
end # module Cabin::Publisher
|
data/test/test_metrics.rb
CHANGED
@@ -44,6 +44,13 @@ describe Cabin::Metrics do
|
|
44
44
|
|
45
45
|
test "meter time-based averages" # TODO(sissel): implement
|
46
46
|
|
47
|
+
test "timer first-run has max == min" do
|
48
|
+
timer = @metrics.timer(self)
|
49
|
+
timer.time { true }
|
50
|
+
assert_equal(timer.to_hash[:min], timer.to_hash[:max],
|
51
|
+
"With a single event, min and max must be equal")
|
52
|
+
end
|
53
|
+
|
47
54
|
test "timer counter" do
|
48
55
|
timer = @metrics.timer(self)
|
49
56
|
30.times do |i|
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: cabin
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.4.1
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -9,11 +9,11 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date: 2012-02-
|
12
|
+
date: 2012-02-11 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: json
|
16
|
-
requirement: &
|
16
|
+
requirement: &5144860 !ruby/object:Gem::Requirement
|
17
17
|
none: false
|
18
18
|
requirements:
|
19
19
|
- - ! '>='
|
@@ -21,7 +21,7 @@ dependencies:
|
|
21
21
|
version: '0'
|
22
22
|
type: :runtime
|
23
23
|
prerelease: false
|
24
|
-
version_requirements: *
|
24
|
+
version_requirements: *5144860
|
25
25
|
description: This is an experiment to try and make logging more flexible and more
|
26
26
|
consumable. Plain text logs are bullshit, let's emit structured and contextual logs.
|
27
27
|
Metrics, too!
|
@@ -34,6 +34,7 @@ extra_rdoc_files: []
|
|
34
34
|
files:
|
35
35
|
- lib/cabin/inspectable.rb
|
36
36
|
- lib/cabin/context.rb
|
37
|
+
- lib/cabin/metric.rb
|
37
38
|
- lib/cabin/timer.rb
|
38
39
|
- lib/cabin/outputs/stdlib-logger.rb
|
39
40
|
- lib/cabin/outputs/em/stdlib-logger.rb
|
@@ -47,11 +48,13 @@ files:
|
|
47
48
|
- lib/cabin/metrics/meter.rb
|
48
49
|
- lib/cabin/metrics/counter.rb
|
49
50
|
- lib/cabin/metrics.rb
|
51
|
+
- lib/cabin/publisher.rb
|
50
52
|
- lib/cabin/channel.rb
|
51
53
|
- lib/cabin.rb
|
52
54
|
- examples/fibonacci-timing.rb
|
53
55
|
- examples/sinatra-logging.rb
|
54
56
|
- examples/sample.rb
|
57
|
+
- examples/metrics.rb
|
55
58
|
- test/test_logging.rb
|
56
59
|
- test/minitest-patch.rb
|
57
60
|
- test/test_metrics.rb
|