cabin 0.1.1 → 0.1.2
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/CHANGELIST +4 -0
- data/examples/{fib.rb → fibonacci-timing.rb} +7 -3
- data/lib/cabin/logger.rb +49 -8
- data/test/test_logging.rb +26 -1
- metadata +34 -51
data/CHANGELIST
ADDED
@@ -2,6 +2,11 @@ require "rubygems"
|
|
2
2
|
require "cabin"
|
3
3
|
require "logger"
|
4
4
|
|
5
|
+
def fib(n)
|
6
|
+
return 1 if n < 2
|
7
|
+
return fib(n - 1) + fib(n - 2)
|
8
|
+
end
|
9
|
+
|
5
10
|
# Logging::... is something I'm implemented and experimenting with.
|
6
11
|
@logger = Cabin::Channel.new
|
7
12
|
|
@@ -15,10 +20,9 @@ require "logger"
|
|
15
20
|
# You can store arbitrary key-value pairs in the logging channel.
|
16
21
|
# These are emitted with every event.
|
17
22
|
|
18
|
-
n =
|
23
|
+
n = 35
|
19
24
|
@logger[:input] = n
|
20
25
|
@logger.time("fibonacci latency") do
|
21
|
-
|
22
|
-
sleep(rand*2)
|
26
|
+
fib(n)
|
23
27
|
end
|
24
28
|
|
data/lib/cabin/logger.rb
CHANGED
@@ -1,5 +1,7 @@
|
|
1
1
|
require "cabin/namespace"
|
2
2
|
|
3
|
+
# This module implements methods that act somewhat like Ruby's Logger class
|
4
|
+
# It is included in Cabin::Channel
|
3
5
|
module Cabin::Logger
|
4
6
|
attr_accessor :level
|
5
7
|
LEVELS = {
|
@@ -10,20 +12,59 @@ module Cabin::Logger
|
|
10
12
|
:debug => 4
|
11
13
|
}
|
12
14
|
|
15
|
+
def level=(value)
|
16
|
+
@level = value.to_sym
|
17
|
+
end # def level
|
18
|
+
|
13
19
|
# Define the usual log methods: info, fatal, etc.
|
14
20
|
# Each level-based method accepts both a message and a hash data.
|
15
21
|
%w(fatal error warn info debug).each do |level|
|
16
22
|
level = level.to_sym
|
23
|
+
predicate = "#{level}?".to_sym
|
24
|
+
|
17
25
|
# def info, def warn, etc...
|
18
26
|
define_method(level) do |message, data={}|
|
19
|
-
|
20
|
-
if message.is_a?(Hash)
|
21
|
-
data.merge!(message)
|
22
|
-
else
|
23
|
-
data[:message] = message
|
24
|
-
end
|
25
|
-
data[:level] = level
|
26
|
-
publish(data)
|
27
|
+
log(level, message, data) if send(predicate)
|
27
28
|
end
|
29
|
+
|
30
|
+
# def info?, def warn? ...
|
31
|
+
# these methods return true if the loglevel allows that level of log.
|
32
|
+
define_method(predicate) do
|
33
|
+
return LEVELS[@level] >= LEVELS[level]
|
34
|
+
end # def info?, def warn? ...
|
28
35
|
end # end defining level-based log methods
|
36
|
+
|
37
|
+
private
|
38
|
+
def log(level, message, data={})
|
39
|
+
# Invoke 'info?' etc to ask if we should act.
|
40
|
+
if message.is_a?(Hash)
|
41
|
+
data.merge!(message)
|
42
|
+
else
|
43
|
+
data[:message] = message
|
44
|
+
end
|
45
|
+
|
46
|
+
# Add extra debugging bits (file, line, method) if level is debug.
|
47
|
+
debugharder(caller, data) if @level == :debug
|
48
|
+
|
49
|
+
data[:level] = level
|
50
|
+
publish(data)
|
51
|
+
end # def info, def warn ...
|
52
|
+
|
53
|
+
private
|
54
|
+
def debugharder(callstack, data)
|
55
|
+
path, line, method = callstack[1].split(/(?::in `|:|')/)
|
56
|
+
whence = $:.detect { |p| path.start_with?(p) }
|
57
|
+
if whence
|
58
|
+
# Remove the RUBYLIB path portion of the full file name
|
59
|
+
file = path[whence.length + 1..-1]
|
60
|
+
else
|
61
|
+
# We get here if the path is not in $:
|
62
|
+
file = path
|
63
|
+
end
|
64
|
+
who = "#{file}:#{line}##{method}"
|
65
|
+
|
66
|
+
data[:file] = file
|
67
|
+
data[:line] = line
|
68
|
+
data[:method] = method
|
69
|
+
end # def debugharder
|
29
70
|
end # module Cabin::Logger
|
data/test/test_logging.rb
CHANGED
@@ -8,6 +8,11 @@ require "stringio"
|
|
8
8
|
require "minitest/autorun" if __FILE__ == $0
|
9
9
|
|
10
10
|
describe Cabin::Channel do
|
11
|
+
|
12
|
+
# Cabin::Channel is a subscription thing, so implement
|
13
|
+
# a simple receiver that just stores events in an array
|
14
|
+
# for later access - this lets us see exactly what is
|
15
|
+
# logged, in order.
|
11
16
|
class Receiver
|
12
17
|
attr_accessor :data
|
13
18
|
|
@@ -84,6 +89,8 @@ describe Cabin::Channel do
|
|
84
89
|
@logger.level = level
|
85
90
|
@logger.send(level, "Hello world")
|
86
91
|
event = @target.data[0]
|
92
|
+
assert(@logger.send("#{level}?"),
|
93
|
+
"At level #{level}, Channel##{level}? should return true.")
|
87
94
|
assert_equal("Hello world", event[:message])
|
88
95
|
assert_equal(level, event[:level])
|
89
96
|
end
|
@@ -98,4 +105,22 @@ describe Cabin::Channel do
|
|
98
105
|
assert_equal(0, @target.data.length)
|
99
106
|
end
|
100
107
|
end
|
101
|
-
|
108
|
+
|
109
|
+
test "extra debugging data" do
|
110
|
+
@logger.level = :debug
|
111
|
+
@logger.info("Hello world")
|
112
|
+
event = @target.data[0]
|
113
|
+
assert(event.include?(:file), "At debug level, there should be a :file attribute")
|
114
|
+
assert(event.include?(:line), "At debug level, there should be a :line attribute")
|
115
|
+
assert(event.include?(:method), "At debug level, there should be a :method attribute")
|
116
|
+
end
|
117
|
+
|
118
|
+
test "extra debugging data absent if log level is not debug" do
|
119
|
+
@logger.level = :info
|
120
|
+
@logger.info("Hello world")
|
121
|
+
event = @target.data[0]
|
122
|
+
assert(!event.include?(:file), "At non-debug level, there should not be a :file attribute")
|
123
|
+
assert(!event.include?(:line), "At non-debug level, there should not be a :line attribute")
|
124
|
+
assert(!event.include?(:method), "At non-debug level, there should not be a :method attribute")
|
125
|
+
end
|
126
|
+
end # describe Cabin::Channel do
|
metadata
CHANGED
@@ -1,45 +1,35 @@
|
|
1
|
-
--- !ruby/object:Gem::Specification
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
2
|
name: cabin
|
3
|
-
version: !ruby/object:Gem::Version
|
4
|
-
|
5
|
-
|
6
|
-
- 0
|
7
|
-
- 1
|
8
|
-
- 1
|
9
|
-
version: 0.1.1
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.1.2
|
5
|
+
prerelease:
|
10
6
|
platform: ruby
|
11
|
-
authors:
|
7
|
+
authors:
|
12
8
|
- Jordan Sissel
|
13
9
|
autorequire:
|
14
10
|
bindir: bin
|
15
11
|
cert_chain: []
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
dependencies:
|
20
|
-
- !ruby/object:Gem::Dependency
|
12
|
+
date: 2011-10-12 00:00:00.000000000Z
|
13
|
+
dependencies:
|
14
|
+
- !ruby/object:Gem::Dependency
|
21
15
|
name: json
|
22
|
-
|
23
|
-
requirement: &id001 !ruby/object:Gem::Requirement
|
16
|
+
requirement: &19828200 !ruby/object:Gem::Requirement
|
24
17
|
none: false
|
25
|
-
requirements:
|
26
|
-
- -
|
27
|
-
- !ruby/object:Gem::Version
|
28
|
-
|
29
|
-
- 0
|
30
|
-
version: "0"
|
18
|
+
requirements:
|
19
|
+
- - ! '>='
|
20
|
+
- !ruby/object:Gem::Version
|
21
|
+
version: '0'
|
31
22
|
type: :runtime
|
32
|
-
|
33
|
-
|
34
|
-
|
23
|
+
prerelease: false
|
24
|
+
version_requirements: *19828200
|
25
|
+
description: This is an experiment to try and make logging more flexible and more
|
26
|
+
consumable. Plain text logs are bullshit, let's emit structured and contextual logs.
|
27
|
+
email:
|
35
28
|
- jls@semicomplete.com
|
36
29
|
executables: []
|
37
|
-
|
38
30
|
extensions: []
|
39
|
-
|
40
31
|
extra_rdoc_files: []
|
41
|
-
|
42
|
-
files:
|
32
|
+
files:
|
43
33
|
- lib/cabin.rb
|
44
34
|
- lib/cabin/outputs/stdlib-logger.rb
|
45
35
|
- lib/cabin/channel.rb
|
@@ -47,44 +37,37 @@ files:
|
|
47
37
|
- lib/cabin/timer.rb
|
48
38
|
- lib/cabin/context.rb
|
49
39
|
- lib/cabin/logger.rb
|
50
|
-
- examples/
|
40
|
+
- examples/fibonacci-timing.rb
|
51
41
|
- examples/sinatra-logging.rb
|
52
42
|
- examples/sample.rb
|
53
43
|
- test/minitest-patch.rb
|
54
44
|
- test/test_logging.rb
|
55
45
|
- LICENSE
|
56
|
-
|
46
|
+
- CHANGELIST
|
57
47
|
homepage: https://github.com/jordansissel/ruby-cabin
|
58
|
-
licenses:
|
48
|
+
licenses:
|
59
49
|
- Apache License (2.0)
|
60
50
|
post_install_message:
|
61
51
|
rdoc_options: []
|
62
|
-
|
63
|
-
require_paths:
|
52
|
+
require_paths:
|
64
53
|
- lib
|
65
54
|
- lib
|
66
|
-
required_ruby_version: !ruby/object:Gem::Requirement
|
55
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
67
56
|
none: false
|
68
|
-
requirements:
|
69
|
-
- -
|
70
|
-
- !ruby/object:Gem::Version
|
71
|
-
|
72
|
-
|
73
|
-
version: "0"
|
74
|
-
required_rubygems_version: !ruby/object:Gem::Requirement
|
57
|
+
requirements:
|
58
|
+
- - ! '>='
|
59
|
+
- !ruby/object:Gem::Version
|
60
|
+
version: '0'
|
61
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
75
62
|
none: false
|
76
|
-
requirements:
|
77
|
-
- -
|
78
|
-
- !ruby/object:Gem::Version
|
79
|
-
|
80
|
-
- 0
|
81
|
-
version: "0"
|
63
|
+
requirements:
|
64
|
+
- - ! '>='
|
65
|
+
- !ruby/object:Gem::Version
|
66
|
+
version: '0'
|
82
67
|
requirements: []
|
83
|
-
|
84
68
|
rubyforge_project:
|
85
|
-
rubygems_version: 1.
|
69
|
+
rubygems_version: 1.8.10
|
86
70
|
signing_key:
|
87
71
|
specification_version: 3
|
88
72
|
summary: Experiments in structured and contextual logging
|
89
73
|
test_files: []
|
90
|
-
|