cabin 0.1.1 → 0.1.2
Sign up to get free protection for your applications and to get access to all the features.
- 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
|
-
|