New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Inter-process locking for log rotation #428
Changes from 1 commit
7e3d8c2
7fefec3
7117c0c
21b038c
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -614,17 +614,51 @@ def check_shift_log | |
if @shift_age.is_a?(Integer) | ||
# Note: always returns false if '0'. | ||
if @filename && (@shift_age > 0) && (@dev.stat.size > @shift_size) | ||
shift_log_age | ||
lock_shift_log { shift_log_age } | ||
end | ||
else | ||
now = Time.now | ||
period_end = previous_period_end(now) | ||
if @dev.stat.mtime <= period_end | ||
shift_log_period(period_end) | ||
lock_shift_log { shift_log_period(period_end) } | ||
end | ||
end | ||
end | ||
|
||
def lock_shift_log | ||
begin | ||
retry_limit = 8 | ||
retry_sleep = 0.1 | ||
begin | ||
lock = File.open(@filename, File::WRONLY | File::APPEND) | ||
begin | ||
# inter-process locking | ||
lock.flock(File::LOCK_EX) | ||
ino = lock.stat.ino | ||
if ino == File.stat(@filename).ino | ||
yield # log shifting | ||
else | ||
@dev.close rescue nil | ||
@dev = File.open(@filename, File::WRONLY | File::APPEND) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Why don't you use create_logfile? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Codes inside There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Finally, I used multiprocess-safe versioned |
||
@dev.sync = true | ||
end | ||
ensure | ||
lock.flock(File::LOCK_UN) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. this line can be removed because close() unlocks it. |
||
lock.close | ||
end | ||
rescue Errno::ENOENT => e | ||
# @filename file would not exist right after #rename and before #create_logfile | ||
raise e if retry_limit <= 0 | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Why re-raise here? if retry_limit <= 0
warn("log rotation inter-process lock failed. #{$!}")
else
sleep retry_sleep
retry_limit -= 1
retry_sleep *= 2
retry
end |
||
sleep retry_sleep | ||
retry_limit -= 1 | ||
retry_sleep *= 2 | ||
retry | ||
end | ||
rescue | ||
warn("log rotation inter-process lock failed. #{$!}") | ||
end | ||
end | ||
|
||
def shift_log_age | ||
(@shift_age-3).downto(0) do |i| | ||
if FileTest.exist?("#{@filename}.#{i}") | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why don't you use block?