bux API Reference 1.9.0
Static library of whatever are seen required in general purpose but not directly supported from Modern C++. Or whatever reusable originated from my side projects.
Loading...
Searching...
No Matches
FileLog.cpp
Go to the documentation of this file.
1#include "FileLog.h"
2#include <format> // std::vformat()
3
4namespace fs = std::filesystem;
5
6namespace bux {
7
8//
9// Class Implementation
10//
11C_PathFmtLogSnap::C_PathFmtLogSnap(const std::chrono::time_zone *tz): m_tz(tz)
12{
13 configPath("{:%Y%m%d}.log");
14}
15
22{
23 if (_pathFmt.empty())
24 RUNTIME_ERROR("Null path format");
25
26 m_PathFmts.clear();
27 m_PathFmts.emplace_back(fs::absolute(_pathFmt).string());
28 m_FileSizeLimit =
29 m_CurPathFmt = 0;
30 return *this;
31}
32
39{
40 m_AutoMkDir = yes;
41 return *this;
42}
43
48{
49 m_OpenMode = std::ios_base::out;
50 if (enabled)
51 m_OpenMode |= std::ios_base::binary;
52
53 m_CurrPath.clear(); // trigger reopen
54 return *this;
55}
56
58{
59 const auto t = time_point_cast<std::chrono::seconds>(std::chrono::system_clock::now());
60 const auto get_new_path = [t,this](auto indFmt) {
61 std::string_view pathFmt = m_PathFmts.at(indFmt);
62 if (m_tz)
63 {
64 const auto lt = m_tz->to_local(t);
65 return std::vformat(pathFmt, make_format_args(lt));
66 }
67 return std::vformat(pathFmt, make_format_args(t));
68 };
69 std::string nextPath;
70 if (m_OldTime == t)
71 nextPath = m_CurrPath;
72 else
73 {
74 m_OldTime = t;
75 nextPath = get_new_path(m_CurPathFmt);
76 }
77OpenNewFile:
78 if (nextPath.empty())
79 return nullptr;
80
81 if (m_CurrPath != nextPath)
82 // Different paths -- Repoen it
83 {
84 if (m_CurrPath.empty())
85 // First time
86 {
87 if (m_FileSizeLimit)
88 while (m_CurPathFmt + 1 < m_PathFmts.size() &&
89 fs::is_regular_file(nextPath) &&
90 fs::file_size(nextPath) >= m_FileSizeLimit)
91 nextPath = get_new_path(++m_CurPathFmt);
92 }
93 else
94 // Find the lowest fallback
95 while (m_CurPathFmt)
96 {
97 auto s2 = get_new_path(m_CurPathFmt - 1);
98 if (fs::exists(s2))
99 break;
100
101 --m_CurPathFmt;
102 nextPath = std::move(s2);
103 }
104
105 // At this stage, nextPath is finalized as the new log path for sure
106 if (m_AutoMkDir)
107 (void)create_directories(fs::path(nextPath).parent_path());
108
109 m_Out.clear();
110 if (m_CurrPath.empty())
111 // First open
112 m_Out.open(nextPath, m_OpenMode|std::ios::ate|std::ios::in);
113 else
114 // Close the opened file
115 m_Out.close();
116
117 if (!m_Out.is_open())
118 // Mostly serve for the latter case
119 {
120 m_Out.clear();
121 m_Out.open(nextPath, m_OpenMode);
122 }
123 if (!m_Out.is_open())
124 RUNTIME_ERROR("{}", nextPath);
125
126 m_CurrPath = nextPath;
127 }
128 else if (
129 m_FileSizeLimit &&
130 m_CurPathFmt + 1 < m_PathFmts.size() &&
131 m_Out.tellp() >= std::streamoff(m_FileSizeLimit))
132 // Size limit is reached and we can fallback to use the next path format
133 {
134 nextPath = get_new_path(++m_CurPathFmt);
135 goto OpenNewFile;
136 }
137 return &m_Out;
138}
139
140} // namespace bux
#define RUNTIME_ERROR(fmtStr,...)
Wrap FILE(DATE)#__LINE__ FUNCTION: msg into std::runtime_error.
Definition XException.h:32
C_PathFmtLogSnap & enableAutoMkDir(bool yes=true)
Definition FileLog.cpp:33
std::ostream * snap() override
Snap the current T value.
Definition FileLog.cpp:57
C_PathFmtLogSnap(const std::chrono::time_zone *tz)
Definition FileLog.cpp:11
C_PathFmtLogSnap & setBinaryMode(bool enabled)
Definition FileLog.cpp:44
C_PathFmtLogSnap & configPath(const std::string &pathFmt)
Definition FileLog.cpp:16
THE common namespace of bux library.
Definition AtomiX.cpp:3