CppLogging  1.0.4.0
C++ Logging Library
file_appender.cpp
Go to the documentation of this file.
1 
10 
11 namespace CppLogging {
12 
13 FileAppender::FileAppender(const CppCommon::Path& file, bool truncate, bool auto_flush, bool auto_start)
14  : _file(file), _truncate(truncate), _auto_flush(auto_flush)
15 {
16  // Start the file appender
17  if (auto_start)
18  Start();
19 }
20 
22 {
23  // Stop the file appender
24  if (IsStarted())
25  Stop();
26 }
27 
29 {
30  if (IsStarted())
31  return false;
32 
33  PrepareFile();
34  _started = true;
35  return true;
36 }
37 
39 {
40  if (!IsStarted())
41  return false;
42 
43  CloseFile();
44  _started = false;
45  return true;
46 }
47 
49 {
50  // Skip logging records without layout
51  if (record.raw.empty())
52  return;
53 
54  if (PrepareFile())
55  {
56  // Try to write logging record content into the opened file
57  try
58  {
59  _file.Write(record.raw.data(), record.raw.size() - 1);
60 
61  // Perform auto-flush if enabled
62  if (_auto_flush)
63  _file.Flush();
64  }
65  catch (const CppCommon::FileSystemException&)
66  {
67  // Try to close the opened file in case of any IO error
68  CloseFile();
69  }
70  }
71 }
72 
74 {
75  if (PrepareFile())
76  {
77  // Try to flush the opened file
78  try
79  {
80  _file.Flush();
81  }
82  catch (const CppCommon::FileSystemException&)
83  {
84  // Try to close the opened file in case of any IO error
85  CloseFile();
86  }
87  }
88 }
89 
90 bool FileAppender::PrepareFile()
91 {
92  try
93  {
94  // 1. Check if the file is already opened for writing
95  if (_file.IsFileWriteOpened())
96  return true;
97 
98  // 2. Check retry timestamp if 100ms elapsed after the last attempt
99  if ((CppCommon::Timestamp::utc() - _retry).milliseconds() < 100)
100  return false;
101 
102  // 3. If the file is opened for reading close it
103  if (_file.IsFileReadOpened())
104  _file.Close();
105 
106  // 4. Open the file for writing
107  _file.OpenOrCreate(false, true, _truncate);
108 
109  // 5. Reset the the retry timestamp
110  _retry = 0;
111 
112  return true;
113  }
114  catch (const CppCommon::FileSystemException&)
115  {
116  // In case of any IO error reset the retry timestamp and return false!
117  _retry = CppCommon::Timestamp::utc();
118  return false;
119  }
120 }
121 
122 bool FileAppender::CloseFile()
123 {
124  try
125  {
126  if (_file)
127  _file.Close();
128  return true;
129  }
130  catch (const CppCommon::FileSystemException&) { return false; }
131 }
132 
133 } // namespace CppLogging
bool IsStarted() const noexcept override
Is the logging element started?
Definition: file_appender.h:48
bool Start() override
Start the logging element.
void AppendRecord(Record &record) override
Append the given logging record.
void Flush() override
Flush the logging appender.
bool Stop() override
Stop the logging element.
FileAppender(const CppCommon::Path &file, bool truncate=false, bool auto_flush=false, bool auto_start=true)
Initialize the appender with a given file, truncate/append and auto-flush flags.
Logging record.
Definition: record.h:37
std::vector< uint8_t > raw
Record content after layout.
Definition: record.h:53
File appender definition.
C++ Logging project definitions.
Definition: appender.h:15