TwP / logging

A flexible logging library for use in Ruby programs based on the design of Java's log4j library.
https://rubygems.org/gems/logging
MIT License
530 stars 101 forks source link

File Appender loses log messages if the file gets deleted #204

Closed jessebs closed 2 years ago

jessebs commented 5 years ago

When using a file appender, if the log file is deleted, it will not be recreated and log messages won't be logged anymore

`require 'logging'

log_file = '/tmp/test.log'

log = Logging.logger['example'] log.add_appenders( Logging.appenders.file(log_file) ) log.level = :debug

log.debug 'Message before delete' raise 'File does not exist when logged before delete' unless File.file? log_file

File.delete(log_file)

log.debug 'Message after delete' raise 'File does not exist when logged after delete' unless File.file? log_file`

The above hits the final raise condition and the second log message is never logged

TwP commented 5 years ago

If the log file is deleted then the appender will need to be reopened.

appender = Logging.appenders["/tmp/test.log"]
appender.reopen

The IO object held by the appender still accepts writes even when the underlying file has been deleted. This sound silly to you and me, but it is just how file descriptors work.

One trick that can be played is to call IO#stat and check the number of hard links to the file descriptor. If that number drops to zero, it means that the underlying file was deleted. The problem is that IO#stat would need to be called before every write operation to guarantee that no writes are lost. I'm not certain of the cost of doing this, but it will definitely slow things down.

Using the reopen method is your best bet here.