I use the add_file_log()
function to initialize a logging sink that stores log records into a text file. When I define several sinks, I have observed:
- a file is created for each sink.
- the output is copied to all files.
This is my logger:
class logger
{
public:
logger(const logger&) =delete;
logger(logger&&) =delete;
logger& operator=(const logger&) =delete;
logger& operator=(logger&&) =delete;
static logger& get_instance(
const std::string& file,
bool console
)
{
boost::log::register_simple_formatter_factory<
boost::log::trivial::severity_level,
char
>("Severity");
std::string the_format = "[%TimeStamp%] (%LineID%) [%Severity%]: %Message%";
if(!file.empty()) {
boost::log::add_file_log(
boost::log::keywords::file_name = file + "_%N.log",
boost::log::keywords::rotation_size = 10 * 1024 * 1024,
boost::log::keywords::time_based_rotation =
boost::log::sinks::file::rotation_at_time_point(0, 0, 0),
boost::log::keywords::auto_flush = true,
//boost::log::keywords::open_mode = (std::ios::out | std::ios::app),
boost::log::keywords::format = the_format
);
}
boost::log::add_common_attributes();
static logger instance{ the_format, console };
return instance;
}
void log(
const std::string& msg
)
{
BOOST_LOG_SEV ( m_log_, boost::log::trivial::info ) << msg;
}
private:
boost::log::sources::severity_logger<
boost::log::trivial::severity_level
> m_log_;
logger(
const std::string& format,
bool console
)
{
if(console) {
boost::log::add_console_log(
std::clog,
boost::log::keywords::format = format
);
}
}
}; // logger
This is my main()
function:
void test(
const std::string& file
)
{
logger& lg1 = logger::get_instance( file, false );
lg1.log( "Hello" );
lg1.log( "World" );
lg1.log( "Bye" );
} // test
int main()
{
unsigned char result = EXIT_SUCCESS;
try
{
std::string file1 = "a.txt",
file2 = "b.txt";
logger& lg = logger::get_instance( file1, false );
for(int i = 1; i<=10; i++) {
lg.log( std::to_string(i) );
if(i == 5) {
test( file2 );
}
}
}
catch ( std::exception& e )
{
std::cerr << "Error: " << e.what() << std::endl;
result = EXIT_FAILURE;
}
return result;
}
After running the example, the files contain:
a.txt_0.log
[2016-Aug-31 11:49:48.584353] (1) [info]: 1
[2016-Aug-31 11:49:48.585376] (2) [info]: 2
[2016-Aug-31 11:49:48.585418] (3) [info]: 3
[2016-Aug-31 11:49:48.585442] (4) [info]: 4
[2016-Aug-31 11:49:48.585462] (5) [info]: 5
[2016-Aug-31 11:49:48.585505] (6) [info]: Hello <--
[2016-Aug-31 11:49:48.585610] (7) [info]: World <-- Generated by second logger
[2016-Aug-31 11:49:48.585672] (8) [info]: Bye <--
[2016-Aug-31 11:49:48.585709] (9) [info]: 6
[2016-Aug-31 11:49:48.585744] (10) [info]: 7
[2016-Aug-31 11:49:48.585777] (11) [info]: 8
[2016-Aug-31 11:49:48.585813] (12) [info]: 9
[2016-Aug-31 11:49:48.585842] (13) [info]: 10
b.txt_0.log
[2016-Aug-31 11:49:48.585505] (6) [info]: Hello
[2016-Aug-31 11:49:48.585610] (7) [info]: World
[2016-Aug-31 11:49:48.585672] (8) [info]: Bye
[2016-Aug-31 11:49:48.585709] (9) [info]: 6 <--
[2016-Aug-31 11:49:48.585744] (10) [info]: 7 <--
[2016-Aug-31 11:49:48.585777] (11) [info]: 8 <-- Generated by the first logger
[2016-Aug-31 11:49:48.585813] (12) [info]: 9 <--
[2016-Aug-31 11:49:48.585842] (13) [info]: 10 <--
How I can prevent this behavior? I want each file only stores the information generated by its associated logger.