Merge pull request #162 from pmconrad/1982_rotate_logs
Check + rotate logs while logging not by scheduled task
This commit is contained in:
commit
bae416a446
1 changed files with 41 additions and 37 deletions
|
|
@ -21,18 +21,13 @@ namespace fc {
|
||||||
boost::mutex slock;
|
boost::mutex slock;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
future<void> _rotation_task;
|
future<void> _deletion_task;
|
||||||
time_point_sec _current_file_start_time;
|
boost::atomic<int64_t> _current_file_number;
|
||||||
|
const int64_t _interval_seconds;
|
||||||
time_point_sec get_file_start_time( const time_point_sec& timestamp, const microseconds& interval )
|
time_point _next_file_time;
|
||||||
{
|
|
||||||
int64_t interval_seconds = interval.to_seconds();
|
|
||||||
int64_t file_number = timestamp.sec_since_epoch() / interval_seconds;
|
|
||||||
return time_point_sec( (uint32_t)(file_number * interval_seconds) );
|
|
||||||
}
|
|
||||||
|
|
||||||
public:
|
public:
|
||||||
impl( const config& c) : cfg( c )
|
impl( const config& c) : cfg( c ), _interval_seconds( cfg.rotation_interval.to_seconds() )
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
|
|
@ -44,6 +39,7 @@ namespace fc {
|
||||||
FC_ASSERT( cfg.rotation_limit >= cfg.rotation_interval );
|
FC_ASSERT( cfg.rotation_limit >= cfg.rotation_interval );
|
||||||
|
|
||||||
rotate_files( true );
|
rotate_files( true );
|
||||||
|
delete_files();
|
||||||
} else {
|
} else {
|
||||||
out.open( cfg.filename, std::ios_base::out | std::ios_base::app);
|
out.open( cfg.filename, std::ios_base::out | std::ios_base::app);
|
||||||
}
|
}
|
||||||
|
|
@ -58,7 +54,7 @@ namespace fc {
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
_rotation_task.cancel_and_wait("file_appender is destructing");
|
_deletion_task.cancel_and_wait("file_appender is destructing");
|
||||||
}
|
}
|
||||||
catch( ... )
|
catch( ... )
|
||||||
{
|
{
|
||||||
|
|
@ -67,9 +63,22 @@ namespace fc {
|
||||||
|
|
||||||
void rotate_files( bool initializing = false )
|
void rotate_files( bool initializing = false )
|
||||||
{
|
{
|
||||||
FC_ASSERT( cfg.rotate );
|
if( !cfg.rotate ) return;
|
||||||
|
|
||||||
fc::time_point now = time_point::now();
|
fc::time_point now = time_point::now();
|
||||||
fc::time_point_sec start_time = get_file_start_time( now, cfg.rotation_interval );
|
if( now < _next_file_time ) return;
|
||||||
|
|
||||||
|
int64_t new_file_number = now.sec_since_epoch() / _interval_seconds;
|
||||||
|
if( initializing )
|
||||||
|
_current_file_number.store( new_file_number );
|
||||||
|
else
|
||||||
|
{
|
||||||
|
int64_t prev_file_number = _current_file_number.load();
|
||||||
|
if( prev_file_number >= new_file_number ) return;
|
||||||
|
if( !_current_file_number.compare_exchange_weak( prev_file_number, new_file_number ) ) return;
|
||||||
|
}
|
||||||
|
fc::time_point_sec start_time = time_point_sec( (uint32_t)(new_file_number * _interval_seconds) );
|
||||||
|
_next_file_time = start_time + _interval_seconds;
|
||||||
string timestamp_string = start_time.to_non_delimited_iso_string();
|
string timestamp_string = start_time.to_non_delimited_iso_string();
|
||||||
fc::path link_filename = cfg.filename;
|
fc::path link_filename = cfg.filename;
|
||||||
fc::path log_filename = link_filename.parent_path() / (link_filename.filename().string() + "." + timestamp_string);
|
fc::path log_filename = link_filename.parent_path() / (link_filename.filename().string() + "." + timestamp_string);
|
||||||
|
|
@ -79,14 +88,6 @@ namespace fc {
|
||||||
|
|
||||||
if( !initializing )
|
if( !initializing )
|
||||||
{
|
{
|
||||||
if( start_time <= _current_file_start_time )
|
|
||||||
{
|
|
||||||
_rotation_task = schedule( [this]() { rotate_files(); },
|
|
||||||
_current_file_start_time + cfg.rotation_interval.to_seconds(),
|
|
||||||
"rotate_files(2)" );
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
out.flush();
|
out.flush();
|
||||||
out.close();
|
out.close();
|
||||||
}
|
}
|
||||||
|
|
@ -94,29 +95,34 @@ namespace fc {
|
||||||
out.open( log_filename, std::ios_base::out | std::ios_base::app );
|
out.open( log_filename, std::ios_base::out | std::ios_base::app );
|
||||||
create_hard_link(log_filename, link_filename);
|
create_hard_link(log_filename, link_filename);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void delete_files()
|
||||||
|
{
|
||||||
/* Delete old log files */
|
/* Delete old log files */
|
||||||
fc::time_point limit_time = now - cfg.rotation_limit;
|
auto current_file = _current_file_number.load();
|
||||||
|
fc::time_point_sec start_time = time_point_sec( (uint32_t)(current_file * _interval_seconds) );
|
||||||
|
fc::time_point limit_time = time_point::now() - cfg.rotation_limit;
|
||||||
|
fc::path link_filename = cfg.filename;
|
||||||
string link_filename_string = link_filename.filename().string();
|
string link_filename_string = link_filename.filename().string();
|
||||||
directory_iterator itr(link_filename.parent_path());
|
directory_iterator itr(link_filename.parent_path());
|
||||||
|
string timestamp_string = start_time.to_non_delimited_iso_string();
|
||||||
for( ; itr != directory_iterator(); itr++ )
|
for( ; itr != directory_iterator(); itr++ )
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
string current_filename = itr->filename().string();
|
string current_filename = itr->filename().string();
|
||||||
if (current_filename.compare(0, link_filename_string.size(), link_filename_string) != 0 ||
|
if( current_filename.compare(0, link_filename_string.size(), link_filename_string) != 0
|
||||||
current_filename.size() <= link_filename_string.size() + 1)
|
|| current_filename.size() <= link_filename_string.size() + 1 )
|
||||||
continue;
|
continue;
|
||||||
string current_timestamp_str = current_filename.substr(link_filename_string.size() + 1,
|
string current_timestamp_str = current_filename.substr(link_filename_string.size() + 1,
|
||||||
timestamp_string.size());
|
timestamp_string.size());
|
||||||
fc::time_point_sec current_timestamp = fc::time_point_sec::from_iso_string( current_timestamp_str );
|
fc::time_point_sec current_timestamp = fc::time_point_sec::from_iso_string( current_timestamp_str );
|
||||||
if( current_timestamp < start_time )
|
if( current_timestamp < start_time
|
||||||
|
&& ( current_timestamp < limit_time || file_size( current_filename ) <= 0 ) )
|
||||||
{
|
{
|
||||||
if( current_timestamp < limit_time || file_size( current_filename ) <= 0 )
|
remove_all( *itr );
|
||||||
{
|
continue;
|
||||||
remove_all( *itr );
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
catch (const fc::canceled_exception&)
|
catch (const fc::canceled_exception&)
|
||||||
|
|
@ -127,11 +133,8 @@ namespace fc {
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
_deletion_task = schedule( [this]() { delete_files(); }, start_time + _interval_seconds,
|
||||||
_current_file_start_time = start_time;
|
"delete_files(3)" );
|
||||||
_rotation_task = schedule( [this]() { rotate_files(); },
|
|
||||||
_current_file_start_time + cfg.rotation_interval.to_seconds(),
|
|
||||||
"rotate_files(3)" );
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
@ -151,8 +154,9 @@ namespace fc {
|
||||||
// MS THREAD METHOD MESSAGE \t\t\t File:Line
|
// MS THREAD METHOD MESSAGE \t\t\t File:Line
|
||||||
void file_appender::log( const log_message& m )
|
void file_appender::log( const log_message& m )
|
||||||
{
|
{
|
||||||
|
my->rotate_files();
|
||||||
|
|
||||||
std::stringstream line;
|
std::stringstream line;
|
||||||
//line << (m.get_context().get_timestamp().time_since_epoch().count() % (1000ll*1000ll*60ll*60))/1000 <<"ms ";
|
|
||||||
line << string(m.get_context().get_timestamp()) << " ";
|
line << string(m.get_context().get_timestamp()) << " ";
|
||||||
line << std::setw( 21 ) << (m.get_context().get_thread_name().substr(0,9) + string(":") + m.get_context().get_task_name()).c_str() << " ";
|
line << std::setw( 21 ) << (m.get_context().get_thread_name().substr(0,9) + string(":") + m.get_context().get_task_name()).c_str() << " ";
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue