1 /* 2 * Copyright Andrey Semashev 2007 - 2015. 3 * Distributed under the Boost Software License, Version 1.0. 4 * (See accompanying file LICENSE_1_0.txt or copy at 5 * http://www.boost.org/LICENSE_1_0.txt) 6 */ 7 /*! 8 * \file text_multifile_backend.cpp 9 * \author Andrey Semashev 10 * \date 09.06.2009 11 * 12 * \brief This header is the Boost.Log library implementation, see the library documentation 13 * at http://www.boost.org/doc/libs/release/libs/log/doc/html/index.html. 14 */ 15 16 #include <boost/log/detail/config.hpp> 17 #include <ios> 18 #include <boost/filesystem/path.hpp> 19 #include <boost/filesystem/fstream.hpp> 20 #include <boost/filesystem/operations.hpp> 21 #include <boost/log/detail/parameter_tools.hpp> 22 #include <boost/log/sinks/auto_newline_mode.hpp> 23 #include <boost/log/sinks/text_multifile_backend.hpp> 24 #include <boost/log/detail/header.hpp> 25 26 namespace boost { 27 28 BOOST_LOG_OPEN_NAMESPACE 29 30 namespace sinks { 31 32 //! Sink implementation data 33 struct text_multifile_backend::implementation 34 { 35 //! File name composer 36 file_name_composer_type m_FileNameComposer; 37 //! Base path for absolute path composition 38 const filesystem::path m_BasePath; 39 //! File stream 40 filesystem::ofstream m_File; 41 //! Indicates whether to append a trailing newline after every log record 42 auto_newline_mode m_AutoNewlineMode; 43 implementationboost::sinks::text_multifile_backend::implementation44 explicit implementation(auto_newline_mode auto_newline) : 45 m_BasePath(filesystem::current_path()), 46 m_AutoNewlineMode(auto_newline) 47 { 48 } 49 50 //! Makes relative path absolute with respect to the base path make_absoluteboost::sinks::text_multifile_backend::implementation51 filesystem::path make_absolute(filesystem::path const& p) 52 { 53 return filesystem::absolute(p, m_BasePath); 54 } 55 }; 56 57 //! Default constructor text_multifile_backend()58BOOST_LOG_API text_multifile_backend::text_multifile_backend() 59 { 60 construct(log::aux::empty_arg_list()); 61 } 62 63 //! Constructor implementation construct(auto_newline_mode auto_newline)64BOOST_LOG_API void text_multifile_backend::construct(auto_newline_mode auto_newline) 65 { 66 m_pImpl = new implementation(auto_newline); 67 } 68 69 //! Destructor ~text_multifile_backend()70BOOST_LOG_API text_multifile_backend::~text_multifile_backend() 71 { 72 delete m_pImpl; 73 } 74 75 //! The method sets the file name composer set_file_name_composer_internal(file_name_composer_type const & composer)76BOOST_LOG_API void text_multifile_backend::set_file_name_composer_internal(file_name_composer_type const& composer) 77 { 78 m_pImpl->m_FileNameComposer = composer; 79 } 80 81 //! Selects whether a trailing newline should be automatically inserted after every log record. set_auto_newline_mode(auto_newline_mode mode)82BOOST_LOG_API void text_multifile_backend::set_auto_newline_mode(auto_newline_mode mode) 83 { 84 m_pImpl->m_AutoNewlineMode = mode; 85 } 86 87 //! The method writes the message to the sink consume(record_view const & rec,string_type const & formatted_message)88BOOST_LOG_API void text_multifile_backend::consume(record_view const& rec, string_type const& formatted_message) 89 { 90 if (BOOST_LIKELY(!m_pImpl->m_FileNameComposer.empty())) 91 { 92 filesystem::path file_name = m_pImpl->make_absolute(m_pImpl->m_FileNameComposer(rec)); 93 filesystem::create_directories(file_name.parent_path()); 94 m_pImpl->m_File.open(file_name, std::ios_base::out | std::ios_base::app); 95 if (BOOST_LIKELY(m_pImpl->m_File.is_open())) 96 { 97 m_pImpl->m_File.write(formatted_message.data(), static_cast< std::streamsize >(formatted_message.size())); 98 if (m_pImpl->m_AutoNewlineMode != disabled_auto_newline) 99 { 100 if (m_pImpl->m_AutoNewlineMode == always_insert || formatted_message.empty() || *formatted_message.rbegin() != static_cast< string_type::value_type >('\n')) 101 m_pImpl->m_File.put(static_cast< string_type::value_type >('\n')); 102 } 103 m_pImpl->m_File.close(); 104 } 105 } 106 } 107 108 } // namespace sinks 109 110 BOOST_LOG_CLOSE_NAMESPACE // namespace log 111 112 } // namespace boost 113 114 #include <boost/log/detail/footer.hpp> 115