summaryrefslogtreecommitdiff
path: root/src/common/Logging/AppenderFile.cpp
diff options
context:
space:
mode:
authorKargatum <dowlandtop@yandex.com>2021-04-17 16:20:07 +0700
committerGitHub <noreply@github.com>2021-04-17 11:20:07 +0200
commit4af4cbd3d966a05c584f4b6c63f69517dad0677d (patch)
tree1c4329a0c64233aaa033ac3788c1e4ddc9422eb9 /src/common/Logging/AppenderFile.cpp
parentb2861be1cd623182fd9e900c9ccfe8e063f28d8e (diff)
feat(Core/Logging): rework logging (#4692)
* feat(Core/Logging): rework logging * correct level for sql.sql * del unused config options * Correct build * correct after merge * whitespace 20:29:37 1. 'Player.cpp'. Replace (1) 20:29:37 2. 'ObjectMgr.cpp'. Replace (3) * 1 * correct logging * correct affter merge * 1 * 2 * LOG_LEVEL_WARN * #include "AppenderDB.h" * 3 * 4 * 5 * 1. 'WorldSocket.cpp'. Replace (1) * 6 * 1
Diffstat (limited to 'src/common/Logging/AppenderFile.cpp')
-rw-r--r--src/common/Logging/AppenderFile.cpp119
1 files changed, 119 insertions, 0 deletions
diff --git a/src/common/Logging/AppenderFile.cpp b/src/common/Logging/AppenderFile.cpp
new file mode 100644
index 0000000000..5f7bdb6349
--- /dev/null
+++ b/src/common/Logging/AppenderFile.cpp
@@ -0,0 +1,119 @@
+/*
+ * Copyright (C) 2016+ AzerothCore <www.azerothcore.org>, released under GNU AGPL v3 license: https://github.com/azerothcore/azerothcore-wotlk/blob/master/LICENSE-AGPL3
+ * Copyright (C) 2008-2021 TrinityCore <http://www.trinitycore.org/>
+ */
+
+#include "AppenderFile.h"
+#include "Log.h"
+#include "LogMessage.h"
+#include "StringConvert.h"
+#include "Util.h"
+#include <algorithm>
+
+AppenderFile::AppenderFile(uint8 id, std::string const& name, LogLevel level, AppenderFlags flags, std::vector<std::string_view> const& args) :
+ Appender(id, name, level, flags),
+ logfile(nullptr),
+ _logDir(sLog->GetLogsDir()),
+ _maxFileSize(0),
+ _fileSize(0)
+{
+ if (args.size() < 4)
+ throw InvalidAppenderArgsException(acore::StringFormat("Log::CreateAppenderFromConfig: Missing file name for appender %s", name.c_str()));
+
+ _fileName.assign(args[3]);
+
+ std::string mode = "a";
+ if (4 < args.size())
+ mode.assign(args[4]);
+
+ if (flags & APPENDER_FLAGS_USE_TIMESTAMP)
+ {
+ size_t dot_pos = _fileName.find_last_of('.');
+ if (dot_pos != std::string::npos)
+ _fileName.insert(dot_pos, sLog->GetLogsTimestamp());
+ else
+ _fileName += sLog->GetLogsTimestamp();
+ }
+
+ if (5 < args.size())
+ {
+ if (Optional<uint32> size = acore::StringTo<uint32>(args[5]))
+ _maxFileSize = *size;
+ else
+ throw InvalidAppenderArgsException(acore::StringFormat("Log::CreateAppenderFromConfig: Invalid size '%s' for appender %s", std::string(args[5]).c_str(), name.c_str()));
+ }
+
+ _dynamicName = std::string::npos != _fileName.find("%s");
+ _backup = (flags & APPENDER_FLAGS_MAKE_FILE_BACKUP) != 0;
+
+ if (!_dynamicName)
+ logfile = OpenFile(_fileName, mode, (mode == "w") && _backup);
+}
+
+AppenderFile::~AppenderFile()
+{
+ CloseFile();
+}
+
+void AppenderFile::_write(LogMessage const* message)
+{
+ bool exceedMaxSize = _maxFileSize > 0 && (_fileSize.load() + message->Size()) > _maxFileSize;
+
+ if (_dynamicName)
+ {
+ char namebuf[ACORE_PATH_MAX];
+ snprintf(namebuf, ACORE_PATH_MAX, _fileName.c_str(), message->param1.c_str());
+
+ // always use "a" with dynamic name otherwise it could delete the log we wrote in last _write() call
+ FILE* file = OpenFile(namebuf, "a", _backup || exceedMaxSize);
+ if (!file)
+ return;
+
+ fprintf(file, "%s%s\n", message->prefix.c_str(), message->text.c_str());
+ fflush(file);
+ _fileSize += uint64(message->Size());
+ fclose(file);
+
+ return;
+ }
+ else if (exceedMaxSize)
+ logfile = OpenFile(_fileName, "w", true);
+
+ if (!logfile)
+ return;
+
+ fprintf(logfile, "%s%s\n", message->prefix.c_str(), message->text.c_str());
+ fflush(logfile);
+ _fileSize += uint64(message->Size());
+}
+
+FILE* AppenderFile::OpenFile(std::string const& filename, std::string const& mode, bool backup)
+{
+ std::string fullName(_logDir + filename);
+ if (backup)
+ {
+ CloseFile();
+ std::string newName(fullName);
+ newName.push_back('.');
+ newName.append(LogMessage::getTimeStr(time(nullptr)));
+ std::replace(newName.begin(), newName.end(), ':', '-');
+ rename(fullName.c_str(), newName.c_str()); // no error handling... if we couldn't make a backup, just ignore
+ }
+
+ if (FILE* ret = fopen(fullName.c_str(), mode.c_str()))
+ {
+ _fileSize = ftell(ret);
+ return ret;
+ }
+
+ return nullptr;
+}
+
+void AppenderFile::CloseFile()
+{
+ if (logfile)
+ {
+ fclose(logfile);
+ logfile = nullptr;
+ }
+}