]> git.proxmox.com Git - ceph.git/blame - ceph/src/boost/boost/log/sinks/text_file_backend.hpp
Add patch for failing prerm scripts
[ceph.git] / ceph / src / boost / boost / log / sinks / text_file_backend.hpp
CommitLineData
7c673cae
FG
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_file_backend.hpp
9 * \author Andrey Semashev
10 * \date 09.06.2009
11 *
12 * The header contains implementation of a text file sink backend.
13 */
14
15#ifndef BOOST_LOG_SINKS_TEXT_FILE_BACKEND_HPP_INCLUDED_
16#define BOOST_LOG_SINKS_TEXT_FILE_BACKEND_HPP_INCLUDED_
17
18#include <ios>
19#include <string>
20#include <ostream>
21#include <boost/limits.hpp>
22#include <boost/cstdint.hpp>
23#include <boost/smart_ptr/shared_ptr.hpp>
24#include <boost/date_time/date_defs.hpp>
25#include <boost/date_time/special_defs.hpp>
26#include <boost/date_time/gregorian/greg_day.hpp>
27#include <boost/date_time/posix_time/posix_time_types.hpp>
28#include <boost/filesystem/path.hpp>
29#include <boost/log/keywords/max_size.hpp>
30#include <boost/log/keywords/max_files.hpp>
31#include <boost/log/keywords/min_free_space.hpp>
32#include <boost/log/keywords/target.hpp>
33#include <boost/log/keywords/file_name.hpp>
34#include <boost/log/keywords/open_mode.hpp>
35#include <boost/log/keywords/auto_flush.hpp>
36#include <boost/log/keywords/rotation_size.hpp>
37#include <boost/log/keywords/time_based_rotation.hpp>
b32b8144 38#include <boost/log/keywords/enable_final_rotation.hpp>
7c673cae
FG
39#include <boost/log/detail/config.hpp>
40#include <boost/log/detail/light_function.hpp>
41#include <boost/log/detail/parameter_tools.hpp>
42#include <boost/log/sinks/basic_sink_backend.hpp>
43#include <boost/log/sinks/frontend_requirements.hpp>
44#include <boost/log/detail/header.hpp>
45
46#ifdef BOOST_HAS_PRAGMA_ONCE
47#pragma once
48#endif
49
50namespace boost {
51
52BOOST_LOG_OPEN_NAMESPACE
53
54namespace sinks {
55
56namespace file {
57
58//! The enumeration of the stored files scan methods
59enum scan_method
60{
61 no_scan, //!< Don't scan for stored files
62 scan_matching, //!< Scan for files with names matching the specified mask
63 scan_all //!< Scan for all files in the directory
64};
65
66/*!
67 * \brief Base class for file collectors
68 *
69 * All file collectors, supported by file sink backends, should inherit this class.
70 */
71struct BOOST_LOG_NO_VTABLE collector
72{
73 /*!
74 * Default constructor
75 */
76 BOOST_DEFAULTED_FUNCTION(collector(), {})
77
78 /*!
79 * Virtual destructor
80 */
81 virtual ~collector() {}
82
83 /*!
84 * The function stores the specified file in the storage. May lead to an older file
85 * deletion and a long file moving.
86 *
87 * \param src_path The name of the file to be stored
88 */
89 virtual void store_file(filesystem::path const& src_path) = 0;
90
91 /*!
92 * Scans the target directory for the files that have already been stored. The found
93 * files are added to the collector in order to be tracked and erased, if needed.
94 *
95 * The function may scan the directory in two ways: it will either consider every
96 * file in the directory a log file, or will only consider files with names that
97 * match the specified pattern. The pattern may contain the following placeholders:
98 *
99 * \li %y, %Y, %m, %d - date components, in Boost.DateTime meaning.
100 * \li %H, %M, %S, %f - time components, in Boost.DateTime meaning.
101 * \li %N - numeric file counter. May also contain width specification
102 * in printf-compatible form (e.g. %5N). The resulting number will always be zero-filled.
103 * \li %% - a percent sign
104 *
105 * All other placeholders are not supported.
106 *
107 * \param method The method of scanning. If \c no_scan is specified, the call has no effect.
108 * \param pattern The file name pattern if \a method is \c scan_matching. Otherwise the parameter
109 * is not used.
110 * \param counter If not \c NULL and \a method is \c scan_matching, the method suggests initial value
111 * of a file counter that may be used in the file name pattern. The parameter
112 * is not used otherwise.
113 * \return The number of found files.
114 *
115 * \note In case if \a method is \c scan_matching the effect of this function is highly dependent
116 * on the \a pattern definition. It is recommended to choose patterns with easily
117 * distinguished placeholders (i.e. having delimiters between them). Otherwise
118 * either some files can be mistakenly found or not found, which in turn may lead
119 * to an incorrect file deletion.
120 */
121 virtual uintmax_t scan_for_files(
122 scan_method method, filesystem::path const& pattern = filesystem::path(), unsigned int* counter = 0) = 0;
123
124 BOOST_DELETED_FUNCTION(collector(collector const&))
125 BOOST_DELETED_FUNCTION(collector& operator= (collector const&))
126};
127
128namespace aux {
129
130 //! Creates and returns a file collector with the specified parameters
131 BOOST_LOG_API shared_ptr< collector > make_collector(
132 filesystem::path const& target_dir,
133 uintmax_t max_size,
134 uintmax_t min_free_space,
135 uintmax_t max_files = (std::numeric_limits< uintmax_t >::max)()
136 );
137 template< typename ArgsT >
138 inline shared_ptr< collector > make_collector(ArgsT const& args)
139 {
140 return aux::make_collector(
141 filesystem::path(args[keywords::target]),
142 args[keywords::max_size | (std::numeric_limits< uintmax_t >::max)()],
143 args[keywords::min_free_space | static_cast< uintmax_t >(0)],
144 args[keywords::max_files | (std::numeric_limits< uintmax_t >::max)()]);
145 }
146
147} // namespace aux
148
149#ifndef BOOST_LOG_DOXYGEN_PASS
150
151template< typename T1 >
152inline shared_ptr< collector > make_collector(T1 const& a1)
153{
154 return aux::make_collector(a1);
155}
156template< typename T1, typename T2 >
157inline shared_ptr< collector > make_collector(T1 const& a1, T2 const& a2)
158{
159 return aux::make_collector((a1, a2));
160}
161template< typename T1, typename T2, typename T3 >
162inline shared_ptr< collector > make_collector(T1 const& a1, T2 const& a2, T3 const& a3)
163{
164 return aux::make_collector((a1, a2, a3));
165}
166template< typename T1, typename T2, typename T3, typename T4 >
167inline shared_ptr< collector > make_collector(T1 const& a1, T2 const& a2, T3 const& a3, T4 const& a4)
168{
169 return aux::make_collector((a1, a2, a3, a4));
170}
171
172#else
173
174/*!
175 * The function creates a file collector for the specified target directory.
176 * Each target directory is managed by a single file collector, so if
177 * this function is called several times for the same directory,
178 * it will return a reference to the same file collector. It is safe
179 * to use the same collector in different sinks, even in a multithreaded
180 * application.
181 *
182 * One can specify certain restrictions for the stored files, such as
183 * maximum total size or minimum free space left in the target directory.
184 * If any of the specified restrictions is not met, the oldest stored file
185 * is deleted. If the same collector is requested more than once with
186 * different restrictions, the collector will act according to the most strict
187 * combination of all specified restrictions.
188 *
189 * The following named parameters are supported:
190 *
191 * \li \c target - Specifies the target directory for the files being stored in. This parameter
192 * is mandatory.
193 * \li \c max_size - Specifies the maximum total size, in bytes, of stored files that the collector
194 * will try not to exceed. If the size exceeds this threshold the oldest file(s) is
195 * deleted to free space. Note that the threshold may be exceeded if the size of
196 * individual files exceed the \c max_size value. The threshold is not maintained,
197 * if not specified.
198 * \li \c min_free_space - Specifies the minimum free space, in bytes, in the target directory that
199 * the collector tries to maintain. If the threshold is exceeded, the oldest
200 * file(s) is deleted to free space. The threshold is not maintained, if not
201 * specified.
202 * \li \c max_files - Specifies the maximum number of log files stored. If the number of files exceeds
203 * this threshold, the oldest file(s) is deleted to free space. The threshhold is
204 * not maintained if not specified.
205 *
206 * \return The file collector.
207 */
208template< typename... ArgsT >
209shared_ptr< collector > make_collector(ArgsT... const& args);
210
211#endif // BOOST_LOG_DOXYGEN_PASS
212
213/*!
214 * The class represents the time point of log file rotation. One can specify one of three
215 * types of time point based rotation:
216 *
217 * \li rotation takes place every day, at the specified time
218 * \li rotation takes place on the specified day of every week, at the specified time
219 * \li rotation takes place on the specified day of every month, at the specified time
220 *
221 * The time points are considered to be local time.
222 */
223class rotation_at_time_point
224{
225public:
226 typedef bool result_type;
227
228private:
229 enum day_kind
230 {
231 not_specified,
232 weekday,
233 monthday
234 };
235
236 day_kind m_DayKind : 2;
237 unsigned char m_Day : 6;
238 unsigned char m_Hour, m_Minute, m_Second;
239
240 mutable posix_time::ptime m_Previous;
241
242public:
243 /*!
244 * Creates a rotation time point of every day at the specified time
245 *
246 * \param hour The rotation hour, should be within 0 and 23
247 * \param minute The rotation minute, should be within 0 and 59
248 * \param second The rotation second, should be within 0 and 59
249 */
250 BOOST_LOG_API explicit rotation_at_time_point(unsigned char hour, unsigned char minute, unsigned char second);
251
252 /*!
253 * Creates a rotation time point of each specified weekday at the specified time
254 *
255 * \param wday The weekday of the rotation
256 * \param hour The rotation hour, should be within 0 and 23
257 * \param minute The rotation minute, should be within 0 and 59
258 * \param second The rotation second, should be within 0 and 59
259 */
260 BOOST_LOG_API explicit rotation_at_time_point(
261 date_time::weekdays wday,
262 unsigned char hour = 0,
263 unsigned char minute = 0,
264 unsigned char second = 0);
265
266 /*!
267 * Creates a rotation time point of each specified day of month at the specified time
268 *
269 * \param mday The monthday of the rotation, should be within 1 and 31
270 * \param hour The rotation hour, should be within 0 and 23
271 * \param minute The rotation minute, should be within 0 and 59
272 * \param second The rotation second, should be within 0 and 59
273 */
274 BOOST_LOG_API explicit rotation_at_time_point(
275 gregorian::greg_day mday,
276 unsigned char hour = 0,
277 unsigned char minute = 0,
278 unsigned char second = 0);
279
280 /*!
281 * Checks if it's time to rotate the file
282 */
283 BOOST_LOG_API bool operator() () const;
284};
285
286/*!
287 * The class represents the time interval of log file rotation. The log file will be rotated
288 * after the specified time interval has passed.
289 */
290class rotation_at_time_interval
291{
292public:
293 typedef bool result_type;
294
295private:
296 posix_time::time_duration m_Interval;
297 mutable posix_time::ptime m_Previous;
298
299public:
300 /*!
301 * Creates a rotation time interval of the specified duration
302 *
303 * \param interval The interval of the rotation, should be no less than 1 second
304 */
305 explicit rotation_at_time_interval(posix_time::time_duration const& interval) :
306 m_Interval(interval)
307 {
308 BOOST_ASSERT(!interval.is_special());
309 BOOST_ASSERT(interval.total_seconds() > 0);
310 }
311
312 /*!
313 * Checks if it's time to rotate the file
314 */
315 BOOST_LOG_API bool operator() () const;
316};
317
318} // namespace file
319
320
321/*!
322 * \brief An implementation of a text file logging sink backend
323 *
324 * The sink backend puts formatted log records to a text file.
325 * The sink supports file rotation and advanced file control, such as
326 * size and file count restriction.
327 */
328class text_file_backend :
329 public basic_formatted_sink_backend<
330 char,
331 combine_requirements< synchronized_feeding, flushing >::type
332 >
333{
334 //! Base type
335 typedef basic_formatted_sink_backend<
336 char,
337 combine_requirements< synchronized_feeding, flushing >::type
338 > base_type;
339
340public:
341 //! Character type
342 typedef base_type::char_type char_type;
343 //! String type to be used as a message text holder
344 typedef base_type::string_type string_type;
345 //! Stream type
346 typedef std::basic_ostream< char_type > stream_type;
347
348 //! File open handler
349 typedef boost::log::aux::light_function< void (stream_type&) > open_handler_type;
350 //! File close handler
351 typedef boost::log::aux::light_function< void (stream_type&) > close_handler_type;
352
353 //! Predicate that defines the time-based condition for file rotation
354 typedef boost::log::aux::light_function< bool () > time_based_rotation_predicate;
355
356private:
357 //! \cond
358
359 struct implementation;
360 implementation* m_pImpl;
361
362 //! \endcond
363
364public:
365 /*!
366 * Default constructor. The constructed sink backend uses default values of all the parameters.
367 */
368 BOOST_LOG_API text_file_backend();
369
370 /*!
371 * Constructor. Creates a sink backend with the specified named parameters.
372 * The following named parameters are supported:
373 *
374 * \li \c file_name - Specifies the file name pattern where logs are actually written to. The pattern may
375 * contain directory and file name portions, but only the file name may contain
376 * placeholders. The backend supports Boost.DateTime placeholders for injecting
377 * current time and date into the file name. Also, an additional %N placeholder is
378 * supported, it will be replaced with an integral increasing file counter. The placeholder
379 * may also contain width specification in the printf-compatible form (e.g. %5N). The
380 * printed file counter will always be zero-filled. If \c file_name is not specified,
381 * pattern "%5N.log" will be used.
382 * \li \c open_mode - File open mode. The mode should be presented in form of mask compatible to
383 * <tt>std::ios_base::openmode</tt>. If not specified, <tt>trunc | out</tt> will be used.
384 * \li \c rotation_size - Specifies the approximate size, in characters written, of the temporary file
385 * upon which the file is passed to the file collector. Note the size does
386 * not count any possible character conversions that may take place during
387 * writing to the file. If not specified, the file won't be rotated upon reaching
388 * any size.
389 * \li \c time_based_rotation - Specifies the predicate for time-based file rotation.
390 * No time-based file rotations will be performed, if not specified.
b32b8144
FG
391 * \li \c enable_final_rotation - Specifies a flag, whether or not perform log file rotation on
392 * sink backend destruction. By default, is \c true.
7c673cae
FG
393 * \li \c auto_flush - Specifies a flag, whether or not to automatically flush the file after each
394 * written log record. By default, is \c false.
395 *
396 * \note Read the caution note regarding file name pattern in the <tt>sinks::file::collector::scan_for_files</tt>
397 * documentation.
398 */
399#ifndef BOOST_LOG_DOXYGEN_PASS
400 BOOST_LOG_PARAMETRIZED_CONSTRUCTORS_CALL(text_file_backend, construct)
401#else
402 template< typename... ArgsT >
403 explicit text_file_backend(ArgsT... const& args);
404#endif
405
406 /*!
407 * Destructor
408 */
409 BOOST_LOG_API ~text_file_backend();
410
411 /*!
412 * The method sets file name wildcard for the files being written. The wildcard supports
413 * date and time injection into the file name.
414 *
415 * \param pattern The name pattern for the file being written.
416 */
417 template< typename PathT >
418 void set_file_name_pattern(PathT const& pattern)
419 {
420 set_file_name_pattern_internal(filesystem::path(pattern));
421 }
422
423 /*!
424 * The method sets the file open mode
425 *
426 * \param mode File open mode
427 */
428 BOOST_LOG_API void set_open_mode(std::ios_base::openmode mode);
429
430 /*!
431 * The method sets the log file collector function. The function is called
432 * on file rotation and is being passed the written file name.
433 *
434 * \param collector The file collector function object
435 */
436 BOOST_LOG_API void set_file_collector(shared_ptr< file::collector > const& collector);
437
438 /*!
439 * The method sets file opening handler. The handler will be called every time
440 * the backend opens a new temporary file. The handler may write a header to the
441 * opened file in order to maintain file validity.
442 *
443 * \param handler The file open handler function object
444 */
445 BOOST_LOG_API void set_open_handler(open_handler_type const& handler);
446
447 /*!
448 * The method sets file closing handler. The handler will be called every time
449 * the backend closes a temporary file. The handler may write a footer to the
450 * opened file in order to maintain file validity.
451 *
452 * \param handler The file close handler function object
453 */
454 BOOST_LOG_API void set_close_handler(close_handler_type const& handler);
455
456 /*!
457 * The method sets maximum file size. When the size is reached, file rotation is performed.
458 *
459 * \note The size does not count any possible character translations that may happen in
460 * the underlying API. This may result in greater actual sizes of the written files.
461 *
462 * \param size The maximum file size, in characters.
463 */
464 BOOST_LOG_API void set_rotation_size(uintmax_t size);
465
466 /*!
467 * The method sets the predicate that defines the time-based condition for file rotation.
468 *
469 * \note The rotation always occurs on writing a log record, so the rotation is
470 * not strictly bound to the specified condition.
471 *
472 * \param predicate The predicate that defines the time-based condition for file rotation.
473 * If empty, no time-based rotation will take place.
474 */
475 BOOST_LOG_API void set_time_based_rotation(time_based_rotation_predicate const& predicate);
476
477 /*!
b32b8144
FG
478 * The method allows to enable or disable log file rotation on sink destruction.
479 *
480 * By default the sink backend will rotate the log file, if it's been written to, on
481 * destruction.
482 *
483 * \param enable The flag indicates whether the final rotation should be performed.
484 */
485 BOOST_LOG_API void enable_final_rotation(bool enable);
486
487 /*!
488 * Sets the flag to automatically flush write buffers of the file being written after each log record.
489 *
490 * \param enable The flag indicates whether the automatic buffer flush should be performed.
7c673cae 491 */
b32b8144 492 BOOST_LOG_API void auto_flush(bool enable = true);
7c673cae
FG
493
494 /*!
495 * \return The name of the currently open log file. If no file is open, returns an empty path.
496 */
497 BOOST_LOG_API filesystem::path get_current_file_name() const;
498
499 /*!
500 * Performs scanning of the target directory for log files that may have been left from
501 * previous runs of the application. The found files are considered by the file collector
502 * as if they were rotated.
503 *
504 * The file scan can be performed in two ways: either all files in the target directory will
505 * be considered as log files, or only those files that satisfy the file name pattern.
506 * See documentation on <tt>sinks::file::collector::scan_for_files</tt> for more information.
507 *
508 * \pre File collector and the proper file name pattern have already been set.
509 *
510 * \param method File scanning method
511 * \param update_counter If \c true and \a method is \c scan_matching, the method attempts
512 * to update the internal file counter according to the found files. The counter
513 * is unaffected otherwise.
514 * \return The number of files found.
515 *
516 * \note The method essentially delegates to the same-named function of the file collector.
517 */
518 BOOST_LOG_API uintmax_t scan_for_files(
519 file::scan_method method = file::scan_matching, bool update_counter = true);
520
521 /*!
522 * The method writes the message to the sink
523 */
524 BOOST_LOG_API void consume(record_view const& rec, string_type const& formatted_message);
525
526 /*!
527 * The method flushes the currently open log file
528 */
529 BOOST_LOG_API void flush();
530
531 /*!
532 * The method rotates the file
533 */
534 BOOST_LOG_API void rotate_file();
535
536private:
537#ifndef BOOST_LOG_DOXYGEN_PASS
538 //! Constructor implementation
539 template< typename ArgsT >
540 void construct(ArgsT const& args)
541 {
542 construct(
543 filesystem::path(args[keywords::file_name | filesystem::path()]),
544 args[keywords::open_mode | (std::ios_base::trunc | std::ios_base::out)],
545 args[keywords::rotation_size | (std::numeric_limits< uintmax_t >::max)()],
546 args[keywords::time_based_rotation | time_based_rotation_predicate()],
b32b8144
FG
547 args[keywords::auto_flush | false],
548 args[keywords::enable_final_rotation | true]);
7c673cae
FG
549 }
550 //! Constructor implementation
551 BOOST_LOG_API void construct(
552 filesystem::path const& pattern,
553 std::ios_base::openmode mode,
554 uintmax_t rotation_size,
555 time_based_rotation_predicate const& time_based_rotation,
b32b8144
FG
556 bool auto_flush,
557 bool enable_final_rotation);
7c673cae
FG
558
559 //! The method sets file name mask
560 BOOST_LOG_API void set_file_name_pattern_internal(filesystem::path const& pattern);
561
562 //! Closes the currently open file
563 void close_file();
564#endif // BOOST_LOG_DOXYGEN_PASS
565};
566
567} // namespace sinks
568
569BOOST_LOG_CLOSE_NAMESPACE // namespace log
570
571} // namespace boost
572
573#include <boost/log/detail/footer.hpp>
574
575#endif // BOOST_LOG_SINKS_TEXT_FILE_BACKEND_HPP_INCLUDED_