qxLib
base_file_logger_stream.inl
Go to the documentation of this file.
1 /**
2 
3  @file base_file_logger_stream.inl
4  @author Khrapov
5  @date 30.07.2021
6  @copyright (c) Nick Khrapov, 2021. All right reserved.
7 
8 **/
9 
10 namespace qx
11 {
12 
13 inline base_file_logger_stream::base_file_logger_stream(const config& streamConfig) noexcept
14  : base_logger_stream(streamConfig)
15 {
16 }
17 
19  const config& config) noexcept
20 {
21  // make sure the destination directory exists
22  std::filesystem::path logDirPath = config.svLogsDirectory;
23  if (!std::filesystem::exists(logDirPath))
24  {
25  if (!std::filesystem::create_directory(logDirPath))
26  {
27  details::get_cerr<char_type>::get() << QXT("Can't create output folder ") << logDirPath;
28  return std::filesystem::path();
29  }
30  }
31 
32  // construct the log name
33  string sLogFile = config.svLogsDirectory;
34  if (!config.svLogsDirectory.empty() && !config.svLogsDirectory.ends_with(QXT('/'))
35  && !config.svLogsDirectory.ends_with(QXT('\\')))
36  {
37  sLogFile += QXT('/');
38  }
39  sLogFile += config.svFilePrefix;
40 
41  if (config.eLogFilePolicy == log_file_policy::time_name)
42  {
43  sLogFile.append_format(
44  QXT("_{:%d-%m-%Y_%H-%M-%S}"),
45  std::chrono::floor<std::chrono::seconds>(std::chrono::system_clock::now()));
46  }
47 
48  sLogFile += config.svFileExtension;
49 
50 
51  // rotate logs
52  if ((config.eLogFilePolicy == log_file_policy::time_name
53  || config.eLogFilePolicy == log_file_policy::time_name_keep_current)
54  && config.nMaxLogFiles > 0)
55  {
56  if (config.eLogFilePolicy == log_file_policy::time_name_keep_current
57  && std::filesystem::exists(sLogFile.c_str()))
58  {
59  const std::filesystem::file_time_type lastWriteTimeFileClock =
60  std::filesystem::last_write_time(sLogFile.c_str());
61  const auto lastWriteTimeSystemClock =
62  std::chrono::clock_cast<std::chrono::system_clock>(lastWriteTimeFileClock);
63  const auto lastWriteTimeSystemClockSeconds =
64  std::chrono::floor<std::chrono::seconds>(lastWriteTimeSystemClock);
65 
66  string sNewFileName = sLogFile;
67  sNewFileName.remove_suffix(config.svFileExtension);
68  sNewFileName.append_format(
69  QXT("_{:%d-%m-%Y_%H-%M-%S}{}"),
70  lastWriteTimeSystemClockSeconds,
71  config.svFileExtension);
72 
73  std::filesystem::rename(sLogFile.c_str(), sNewFileName.c_str());
74  }
75 
76  std::vector<std::filesystem::directory_entry> logFiles;
77  for (const std::filesystem::directory_entry& entry :
78  std::filesystem::directory_iterator(logDirPath)
79  | std::views::filter(
80  [&config](const std::filesystem::directory_entry& entry)
81  {
82  return entry.path().extension() == config.svFileExtension;
83  }))
84  {
85  const std::basic_string<char_type> sFilename = entry.path().filename().generic_string<char_type>();
86  if (sFilename.starts_with(config.svFilePrefix))
87  logFiles.push_back(entry);
88  }
89 
90  if (logFiles.size() > config.nMaxLogFiles - 1)
91  {
92  std::ranges::sort(
93  logFiles,
94  [](const std::filesystem::directory_entry& left, const std::filesystem::directory_entry& right)
95  {
96  return std::filesystem::last_write_time(left) > std::filesystem::last_write_time(right);
97  });
98 
99  for (size_t i = config.nMaxLogFiles - 1; i < logFiles.size(); ++i)
100  std::filesystem::remove(logFiles[i]);
101  }
102  }
103 
104  return sLogFile.c_str();
105 }
106 
107 } // namespace qx
base_file_logger_stream(const config &streamConfig) noexcept
file_logger_stream object constructor
std::filesystem::path prepare_folder_and_get_log_file_path(const config &config) noexcept
Create a folder (if required) and get log file path.
Base class for logger streams.
requires format_acceptable_args_c< char_t, args_t... > void append_format(const format_string_type< std::type_identity_t< args_t >... > sFormat, args_t &&... args) noexcept
Append the formatted string to the current one.
Definition: string.inl:146
bool remove_suffix(value_type chSymbol) noexcept
Remove string suffix if matches.
Definition: string.inl:1067
const_pointer c_str() const noexcept
Get pointer to string zero terminated.
Definition: string.inl:273