birling 0.1.2 → 0.3.0
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.
- checksums.yaml +7 -0
- data/.travis.yml +9 -0
- data/Gemfile +4 -3
- data/LICENSE.txt +1 -1
- data/README.md +6 -6
- data/Rakefile +3 -1
- data/VERSION +1 -1
- data/birling.gemspec +23 -22
- data/lib/birling.rb +9 -0
- data/lib/birling/formatter.rb +8 -0
- data/lib/birling/logger.rb +122 -69
- data/lib/birling/support.rb +4 -0
- data/test/helper.rb +3 -3
- data/test/test_birling.rb +0 -13
- data/test/test_birling_logger.rb +104 -63
- data/test/test_birling_support.rb +6 -0
- metadata +31 -23
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA256:
|
3
|
+
metadata.gz: a2d34d601f2ff30378ab9b5e133d806978b9da61a64de3ac878b1ed10b04fd96
|
4
|
+
data.tar.gz: 363723fcff5a1ba4ba67ebfcd89619d4377087e780120c1ad0d37acf8cf28471
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 1b5c2cb58a1a7130b66c1dfb67aaa9b48e2a843d72f32abbc95bfdb6c087a0d688a9c080f2ed33d3728d7abe93ac250e490d44019f23f9b3af7964321061d6f0
|
7
|
+
data.tar.gz: 73c01e0ad63f2c53350814b17342f489114255eab32f3f5ea49db0d20f6c5554e173fc21ba99b45624e0390a45200d677f3883dae6cd86821b85f6e992fc5c58
|
data/.travis.yml
ADDED
data/Gemfile
CHANGED
data/LICENSE.txt
CHANGED
data/README.md
CHANGED
@@ -34,8 +34,8 @@ of ten hourly logs:
|
|
34
34
|
```ruby
|
35
35
|
logger = Birling.open(
|
36
36
|
'test.log',
|
37
|
-
:
|
38
|
-
:
|
37
|
+
period: :hourly,
|
38
|
+
retain_count: 10
|
39
39
|
)
|
40
40
|
```
|
41
41
|
|
@@ -46,8 +46,8 @@ that period will be removed:
|
|
46
46
|
```ruby
|
47
47
|
logger = Birling.open(
|
48
48
|
'test.log',
|
49
|
-
:
|
50
|
-
:
|
49
|
+
period: :hourly,
|
50
|
+
retain_period: 10 * 3600
|
51
51
|
)
|
52
52
|
```
|
53
53
|
|
@@ -60,7 +60,7 @@ Example:
|
|
60
60
|
```ruby
|
61
61
|
logger = Birling.open(
|
62
62
|
'test.log',
|
63
|
-
:
|
63
|
+
formatter: -> (severity, time, program, message) { "#{time}> #{message}\n" }
|
64
64
|
)
|
65
65
|
```
|
66
66
|
|
@@ -76,4 +76,4 @@ using `STDOUT` the logger will not rotate.
|
|
76
76
|
|
77
77
|
## Copyright
|
78
78
|
|
79
|
-
Copyright (c) 2011-
|
79
|
+
Copyright (c) 2011-2019 Scott Tadman, PostageApp Ltd.
|
data/Rakefile
CHANGED
@@ -14,7 +14,7 @@ require 'jeweler'
|
|
14
14
|
|
15
15
|
Jeweler::Tasks.new do |gem|
|
16
16
|
gem.name = "birling"
|
17
|
-
gem.homepage = "http://github.com/
|
17
|
+
gem.homepage = "http://github.com/postageapp/birling"
|
18
18
|
gem.license = "MIT"
|
19
19
|
gem.summary = %Q{Logger with simple log rotation system}
|
20
20
|
gem.description = %Q{Mostly drop-in replacement for Logger with a more robust log rotation facility}
|
@@ -31,3 +31,5 @@ Rake::TestTask.new(:test) do |test|
|
|
31
31
|
test.pattern = 'test/**/test_*.rb'
|
32
32
|
test.verbose = true
|
33
33
|
end
|
34
|
+
|
35
|
+
task default: :test
|
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
0.
|
1
|
+
0.3.0
|
data/birling.gemspec
CHANGED
@@ -2,22 +2,25 @@
|
|
2
2
|
# DO NOT EDIT THIS FILE DIRECTLY
|
3
3
|
# Instead, edit Jeweler::Tasks in Rakefile, and run 'rake gemspec'
|
4
4
|
# -*- encoding: utf-8 -*-
|
5
|
+
# stub: birling 0.3.0 ruby lib
|
5
6
|
|
6
7
|
Gem::Specification.new do |s|
|
7
|
-
s.name = "birling"
|
8
|
-
s.version = "0.
|
8
|
+
s.name = "birling".freeze
|
9
|
+
s.version = "0.3.0"
|
9
10
|
|
10
|
-
s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
|
11
|
-
s.
|
12
|
-
s.
|
13
|
-
s.
|
14
|
-
s.
|
11
|
+
s.required_rubygems_version = Gem::Requirement.new(">= 0".freeze) if s.respond_to? :required_rubygems_version=
|
12
|
+
s.require_paths = ["lib".freeze]
|
13
|
+
s.authors = ["Scott Tadman".freeze]
|
14
|
+
s.date = "2021-02-17"
|
15
|
+
s.description = "Mostly drop-in replacement for Logger with a more robust log rotation facility".freeze
|
16
|
+
s.email = "github@tadman.ca".freeze
|
15
17
|
s.extra_rdoc_files = [
|
16
18
|
"LICENSE.txt",
|
17
19
|
"README.md"
|
18
20
|
]
|
19
21
|
s.files = [
|
20
22
|
".document",
|
23
|
+
".travis.yml",
|
21
24
|
"Gemfile",
|
22
25
|
"LICENSE.txt",
|
23
26
|
"README.md",
|
@@ -33,25 +36,23 @@ Gem::Specification.new do |s|
|
|
33
36
|
"test/test_birling_logger.rb",
|
34
37
|
"test/test_birling_support.rb"
|
35
38
|
]
|
36
|
-
s.homepage = "http://github.com/
|
37
|
-
s.licenses = ["MIT"]
|
38
|
-
s.
|
39
|
-
s.
|
40
|
-
s.summary = "Logger with simple log rotation system"
|
39
|
+
s.homepage = "http://github.com/postageapp/birling".freeze
|
40
|
+
s.licenses = ["MIT".freeze]
|
41
|
+
s.rubygems_version = "3.1.4".freeze
|
42
|
+
s.summary = "Logger with simple log rotation system".freeze
|
41
43
|
|
42
44
|
if s.respond_to? :specification_version then
|
43
|
-
s.specification_version =
|
45
|
+
s.specification_version = 4
|
46
|
+
end
|
44
47
|
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
s.add_dependency(%q<bundler>, [">= 0"])
|
50
|
-
s.add_dependency(%q<jeweler>, [">= 0"])
|
51
|
-
end
|
48
|
+
if s.respond_to? :add_runtime_dependency then
|
49
|
+
s.add_development_dependency(%q<bundler>.freeze, [">= 0"])
|
50
|
+
s.add_development_dependency(%q<test-unit>.freeze, [">= 0"])
|
51
|
+
s.add_development_dependency(%q<jeweler>.freeze, [">= 0"])
|
52
52
|
else
|
53
|
-
s.add_dependency(%q<bundler
|
54
|
-
s.add_dependency(%q<
|
53
|
+
s.add_dependency(%q<bundler>.freeze, [">= 0"])
|
54
|
+
s.add_dependency(%q<test-unit>.freeze, [">= 0"])
|
55
|
+
s.add_dependency(%q<jeweler>.freeze, [">= 0"])
|
55
56
|
end
|
56
57
|
end
|
57
58
|
|
data/lib/birling.rb
CHANGED
@@ -7,6 +7,15 @@ class Birling
|
|
7
7
|
|
8
8
|
# == Module Methods =======================================================
|
9
9
|
|
10
|
+
# Opens a new log file at the given path with options:
|
11
|
+
# * encoding: The encoding of the file (default: 'UTF8')
|
12
|
+
# * period: The rotation period to use (optional)
|
13
|
+
# * retain_count: How many log files to retain when rotating (optional)
|
14
|
+
# * retain_period: How long rotated log files are retained for (optional)
|
15
|
+
# * formatter: Custom log formatter (optional)
|
16
|
+
# * program: Name of program being logged (optional)
|
17
|
+
# * time_source: Source of time to use (optional)
|
18
|
+
# * path_format: The strftime-compatible format for the path (optional)
|
10
19
|
def self.open(path, options = nil)
|
11
20
|
Birling::Logger.new(path, options)
|
12
21
|
end
|
data/lib/birling/formatter.rb
CHANGED
@@ -1,3 +1,5 @@
|
|
1
|
+
require 'time'
|
2
|
+
|
1
3
|
module Birling::Formatter
|
2
4
|
# == Constants ============================================================
|
3
5
|
|
@@ -5,6 +7,12 @@ module Birling::Formatter
|
|
5
7
|
|
6
8
|
# == Module Methods =======================================================
|
7
9
|
|
10
|
+
# Default time formatter method.
|
11
|
+
def self.time_format(time)
|
12
|
+
(time || Time.now).strftime(TIME_FORMAT_DEFAULT)
|
13
|
+
end
|
14
|
+
|
15
|
+
# Implementation for a plug-in Logger formatter.
|
8
16
|
def self.call(severity, time, program, message)
|
9
17
|
if (program)
|
10
18
|
"[#{time.strftime(TIME_FORMAT_DEFAULT)}] <#{program}> #{message}\n"
|
data/lib/birling/logger.rb
CHANGED
@@ -1,29 +1,29 @@
|
|
1
1
|
class Birling::Logger
|
2
2
|
# == Constants ============================================================
|
3
|
-
|
3
|
+
|
4
4
|
# These level constants are the same as the syslog system utility
|
5
5
|
SEVERITY = {
|
6
|
-
:
|
7
|
-
:
|
8
|
-
:
|
9
|
-
:
|
10
|
-
:
|
11
|
-
:
|
12
|
-
:
|
13
|
-
:
|
14
|
-
:
|
6
|
+
emergency: EMERGENCY = 0,
|
7
|
+
alert: ALERT = 1,
|
8
|
+
critical: CRITICAL = 2,
|
9
|
+
error: ERROR = 3,
|
10
|
+
warning: WARNING = 4,
|
11
|
+
notice: NOTICE = 5,
|
12
|
+
info: INFO = 6,
|
13
|
+
debug: DEBUG = 7,
|
14
|
+
unknown: UNKNOWN = 999
|
15
15
|
}.freeze
|
16
|
-
|
16
|
+
|
17
17
|
DEFAULT_SEVERITY = UNKNOWN
|
18
18
|
|
19
19
|
SEVERITY_LABEL = SEVERITY.invert.freeze
|
20
|
-
|
20
|
+
|
21
21
|
PATH_TIME_DEFAULT = {
|
22
|
-
:
|
23
|
-
:
|
24
|
-
:
|
22
|
+
hourly: '%Y%m%d%H'.freeze,
|
23
|
+
daily: '%Y%m%d'.freeze,
|
24
|
+
default: '%s'.freeze
|
25
25
|
}.freeze
|
26
|
-
|
26
|
+
|
27
27
|
# == Properties ===========================================================
|
28
28
|
|
29
29
|
attr_reader :severity
|
@@ -38,25 +38,27 @@ class Birling::Logger
|
|
38
38
|
attr_reader :retain_period
|
39
39
|
attr_reader :period
|
40
40
|
attr_reader :rotation_time
|
41
|
-
|
41
|
+
|
42
42
|
# == Class Methods ========================================================
|
43
|
-
|
43
|
+
|
44
44
|
def self.severity(value)
|
45
45
|
case (value)
|
46
46
|
when Symbol
|
47
47
|
SEVERITY[value] or DEFAULT_SEVERITY
|
48
48
|
when String
|
49
49
|
SEVERITY[value.to_sym] or DEFAULT_SEVERITY
|
50
|
-
when
|
50
|
+
when Integer
|
51
51
|
SEVERITY_LABEL[value] and value or DEFAULT_SEVERITY
|
52
52
|
else
|
53
53
|
DEFAULT_SEVERITY
|
54
54
|
end
|
55
55
|
end
|
56
|
-
|
56
|
+
|
57
57
|
# == Instance Methods =====================================================
|
58
58
|
|
59
|
+
# Use Birling.open(...) to create new instances.
|
59
60
|
def initialize(log, options = nil)
|
61
|
+
@encoding = (options and options[:encoding])
|
60
62
|
@period = (options and options[:period])
|
61
63
|
@severity = self.class.severity(options && options[:severity])
|
62
64
|
@retain_count = (options and options[:retain_count])
|
@@ -66,85 +68,128 @@ class Birling::Logger
|
|
66
68
|
@time_source = (options and options[:time_source] or Time)
|
67
69
|
@path_format = (options and options[:path_format])
|
68
70
|
|
71
|
+
@file_open_options = { }
|
72
|
+
|
73
|
+
@rotation_time = nil
|
74
|
+
@path = nil
|
75
|
+
@log = nil
|
76
|
+
|
77
|
+
if (@encoding)
|
78
|
+
@file_open_options[:encoding] = @encoding
|
79
|
+
end
|
80
|
+
|
69
81
|
case (log)
|
70
82
|
when IO, StringIO
|
71
83
|
@log = log
|
72
84
|
when String
|
73
85
|
@path = log
|
74
86
|
end
|
75
|
-
|
87
|
+
|
76
88
|
if (@path and @period)
|
77
89
|
@rotation_time = self.next_rotation_time
|
78
|
-
|
90
|
+
|
79
91
|
@path_time_format = (PATH_TIME_DEFAULT[@period] or PATH_TIME_DEFAULT[:default])
|
80
|
-
|
92
|
+
|
81
93
|
@path_format ||=
|
82
94
|
@path.sub(/\.(\w+)$/) do |s|
|
83
95
|
'.' + @path_time_format + '.' + $1
|
84
96
|
end
|
85
97
|
end
|
86
|
-
|
98
|
+
|
87
99
|
if (@path and !@log)
|
88
100
|
self.log_open!
|
89
101
|
end
|
90
|
-
|
102
|
+
|
91
103
|
yield(self) if (block_given?)
|
92
104
|
end
|
93
|
-
|
105
|
+
|
106
|
+
# Sets the severity filter for logging. Any messages with a lower severity
|
107
|
+
# will be ignored. Any invalid severity options will reset the severity
|
108
|
+
# filter to defaults.
|
94
109
|
def severity=(value)
|
95
110
|
@severity = self.class.severity(value)
|
96
111
|
end
|
97
|
-
|
112
|
+
|
113
|
+
# Returns true if the log can be rotated, false otherwise.
|
98
114
|
def can_rotate?
|
99
115
|
!!@path
|
100
116
|
end
|
101
|
-
|
102
|
-
|
103
|
-
|
104
|
-
|
105
|
-
|
117
|
+
|
118
|
+
# Sets the retention interval for log files. Value should respond to to_i
|
119
|
+
# and yield an integer value that's a positive number of seconds between
|
120
|
+
# rotation operations.
|
106
121
|
def retain=(value)
|
107
122
|
@retain = value ? value.to_i : nil
|
108
|
-
|
123
|
+
|
109
124
|
if (@retain_period and @retain_period <= 0)
|
110
125
|
@retain_period = nil
|
111
126
|
end
|
112
|
-
|
127
|
+
|
113
128
|
@retain_period
|
114
129
|
end
|
115
|
-
|
130
|
+
|
131
|
+
# An IO compatible method for writing a message to the file. Only non-empty
|
132
|
+
# messages are actually logged.
|
133
|
+
def write(message)
|
134
|
+
return unless (message.match(/\S/))
|
135
|
+
|
136
|
+
self.log(:debug, message.chomp)
|
137
|
+
end
|
138
|
+
|
139
|
+
def sync=(sync)
|
140
|
+
# Auto-sync is always turned on, so this operation is ignored.
|
141
|
+
end
|
142
|
+
|
143
|
+
def flush
|
144
|
+
# Auto-sync is always turned on, so this operation is ignored.
|
145
|
+
end
|
146
|
+
|
147
|
+
# Log the message for the (optional) program at the given log level. No
|
148
|
+
# data will be written if the current log level is not sufficiently high.
|
116
149
|
def log(level, message = nil, program = nil)
|
117
150
|
return unless (@log)
|
118
|
-
|
151
|
+
|
119
152
|
level = self.class.severity(level)
|
120
153
|
program ||= @program
|
121
154
|
|
122
155
|
self.check_log_rotation!
|
123
|
-
|
156
|
+
|
124
157
|
@log.write(@formatter.call(level, @time_source.now, program, message))
|
125
158
|
end
|
126
159
|
alias_method :add, :log
|
127
160
|
|
161
|
+
def puts(*args)
|
162
|
+
args.each do |arg|
|
163
|
+
self.log(:debug, arg)
|
164
|
+
end
|
165
|
+
end
|
166
|
+
|
167
|
+
# Writes to the log file regardless of log level.
|
128
168
|
def <<(message)
|
129
169
|
return unless (@log)
|
130
|
-
|
170
|
+
|
131
171
|
self.check_log_rotation!
|
132
|
-
|
172
|
+
|
133
173
|
@log.write(message)
|
134
174
|
end
|
135
|
-
|
175
|
+
|
176
|
+
# Each of the severity levels has an associated method name. For example:
|
177
|
+
# * debug? - Returns true if the logging level is at least debug, false
|
178
|
+
# otherwise.
|
179
|
+
# * debug(message, program = nil) - Used to log a message with an optional
|
180
|
+
# program name.
|
136
181
|
SEVERITY.each do |name, level|
|
137
182
|
define_method(:"#{name}?") do
|
138
183
|
@severity >= level
|
139
184
|
end
|
140
|
-
|
141
|
-
define_method(name) do |message = nil, program = nil|
|
185
|
+
|
186
|
+
define_method(name) do |message = nil, program = nil, &block|
|
142
187
|
return unless (@log and @severity >= level)
|
143
|
-
|
188
|
+
|
144
189
|
program ||= @program
|
145
|
-
|
190
|
+
|
146
191
|
if (!message and block_given?)
|
147
|
-
message =
|
192
|
+
message = block.call
|
148
193
|
end
|
149
194
|
|
150
195
|
self.check_log_rotation!
|
@@ -153,37 +198,43 @@ class Birling::Logger
|
|
153
198
|
end
|
154
199
|
end
|
155
200
|
|
201
|
+
# Closes the log.
|
156
202
|
def close
|
157
203
|
return unless (@log)
|
158
|
-
|
204
|
+
|
159
205
|
@log.close
|
160
206
|
@log = nil
|
161
207
|
end
|
162
|
-
|
208
|
+
|
209
|
+
# Returns true if the log is opened, false otherwise.
|
163
210
|
def opened?
|
164
211
|
!!@log
|
165
212
|
end
|
166
213
|
|
214
|
+
# Returns true if the log is closed, false otherwise.
|
167
215
|
def closed?
|
168
216
|
!@log
|
169
217
|
end
|
170
218
|
|
219
|
+
# Returns the creation time of the log if opened, nil otherwise.
|
171
220
|
def create_time
|
172
221
|
@log and @log.ctime
|
173
222
|
end
|
174
|
-
|
223
|
+
|
224
|
+
# Returns size of the log if opened, nil otherwise.
|
175
225
|
def size
|
176
226
|
@log and @log.size
|
177
227
|
end
|
178
|
-
|
228
|
+
|
229
|
+
# Returns the age of the log file in seconds if opened, nil otherwise.
|
179
230
|
def age(relative_to = nil)
|
180
|
-
(relative_to || @time_source.now) - @log.ctime
|
231
|
+
@log and (relative_to || @time_source.now) - @log.ctime
|
181
232
|
end
|
182
|
-
|
233
|
+
|
183
234
|
protected
|
184
235
|
def next_rotation_time
|
185
236
|
case (@period)
|
186
|
-
when
|
237
|
+
when Integer, Float
|
187
238
|
@time_source.now + @period
|
188
239
|
when :daily
|
189
240
|
Birling::Support.next_day(@time_source.now)
|
@@ -193,21 +244,21 @@ protected
|
|
193
244
|
nil
|
194
245
|
end
|
195
246
|
end
|
196
|
-
|
247
|
+
|
197
248
|
def prune_logs!
|
198
249
|
return unless (@path and (@retain_period or @retain_count))
|
199
|
-
|
250
|
+
|
200
251
|
log_spec = @path.sub(/\.(\w+)$/, '*')
|
201
|
-
|
252
|
+
|
202
253
|
logs = (Dir.glob(log_spec) - [ @path ]).collect do |p|
|
203
254
|
stat = File.stat(p)
|
204
255
|
create_time = (stat and stat.ctime or @time_source.now)
|
205
|
-
|
256
|
+
|
206
257
|
[ p, create_time ]
|
207
258
|
end.sort_by do |r|
|
208
259
|
r[1] || @time_source.now
|
209
260
|
end
|
210
|
-
|
261
|
+
|
211
262
|
if (@retain_period)
|
212
263
|
logs.reject! do |r|
|
213
264
|
if (Time.now - r[1] > @retain_period)
|
@@ -215,23 +266,23 @@ protected
|
|
215
266
|
end
|
216
267
|
end
|
217
268
|
end
|
218
|
-
|
269
|
+
|
219
270
|
if (@retain_count)
|
220
271
|
# The logs array is sorted from oldest to newest, so retaining the N
|
221
272
|
# newest entries entails stripping them off the end with pop.
|
222
273
|
|
223
274
|
logs.pop(@retain_count)
|
224
|
-
|
275
|
+
|
225
276
|
FileUtils.rm_f(logs.collect { |r| r[0] })
|
226
277
|
end
|
227
278
|
end
|
228
|
-
|
279
|
+
|
229
280
|
def check_log_rotation!
|
230
281
|
return unless (@rotation_time)
|
231
|
-
|
282
|
+
|
232
283
|
if (@time_source.now >= @rotation_time)
|
233
284
|
self.log_open!
|
234
|
-
|
285
|
+
|
235
286
|
@rotation_time = self.next_rotation_time
|
236
287
|
end
|
237
288
|
end
|
@@ -239,23 +290,25 @@ protected
|
|
239
290
|
def log_open!
|
240
291
|
if (@path_format)
|
241
292
|
@current_path = @time_source.now.strftime(@path_format)
|
242
|
-
|
243
|
-
@log = File.open(@current_path, 'a')
|
293
|
+
|
294
|
+
@log = File.open(@current_path, 'a', **@file_open_options)
|
244
295
|
@log.sync = true
|
245
|
-
|
246
|
-
if (File.
|
296
|
+
|
297
|
+
if (File.symlink?(@path))
|
247
298
|
File.unlink(@path)
|
248
299
|
end
|
249
300
|
|
250
301
|
unless (File.exist?(@path))
|
251
302
|
File.symlink(@current_path, @path)
|
252
303
|
end
|
253
|
-
|
304
|
+
|
254
305
|
self.prune_logs!
|
255
306
|
else
|
256
307
|
@current_path = @path
|
257
|
-
|
258
|
-
@log = File.open(@current_path, 'a')
|
308
|
+
|
309
|
+
@log = File.open(@current_path, 'a', **@file_open_options)
|
310
|
+
|
311
|
+
@log.sync = true
|
259
312
|
end
|
260
313
|
end
|
261
314
|
end
|
data/lib/birling/support.rb
CHANGED
@@ -1,4 +1,7 @@
|
|
1
1
|
module Birling::Support
|
2
|
+
# == Module + Mixin Methods ===============================================
|
3
|
+
|
4
|
+
# Computes the beginning of the next day.
|
2
5
|
def next_day(time, time_source = nil)
|
3
6
|
(time_source || Time).local(
|
4
7
|
time.year,
|
@@ -10,6 +13,7 @@ module Birling::Support
|
|
10
13
|
) + 1
|
11
14
|
end
|
12
15
|
|
16
|
+
# Computes the beginning of the next hour.
|
13
17
|
def next_hour(time, time_source = nil)
|
14
18
|
seconds_left = time.to_i % 3600
|
15
19
|
|
data/test/helper.rb
CHANGED
@@ -54,9 +54,9 @@ class Test::Unit::TestCase
|
|
54
54
|
name = "#{name}.log"
|
55
55
|
end
|
56
56
|
|
57
|
-
|
57
|
+
temp_path ||= File.expand_path('../tmp', File.dirname(__FILE__))
|
58
58
|
|
59
|
-
full_path = File.expand_path(name,
|
59
|
+
full_path = File.expand_path(name, temp_path)
|
60
60
|
|
61
61
|
FileUtils::mkdir_p(File.dirname(full_path))
|
62
62
|
|
@@ -64,7 +64,7 @@ class Test::Unit::TestCase
|
|
64
64
|
begin
|
65
65
|
yield(full_path)
|
66
66
|
ensure
|
67
|
-
remove_spec = File.expand_path('*',
|
67
|
+
remove_spec = File.expand_path('*', temp_path)
|
68
68
|
|
69
69
|
FileUtils.rm_f(Dir.glob(remove_spec))
|
70
70
|
end
|
data/test/test_birling.rb
CHANGED
@@ -35,17 +35,4 @@ class TestBirling < Test::Unit::TestCase
|
|
35
35
|
|
36
36
|
assert !File.exist?(_path)
|
37
37
|
end
|
38
|
-
|
39
|
-
def test_time_warped
|
40
|
-
_now = Time.now
|
41
|
-
|
42
|
-
Time::Warped.now = _now
|
43
|
-
|
44
|
-
assert_not_equal Time.now, Time.now
|
45
|
-
assert_equal _now, Time::Warped.now
|
46
|
-
|
47
|
-
Time::Warped.now = nil
|
48
|
-
|
49
|
-
assert_not_equal _now, Time::Warped.now
|
50
|
-
end
|
51
38
|
end
|
data/test/test_birling_logger.rb
CHANGED
@@ -1,47 +1,77 @@
|
|
1
|
-
require File.expand_path('helper',
|
1
|
+
require File.expand_path('helper', __dir__)
|
2
|
+
require 'stringio'
|
2
3
|
|
3
4
|
class TestBirlingLogger < Test::Unit::TestCase
|
4
5
|
def test_defaults
|
5
6
|
temp_path do |path|
|
6
7
|
log = Birling::Logger.new(path)
|
7
|
-
|
8
|
+
|
8
9
|
assert log
|
9
10
|
|
10
11
|
assert log.opened?
|
11
12
|
assert !log.closed?
|
12
13
|
assert_equal 0, log.size
|
13
14
|
assert Time.now >= log.create_time
|
14
|
-
|
15
|
+
|
15
16
|
assert_equal Birling::Formatter, log.formatter
|
16
17
|
assert_equal Time, log.time_source
|
17
18
|
assert_equal nil, log.period
|
18
19
|
end
|
19
20
|
end
|
20
|
-
|
21
|
+
|
21
22
|
def test_with_handle
|
22
23
|
s = StringIO.new
|
23
|
-
|
24
|
+
|
24
25
|
log = Birling::Logger.new(s)
|
25
|
-
|
26
|
+
|
26
27
|
assert log.opened?
|
27
|
-
|
28
|
+
|
28
29
|
assert_equal 0, log.size
|
29
30
|
end
|
30
|
-
|
31
|
+
|
32
|
+
def test_io_compatible
|
33
|
+
stdout = $stdout
|
34
|
+
|
35
|
+
buffer = StringIO.new
|
36
|
+
|
37
|
+
log = Birling::Logger.new(buffer, time_source: Time::Warped)
|
38
|
+
|
39
|
+
assert log.opened?
|
40
|
+
|
41
|
+
assert_equal 0, log.size
|
42
|
+
|
43
|
+
$stdout = log
|
44
|
+
|
45
|
+
start = Time.parse('2017-10-10 12:00:00')
|
46
|
+
|
47
|
+
Time::Warped.now = start
|
48
|
+
|
49
|
+
puts "Test"
|
50
|
+
|
51
|
+
log.close
|
52
|
+
|
53
|
+
expected = "[2017-10-10 12:00:00] Test\n"
|
54
|
+
|
55
|
+
assert_equal expected, buffer.string.to_s
|
56
|
+
|
57
|
+
ensure
|
58
|
+
$stdout = stdout
|
59
|
+
end
|
60
|
+
|
31
61
|
def test_formatter
|
32
62
|
formatter_called = false
|
33
63
|
formatter = lambda do |severity, time, program, message|
|
34
64
|
formatter_called = true
|
35
65
|
message
|
36
66
|
end
|
37
|
-
|
67
|
+
|
38
68
|
output = StringIO.new
|
39
|
-
log = Birling::Logger.new(output, :
|
40
|
-
|
69
|
+
log = Birling::Logger.new(output, formatter: formatter)
|
70
|
+
|
41
71
|
log.debug("Test")
|
42
|
-
|
72
|
+
|
43
73
|
assert_equal true, formatter_called
|
44
|
-
|
74
|
+
|
45
75
|
output.rewind
|
46
76
|
assert_equal "Test", output.read
|
47
77
|
end
|
@@ -49,45 +79,44 @@ class TestBirlingLogger < Test::Unit::TestCase
|
|
49
79
|
def test_default_level
|
50
80
|
temp_path do |path|
|
51
81
|
log = Birling::Logger.new(path)
|
52
|
-
|
82
|
+
|
53
83
|
assert log
|
54
84
|
|
55
85
|
assert log.opened?
|
56
86
|
assert !log.closed?
|
57
87
|
assert_equal 0, log.size
|
58
|
-
|
88
|
+
|
59
89
|
assert log.debug?
|
60
90
|
|
61
91
|
log.debug("Test")
|
62
|
-
|
92
|
+
|
63
93
|
current_size = log.size
|
64
94
|
assert current_size > 0
|
65
95
|
end
|
66
96
|
end
|
67
|
-
|
97
|
+
|
68
98
|
def test_direct_write
|
69
99
|
output = StringIO.new
|
70
|
-
|
100
|
+
|
71
101
|
log = Birling::Logger.new(output)
|
72
|
-
|
102
|
+
|
73
103
|
log << "TEST"
|
74
|
-
|
75
|
-
output.
|
76
|
-
assert_equal "TEST", output.read
|
104
|
+
|
105
|
+
assert_equal "TEST", output.string
|
77
106
|
end
|
78
|
-
|
107
|
+
|
79
108
|
def test_level_filter
|
80
109
|
output = StringIO.new
|
81
|
-
|
110
|
+
|
82
111
|
log = Birling::Logger.new(
|
83
112
|
output,
|
84
|
-
:
|
85
|
-
:
|
113
|
+
formatter: lambda { |s, t, p, m| "#{m}\n" },
|
114
|
+
severity: :info
|
86
115
|
)
|
87
|
-
|
116
|
+
|
88
117
|
log.debug("DEBUG")
|
89
118
|
log.info("INFO")
|
90
|
-
|
119
|
+
|
91
120
|
output.rewind
|
92
121
|
assert_equal "INFO\n", output.read
|
93
122
|
end
|
@@ -99,98 +128,100 @@ class TestBirlingLogger < Test::Unit::TestCase
|
|
99
128
|
assert log.debug?
|
100
129
|
|
101
130
|
log.debug("Test")
|
102
|
-
|
131
|
+
|
103
132
|
current_size = log.size
|
104
133
|
assert current_size > 0
|
105
|
-
|
134
|
+
|
106
135
|
create_time = log.create_time
|
107
136
|
assert create_time <= Time.now
|
108
|
-
|
137
|
+
|
109
138
|
log.close
|
110
|
-
|
139
|
+
|
111
140
|
log = Birling::Logger.new(path)
|
112
|
-
|
141
|
+
|
113
142
|
assert_equal current_size, log.size
|
114
143
|
assert_equal create_time, log.create_time
|
115
144
|
end
|
116
145
|
end
|
117
|
-
|
146
|
+
|
118
147
|
def test_time_source
|
119
148
|
temp_path do |path|
|
120
149
|
frozen_time = Time.now
|
121
150
|
Time::Warped.now = frozen_time
|
122
|
-
|
123
|
-
logger = Birling::Logger.new(path, :
|
124
|
-
|
151
|
+
|
152
|
+
logger = Birling::Logger.new(path, time_source: Time::Warped)
|
153
|
+
|
125
154
|
assert_equal frozen_time, logger.time_source.now
|
126
155
|
end
|
127
156
|
end
|
128
|
-
|
157
|
+
|
129
158
|
def test_cycling
|
130
159
|
temp_path(:cycle) do |path|
|
131
160
|
start = Time.now
|
132
161
|
Time::Warped.now = start
|
133
|
-
logger = Birling::Logger.new(path, :
|
134
|
-
|
162
|
+
logger = Birling::Logger.new(path, period: 1, time_source: Time::Warped)
|
163
|
+
|
135
164
|
assert_equal 1, logger.period
|
136
|
-
|
165
|
+
|
137
166
|
current_path = logger.current_path
|
138
167
|
assert_equal '%s', logger.path_time_format
|
139
|
-
|
168
|
+
|
140
169
|
logger.debug("Test")
|
141
|
-
|
170
|
+
|
142
171
|
Time::Warped.now += 1
|
143
|
-
|
172
|
+
|
144
173
|
logger.debug("Test")
|
145
174
|
|
146
175
|
assert_not_equal current_path, logger.current_path
|
147
|
-
|
176
|
+
|
148
177
|
current_path = logger.current_path
|
149
178
|
|
150
179
|
Time::Warped.now += 1
|
151
|
-
|
180
|
+
|
152
181
|
logger.debug("Test")
|
153
|
-
|
182
|
+
|
154
183
|
assert_not_equal current_path, logger.current_path
|
155
184
|
end
|
156
185
|
end
|
157
|
-
|
186
|
+
|
158
187
|
def test_retain_count
|
159
188
|
temp_path(:cycle) do |path|
|
160
189
|
start = Time.now
|
161
190
|
Time::Warped.now = start
|
162
|
-
|
191
|
+
|
163
192
|
retain_count = 10
|
164
193
|
|
165
194
|
logger = Birling::Logger.new(
|
166
195
|
path,
|
167
|
-
:
|
168
|
-
:
|
169
|
-
:
|
196
|
+
period: 1,
|
197
|
+
time_source: Time::Warped,
|
198
|
+
retain_count: retain_count
|
170
199
|
)
|
171
200
|
|
172
201
|
(retain_count + 5).times do |n|
|
173
202
|
logger.debug("Test")
|
203
|
+
|
174
204
|
Time::Warped.now += 1
|
205
|
+
|
175
206
|
logger.debug("Test")
|
176
207
|
end
|
177
|
-
|
208
|
+
|
178
209
|
assert_equal retain_count, Dir.glob(logger.path_format % '*').length
|
179
210
|
end
|
180
211
|
end
|
181
|
-
|
212
|
+
|
182
213
|
def test_default_formatter
|
183
214
|
temp_path(:cycle) do |path|
|
184
215
|
logger = Birling::Logger.new(path)
|
185
|
-
|
216
|
+
|
186
217
|
lines = 100
|
187
|
-
|
218
|
+
|
188
219
|
lines.times do
|
189
220
|
logger.debug("Test")
|
190
221
|
end
|
191
|
-
|
222
|
+
|
192
223
|
logger.close
|
193
|
-
|
224
|
+
|
194
225
|
assert_equal lines, File.readlines(path).length
|
195
226
|
end
|
196
227
|
end
|
@@ -198,13 +229,13 @@ class TestBirlingLogger < Test::Unit::TestCase
|
|
198
229
|
def test_retain_period
|
199
230
|
temp_path(:cycle) do |path|
|
200
231
|
retain_period = 3
|
201
|
-
|
232
|
+
|
202
233
|
logger = Birling::Logger.new(
|
203
234
|
path,
|
204
|
-
:
|
205
|
-
:
|
235
|
+
period: 1,
|
236
|
+
retain_period: retain_period
|
206
237
|
)
|
207
|
-
|
238
|
+
|
208
239
|
assert_equal true, File.exist?(path)
|
209
240
|
assert_equal true, File.symlink?(path)
|
210
241
|
|
@@ -215,8 +246,18 @@ class TestBirlingLogger < Test::Unit::TestCase
|
|
215
246
|
Time::Warped.now += 1
|
216
247
|
logger.debug("Test")
|
217
248
|
end
|
218
|
-
|
249
|
+
|
219
250
|
assert_equal retain_period + 1, Dir.glob(logger.path_format % '*').length
|
220
251
|
end
|
221
252
|
end
|
253
|
+
|
254
|
+
def test_irregular_utf8_data
|
255
|
+
temp_path(:cycle) do |path|
|
256
|
+
logger = Birling::Logger.new(path, encoding: 'BINARY')
|
257
|
+
|
258
|
+
invalid = (0..255).to_a.pack('C*')
|
259
|
+
|
260
|
+
logger.debug(invalid)
|
261
|
+
end
|
262
|
+
end
|
222
263
|
end
|
@@ -4,6 +4,8 @@ class TestBirlingSupport < Test::Unit::TestCase
|
|
4
4
|
def test_next_day_on_dst_flip
|
5
5
|
in_time_zone('EST5EDT') do
|
6
6
|
time = Time.new(2012, 11, 4)
|
7
|
+
|
8
|
+
assert_equal 'EDT', time.zone
|
7
9
|
|
8
10
|
assert_equal time.day, (time + 86400).day
|
9
11
|
|
@@ -21,6 +23,8 @@ class TestBirlingSupport < Test::Unit::TestCase
|
|
21
23
|
def test_hour_day_on_dst_flip
|
22
24
|
in_time_zone('EST5EDT') do
|
23
25
|
time = Time.new(2012, 11, 4, 0, 59, 59) + 1
|
26
|
+
|
27
|
+
assert_equal 'EDT', time.zone
|
24
28
|
|
25
29
|
assert_equal time.hour, (time + 3600).hour
|
26
30
|
|
@@ -40,6 +44,8 @@ class TestBirlingSupport < Test::Unit::TestCase
|
|
40
44
|
def test_next_day_at_year_end
|
41
45
|
in_time_zone('EST5EDT') do
|
42
46
|
time = Time.new(2012, 12, 31)
|
47
|
+
|
48
|
+
assert_equal 'EST', time.zone
|
43
49
|
|
44
50
|
next_day = Birling::Support.next_day(time)
|
45
51
|
|
metadata
CHANGED
@@ -1,46 +1,55 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: birling
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
5
|
-
prerelease:
|
4
|
+
version: 0.3.0
|
6
5
|
platform: ruby
|
7
6
|
authors:
|
8
7
|
- Scott Tadman
|
9
|
-
autorequire:
|
8
|
+
autorequire:
|
10
9
|
bindir: bin
|
11
10
|
cert_chain: []
|
12
|
-
date:
|
11
|
+
date: 2021-02-17 00:00:00.000000000 Z
|
13
12
|
dependencies:
|
14
13
|
- !ruby/object:Gem::Dependency
|
15
14
|
name: bundler
|
16
15
|
requirement: !ruby/object:Gem::Requirement
|
17
|
-
none: false
|
18
16
|
requirements:
|
19
|
-
- -
|
17
|
+
- - ">="
|
20
18
|
- !ruby/object:Gem::Version
|
21
19
|
version: '0'
|
22
20
|
type: :development
|
23
21
|
prerelease: false
|
24
22
|
version_requirements: !ruby/object:Gem::Requirement
|
25
|
-
none: false
|
26
23
|
requirements:
|
27
|
-
- -
|
24
|
+
- - ">="
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: '0'
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: test-unit
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - ">="
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: '0'
|
34
|
+
type: :development
|
35
|
+
prerelease: false
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - ">="
|
28
39
|
- !ruby/object:Gem::Version
|
29
40
|
version: '0'
|
30
41
|
- !ruby/object:Gem::Dependency
|
31
42
|
name: jeweler
|
32
43
|
requirement: !ruby/object:Gem::Requirement
|
33
|
-
none: false
|
34
44
|
requirements:
|
35
|
-
- -
|
45
|
+
- - ">="
|
36
46
|
- !ruby/object:Gem::Version
|
37
47
|
version: '0'
|
38
48
|
type: :development
|
39
49
|
prerelease: false
|
40
50
|
version_requirements: !ruby/object:Gem::Requirement
|
41
|
-
none: false
|
42
51
|
requirements:
|
43
|
-
- -
|
52
|
+
- - ">="
|
44
53
|
- !ruby/object:Gem::Version
|
45
54
|
version: '0'
|
46
55
|
description: Mostly drop-in replacement for Logger with a more robust log rotation
|
@@ -52,7 +61,8 @@ extra_rdoc_files:
|
|
52
61
|
- LICENSE.txt
|
53
62
|
- README.md
|
54
63
|
files:
|
55
|
-
- .document
|
64
|
+
- ".document"
|
65
|
+
- ".travis.yml"
|
56
66
|
- Gemfile
|
57
67
|
- LICENSE.txt
|
58
68
|
- README.md
|
@@ -67,29 +77,27 @@ files:
|
|
67
77
|
- test/test_birling.rb
|
68
78
|
- test/test_birling_logger.rb
|
69
79
|
- test/test_birling_support.rb
|
70
|
-
homepage: http://github.com/
|
80
|
+
homepage: http://github.com/postageapp/birling
|
71
81
|
licenses:
|
72
82
|
- MIT
|
73
|
-
|
83
|
+
metadata: {}
|
84
|
+
post_install_message:
|
74
85
|
rdoc_options: []
|
75
86
|
require_paths:
|
76
87
|
- lib
|
77
88
|
required_ruby_version: !ruby/object:Gem::Requirement
|
78
|
-
none: false
|
79
89
|
requirements:
|
80
|
-
- -
|
90
|
+
- - ">="
|
81
91
|
- !ruby/object:Gem::Version
|
82
92
|
version: '0'
|
83
93
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
84
|
-
none: false
|
85
94
|
requirements:
|
86
|
-
- -
|
95
|
+
- - ">="
|
87
96
|
- !ruby/object:Gem::Version
|
88
97
|
version: '0'
|
89
98
|
requirements: []
|
90
|
-
|
91
|
-
|
92
|
-
|
93
|
-
specification_version: 3
|
99
|
+
rubygems_version: 3.1.4
|
100
|
+
signing_key:
|
101
|
+
specification_version: 4
|
94
102
|
summary: Logger with simple log rotation system
|
95
103
|
test_files: []
|