1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153
|
/*
* Copyright Andrey Semashev 2007 - 2015.
* Distributed under the Boost Software License, Version 1.0.
* (See accompanying file LICENSE_1_0.txt or copy at
* http://www.boost.org/LICENSE_1_0.txt)
*/
#include <stdexcept>
#include <string>
#include <iostream>
#include <boost/smart_ptr/shared_ptr.hpp>
#include <boost/lambda/lambda.hpp>
#include <boost/date_time/posix_time/posix_time.hpp>
#include <boost/log/common.hpp>
#include <boost/log/expressions.hpp>
#include <boost/log/attributes.hpp>
#include <boost/log/sinks.hpp>
#include <boost/log/sources/logger.hpp>
namespace logging = boost::log;
namespace attrs = boost::log::attributes;
namespace src = boost::log::sources;
namespace sinks = boost::log::sinks;
namespace expr = boost::log::expressions;
namespace keywords = boost::log::keywords;
typedef sinks::synchronous_sink< sinks::text_file_backend > file_sink;
//[ example_sinks_xml_file_collecting
void init_file_collecting(boost::shared_ptr< file_sink > sink)
{
sink->locked_backend()->set_file_collector(sinks::file::make_collector(
keywords::target = "logs", /*< the target directory >*/
keywords::max_size = 16 * 1024 * 1024, /*< maximum total size of the stored files, in bytes >*/
keywords::min_free_space = 100 * 1024 * 1024, /*< minimum free space on the drive, in bytes >*/
keywords::max_files = 512 /*< maximum number of stored files >*/
));
}
//]
#if 0
//[ example_sinks_xml_file
// Complete file sink type
typedef sinks::synchronous_sink< sinks::text_file_backend > file_sink;
void write_header(sinks::text_file_backend::stream_type& file)
{
file << "<?xml version=\"1.0\"?>\n<log>\n";
}
void write_footer(sinks::text_file_backend::stream_type& file)
{
file << "</log>\n";
}
void init_logging()
{
// Create a text file sink
boost::shared_ptr< file_sink > sink(new file_sink(
keywords::file_name = "%Y%m%d_%H%M%S_%5N.xml", /*< the resulting file name pattern >*/
keywords::rotation_size = 16384 /*< rotation size, in characters >*/
));
sink->set_formatter
(
expr::format("\t<record id=\"%1%\" timestamp=\"%2%\">%3%</record>")
% expr::attr< unsigned int >("RecordID")
% expr::attr< boost::posix_time::ptime >("TimeStamp")
% expr::xml_decor[ expr::stream << expr::smessage ] /*< the log message has to be decorated, if it contains special characters >*/
);
// Set header and footer writing functors
sink->locked_backend()->set_open_handler(&write_header);
sink->locked_backend()->set_close_handler(&write_footer);
// Add the sink to the core
logging::core::get()->add_sink(sink);
}
//]
#endif
//[ example_sinks_xml_file_final
void init_logging()
{
// Create a text file sink
boost::shared_ptr< file_sink > sink(new file_sink(
keywords::file_name = "%Y%m%d_%H%M%S_%5N.xml",
keywords::rotation_size = 16384
));
// Set up where the rotated files will be stored
init_file_collecting(sink);
// Upon restart, scan the directory for files matching the file_name pattern
sink->locked_backend()->scan_for_files();
sink->set_formatter
(
expr::format("\t<record id=\"%1%\" timestamp=\"%2%\">%3%</record>")
% expr::attr< unsigned int >("RecordID")
% expr::attr< boost::posix_time::ptime >("TimeStamp")
% expr::xml_decor[ expr::stream << expr::smessage ]
);
// Set header and footer writing functors
namespace bll = boost::lambda;
sink->locked_backend()->set_open_handler
(
bll::_1 << "<?xml version=\"1.0\"?>\n<log>\n"
);
sink->locked_backend()->set_close_handler
(
bll::_1 << "</log>\n"
);
// Add the sink to the core
logging::core::get()->add_sink(sink);
}
//]
enum { LOG_RECORDS_TO_WRITE = 2000 };
int main(int argc, char* argv[])
{
try
{
// Initialize logging library
init_logging();
// And also add some attributes
logging::core::get()->add_global_attribute("TimeStamp", attrs::local_clock());
logging::core::get()->add_global_attribute("RecordID", attrs::counter< unsigned int >());
// Do some logging
src::logger lg;
for (unsigned int i = 0; i < LOG_RECORDS_TO_WRITE; ++i)
{
BOOST_LOG(lg) << "XML log record " << i;
}
// Test that XML character decoration works
BOOST_LOG(lg) << "Special XML characters: &, <, >, \", '";
return 0;
}
catch (std::exception& e)
{
std::cout << "FAILURE: " << e.what() << std::endl;
return 1;
}
}
|