Skip to content

Commit bae416a

Browse files
authored
Merge pull request #162 from pmconrad/1982_rotate_logs
Check + rotate logs while logging not by scheduled task
2 parents f052ac9 + e168b64 commit bae416a

File tree

1 file changed

+41
-37
lines changed

1 file changed

+41
-37
lines changed

src/log/file_appender.cpp

+41-37
Original file line numberDiff line numberDiff line change
@@ -21,18 +21,13 @@ namespace fc {
2121
boost::mutex slock;
2222

2323
private:
24-
future<void> _rotation_task;
25-
time_point_sec _current_file_start_time;
26-
27-
time_point_sec get_file_start_time( const time_point_sec& timestamp, const microseconds& interval )
28-
{
29-
int64_t interval_seconds = interval.to_seconds();
30-
int64_t file_number = timestamp.sec_since_epoch() / interval_seconds;
31-
return time_point_sec( (uint32_t)(file_number * interval_seconds) );
32-
}
24+
future<void> _deletion_task;
25+
boost::atomic<int64_t> _current_file_number;
26+
const int64_t _interval_seconds;
27+
time_point _next_file_time;
3328

3429
public:
35-
impl( const config& c) : cfg( c )
30+
impl( const config& c) : cfg( c ), _interval_seconds( cfg.rotation_interval.to_seconds() )
3631
{
3732
try
3833
{
@@ -44,6 +39,7 @@ namespace fc {
4439
FC_ASSERT( cfg.rotation_limit >= cfg.rotation_interval );
4540

4641
rotate_files( true );
42+
delete_files();
4743
} else {
4844
out.open( cfg.filename, std::ios_base::out | std::ios_base::app);
4945
}
@@ -58,7 +54,7 @@ namespace fc {
5854
{
5955
try
6056
{
61-
_rotation_task.cancel_and_wait("file_appender is destructing");
57+
_deletion_task.cancel_and_wait("file_appender is destructing");
6258
}
6359
catch( ... )
6460
{
@@ -67,9 +63,22 @@ namespace fc {
6763

6864
void rotate_files( bool initializing = false )
6965
{
70-
FC_ASSERT( cfg.rotate );
66+
if( !cfg.rotate ) return;
67+
7168
fc::time_point now = time_point::now();
72-
fc::time_point_sec start_time = get_file_start_time( now, cfg.rotation_interval );
69+
if( now < _next_file_time ) return;
70+
71+
int64_t new_file_number = now.sec_since_epoch() / _interval_seconds;
72+
if( initializing )
73+
_current_file_number.store( new_file_number );
74+
else
75+
{
76+
int64_t prev_file_number = _current_file_number.load();
77+
if( prev_file_number >= new_file_number ) return;
78+
if( !_current_file_number.compare_exchange_weak( prev_file_number, new_file_number ) ) return;
79+
}
80+
fc::time_point_sec start_time = time_point_sec( (uint32_t)(new_file_number * _interval_seconds) );
81+
_next_file_time = start_time + _interval_seconds;
7382
string timestamp_string = start_time.to_non_delimited_iso_string();
7483
fc::path link_filename = cfg.filename;
7584
fc::path log_filename = link_filename.parent_path() / (link_filename.filename().string() + "." + timestamp_string);
@@ -79,44 +88,41 @@ namespace fc {
7988

8089
if( !initializing )
8190
{
82-
if( start_time <= _current_file_start_time )
83-
{
84-
_rotation_task = schedule( [this]() { rotate_files(); },
85-
_current_file_start_time + cfg.rotation_interval.to_seconds(),
86-
"rotate_files(2)" );
87-
return;
88-
}
89-
9091
out.flush();
9192
out.close();
9293
}
9394
remove_all(link_filename); // on windows, you can't delete the link while the underlying file is opened for writing
9495
out.open( log_filename, std::ios_base::out | std::ios_base::app );
9596
create_hard_link(log_filename, link_filename);
9697
}
98+
}
9799

100+
void delete_files()
101+
{
98102
/* Delete old log files */
99-
fc::time_point limit_time = now - cfg.rotation_limit;
103+
auto current_file = _current_file_number.load();
104+
fc::time_point_sec start_time = time_point_sec( (uint32_t)(current_file * _interval_seconds) );
105+
fc::time_point limit_time = time_point::now() - cfg.rotation_limit;
106+
fc::path link_filename = cfg.filename;
100107
string link_filename_string = link_filename.filename().string();
101108
directory_iterator itr(link_filename.parent_path());
109+
string timestamp_string = start_time.to_non_delimited_iso_string();
102110
for( ; itr != directory_iterator(); itr++ )
103111
{
104112
try
105113
{
106114
string current_filename = itr->filename().string();
107-
if (current_filename.compare(0, link_filename_string.size(), link_filename_string) != 0 ||
108-
current_filename.size() <= link_filename_string.size() + 1)
109-
continue;
115+
if( current_filename.compare(0, link_filename_string.size(), link_filename_string) != 0
116+
|| current_filename.size() <= link_filename_string.size() + 1 )
117+
continue;
110118
string current_timestamp_str = current_filename.substr(link_filename_string.size() + 1,
111119
timestamp_string.size());
112120
fc::time_point_sec current_timestamp = fc::time_point_sec::from_iso_string( current_timestamp_str );
113-
if( current_timestamp < start_time )
121+
if( current_timestamp < start_time
122+
&& ( current_timestamp < limit_time || file_size( current_filename ) <= 0 ) )
114123
{
115-
if( current_timestamp < limit_time || file_size( current_filename ) <= 0 )
116-
{
117-
remove_all( *itr );
118-
continue;
119-
}
124+
remove_all( *itr );
125+
continue;
120126
}
121127
}
122128
catch (const fc::canceled_exception&)
@@ -127,11 +133,8 @@ namespace fc {
127133
{
128134
}
129135
}
130-
131-
_current_file_start_time = start_time;
132-
_rotation_task = schedule( [this]() { rotate_files(); },
133-
_current_file_start_time + cfg.rotation_interval.to_seconds(),
134-
"rotate_files(3)" );
136+
_deletion_task = schedule( [this]() { delete_files(); }, start_time + _interval_seconds,
137+
"delete_files(3)" );
135138
}
136139
};
137140

@@ -151,8 +154,9 @@ namespace fc {
151154
// MS THREAD METHOD MESSAGE \t\t\t File:Line
152155
void file_appender::log( const log_message& m )
153156
{
157+
my->rotate_files();
158+
154159
std::stringstream line;
155-
//line << (m.get_context().get_timestamp().time_since_epoch().count() % (1000ll*1000ll*60ll*60))/1000 <<"ms ";
156160
line << string(m.get_context().get_timestamp()) << " ";
157161
line << std::setw( 21 ) << (m.get_context().get_thread_name().substr(0,9) + string(":") + m.get_context().get_task_name()).c_str() << " ";
158162

0 commit comments

Comments
 (0)