Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion example/doc/sinks_xml_file.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,8 @@ 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::min_free_space = 100 * 1024 * 1024, /*< minimum free space on the drive, in bytes >*/
keywords::max_files = 512 /*< maximum number of stored files>*/
));
}
//]
Expand Down
3 changes: 2 additions & 1 deletion example/rotating_file/main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,8 @@ int main(int argc, char* argv[])
sink->locked_backend()->set_file_collector(sinks::file::make_collector(
keywords::target = "logs", // where to store rotated files
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::min_free_space = 100 * 1024 * 1024, // minimum free space on the drive, in bytes
keywords::max_files = 512 // maximum number of stored files
));

// Upon restart, scan the target directory for files matching the file_name pattern
Expand Down
40 changes: 40 additions & 0 deletions include/boost/log/keywords/max_files.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
/*
* 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)
*/
/*!
* \file keywords/max_files.hpp
* \author Erich Keane
* \date 29.12.2015
*
* The header contains the \c max_files keyword declaration.
*/

#ifndef BOOST_LOG_KEYWORDS_MAX_FILES_HPP_INCLUDED_
#define BOOST_LOG_KEYWORDS_MAX_FILES_HPP_INCLUDED_

#include <boost/parameter/keyword.hpp>
#include <boost/log/detail/config.hpp>

#ifdef BOOST_HAS_PRAGMA_ONCE
#pragma once
#endif

namespace boost {

BOOST_LOG_OPEN_NAMESPACE

namespace keywords {

//! The keyword allows to specify maximum total number of log files
BOOST_PARAMETER_KEYWORD(tag, max_files)

} // namespace keywords

BOOST_LOG_CLOSE_NAMESPACE // namespace log

} // namespace boost

#endif // BOOST_LOG_KEYWORDS_MAX_FILES_HPP_INCLUDED_
15 changes: 13 additions & 2 deletions include/boost/log/sinks/text_file_backend.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@
#include <boost/date_time/posix_time/posix_time_types.hpp>
#include <boost/filesystem/path.hpp>
#include <boost/log/keywords/max_size.hpp>
#include <boost/log/keywords/max_files.hpp>
#include <boost/log/keywords/min_free_space.hpp>
#include <boost/log/keywords/target.hpp>
#include <boost/log/keywords/file_name.hpp>
Expand Down Expand Up @@ -129,15 +130,17 @@ namespace aux {
BOOST_LOG_API shared_ptr< collector > make_collector(
filesystem::path const& target_dir,
uintmax_t max_size,
uintmax_t min_free_space
uintmax_t min_free_space,
uintmax_t max_files = (std::numeric_limits< uintmax_t >::max)()
);
template< typename ArgsT >
inline shared_ptr< collector > make_collector(ArgsT const& args)
{
return aux::make_collector(
filesystem::path(args[keywords::target]),
args[keywords::max_size | (std::numeric_limits< uintmax_t >::max)()],
args[keywords::min_free_space | static_cast< uintmax_t >(0)]);
args[keywords::min_free_space | static_cast< uintmax_t >(0)],
args[keywords::max_files | (std::numeric_limits< uintmax_t >::max)()]);
}

} // namespace aux
Expand All @@ -159,6 +162,11 @@ inline shared_ptr< collector > make_collector(T1 const& a1, T2 const& a2, T3 con
{
return aux::make_collector((a1, a2, a3));
}
template< typename T1, typename T2, typename T3, typename T4 >
inline shared_ptr< collector > make_collector(T1 const& a1, T2 const& a2, T3 const& a3, T4 const& a4)
{
return aux::make_collector((a1, a2, a3, a4));
}

#else

Expand Down Expand Up @@ -190,6 +198,9 @@ inline shared_ptr< collector > make_collector(T1 const& a1, T2 const& a2, T3 con
* the collector tries to maintain. If the threshold is exceeded, the oldest
* file(s) is deleted to free space. The threshold is not maintained, if not
* specified.
* \li \c max_files - Specifies the maximum number of log files stored. If the number of files exceeds
* this threshold, the oldest file(s) is deleted to free space. The threshhold is
* not maintained if not specified.
*
* \return The file collector.
*/
Expand Down
7 changes: 6 additions & 1 deletion src/init_from_settings.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -488,10 +488,15 @@ class default_text_file_sink_factory :
if (optional< string_type > min_space_param = params["MinFreeSpace"])
space = param_cast_to_int< uintmax_t >("MinFreeSpace", min_space_param.get());

uintmax_t max_files = (std::numeric_limits< uintmax_t >::max)();
if (optional< string_type > max_files_param = params["MaxFiles"])
max_files = param_cast_to_int< uintmax_t >("MaxFiles", max_files_param.get());

backend->set_file_collector(sinks::file::make_collector(
keywords::target = target_dir,
keywords::max_size = max_size,
keywords::min_free_space = space));
keywords::min_free_space = space,
keywords::max_files = max_files));

// Scan for log files
if (optional< string_type > scan_param = params["ScanForFiles"])
Expand Down
2 changes: 2 additions & 0 deletions src/parser_utils.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -106,6 +106,7 @@ struct char_constants< char >
static const char_type* target_address_param_name() { return "TargetAddress"; }
static const char_type* target_param_name() { return "Target"; }
static const char_type* max_size_param_name() { return "MaxSize"; }
static const char_type* max_files_param_name() { return "MaxFiles"; }
static const char_type* min_free_space_param_name() { return "MinFreeSpace"; }
static const char_type* scan_for_files_param_name() { return "ScanForFiles"; }

