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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: e4685d19b4094e975b08164b4041c82d20a0d843
4
- data.tar.gz: 87f197078fead7232cc75b576a5eee36def4b0dd
3
+ metadata.gz: 088ff7e10a40407ed7bb375eb699a92f50c5d1ec
4
+ data.tar.gz: 4c24284de175508bd2b3d2966701c211929fefb5
5
5
  SHA512:
6
- metadata.gz: 6c453b8b694c821b515c7b40a4b8641e2fad33295676b11894aa6e6efedc995dffc1dd91ff83b5ee0a07e554a2b7fa943e1f173e0f0f540bcb334ec45535d57c
7
- data.tar.gz: 53db7768b5ecfbafded33375ccf583faed190bf2997c78cb25ebb2e41e0db00189d1737c039b254ea762b678b9b7a7501d94b74122962065b8fcbe733af676f2
6
+ metadata.gz: 8b1840ba67d2002c388a1cf76d2a5b4c20d42fc2fb759f7b972bacd26b9fbba4e8008ea2bb83cee1d6939e5d704d2bbd37e2988b7b48cea43fce2e775bf6b137
7
+ data.tar.gz: b51831122c18dddd0eaa2c26ea1454568f3d5830c3add968dc359281c016f6b4963d9284bdacaa57dd1fb21fd786ebd74f35f25f58e761592701f3fbe6f04aaa
data/.travis.yml CHANGED
@@ -1,3 +1,7 @@
1
1
  language: ruby
2
2
  rvm:
3
+ - 2.0.0-p598
3
4
  - 2.1.5
5
+ - 2.2.0
6
+ sudo: false
7
+ cache: bundler
data/README.md CHANGED
@@ -1,5 +1,11 @@
1
1
  # ChronoLogger
2
2
 
3
+ [![Gem Version](https://badge.fury.io/rb/chrono_logger.svg)](http://badge.fury.io/rb/chrono_logger)
4
+ [![Build Status](https://travis-ci.org/ma2gedev/chrono_logger.svg)](https://travis-ci.org/ma2gedev/chrono_logger)
5
+ [![Code Climate](https://codeclimate.com/github/ma2gedev/chrono_logger/badges/gpa.svg)](https://codeclimate.com/github/ma2gedev/chrono_logger)
6
+ [![Coverage Status](https://coveralls.io/repos/ma2gedev/chrono_logger/badge.svg)](https://coveralls.io/r/ma2gedev/chrono_logger)
7
+ [![endorse](https://api.coderwall.com/ma2gedev/endorsecount.png)](https://coderwall.com/ma2gedev)
8
+
3
9
  A lock-free logger with timebased file rotation.
4
10
 
5
11
  ## Installation
@@ -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
- @filename = Time.now.strftime(@pattern)
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 && @dev.respond_to?(:stat)
34
- begin
35
- check_shift_log
36
- rescue
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
- unless Time.now.strftime(@pattern) == @filename
75
- new_filename = Time.now.strftime(@pattern)
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
 
@@ -1,5 +1,5 @@
1
1
  require 'logger'
2
2
 
3
3
  class ChronoLogger < Logger
4
- VERSION = "0.0.2"
4
+ VERSION = "0.0.3"
5
5
  end
@@ -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.create(File.basename(__FILE__) + '.log') {|logdev|
30
- logger.instance_eval { @logdev = ChronoLogger::TimeBasedLogDevice.new(logdev) }
31
- logger.__send__(msg_id, *arg, &block)
32
- logdev.rewind
33
- logdev.read
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
@@ -1,3 +1,6 @@
1
+ require 'coveralls'
2
+ Coveralls.wear!
3
+
1
4
  $LOAD_PATH.unshift File.expand_path('../../lib', __FILE__)
2
5
  require 'chrono_logger'
3
6
 
@@ -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.2
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-22 00:00:00.000000000 Z
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