scrolls 0.3.7 → 0.9.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +5 -5
- data/Gemfile +2 -0
- data/README.md +52 -14
- data/Rakefile +4 -2
- data/docs/global-context.md +1 -1
- data/docs/syslog.md +14 -1
- data/lib/scrolls.rb +62 -83
- data/lib/scrolls/iologger.rb +14 -0
- data/lib/scrolls/logger.rb +318 -0
- data/lib/scrolls/parser.rb +3 -1
- data/lib/scrolls/sysloglogger.rb +17 -0
- data/lib/scrolls/utils.rb +55 -13
- data/lib/scrolls/version.rb +1 -1
- data/test/test_helper.rb +4 -1
- data/test/test_parser.rb +11 -2
- data/test/test_scrolls.rb +78 -41
- metadata +6 -9
- data/lib/scrolls/atomic.rb +0 -59
- data/lib/scrolls/log.rb +0 -274
- data/lib/scrolls/syslog.rb +0 -46
- data/test/test_atomic.rb +0 -33
data/test/test_parser.rb
CHANGED
@@ -1,6 +1,6 @@
|
|
1
|
-
|
1
|
+
require File.expand_path("../test_helper", __FILE__)
|
2
2
|
|
3
|
-
class TestScrollsParser < Test
|
3
|
+
class TestScrollsParser < Minitest::Test
|
4
4
|
include Scrolls::Parser
|
5
5
|
|
6
6
|
def test_parse_bool
|
@@ -79,6 +79,15 @@ class TestScrollsParser < Test::Unit::TestCase
|
|
79
79
|
assert_equal 't="2012-06-19T16:02:35+01:00"', unparse(data)
|
80
80
|
end
|
81
81
|
|
82
|
+
def test_unparse_escape_keys
|
83
|
+
html = "<p>p</p>"
|
84
|
+
slash = "p/p"
|
85
|
+
|
86
|
+
data = { html => "d", slash => "d" }
|
87
|
+
assert_equal '<p>p</p>=d p/p=d',
|
88
|
+
unparse(data, escape_keys=true)
|
89
|
+
end
|
90
|
+
|
82
91
|
def test_parse_time
|
83
92
|
time = Time.new(2012, 06, 19, 16, 02, 35, "+01:00")
|
84
93
|
string = "t=2012-06-19T16:02:35+01:00"
|
data/test/test_scrolls.rb
CHANGED
@@ -1,44 +1,35 @@
|
|
1
|
-
|
1
|
+
require File.expand_path("../test_helper", __FILE__)
|
2
2
|
|
3
|
-
class TestScrolls < Test
|
3
|
+
class TestScrolls < Minitest::Test
|
4
4
|
def setup
|
5
5
|
@out = StringIO.new
|
6
|
-
Scrolls.
|
6
|
+
Scrolls.init(
|
7
|
+
:stream => @out
|
8
|
+
)
|
7
9
|
end
|
8
10
|
|
9
|
-
def
|
10
|
-
Scrolls.
|
11
|
-
|
12
|
-
Scrolls.facility = Scrolls::LOG_FACILITY
|
13
|
-
Scrolls.add_timestamp = false
|
14
|
-
end
|
15
|
-
|
16
|
-
def test_construct
|
17
|
-
assert_equal StringIO, Scrolls.stream.class
|
11
|
+
def test_default_construct
|
12
|
+
Scrolls.init
|
13
|
+
assert_equal Scrolls::IOLogger, Scrolls.logger.class
|
18
14
|
end
|
19
15
|
|
20
16
|
def test_default_global_context
|
17
|
+
Scrolls.init(:stream => @out)
|
21
18
|
assert_equal Hash.new, Scrolls.global_context
|
22
19
|
end
|
23
20
|
|
24
21
|
def test_setting_global_context
|
25
|
-
Scrolls.
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
end
|
30
|
-
|
31
|
-
def test_adding_to_global_context
|
32
|
-
Scrolls.global_context(:g => "g")
|
33
|
-
Scrolls.add_global_context(:h => "h")
|
22
|
+
Scrolls.init(
|
23
|
+
:stream => @out,
|
24
|
+
:global_context => {:g => "g"},
|
25
|
+
)
|
34
26
|
Scrolls.log(:d => "d")
|
35
|
-
|
36
|
-
assert_match /g=g.*h=h.*d=d/, global
|
27
|
+
assert_equal "g=g d=d\n", @out.string
|
37
28
|
end
|
38
29
|
|
39
30
|
def test_default_context
|
40
|
-
Scrolls.log(:
|
41
|
-
assert_equal Hash.new, Scrolls
|
31
|
+
Scrolls.log(:d => "d")
|
32
|
+
assert_equal Hash.new, Scrolls.internal.context
|
42
33
|
end
|
43
34
|
|
44
35
|
def test_setting_context
|
@@ -48,15 +39,19 @@ class TestScrolls < Test::Unit::TestCase
|
|
48
39
|
end
|
49
40
|
|
50
41
|
def test_all_the_contexts
|
51
|
-
Scrolls.
|
42
|
+
Scrolls.init(
|
43
|
+
:stream => @out,
|
44
|
+
:global_context => {:g => "g"},
|
45
|
+
)
|
52
46
|
Scrolls.log(:o => "o") do
|
53
47
|
Scrolls.context(:c => "c") do
|
54
48
|
Scrolls.log(:ic => "i")
|
55
49
|
end
|
56
50
|
Scrolls.log(:i => "i")
|
57
51
|
end
|
58
|
-
|
59
|
-
|
52
|
+
@out.truncate(37)
|
53
|
+
output = "g=g o=o at=start\ng=g c=c ic=i\ng=g i=i"
|
54
|
+
assert_equal output, @out.string
|
60
55
|
end
|
61
56
|
|
62
57
|
def test_deeply_nested_context
|
@@ -89,12 +84,27 @@ class TestScrolls < Test::Unit::TestCase
|
|
89
84
|
raise "Error from inside of context"
|
90
85
|
end
|
91
86
|
fail "Exception did not escape context block"
|
92
|
-
rescue
|
87
|
+
rescue
|
93
88
|
Scrolls.log(:o => 'o')
|
94
89
|
assert_equal "o=o\n", @out.string
|
95
90
|
end
|
96
91
|
end
|
97
92
|
|
93
|
+
def test_deeply_nested_context_after_exception
|
94
|
+
Scrolls.log(:o => "o") do
|
95
|
+
begin
|
96
|
+
Scrolls.log(:io => 'io') do
|
97
|
+
raise "Error from inside of nested logging"
|
98
|
+
end
|
99
|
+
rescue
|
100
|
+
Scrolls.log(:o => 'o')
|
101
|
+
end
|
102
|
+
end
|
103
|
+
@out.truncate(124)
|
104
|
+
output = "o=o at=start\nio=io at=start\nio=io at=exception reraise=true class=RuntimeError message=\"Error from inside of nested logging\""
|
105
|
+
assert_equal output, @out.string
|
106
|
+
end
|
107
|
+
|
98
108
|
def test_default_time_unit
|
99
109
|
assert_equal "seconds", Scrolls.time_unit
|
100
110
|
end
|
@@ -105,8 +115,15 @@ class TestScrolls < Test::Unit::TestCase
|
|
105
115
|
end
|
106
116
|
|
107
117
|
def test_setting_incorrect_time_unit
|
108
|
-
|
118
|
+
assert_raises Scrolls::TimeUnitError do
|
109
119
|
Scrolls.time_unit = "years"
|
120
|
+
Scrolls.log(:tu => "yrs")
|
121
|
+
end
|
122
|
+
end
|
123
|
+
|
124
|
+
def test_unknown_log_level
|
125
|
+
assert_raises Scrolls::LogLevelError do
|
126
|
+
Scrolls.log(:level => "nope")
|
110
127
|
end
|
111
128
|
end
|
112
129
|
|
@@ -125,28 +142,28 @@ class TestScrolls < Test::Unit::TestCase
|
|
125
142
|
begin
|
126
143
|
raise Exception
|
127
144
|
rescue Exception => e
|
128
|
-
Scrolls.log_exception({:test => "exception"}
|
145
|
+
Scrolls.log_exception(e, {:test => "exception"})
|
129
146
|
end
|
130
147
|
|
131
|
-
|
132
|
-
|
133
|
-
assert_match /test=exception at=exception.*test_log_exception.*XX.*minitest/,
|
134
|
-
oneline_backtrace
|
148
|
+
oneline_bt = @out.string.gsub("\n", 'XX')
|
149
|
+
assert_match(/test=exception at=exception.*test_log_exception.*XX/, oneline_bt)
|
135
150
|
end
|
136
151
|
|
137
|
-
def
|
138
|
-
Scrolls.single_line_exceptions =
|
152
|
+
def test_multi_line_exceptions
|
153
|
+
Scrolls.single_line_exceptions = "multi"
|
139
154
|
begin
|
140
155
|
raise Exception
|
141
156
|
rescue Exception => e
|
142
|
-
Scrolls.log_exception({:o => "o"}
|
157
|
+
Scrolls.log_exception(e, {:o => "o"})
|
143
158
|
end
|
144
|
-
|
159
|
+
|
160
|
+
oneline_bt = @out.string.gsub("\n", 'XX')
|
161
|
+
assert_match(/o=o at=exception.*test_multi_line_exceptions.*XX/, oneline_bt)
|
145
162
|
end
|
146
163
|
|
147
164
|
def test_syslog_integration
|
148
165
|
Scrolls.stream = 'syslog'
|
149
|
-
assert_equal Scrolls::SyslogLogger, Scrolls.
|
166
|
+
assert_equal Scrolls::SyslogLogger, Scrolls.internal.logger.class
|
150
167
|
end
|
151
168
|
|
152
169
|
def test_syslog_facility
|
@@ -162,7 +179,7 @@ class TestScrolls < Test::Unit::TestCase
|
|
162
179
|
def test_setting_syslog_facility_after_instantiation
|
163
180
|
Scrolls.stream = 'syslog'
|
164
181
|
Scrolls.facility = 'local7'
|
165
|
-
assert_match
|
182
|
+
assert_match(/facility=184/, Scrolls.internal.logger.inspect)
|
166
183
|
end
|
167
184
|
|
168
185
|
def test_add_timestamp
|
@@ -204,4 +221,24 @@ class TestScrolls < Test::Unit::TestCase
|
|
204
221
|
assert_equal "t=t level=alert\n", @out.string
|
205
222
|
end
|
206
223
|
|
224
|
+
def test_sending_string_error
|
225
|
+
Scrolls.error("error")
|
226
|
+
assert_equal "log_message=error\n", @out.string
|
227
|
+
end
|
228
|
+
|
229
|
+
def test_sending_string_fatal
|
230
|
+
Scrolls.fatal("fatal")
|
231
|
+
assert_equal "log_message=fatal\n", @out.string
|
232
|
+
end
|
233
|
+
|
234
|
+
def test_sending_string_warn
|
235
|
+
Scrolls.warn("warn")
|
236
|
+
assert_equal "log_message=warn\n", @out.string
|
237
|
+
end
|
238
|
+
|
239
|
+
def test_sending_string_unknown
|
240
|
+
Scrolls.unknown("unknown")
|
241
|
+
assert_equal "log_message=unknown\n", @out.string
|
242
|
+
end
|
243
|
+
|
207
244
|
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: scrolls
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.9.1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Curt Micol
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2021-06-06 00:00:00.000000000 Z
|
12
12
|
dependencies: []
|
13
13
|
description: Logging, easier, more consistent.
|
14
14
|
email:
|
@@ -25,14 +25,13 @@ files:
|
|
25
25
|
- docs/global-context.md
|
26
26
|
- docs/syslog.md
|
27
27
|
- lib/scrolls.rb
|
28
|
-
- lib/scrolls/
|
29
|
-
- lib/scrolls/
|
28
|
+
- lib/scrolls/iologger.rb
|
29
|
+
- lib/scrolls/logger.rb
|
30
30
|
- lib/scrolls/parser.rb
|
31
|
-
- lib/scrolls/
|
31
|
+
- lib/scrolls/sysloglogger.rb
|
32
32
|
- lib/scrolls/utils.rb
|
33
33
|
- lib/scrolls/version.rb
|
34
34
|
- scrolls.gemspec
|
35
|
-
- test/test_atomic.rb
|
36
35
|
- test/test_helper.rb
|
37
36
|
- test/test_parser.rb
|
38
37
|
- test/test_scrolls.rb
|
@@ -55,13 +54,11 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
55
54
|
- !ruby/object:Gem::Version
|
56
55
|
version: '0'
|
57
56
|
requirements: []
|
58
|
-
|
59
|
-
rubygems_version: 2.2.0
|
57
|
+
rubygems_version: 3.0.3
|
60
58
|
signing_key:
|
61
59
|
specification_version: 4
|
62
60
|
summary: When do we log? All the time.
|
63
61
|
test_files:
|
64
|
-
- test/test_atomic.rb
|
65
62
|
- test/test_helper.rb
|
66
63
|
- test/test_parser.rb
|
67
64
|
- test/test_scrolls.rb
|
data/lib/scrolls/atomic.rb
DELETED
@@ -1,59 +0,0 @@
|
|
1
|
-
require 'thread'
|
2
|
-
|
3
|
-
module Scrolls
|
4
|
-
# The result of issues with an update I made to Scrolls. After talking with
|
5
|
-
# Fabio Kung about a fix I started work on an atomic object, but he added some
|
6
|
-
# fixes to #context without it and then used Headius' atomic gem.
|
7
|
-
#
|
8
|
-
# The code below is the start and cleanup of my atomic object. It's slim on
|
9
|
-
# details and eventually cleaned up around inspiration from Headius' code.
|
10
|
-
#
|
11
|
-
# LICENSE: Apache 2.0
|
12
|
-
#
|
13
|
-
# See Headius' atomic gem here:
|
14
|
-
# https://github.com/headius/ruby-atomic
|
15
|
-
class AtomicObject
|
16
|
-
def initialize(o)
|
17
|
-
@mtx = Mutex.new
|
18
|
-
@o = o
|
19
|
-
end
|
20
|
-
|
21
|
-
def get
|
22
|
-
@mtx.synchronize { @o }
|
23
|
-
end
|
24
|
-
|
25
|
-
def set(n)
|
26
|
-
@mtx.synchronize { @o = n }
|
27
|
-
end
|
28
|
-
|
29
|
-
def verify_set(o, n)
|
30
|
-
return false unless @mtx.try_lock
|
31
|
-
begin
|
32
|
-
return false unless @o.equal? o
|
33
|
-
@o = n
|
34
|
-
ensure
|
35
|
-
@mtx.unlock
|
36
|
-
end
|
37
|
-
end
|
38
|
-
end
|
39
|
-
|
40
|
-
class Atomic < AtomicObject
|
41
|
-
def initialize(v=nil)
|
42
|
-
super(v)
|
43
|
-
end
|
44
|
-
|
45
|
-
def value
|
46
|
-
self.get
|
47
|
-
end
|
48
|
-
|
49
|
-
def value=(v)
|
50
|
-
self.set(v)
|
51
|
-
v
|
52
|
-
end
|
53
|
-
|
54
|
-
def update
|
55
|
-
true until self.verify_set(o = self.get, n = yield(o))
|
56
|
-
n
|
57
|
-
end
|
58
|
-
end
|
59
|
-
end
|
data/lib/scrolls/log.rb
DELETED
@@ -1,274 +0,0 @@
|
|
1
|
-
require "scrolls/parser"
|
2
|
-
require "scrolls/utils"
|
3
|
-
require "scrolls/syslog"
|
4
|
-
|
5
|
-
module Scrolls
|
6
|
-
|
7
|
-
class TimeUnitError < RuntimeError; end
|
8
|
-
|
9
|
-
module Log
|
10
|
-
extend self
|
11
|
-
|
12
|
-
extend Parser
|
13
|
-
extend Utils
|
14
|
-
|
15
|
-
LOG_LEVEL = (ENV['LOG_LEVEL'] || 6).to_i
|
16
|
-
LOG_LEVEL_MAP = {
|
17
|
-
"emergency" => 0,
|
18
|
-
"alert" => 1,
|
19
|
-
"critical" => 2,
|
20
|
-
"error" => 3,
|
21
|
-
"warning" => 4,
|
22
|
-
"notice" => 5,
|
23
|
-
"info" => 6,
|
24
|
-
"debug" => 7
|
25
|
-
}
|
26
|
-
|
27
|
-
def context
|
28
|
-
Thread.current[:scrolls_context] ||= {}
|
29
|
-
end
|
30
|
-
|
31
|
-
def context=(h)
|
32
|
-
Thread.current[:scrolls_context] = h
|
33
|
-
end
|
34
|
-
|
35
|
-
def global_context
|
36
|
-
get_global_context
|
37
|
-
end
|
38
|
-
|
39
|
-
def global_context=(data)
|
40
|
-
set_global_context(data)
|
41
|
-
end
|
42
|
-
|
43
|
-
def add_global_context(new_data)
|
44
|
-
default_global_context unless @global_context
|
45
|
-
@global_context.update { |previous_data| previous_data.merge(new_data) }
|
46
|
-
end
|
47
|
-
|
48
|
-
def facility=(f)
|
49
|
-
@facility = LOG_FACILITY_MAP[f] if f
|
50
|
-
if Scrolls::SyslogLogger.opened?
|
51
|
-
Scrolls::SyslogLogger.new(progname, facility)
|
52
|
-
end
|
53
|
-
end
|
54
|
-
|
55
|
-
def facility
|
56
|
-
@facility ||= default_log_facility
|
57
|
-
end
|
58
|
-
|
59
|
-
def stream=(out=nil)
|
60
|
-
@defined = out.nil? ? false : true
|
61
|
-
if out == 'syslog'
|
62
|
-
@stream = Scrolls::SyslogLogger.new(progname, facility)
|
63
|
-
else
|
64
|
-
@stream = sync_stream(out)
|
65
|
-
end
|
66
|
-
end
|
67
|
-
|
68
|
-
def stream
|
69
|
-
@stream ||= sync_stream
|
70
|
-
end
|
71
|
-
|
72
|
-
def time_unit=(u)
|
73
|
-
set_time_unit(u)
|
74
|
-
end
|
75
|
-
|
76
|
-
def time_unit
|
77
|
-
@tunit ||= default_time_unit
|
78
|
-
end
|
79
|
-
|
80
|
-
def add_timestamp=(b)
|
81
|
-
@add_timestamp = !!b
|
82
|
-
end
|
83
|
-
|
84
|
-
def add_timestamp
|
85
|
-
@add_timestamp || false
|
86
|
-
end
|
87
|
-
|
88
|
-
def single_line_exceptions=(b)
|
89
|
-
@single_line_exceptions = !!b
|
90
|
-
end
|
91
|
-
|
92
|
-
def single_line_exceptions?
|
93
|
-
@single_line_exceptions || false
|
94
|
-
end
|
95
|
-
|
96
|
-
def log(data, &blk)
|
97
|
-
# If we get a string lets bring it into our structure.
|
98
|
-
if data.kind_of? String
|
99
|
-
rawhash = { "log_message" => data }
|
100
|
-
else
|
101
|
-
rawhash = data
|
102
|
-
end
|
103
|
-
|
104
|
-
if gc = get_global_context
|
105
|
-
ctx = gc.merge(context)
|
106
|
-
logdata = ctx.merge(rawhash)
|
107
|
-
end
|
108
|
-
|
109
|
-
# By merging the logdata into the timestamp, rather than vice-versa, we
|
110
|
-
# ensure that the timestamp comes first in the Hash, and is placed first
|
111
|
-
# on the output, which helps with readability.
|
112
|
-
logdata = { :now => Time.now.utc }.merge(logdata) if add_timestamp
|
113
|
-
|
114
|
-
unless blk
|
115
|
-
write(logdata)
|
116
|
-
else
|
117
|
-
start = Time.now
|
118
|
-
res = nil
|
119
|
-
log(logdata.merge(:at => "start"))
|
120
|
-
begin
|
121
|
-
res = yield
|
122
|
-
rescue StandardError => e
|
123
|
-
log(logdata.merge(
|
124
|
-
:at => "exception",
|
125
|
-
:reraise => true,
|
126
|
-
:class => e.class,
|
127
|
-
:message => e.message,
|
128
|
-
:exception_id => e.object_id.abs,
|
129
|
-
:elapsed => calc_time(start, Time.now)
|
130
|
-
))
|
131
|
-
raise e
|
132
|
-
end
|
133
|
-
log(logdata.merge(:at => "finish", :elapsed => calc_time(start, Time.now)))
|
134
|
-
res
|
135
|
-
end
|
136
|
-
end
|
137
|
-
|
138
|
-
def log_exception(data, e)
|
139
|
-
sync_stream(STDERR) unless @defined
|
140
|
-
|
141
|
-
# If we get a string lets bring it into our structure.
|
142
|
-
if data.kind_of? String
|
143
|
-
rawhash = { "log_message" => data }
|
144
|
-
else
|
145
|
-
rawhash = data
|
146
|
-
end
|
147
|
-
|
148
|
-
if gc = get_global_context
|
149
|
-
logdata = gc.merge(rawhash)
|
150
|
-
end
|
151
|
-
|
152
|
-
excepdata = {
|
153
|
-
:at => "exception",
|
154
|
-
:class => e.class,
|
155
|
-
:message => e.message,
|
156
|
-
:exception_id => e.object_id.abs
|
157
|
-
}
|
158
|
-
|
159
|
-
if e.backtrace
|
160
|
-
if single_line_exceptions?
|
161
|
-
btlines = []
|
162
|
-
e.backtrace.each do |line|
|
163
|
-
btlines << line.gsub(/[`'"]/, "")
|
164
|
-
end
|
165
|
-
|
166
|
-
if btlines.length > 0
|
167
|
-
squish = { :site => btlines.join('\n') }
|
168
|
-
log(logdata.merge(excepdata.merge(squish)))
|
169
|
-
end
|
170
|
-
else
|
171
|
-
log(logdata.merge(excepdata))
|
172
|
-
|
173
|
-
e.backtrace.each do |line|
|
174
|
-
log(logdata.merge(excepdata).merge(
|
175
|
-
:at => "exception",
|
176
|
-
:class => e.class,
|
177
|
-
:exception_id => e.object_id.abs,
|
178
|
-
:site => line.gsub(/[`'"]/, "")
|
179
|
-
))
|
180
|
-
end
|
181
|
-
end
|
182
|
-
end
|
183
|
-
end
|
184
|
-
|
185
|
-
def with_context(prefix)
|
186
|
-
return unless block_given?
|
187
|
-
old = context
|
188
|
-
self.context = old.merge(prefix)
|
189
|
-
res = yield if block_given?
|
190
|
-
ensure
|
191
|
-
self.context = old
|
192
|
-
res
|
193
|
-
end
|
194
|
-
|
195
|
-
private
|
196
|
-
|
197
|
-
def get_global_context
|
198
|
-
default_global_context unless @global_context
|
199
|
-
@global_context.value
|
200
|
-
end
|
201
|
-
|
202
|
-
def set_global_context(data=nil)
|
203
|
-
default_global_context unless @global_context
|
204
|
-
@global_context.update { |_| data }
|
205
|
-
end
|
206
|
-
|
207
|
-
def default_global_context
|
208
|
-
@global_context = Atomic.new({})
|
209
|
-
end
|
210
|
-
|
211
|
-
def set_time_unit(u=nil)
|
212
|
-
unless ["ms","milli","milliseconds","s","seconds"].include?(u)
|
213
|
-
raise TimeUnitError, "Specify only 'seconds' or 'milliseconds'"
|
214
|
-
end
|
215
|
-
|
216
|
-
if ["ms", "milli", "milliseconds", 1000].include?(u)
|
217
|
-
@tunit = "milliseconds"
|
218
|
-
@t = 1000.0
|
219
|
-
else
|
220
|
-
default_time_unit
|
221
|
-
end
|
222
|
-
end
|
223
|
-
|
224
|
-
def default_time_unit
|
225
|
-
@t = 1.0
|
226
|
-
@tunit = "seconds"
|
227
|
-
end
|
228
|
-
|
229
|
-
def calc_time(start, finish)
|
230
|
-
default_time_unit unless @t
|
231
|
-
((finish - start).to_f * @t)
|
232
|
-
end
|
233
|
-
|
234
|
-
def mtx
|
235
|
-
@mtx ||= Mutex.new
|
236
|
-
end
|
237
|
-
|
238
|
-
def sync_stream(out=nil)
|
239
|
-
out = STDOUT if out.nil?
|
240
|
-
s = out
|
241
|
-
s.sync = true
|
242
|
-
s
|
243
|
-
end
|
244
|
-
|
245
|
-
def write(data)
|
246
|
-
if log_level_ok?(data[:level])
|
247
|
-
msg = unparse(data)
|
248
|
-
mtx.synchronize do
|
249
|
-
begin
|
250
|
-
stream.puts(msg)
|
251
|
-
rescue NoMethodError => e
|
252
|
-
raise
|
253
|
-
end
|
254
|
-
end
|
255
|
-
end
|
256
|
-
end
|
257
|
-
|
258
|
-
def log_level_ok?(level)
|
259
|
-
if level
|
260
|
-
LOG_LEVEL_MAP[level.to_s] <= LOG_LEVEL
|
261
|
-
else
|
262
|
-
true
|
263
|
-
end
|
264
|
-
end
|
265
|
-
|
266
|
-
def progname
|
267
|
-
File.basename($0)
|
268
|
-
end
|
269
|
-
|
270
|
-
def default_log_facility
|
271
|
-
LOG_FACILITY
|
272
|
-
end
|
273
|
-
end
|
274
|
-
end
|