1 #ifndef FILE_LOGGER_CLASS
2 #define FILE_LOGGER_CLASS
4 /*****************************************************************************\
7 * Author : Chris Koeritz *
9 *******************************************************************************
10 * Copyright (c) 2000-$now By Author. This program is free software; you can *
11 * redistribute it and/or modify it under the terms of the GNU General Public *
12 * License as published by the Free Software Foundation; either version 2 of *
13 * the License or (at your option) any later version. This is online at: *
14 * http://www.fsf.org/copyleft/gpl.html *
15 * Please send any updates to: fred@gruntose.com *
16 \*****************************************************************************/
18 //! Enables the printing of information to a log file.
20 The information can be conditionally printed using the filter support.
21 The log file will automatically be truncated when it passes the size limit.
24 #include "console_logger.h"
25 #include "eol_aware.h"
26 #include "filter_set.h"
28 #include <basis/astring.h>
29 #include <basis/contracts.h>
30 #include <basis/functions.h>
31 #include <basis/mutex.h>
32 #include <filesystem/byte_filer.h>
33 #include <textual/parser_bits.h>
37 class file_logger : public virtual standard_log_base
41 //!< creates a logger without a log file and with the default size limit.
42 /*!< the log file name can be changed using filename(). */
44 file_logger(const basis::astring &filename, int limit = DEFAULT_LOG_FILE_SIZE);
45 //!< constructs a logger using the "filename" for output.
46 /*!< there will be no logging if the "filename" is empty. the "limit"
47 specifies how large the log file can be (in bytes). */
49 virtual ~file_logger();
51 DEFINE_CLASS_NAME("file_logger");
54 //! this just defines the default for the log file size.
55 DEFAULT_LOG_FILE_SIZE = 0x10F00D
59 //!< returns true if the logger appears correctly hooked up to a file.
60 /*!< note that we don't open the file when file_logger is constructed;
61 it is only opened once the first logging is attempted. */
64 //!< closes the current file and attempts to reopen it.
65 /*!< this is handy if the original opening of the file failed. */
67 basis::outcome log(const basis::base_string &info, int filter = basis::ALWAYS_PRINT);
68 //!< writes information to the log file (if the filename is valid).
69 /*!< the "filter" value is checked to see if it is in the current set
70 of allowed filters. a value of zero is always printed. if the filename()
71 has not been set, then the information is lost. */
73 basis::outcome log_bytes(const basis::byte_array &to_log, int filter = basis::ALWAYS_PRINT);
74 //!< sends a stream of bytes "to_log" without interpretation into the log.
75 /*!< if the "filter" is not enabled, then the info is just tossed out. */
77 basis::outcome format_bytes(const basis::byte_array &to_log, int filter = basis::ALWAYS_PRINT);
78 //!< fancifully formats a stream of bytes "to_log" and sends them into log.
80 basis::astring name() const;
81 //!< observes the filename where logged information is written.
82 void name(const basis::astring &new_name);
83 //!< modifies the filename where logged information will be written.
84 /*!< if "new_name" is blank, then the logged information will not
87 int limit() const { return int(_file_limit); }
88 //!< observes the allowable size of the log file.
89 void limit(int new_limit) { _file_limit = new_limit; }
90 //!< modifies the allowable size of the log file.
93 //!< causes any pending writes to be sent to the output file.
95 void truncate(size_t new_size);
96 //!< chops the file to ensure it doesn't go much over the file size limit.
97 /*!< this can be used externally also, but be careful with it. */
99 //! returns a log file name for file_logger based on the program name.
100 /*! for a program named myapp.exe, this will be in the form:
101 {logging_dir}/myapp.log
103 static basis::astring log_file_for_app_name();
106 basis::astring *_filename; //!< debugging output file.
107 size_t _file_limit; //!< maximum length of file before truncation.
108 filesystem::byte_filer *_outfile; //!< the object that points at our output file.
109 basis::mutex *_flock; //!< protects the file and other parameters.
111 int size_reduction() const;
112 //!< returns the size of the chunk to truncate from the file.
113 /*!< this is a percentage of the maximum size allowed. */
116 //!< if the opening of the file is successful, then true is returned.
117 /*!< also, the _outfile member variable is non-zero. */
120 //!< shuts down the file, if any, we had opened for logging.
123 file_logger(const file_logger &);
124 file_logger &operator =(const file_logger &);
129 //! a macro that retasks the program-wide logger as a file_logger.
130 #define SETUP_FILE_LOGGER { \
131 loggers::standard_log_base *old_log = loggers::program_wide_logger::set \
132 (new loggers::file_logger(loggers::file_logger::log_file_for_app_name())); \