Expand Down Expand Up @@ -235,6 +236,7 @@ struct char_constants< wchar_t >
static const char_type* target_address_param_name() { return L"TargetAddress"; }
static const char_type* target_param_name() { return L"Target"; }
static const char_type* max_size_param_name() { return L"MaxSize"; }
static const char_type* max_files_param_name() { return L"MaxFiles"; }
static const char_type* min_free_space_param_name() { return L"MinFreeSpace"; }
static const char_type* scan_for_files_param_name() { return L"ScanForFiles"; }

Expand Down
30 changes: 19 additions & 11 deletions src/text_file_backend.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -545,6 +545,9 @@ BOOST_LOG_ANONYMOUS_NAMESPACE {
uintmax_t m_MaxSize;
//! Free space lower limit
uintmax_t m_MinFreeSpace;
//! File count upper limit
uintmax_t m_MaxFiles;

//! The current path at the point when the collector is created
/*
* The special member is required to calculate absolute paths with no
Expand All @@ -565,7 +568,8 @@ BOOST_LOG_ANONYMOUS_NAMESPACE {
shared_ptr< file_collector_repository > const& repo,
filesystem::path const& target_dir,
uintmax_t max_size,
uintmax_t min_free_space);
uintmax_t min_free_space,
uintmax_t max_files);

//! Destructor
~file_collector();
Expand All @@ -578,7 +582,7 @@ BOOST_LOG_ANONYMOUS_NAMESPACE {
file::scan_method method, filesystem::path const& pattern, unsigned int* counter);

//! The function updates storage restrictions
void update(uintmax_t max_size, uintmax_t min_free_space);
void update(uintmax_t max_size, uintmax_t min_free_space, uintmax_t max_files);

//! The function checks if the directory is governed by this collector
bool is_governed(filesystem::path const& dir) const
Expand Down Expand Up @@ -631,7 +635,7 @@ BOOST_LOG_ANONYMOUS_NAMESPACE {
public:
//! Finds or creates a file collector
shared_ptr< file::collector > get_collector(
filesystem::path const& target_dir, uintmax_t max_size, uintmax_t min_free_space);
filesystem::path const& target_dir, uintmax_t max_size, uintmax_t min_free_space, uintmax_t max_files);

//! Removes the file collector from the list
void remove_collector(file_collector* p);
Expand All @@ -649,11 +653,13 @@ BOOST_LOG_ANONYMOUS_NAMESPACE {
shared_ptr< file_collector_repository > const& repo,
filesystem::path const& target_dir,
uintmax_t max_size,
uintmax_t min_free_space
uintmax_t min_free_space,
uintmax_t max_files
) :
m_pRepository(repo),
m_MaxSize(max_size),
m_MinFreeSpace(min_free_space),
m_MaxFiles(max_files),
m_BasePath(filesystem::current_path()),
m_TotalSize(0)
{
Expand Down Expand Up @@ -715,7 +721,7 @@ BOOST_LOG_ANONYMOUS_NAMESPACE {
uintmax_t free_space = m_MinFreeSpace ? filesystem::space(m_StorageDir).available : static_cast< uintmax_t >(0);
file_list::iterator it = m_Files.begin(), end = m_Files.end();
while (it != end &&
(m_TotalSize + info.m_Size > m_MaxSize || (m_MinFreeSpace && m_MinFreeSpace > free_space)))
(m_TotalSize + info.m_Size > m_MaxSize || (m_MinFreeSpace && m_MinFreeSpace > free_space) || m_MaxFiles <= m_Files.size()))
{
file_info& old_info = *it;
if (filesystem::exists(old_info.m_Path) && filesystem::is_regular_file(old_info.m_Path))
Expand Down Expand Up @@ -830,18 +836,19 @@ BOOST_LOG_ANONYMOUS_NAMESPACE {
}

//! The function updates storage restrictions
void file_collector::update(uintmax_t max_size, uintmax_t min_free_space)
void file_collector::update(uintmax_t max_size, uintmax_t min_free_space, uintmax_t max_files)
{
BOOST_LOG_EXPR_IF_MT(lock_guard< mutex > lock(m_Mutex);)

m_MaxSize = (std::min)(m_MaxSize, max_size);
m_MinFreeSpace = (std::max)(m_MinFreeSpace, min_free_space);
m_MaxFiles = (std::min)(m_MaxFiles, max_files);
}


//! Finds or creates a file collector
shared_ptr< file::collector > file_collector_repository::get_collector(
filesystem::path const& target_dir, uintmax_t max_size, uintmax_t min_free_space)
filesystem::path const& target_dir, uintmax_t max_size, uintmax_t min_free_space, uintmax_t max_files)
{
BOOST_LOG_EXPR_IF_MT(lock_guard< mutex > lock(m_Mutex);)

Expand All @@ -852,7 +859,7 @@ BOOST_LOG_ANONYMOUS_NAMESPACE {
{
// This may throw if the collector is being currently destroyed
p = it->shared_from_this();
p->update(max_size, min_free_space);
p->update(max_size, min_free_space, max_files);
}
catch (bad_weak_ptr&)
{
Expand All @@ -861,7 +868,7 @@ BOOST_LOG_ANONYMOUS_NAMESPACE {
if (!p)
{
p = boost::make_shared< file_collector >(
file_collector_repository::get(), target_dir, max_size, min_free_space);
file_collector_repository::get(), target_dir, max_size, min_free_space, max_files);
m_Collectors.push_back(*p);
}

Expand Down Expand Up @@ -908,9 +915,10 @@ namespace aux {
BOOST_LOG_API shared_ptr< collector > make_collector(
filesystem::path const& target_dir,
uintmax_t max_size,
uintmax_t min_free_space)
uintmax_t min_free_space,
uintmax_t max_files)
{
return file_collector_repository::get()->get_collector(target_dir, max_size, min_free_space);
return file_collector_repository::get()->get_collector(target_dir, max_size, min_free_space, max_files);
}

} // namespace aux
Expand Down