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