chrono_logger 0.0.2 → 0.0.3
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 +4 -4
- data/.travis.yml +4 -0
- data/README.md +6 -0
- data/chrono_logger.gemspec +5 -0
- data/lib/chrono_logger.rb +45 -15
- data/lib/chrono_logger/version.rb +1 -1
- data/test/from_ruby_repo/test_logdevice.rb +0 -24
- data/test/from_ruby_repo/test_logger.rb +7 -6
- data/test/helper.rb +3 -0
- data/test/test_chrono_logger.rb +59 -0
- metadata +44 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 088ff7e10a40407ed7bb375eb699a92f50c5d1ec
|
4
|
+
data.tar.gz: 4c24284de175508bd2b3d2966701c211929fefb5
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 8b1840ba67d2002c388a1cf76d2a5b4c20d42fc2fb759f7b972bacd26b9fbba4e8008ea2bb83cee1d6939e5d704d2bbd37e2988b7b48cea43fce2e775bf6b137
|
7
|
+
data.tar.gz: b51831122c18dddd0eaa2c26ea1454568f3d5830c3add968dc359281c016f6b4963d9284bdacaa57dd1fb21fd786ebd74f35f25f58e761592701f3fbe6f04aaa
|
data/.travis.yml
CHANGED
data/README.md
CHANGED
@@ -1,5 +1,11 @@
|
|
1
1
|
# ChronoLogger
|
2
2
|
|
3
|
+
[](http://badge.fury.io/rb/chrono_logger)
|
4
|
+
[](https://travis-ci.org/ma2gedev/chrono_logger)
|
5
|
+
[](https://codeclimate.com/github/ma2gedev/chrono_logger)
|
6
|
+
[](https://coveralls.io/r/ma2gedev/chrono_logger)
|
7
|
+
[](https://coderwall.com/ma2gedev)
|
8
|
+
|
3
9
|
A lock-free logger with timebased file rotation.
|
4
10
|
|
5
11
|
## Installation
|
data/chrono_logger.gemspec
CHANGED
@@ -24,4 +24,9 @@ Gem::Specification.new do |spec|
|
|
24
24
|
spec.add_development_dependency "pry"
|
25
25
|
spec.add_development_dependency "delorean"
|
26
26
|
spec.add_development_dependency "parallel"
|
27
|
+
spec.add_development_dependency "coveralls"
|
28
|
+
|
29
|
+
# for performance check
|
30
|
+
spec.add_development_dependency "mono_logger"
|
31
|
+
spec.add_development_dependency "log4r"
|
27
32
|
end
|
data/lib/chrono_logger.rb
CHANGED
@@ -13,7 +13,31 @@ class ChronoLogger < Logger
|
|
13
13
|
end
|
14
14
|
end
|
15
15
|
|
16
|
+
module Period
|
17
|
+
DAILY = 1
|
18
|
+
|
19
|
+
SiD = 24 * 60 * 60
|
20
|
+
|
21
|
+
def determine_period(format)
|
22
|
+
case format
|
23
|
+
when /%d/ then DAILY
|
24
|
+
else nil
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
def next_start_period(now, period)
|
29
|
+
case period
|
30
|
+
when DAILY
|
31
|
+
Time.mktime(now.year, now.month, now.mday) + SiD
|
32
|
+
else
|
33
|
+
nil
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
16
38
|
class TimeBasedLogDevice < LogDevice
|
39
|
+
include Period
|
40
|
+
|
17
41
|
DELAY_SECOND_TO_CLOSE_FILE = 5
|
18
42
|
|
19
43
|
def initialize(log = nil, opt = {})
|
@@ -23,25 +47,20 @@ class ChronoLogger < Logger
|
|
23
47
|
@dev = log
|
24
48
|
else
|
25
49
|
@pattern = log
|
26
|
-
@
|
50
|
+
@period = determine_period(@pattern)
|
51
|
+
now = Time.now
|
52
|
+
@filename = now.strftime(@pattern)
|
53
|
+
@next_start_period = next_start_period(now, @period)
|
27
54
|
@dev = open_logfile(@filename)
|
28
55
|
@dev.sync = true
|
29
56
|
end
|
30
57
|
end
|
31
58
|
|
32
59
|
def write(message)
|
33
|
-
if @pattern
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
warn("log shifting failed. #{$!}")
|
38
|
-
end
|
39
|
-
end
|
40
|
-
begin
|
41
|
-
@dev.write(message)
|
42
|
-
rescue
|
43
|
-
warn("log writing failed. #{$!}")
|
44
|
-
end
|
60
|
+
check_shift_log if @pattern
|
61
|
+
@dev.write(message)
|
62
|
+
rescue
|
63
|
+
warn("log writing failed. #{$!}")
|
45
64
|
end
|
46
65
|
|
47
66
|
def close
|
@@ -71,10 +90,21 @@ class ChronoLogger < Logger
|
|
71
90
|
end
|
72
91
|
|
73
92
|
def check_shift_log
|
74
|
-
|
75
|
-
|
93
|
+
if next_period?(Time.now)
|
94
|
+
now = Time.now
|
95
|
+
new_filename = now.strftime(@pattern)
|
96
|
+
next_start_period = next_start_period(now, @period)
|
76
97
|
shift_log_period(new_filename)
|
77
98
|
@filename = new_filename
|
99
|
+
@next_start_period = next_start_period
|
100
|
+
end
|
101
|
+
end
|
102
|
+
|
103
|
+
def next_period?(now)
|
104
|
+
if @period
|
105
|
+
@next_start_period <= now
|
106
|
+
else
|
107
|
+
Time.now.strftime(@pattern) != @filename
|
78
108
|
end
|
79
109
|
end
|
80
110
|
|
@@ -98,30 +98,6 @@ class TestLogDevice < Test::Unit::TestCase
|
|
98
98
|
r.close
|
99
99
|
end
|
100
100
|
|
101
|
-
def test_shifting_age_in_multiprocess
|
102
|
-
old_log = [@tempfile.path, '20150122'].join
|
103
|
-
new_log = [@tempfile.path, '20150123'].join
|
104
|
-
$stderr, stderr = StringIO.new, $stderr
|
105
|
-
begin
|
106
|
-
Delorean.time_travel_to '2015-01-22 23:59:59'
|
107
|
-
logger = ChronoLogger.new(@format)
|
108
|
-
Parallel.map(['a', 'b'], :in_processes => 2) do |letter|
|
109
|
-
5000.times do
|
110
|
-
logger.info letter * 5000
|
111
|
-
end
|
112
|
-
end
|
113
|
-
assert_no_match(/log shifting failed/, $stderr.string)
|
114
|
-
assert_no_match(/log writing failed/, $stderr.string)
|
115
|
-
assert { File.exist?(old_log) }
|
116
|
-
assert { File.exist?(new_log) }
|
117
|
-
ensure
|
118
|
-
$stderr, stderr = stderr, $stderr
|
119
|
-
Delorean.back_to_the_present
|
120
|
-
File.unlink(old_log)
|
121
|
-
File.unlink(new_log)
|
122
|
-
end
|
123
|
-
end
|
124
|
-
|
125
101
|
def test_shifting_midnight
|
126
102
|
Dir.mktmpdir do |tmpdir|
|
127
103
|
log = "log20140102"
|
@@ -26,12 +26,13 @@ class TestLogger < Test::Unit::TestCase
|
|
26
26
|
end
|
27
27
|
|
28
28
|
def log_raw(logger, msg_id, *arg, &block)
|
29
|
-
Tempfile.
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
29
|
+
logdev = Tempfile.new(File.basename(__FILE__) + '.log')
|
30
|
+
logger.instance_eval { @logdev = ChronoLogger::TimeBasedLogDevice.new(logdev) }
|
31
|
+
logger.__send__(msg_id, *arg, &block)
|
32
|
+
logdev.open
|
33
|
+
msg = logdev.read
|
34
|
+
logdev.close(true)
|
35
|
+
msg
|
35
36
|
end
|
36
37
|
|
37
38
|
def test_level
|
data/test/helper.rb
CHANGED
data/test/test_chrono_logger.rb
CHANGED
@@ -1,7 +1,66 @@
|
|
1
1
|
require 'helper'
|
2
|
+
require 'tempfile'
|
3
|
+
require 'parallel'
|
4
|
+
require 'delorean'
|
2
5
|
|
3
6
|
class TestChronoLogger < Test::Unit::TestCase
|
7
|
+
def setup
|
8
|
+
@tempfile = Tempfile.new("logger")
|
9
|
+
@tempfile.close
|
10
|
+
@format = [@tempfile.path, '%Y%m%d'].join
|
11
|
+
@filename = Time.now.strftime(@format)
|
12
|
+
File.unlink(@tempfile.path)
|
13
|
+
end
|
14
|
+
|
15
|
+
def teardown
|
16
|
+
@tempfile.close(true)
|
17
|
+
end
|
18
|
+
|
4
19
|
def test_that_it_has_a_version_number
|
5
20
|
refute_nil ::ChronoLogger::VERSION
|
6
21
|
end
|
22
|
+
|
23
|
+
def test_shifting_age_in_multithreads
|
24
|
+
confirm_daily_rotation(in_threads: 2)
|
25
|
+
end
|
26
|
+
|
27
|
+
def test_shifting_age_in_multiprocess
|
28
|
+
confirm_daily_rotation(in_processes: 2)
|
29
|
+
end
|
30
|
+
|
31
|
+
private
|
32
|
+
|
33
|
+
def confirm_daily_rotation(option)
|
34
|
+
old_log = [@tempfile.path, '20150122'].join
|
35
|
+
new_log = [@tempfile.path, '20150123'].join
|
36
|
+
$stderr, stderr = StringIO.new, $stderr
|
37
|
+
begin
|
38
|
+
Delorean.time_travel_to '2015-01-22 23:59:59.990'
|
39
|
+
logger = ChronoLogger.new(@format)
|
40
|
+
old_logdev = logger.instance_variable_get('@logdev').dev
|
41
|
+
Parallel.map(['a', 'b'], option) do |letter|
|
42
|
+
5000.times do
|
43
|
+
logger.info letter * 5000
|
44
|
+
end
|
45
|
+
end
|
46
|
+
assert_no_match(/log shifting failed/, $stderr.string)
|
47
|
+
assert_no_match(/log writing failed/, $stderr.string)
|
48
|
+
assert { !old_logdev.closed? }
|
49
|
+
assert { File.exist?(old_log) }
|
50
|
+
assert { File.exist?(new_log) }
|
51
|
+
assert { File.read(old_log).count("\n") + File.read(new_log).count("\n") == 10000 }
|
52
|
+
|
53
|
+
sleep ChronoLogger::TimeBasedLogDevice::DELAY_SECOND_TO_CLOSE_FILE + 1
|
54
|
+
old_logdev.close if option[:in_processes]
|
55
|
+
assert { old_logdev.closed? } # TODO: check in multiprocess
|
56
|
+
assert { File.exist?(old_log) }
|
57
|
+
assert { File.exist?(new_log) }
|
58
|
+
assert { File.read(old_log).count("\n") + File.read(new_log).count("\n") == 10000 }
|
59
|
+
ensure
|
60
|
+
$stderr, stderr = stderr, $stderr
|
61
|
+
Delorean.back_to_the_present
|
62
|
+
File.unlink(old_log)
|
63
|
+
File.unlink(new_log)
|
64
|
+
end
|
65
|
+
end
|
7
66
|
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: chrono_logger
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0.
|
4
|
+
version: 0.0.3
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Takayuki Matsubara
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2015-01-
|
11
|
+
date: 2015-01-24 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: bundler
|
@@ -94,6 +94,48 @@ dependencies:
|
|
94
94
|
- - ">="
|
95
95
|
- !ruby/object:Gem::Version
|
96
96
|
version: '0'
|
97
|
+
- !ruby/object:Gem::Dependency
|
98
|
+
name: coveralls
|
99
|
+
requirement: !ruby/object:Gem::Requirement
|
100
|
+
requirements:
|
101
|
+
- - ">="
|
102
|
+
- !ruby/object:Gem::Version
|
103
|
+
version: '0'
|
104
|
+
type: :development
|
105
|
+
prerelease: false
|
106
|
+
version_requirements: !ruby/object:Gem::Requirement
|
107
|
+
requirements:
|
108
|
+
- - ">="
|
109
|
+
- !ruby/object:Gem::Version
|
110
|
+
version: '0'
|
111
|
+
- !ruby/object:Gem::Dependency
|
112
|
+
name: mono_logger
|
113
|
+
requirement: !ruby/object:Gem::Requirement
|
114
|
+
requirements:
|
115
|
+
- - ">="
|
116
|
+
- !ruby/object:Gem::Version
|
117
|
+
version: '0'
|
118
|
+
type: :development
|
119
|
+
prerelease: false
|
120
|
+
version_requirements: !ruby/object:Gem::Requirement
|
121
|
+
requirements:
|
122
|
+
- - ">="
|
123
|
+
- !ruby/object:Gem::Version
|
124
|
+
version: '0'
|
125
|
+
- !ruby/object:Gem::Dependency
|
126
|
+
name: log4r
|
127
|
+
requirement: !ruby/object:Gem::Requirement
|
128
|
+
requirements:
|
129
|
+
- - ">="
|
130
|
+
- !ruby/object:Gem::Version
|
131
|
+
version: '0'
|
132
|
+
type: :development
|
133
|
+
prerelease: false
|
134
|
+
version_requirements: !ruby/object:Gem::Requirement
|
135
|
+
requirements:
|
136
|
+
- - ">="
|
137
|
+
- !ruby/object:Gem::Version
|
138
|
+
version: '0'
|
97
139
|
description: A lock-free logger with timebased file rotation.
|
98
140
|
email:
|
99
141
|
- takayuki.1229@gmail.com
|