AzerothCore 3.3.5a
OpenSource WoW Emulator
Loading...
Searching...
No Matches
AppenderFile Class Reference

#include "AppenderFile.h"

Inheritance diagram for AppenderFile:
Appender

Public Member Functions

 AppenderFile (uint8 id, std::string const &name, LogLevel level, AppenderFlags flags, std::vector< std::string_view > const &args)
 
 ~AppenderFile ()
 
FILE * OpenFile (std::string const &name, std::string const &mode, bool backup)
 
AppenderType getType () const override
 
- Public Member Functions inherited from Appender
 Appender (uint8 _id, std::string const &name, LogLevel level=LOG_LEVEL_DISABLED, AppenderFlags flags=APPENDER_FLAGS_NONE)
 
virtual ~Appender ()
 
uint8 getId () const
 
std::string const & getName () const
 
virtual AppenderType getType () const =0
 
LogLevel getLogLevel () const
 
AppenderFlags getFlags () const
 
void setLogLevel (LogLevel)
 
void write (LogMessage *message)
 
virtual void setRealmId (uint32)
 

Static Public Attributes

static constexpr AppenderType type = APPENDER_FILE
 

Private Member Functions

void CloseFile ()
 
void _write (LogMessage const *message) override
 

Private Attributes

FILE * logfile
 
std::string _fileName
 
std::string _logDir
 
bool _dynamicName
 
bool _backup
 
uint64 _maxFileSize
 
std::atomic< uint64_fileSize
 

Additional Inherited Members

- Static Public Member Functions inherited from Appender
static char const * getLogLevelString (LogLevel level)
 

Detailed Description

Constructor & Destructor Documentation

◆ AppenderFile()

AppenderFile::AppenderFile ( uint8  id,
std::string const &  name,
LogLevel  level,
AppenderFlags  flags,
std::vector< std::string_view > const &  args 
)
25 :
26 Appender(id, name, level, flags),
27 logfile(nullptr),
28 _logDir(sLog->GetLogsDir()),
29 _maxFileSize(0),
30 _fileSize(0)
31{
32 if (args.size() < 4)
33 {
34 throw InvalidAppenderArgsException(Acore::StringFormat("Log::CreateAppenderFromConfig: Missing file name for appender {}", name));
35 }
36
37 _fileName.assign(args[3]);
38
39 std::string mode = "a";
40 if (4 < args.size())
41 {
42 mode.assign(args[4]);
43 }
44
46 {
47 std::size_t dot_pos = _fileName.find_last_of('.');
48 if (dot_pos != std::string::npos)
49 {
50 _fileName.insert(dot_pos, sLog->GetLogsTimestamp());
51 }
52 else
53 {
54 _fileName += sLog->GetLogsTimestamp();
55 }
56 }
57
58 if (5 < args.size())
59 {
60 if (Optional<uint32> size = Acore::StringTo<uint32>(args[5]))
61 {
62 _maxFileSize = *size;
63 }
64 else
65 {
66 throw InvalidAppenderArgsException(Acore::StringFormat("Log::CreateAppenderFromConfig: Invalid size '{}' for appender {}", args[5], name));
67 }
68 }
69
70 _dynamicName = std::string::npos != _fileName.find("%s");
72
73 if (!_dynamicName)
74 {
75 logfile = OpenFile(_fileName, mode, (mode == "w") && _backup);
76 }
77}
#define sLog
Definition: Log.h:126
@ APPENDER_FLAGS_MAKE_FILE_BACKUP
Definition: LogCommon.h:57
@ APPENDER_FLAGS_USE_TIMESTAMP
Definition: LogCommon.h:56
std::optional< T > Optional
Optional helper class to wrap optional values within.
Definition: Optional.h:24
std::string StringFormat(FormatString< Args... > fmt, Args &&... args)
Default AC string format function.
Definition: StringFormat.h:34
Definition: Appender.h:29
std::string name
Definition: Appender.h:49
LogLevel level
Definition: Appender.h:50
AppenderFlags flags
Definition: Appender.h:51
Definition: Appender.h:55
std::atomic< uint64 > _fileSize
Definition: AppenderFile.h:44
bool _dynamicName
Definition: AppenderFile.h:41
uint64 _maxFileSize
Definition: AppenderFile.h:43
bool _backup
Definition: AppenderFile.h:42
std::string _fileName
Definition: AppenderFile.h:39
FILE * logfile
Definition: AppenderFile.h:38
std::string _logDir
Definition: AppenderFile.h:40
FILE * OpenFile(std::string const &name, std::string const &mode, bool backup)
Definition: AppenderFile.cpp:122

