Cleanup eqemu_logsys code and automatically inject new logging categories into the database if they do not exist

This commit is contained in:
Akkadius
2018-10-20 22:29:59 -05:00
parent 8115db3576
commit ab8075d629
4 changed files with 569 additions and 339 deletions
+283 -138
View File
@@ -1,22 +1,23 @@
/* EQEMu: Everquest Server Emulator
Copyright (C) 2001-2015 EQEMu Development Team (http://eqemulator.net)
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; version 2 of the License.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY except by those people which sell it, which
are required to give you total support for your newly bought product;
without even the implied warranty of MERCHANTABILITY or FITNESS FOR
A PARTICULAR PURPOSE. See the GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
/**
* EQEmulator: Everquest Server Emulator
* Copyright (C) 2001-2018 EQEmulator Development Team (https://github.com/EQEmu/Server)
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; version 2 of the License.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY except by those people which sell it, which
* are required to give you total support for your newly bought product;
* without even the implied warranty of MERCHANTABILITY or FITNESS FOR
* A PARTICULAR PURPOSE. See the GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
*/
#include "eqemu_logsys.h"
#include "platform.h"
#include "string_util.h"
@@ -33,106 +34,144 @@
std::ofstream process_log;
#ifdef _WINDOWS
#include <direct.h>
#include <conio.h>
#include <iostream>
#include <dos.h>
#include <windows.h>
#include <process.h>
#include <direct.h>
#include <conio.h>
#include <iostream>
#include <dos.h>
#include <windows.h>
#include <process.h>
#else
#include <unistd.h>
#include <sys/stat.h>
#include <unistd.h>
#include <sys/stat.h>
#endif
/* Linux ANSI console color defines */
/**
* Linux ANSI console color defines
*/
#define LC_RESET "\033[0m"
#define LC_BLACK "\033[30m" /* Black */
#define LC_RED "\033[31m" /* Red */
#define LC_GREEN "\033[32m" /* Green */
#define LC_YELLOW "\033[33m" /* Yellow */
#define LC_BLUE "\033[34m" /* Blue */
#define LC_MAGENTA "\033[35m" /* Magenta */
#define LC_CYAN "\033[36m" /* Cyan */
#define LC_WHITE "\033[37m" /* White */
#define LC_BLACK "\033[30m" /* Black */
#define LC_RED "\033[31m" /* Red */
#define LC_GREEN "\033[32m" /* Green */
#define LC_YELLOW "\033[33m" /* Yellow */
#define LC_BLUE "\033[34m" /* Blue */
#define LC_MAGENTA "\033[35m" /* Magenta */
#define LC_CYAN "\033[36m" /* Cyan */
#define LC_WHITE "\033[37m" /* White */
namespace Console {
enum Color {
Black = 0,
Blue = 1,
Green = 2,
Cyan = 3,
Red = 4,
Magenta = 5,
Brown = 6,
LightGray = 7,
DarkGray = 8,
LightBlue = 9,
LightGreen = 10,
LightCyan = 11,
LightRed = 12,
Black = 0,
Blue = 1,
Green = 2,
Cyan = 3,
Red = 4,
Magenta = 5,
Brown = 6,
LightGray = 7,
DarkGray = 8,
LightBlue = 9,
LightGreen = 10,
LightCyan = 11,
LightRed = 12,
LightMagenta = 13,
Yellow = 14,
White = 15
Yellow = 14,
White = 15
};
}
enum GameChatColor {
yellow = 15,
red = 13,
light_green = 14,
light_cyan = 258,
light_purple = 5
};
/**
* EQEmuLogSys Constructor
*/
EQEmuLogSys::EQEmuLogSys()
{
on_log_gmsay_hook = [](uint16 log_type, const std::string&) {};
on_log_gmsay_hook = [](uint16 log_type, const std::string &) {};
bool file_logs_enabled = false;
int log_platform = 0;
int log_platform = 0;
}
/**
* EQEmuLogSys Deconstructor
*/
EQEmuLogSys::~EQEmuLogSys()
{
}
void EQEmuLogSys::LoadLogSettingsDefaults()
{
/* Get Executable platform currently running this code (Zone/World/etc) */
/**
* Get Executable platform currently running this code (Zone/World/etc)
*/
log_platform = GetExecutablePlatformInt();
/* Zero out Array */
/**
* Zero out Array
*/
memset(log_settings, 0, sizeof(LogSettings) * Logs::LogCategory::MaxCategoryID);
/* Set Defaults */
log_settings[Logs::World_Server].log_to_console = Logs::General;
log_settings[Logs::Zone_Server].log_to_console = Logs::General;
log_settings[Logs::QS_Server].log_to_console = Logs::General;
log_settings[Logs::UCS_Server].log_to_console = Logs::General;
log_settings[Logs::Crash].log_to_console = Logs::General;
log_settings[Logs::MySQLError].log_to_console = Logs::General;
log_settings[Logs::Login_Server].log_to_console = Logs::General;
/**
* Set Defaults
*/
log_settings[Logs::World_Server].log_to_console = Logs::General;
log_settings[Logs::Zone_Server].log_to_console = Logs::General;
log_settings[Logs::QS_Server].log_to_console = Logs::General;
log_settings[Logs::UCS_Server].log_to_console = Logs::General;
log_settings[Logs::Crash].log_to_console = Logs::General;
log_settings[Logs::MySQLError].log_to_console = Logs::General;
log_settings[Logs::Login_Server].log_to_console = Logs::General;
log_settings[Logs::Headless_Client].log_to_console = Logs::General;
/* Set Category enabled status on defaults */
/**
* Set Category enabled status on defaults
*/
log_settings[Logs::World_Server].is_category_enabled = 1;
log_settings[Logs::Zone_Server].is_category_enabled = 1;
log_settings[Logs::QS_Server].is_category_enabled = 1;
log_settings[Logs::UCS_Server].is_category_enabled = 1;
log_settings[Logs::Crash].is_category_enabled = 1;
log_settings[Logs::MySQLError].is_category_enabled = 1;
log_settings[Logs::Zone_Server].is_category_enabled = 1;
log_settings[Logs::QS_Server].is_category_enabled = 1;
log_settings[Logs::UCS_Server].is_category_enabled = 1;
log_settings[Logs::Crash].is_category_enabled = 1;
log_settings[Logs::MySQLError].is_category_enabled = 1;
log_settings[Logs::Login_Server].is_category_enabled = 1;
/* Declare process file names for log writing
If there is no process_file_name declared, no log file will be written, simply
*/
if (EQEmuLogSys::log_platform == EQEmuExePlatform::ExePlatformWorld)
/**
* Declare process file names for log writing=
*/
if (EQEmuLogSys::log_platform == EQEmuExePlatform::ExePlatformWorld) {
platform_file_name = "world";
else if (EQEmuLogSys::log_platform == EQEmuExePlatform::ExePlatformQueryServ)
}
else if (EQEmuLogSys::log_platform == EQEmuExePlatform::ExePlatformQueryServ) {
platform_file_name = "query_server";
else if (EQEmuLogSys::log_platform == EQEmuExePlatform::ExePlatformZone)
}
else if (EQEmuLogSys::log_platform == EQEmuExePlatform::ExePlatformZone) {
platform_file_name = "zone";
else if (EQEmuLogSys::log_platform == EQEmuExePlatform::ExePlatformUCS)
}
else if (EQEmuLogSys::log_platform == EQEmuExePlatform::ExePlatformUCS) {
platform_file_name = "ucs";
else if (EQEmuLogSys::log_platform == EQEmuExePlatform::ExePlatformLogin)
}
else if (EQEmuLogSys::log_platform == EQEmuExePlatform::ExePlatformLogin) {
platform_file_name = "login";
else if (EQEmuLogSys::log_platform == EQEmuExePlatform::ExePlatformLaunch)
}
else if (EQEmuLogSys::log_platform == EQEmuExePlatform::ExePlatformLaunch) {
platform_file_name = "launcher";
else if (EQEmuLogSys::log_platform == EQEmuExePlatform::ExePlatformHC)
}
else if (EQEmuLogSys::log_platform == EQEmuExePlatform::ExePlatformHC) {
platform_file_name = "hc";
}
}
/**
* @param log_category
* @param in_message
* @return
*/
std::string EQEmuLogSys::FormatOutMessageString(uint16 log_category, const std::string &in_message)
{
std::string ret;
@@ -144,17 +183,33 @@ std::string EQEmuLogSys::FormatOutMessageString(uint16 log_category, const std::
return ret;
}
/**
* @param debug_level
* @param log_category
* @param message
*/
void EQEmuLogSys::ProcessGMSay(uint16 debug_level, uint16 log_category, const std::string &message)
{
/* Enabling Netcode based GMSay output creates a feedback loop that ultimately ends in a crash */
if (log_category == Logs::LogCategory::Netcode)
/**
* Enabling Netcode based GMSay output creates a feedback loop that ultimately ends in a crash
*/
if (log_category == Logs::LogCategory::Netcode) {
return;
}
/* Check to see if the process that actually ran this is zone */
if (EQEmuLogSys::log_platform == EQEmuExePlatform::ExePlatformZone)
/**
* Check to see if the process that actually ran this is zone
*/
if (EQEmuLogSys::log_platform == EQEmuExePlatform::ExePlatformZone) {
on_log_gmsay_hook(log_category, message);
}
}
/**
* @param debug_level
* @param log_category
* @param message
*/
void EQEmuLogSys::ProcessLogWrite(uint16 debug_level, uint16 log_category, const std::string &message)
{
if (log_category == Logs::Crash) {
@@ -162,7 +217,10 @@ void EQEmuLogSys::ProcessLogWrite(uint16 debug_level, uint16 log_category, const
EQEmuLogSys::SetCurrentTimeStamp(time_stamp);
std::ofstream crash_log;
EQEmuLogSys::MakeDirectory("logs/crashes");
crash_log.open(StringFormat("logs/crashes/crash_%s_%i.log", platform_file_name.c_str(), getpid()), std::ios_base::app | std::ios_base::out);
crash_log.open(
StringFormat("logs/crashes/crash_%s_%i.log", platform_file_name.c_str(), getpid()),
std::ios_base::app | std::ios_base::out
);
crash_log << time_stamp << " " << message << "\n";
crash_log.close();
}
@@ -170,11 +228,17 @@ void EQEmuLogSys::ProcessLogWrite(uint16 debug_level, uint16 log_category, const
char time_stamp[80];
EQEmuLogSys::SetCurrentTimeStamp(time_stamp);
if (process_log)
if (process_log) {
process_log << time_stamp << " " << message << std::endl;
}
}
uint16 EQEmuLogSys::GetWindowsConsoleColorFromCategory(uint16 log_category) {
/**
* @param log_category
* @return
*/
uint16 EQEmuLogSys::GetWindowsConsoleColorFromCategory(uint16 log_category)
{
switch (log_category) {
case Logs::Status:
case Logs::Normal:
@@ -197,7 +261,12 @@ uint16 EQEmuLogSys::GetWindowsConsoleColorFromCategory(uint16 log_category) {
}
}
std::string EQEmuLogSys::GetLinuxConsoleColorFromCategory(uint16 log_category) {
/**
* @param log_category
* @return
*/
std::string EQEmuLogSys::GetLinuxConsoleColorFromCategory(uint16 log_category)
{
switch (log_category) {
case Logs::Status:
case Logs::Normal:
@@ -220,52 +289,68 @@ std::string EQEmuLogSys::GetLinuxConsoleColorFromCategory(uint16 log_category) {
}
}
uint16 EQEmuLogSys::GetGMSayColorFromCategory(uint16 log_category) {
/**
* @param log_category
* @return
*/
uint16 EQEmuLogSys::GetGMSayColorFromCategory(uint16 log_category)
{
switch (log_category) {
case Logs::Status:
case Logs::Normal:
return 15; /* Yellow */
return GameChatColor::yellow;
case Logs::MySQLError:
case Logs::Error:
return 13; /* Red */
return GameChatColor::red;
case Logs::MySQLQuery:
case Logs::Debug:
return 14; /* Light Green */
return GameChatColor::light_green;
case Logs::Quests:
return 258; /* Light Cyan */
return GameChatColor::light_cyan;
case Logs::Commands:
case Logs::Mercenaries:
return 5; /* Light Purple */
return GameChatColor::light_purple;
case Logs::Crash:
return 13; /* Red */
return GameChatColor::red;
default:
return 15; /* Yellow */
return GameChatColor::yellow;
}
}
/**
* @param debug_level
* @param log_category
* @param message
*/
void EQEmuLogSys::ProcessConsoleMessage(uint16 debug_level, uint16 log_category, const std::string &message)
{
#ifdef _WINDOWS
HANDLE console_handle;
console_handle = GetStdHandle(STD_OUTPUT_HANDLE);
CONSOLE_FONT_INFOEX info = { 0 };
info.cbSize = sizeof(info);
info.dwFontSize.Y = 12; // leave X as zero
info.FontWeight = FW_NORMAL;
wcscpy(info.FaceName, L"Lucida Console");
SetCurrentConsoleFontEx(console_handle, NULL, &info);
SetConsoleTextAttribute(console_handle, EQEmuLogSys::GetWindowsConsoleColorFromCategory(log_category));
std::cout << message << "\n";
SetConsoleTextAttribute(console_handle, Console::Color::White);
#else
std::cout << EQEmuLogSys::GetLinuxConsoleColorFromCategory(log_category) << message << LC_RESET << std::endl;
#endif
#ifdef _WINDOWS
HANDLE console_handle;
console_handle = GetStdHandle(STD_OUTPUT_HANDLE);
CONSOLE_FONT_INFOEX info = { 0 };
info.cbSize = sizeof(info);
info.dwFontSize.Y = 12; // leave X as zero
info.FontWeight = FW_NORMAL;
wcscpy(info.FaceName, L"Lucida Console");
SetCurrentConsoleFontEx(console_handle, NULL, &info);
SetConsoleTextAttribute(console_handle, EQEmuLogSys::GetWindowsConsoleColorFromCategory(log_category));
std::cout << message << "\n";
SetConsoleTextAttribute(console_handle, Console::Color::White);
#else
std::cout << EQEmuLogSys::GetLinuxConsoleColorFromCategory(log_category) << message << LC_RESET << std::endl;
#endif
}
/**
* Core logging function
*
* @param debug_level
* @param log_category
* @param message
* @param ...
*/
void EQEmuLogSys::Out(Logs::DebugLevel debug_level, uint16 log_category, std::string message, ...)
{
bool log_to_console = true;
if (log_settings[log_category].log_to_console < debug_level) {
log_to_console = false;
@@ -282,8 +367,9 @@ void EQEmuLogSys::Out(Logs::DebugLevel debug_level, uint16 log_category, std::st
}
const bool nothing_to_log = !log_to_console && !log_to_file && !log_to_gmsay;
if (nothing_to_log)
if (nothing_to_log) {
return;
}
va_list args;
va_start(args, message);
@@ -292,20 +378,32 @@ void EQEmuLogSys::Out(Logs::DebugLevel debug_level, uint16 log_category, std::st
std::string output_debug_message = EQEmuLogSys::FormatOutMessageString(log_category, output_message);
if (log_to_console) EQEmuLogSys::ProcessConsoleMessage(debug_level, log_category, output_debug_message);
if (log_to_gmsay) EQEmuLogSys::ProcessGMSay(debug_level, log_category, output_debug_message);
if (log_to_file) EQEmuLogSys::ProcessLogWrite(debug_level, log_category, output_debug_message);
if (log_to_console) {
EQEmuLogSys::ProcessConsoleMessage(debug_level, log_category, output_debug_message);
}
if (log_to_gmsay) {
EQEmuLogSys::ProcessGMSay(debug_level, log_category, output_debug_message);
}
if (log_to_file) {
EQEmuLogSys::ProcessLogWrite(debug_level, log_category, output_debug_message);
}
}
void EQEmuLogSys::SetCurrentTimeStamp(char* time_stamp)
/**
* @param time_stamp
*/
void EQEmuLogSys::SetCurrentTimeStamp(char *time_stamp)
{
time_t raw_time;
struct tm * time_info;
time_t raw_time;
struct tm *time_info;
time(&raw_time);
time_info = localtime(&raw_time);
strftime(time_stamp, 80, "[%m-%d-%Y :: %H:%M:%S]", time_info);
}
/**
* @param directory_name
*/
void EQEmuLogSys::MakeDirectory(const std::string &directory_name)
{
#ifdef _WINDOWS
@@ -315,8 +413,9 @@ void EQEmuLogSys::MakeDirectory(const std::string &directory_name)
_mkdir(directory_name.c_str());
#else
struct stat st;
if (stat(directory_name.c_str(), &st) == 0) // exists
if (stat(directory_name.c_str(), &st) == 0) { // exists
return;
}
mkdir(directory_name.c_str(), 0755);
#endif
}
@@ -328,29 +427,75 @@ void EQEmuLogSys::CloseFileLogs()
}
}
/**
* @param log_name
*/
void EQEmuLogSys::StartFileLogs(const std::string &log_name)
{
EQEmuLogSys::CloseFileLogs();
/* When loading settings, we must have been given a reason in category based logging to output to a file in order to even create or open one... */
if (file_logs_enabled == false)
/**
* When loading settings, we must have been given a reason in category based logging to output to a file in order to even create or open one...
*/
if (!file_logs_enabled) {
return;
if (EQEmuLogSys::log_platform == EQEmuExePlatform::ExePlatformZone) {
if (!log_name.empty())
platform_file_name = log_name;
if (platform_file_name.empty())
return;
EQEmuLogSys::Out(Logs::General, Logs::Status, "Starting File Log 'logs/%s_%i.log'", platform_file_name.c_str(), getpid());
EQEmuLogSys::MakeDirectory("logs/zone");
process_log.open(StringFormat("logs/zone/%s_%i.log", platform_file_name.c_str(), getpid()), std::ios_base::app | std::ios_base::out);
} else {
if (platform_file_name.empty())
return;
EQEmuLogSys::Out(Logs::General, Logs::Status, "Starting File Log 'logs/%s_%i.log'", platform_file_name.c_str(), getpid());
process_log.open(StringFormat("logs/%s_%i.log", platform_file_name.c_str(), getpid()), std::ios_base::app | std::ios_base::out);
}
}
/**
* Zone
*/
if (EQEmuLogSys::log_platform == EQEmuExePlatform::ExePlatformZone) {
if (!log_name.empty()) {
platform_file_name = log_name;
}
if (platform_file_name.empty()) {
return;
}
EQEmuLogSys::Out(
Logs::General,
Logs::Status,
"Starting File Log 'logs/%s_%i.log'",
platform_file_name.c_str(),
getpid());
/**
* Make directory if not exists
*/
EQEmuLogSys::MakeDirectory("logs/zone");
/**
* Open file pointer
*/
process_log.open(
StringFormat("logs/zone/%s_%i.log", platform_file_name.c_str(), getpid()),
std::ios_base::app | std::ios_base::out
);
}
else {
/**
* All other processes
*/
if (platform_file_name.empty()) {
return;
}
EQEmuLogSys::Out(
Logs::General,
Logs::Status,
"Starting File Log 'logs/%s_%i.log'",
platform_file_name.c_str(),
getpid());
/**
* Open file pointer
*/
process_log.open(
StringFormat("logs/%s_%i.log", platform_file_name.c_str(), getpid()),
std::ios_base::app | std::ios_base::out
);
}
}