References _backup, _dynamicName, _fileName, _maxFileSize, APPENDER_FLAGS_MAKE_FILE_BACKUP, APPENDER_FLAGS_USE_TIMESTAMP, Appender::flags, logfile, Appender::name, OpenFile(), sLog, and Acore::StringFormat().

◆ ~AppenderFile()

AppenderFile::~AppenderFile ( )
80{
81 CloseFile();
82}
void CloseFile()
Definition: AppenderFile.cpp:144

References CloseFile().

Member Function Documentation

◆ _write()

void AppenderFile::_write ( LogMessage const *  message)
overrideprivatevirtual

Implements Appender.

85{
86 bool exceedMaxSize = _maxFileSize > 0 && (_fileSize.load() + message->Size()) > _maxFileSize;
87
88 if (_dynamicName)
89 {
90 char namebuf[ACORE_PATH_MAX];
91 snprintf(namebuf, ACORE_PATH_MAX, _fileName.c_str(), message->param1.c_str());
92
93 // always use "a" with dynamic name otherwise it could delete the log we wrote in last _write() call
94 FILE* file = OpenFile(namebuf, "a", _backup || exceedMaxSize);
95 if (!file)
96 {
97 return;
98 }
99
100 fprintf(file, "%s%s\n", message->prefix.c_str(), message->text.c_str());
101 fflush(file);
102 _fileSize += uint64(message->Size());
103 fclose(file);
104
105 return;
106 }
107 else if (exceedMaxSize)
108 {
109 logfile = OpenFile(_fileName, "w", true);
110 }
111
112 if (!logfile)
113 {
114 return;
115 }
116
117 fprintf(logfile, "%s%s\n", message->prefix.c_str(), message->text.c_str());
118 fflush(logfile);
119 _fileSize += uint64(message->Size());
120}
#define ACORE_PATH_MAX
Definition: Define.h:40
std::uint64_t uint64
Definition: Define.h:106

References _backup, _dynamicName, _fileName, _fileSize, _maxFileSize, ACORE_PATH_MAX, logfile, OpenFile(), LogMessage::param1, LogMessage::prefix, LogMessage::Size(), and LogMessage::text.

◆ CloseFile()

void AppenderFile::CloseFile ( )
private
145{
146 if (logfile)
147 {
148 fclose(logfile);
149 logfile = nullptr;
150 }
151}

References logfile.

Referenced by OpenFile(), and ~AppenderFile().

◆ getType()

AppenderType AppenderFile::getType ( ) const
inlineoverridevirtual

Implements Appender.

33{ return type; }
static constexpr AppenderType type
Definition: AppenderFile.h:28

References type.

◆ OpenFile()

FILE * AppenderFile::OpenFile ( std::string const &  name,
std::string const &  mode,
bool  backup 
)
123{
124 std::string fullName(_logDir + filename);
125 if (backup)
126 {
127 CloseFile();
128 std::string newName(fullName);
129 newName.push_back('.');
130 newName.append(LogMessage::getTimeStr(GetEpochTime()));
131 std::replace(newName.begin(), newName.end(), ':', '-');
132 rename(fullName.c_str(), newName.c_str()); // no error handling... if we couldn't make a backup, just ignore
133 }
134
135 if (FILE* ret = fopen(fullName.c_str(), mode.c_str()))
136 {
137 _fileSize = ftell(ret);
138 return ret;
139 }
140
141 return nullptr;
142}
Seconds GetEpochTime()
Definition: Timer.h:141
std::string getTimeStr() const
Definition: LogMessage.cpp:32

References _fileSize, _logDir, CloseFile(), GetEpochTime(), and LogMessage::getTimeStr().

Referenced by _write(), and AppenderFile().

Member Data Documentation

◆ _backup

bool AppenderFile::_backup
private

Referenced by _write(), and AppenderFile().

◆ _dynamicName

bool AppenderFile::_dynamicName
private

Referenced by _write(), and AppenderFile().

◆ _fileName

std::string AppenderFile::_fileName
private

Referenced by _write(), and AppenderFile().

◆ _fileSize

std::atomic<uint64> AppenderFile::_fileSize
private

Referenced by _write(), and OpenFile().

◆ _logDir

std::string AppenderFile::_logDir
private

Referenced by OpenFile().

◆ _maxFileSize

uint64 AppenderFile::_maxFileSize
private

Referenced by _write(), and AppenderFile().

◆ logfile

FILE* AppenderFile::logfile
private

Referenced by _write(), AppenderFile(), and CloseFile().

◆ type

constexpr AppenderType AppenderFile::type = APPENDER_FILE
staticconstexpr

Referenced by getType().