Compare commits

...

4 Commits

Author SHA1 Message Date
Akkadius 9f77217da0 Create logging_paramterized_convert.py 2024-10-08 18:27:36 -05:00
Akkadius 108a7013db Update eqemu_logsys.cpp 2024-10-08 07:25:08 -05:00
Akkadius d9e6665bd3 Testing 2024-10-08 06:01:51 -05:00
Akkadius a9ad681a35 Work 2024-10-08 05:57:09 -05:00
4 changed files with 252 additions and 49 deletions
+1 -1
View File
@@ -177,7 +177,7 @@ void WorldContentService::ReloadContentFlags()
set_content_flags.push_back(f);
LogInfo(
"Loaded content flag [{}] [{}]",
"Loaded content flag [flag|{}] [status|{}]",
f.flag_name,
(f.enabled ? "enabled" : "disabled")
);
+57 -46
View File
@@ -233,24 +233,17 @@ void EQEmuLogSys::ProcessConsoleMessage(
(!is_error ? std::cout : std::cerr)
<< ""
<< rang::fgB::black
<< rang::style::bold
<< fmt::format("{:>6}", GetPlatformName().substr(0, 6))
<< rang::style::reset
<< rang::fgB::gray
<< " | "
<< rang::style::bold
<< fmt::format("{}", GetPlatformName().substr(0, 6))
<< " "
<< ((is_error || is_warning) ? rang::fgB::red : rang::fgB::gray)
<< rang::style::bold
<< fmt::format("{:^10}", fmt::format("{}", Logs::LogCategoryName[log_category]).substr(0, 10))
<< rang::style::reset
<< rang::fgB::gray
<< " | "
<< rang::fgB::gray
<< rang::style::bold
<< fmt::format("{}", fmt::format("{}", Logs::LogCategoryName[log_category]).substr(0, 10))
<< " "
<< fmt::format("{}", func)
<< rang::style::reset
<< rang::fgB::gray
<< " ";
<< " ";
if (RuleB(Logging, PrintFileFunctionAndLine)) {
(!is_error ? std::cout : std::cerr)
@@ -262,8 +255,31 @@ void EQEmuLogSys::ProcessConsoleMessage(
<< " | ";
}
std::map<std::string, std::string> key_value_map = {};
std::string msg = message;
if (Strings::Contains(msg, "[") && Strings::Contains(msg, "]") && Strings::Contains(msg, "|")) {
for (auto &e: Strings::Split(msg, "[")) {
const auto &r = Strings::Split(e, "]");
const auto &contents = r[0];
if (Strings::Contains(contents, "|")) {
auto s = Strings::Split(contents, "|");
if (s.size() == 2) {
std::string key = s[0];
std::string value = s[1];
key_value_map[key] = value;
// remove it from original string
msg = Strings::Replace(msg, fmt::format("[{}|{}]", key, value), "");
}
}
}
msg = Strings::Replace(msg, " ", " ");
msg = Strings::Trim(msg);
}
if (log_category == Logs::LogCategory::MySQLQuery) {
auto s = Strings::Split(message, "--");
auto s = Strings::Split(msg, "--");
if (s.size() > 1) {
std::string query = Strings::Trim(s[0]);
std::string meta = Strings::Trim(s[1]);
@@ -285,19 +301,12 @@ void EQEmuLogSys::ProcessConsoleMessage(
rang::style::reset;
}
}
else if (Strings::Contains(message, "[")) {
for (auto &e: Strings::Split(message, " ")) {
else if (Strings::Contains(msg, "[")) {
for (auto &e: Strings::Split(msg, " ")) {
if (Strings::Contains(e, "[") && Strings::Contains(e, "]")) {
e = Strings::Replace(e, "[", "");
e = Strings::Replace(e, "]", "");
bool is_upper = false;
for (int i = 0; i < strlen(e.c_str()); i++) {
if (isupper(e[i])) {
is_upper = true;
}
}
// color matching in []
// ex: [<red>variable] would produce [variable] with red inside brackets
@@ -353,22 +362,15 @@ void EQEmuLogSys::ProcessConsoleMessage(
// if we don't match a color in either the string matching or
// the color tag matching, we default to yellow inside brackets
// if uppercase, does not get colored
if (!match_color) {
if (!is_upper) {
(!is_error ? std::cout : std::cerr)
<< rang::fgB::gray
<< "["
<< rang::style::bold
<< rang::fgB::yellow
<< e
<< rang::style::reset
<< rang::fgB::gray
<< "] ";
}
else {
(!is_error ? std::cout : std::cerr) << rang::fgB::gray << "[" << e << "] ";
}
(!is_error ? std::cout : std::cerr)
<< rang::fgB::gray
<< "["
<< rang::fgB::green
<< e
<< rang::style::reset
<< rang::fgB::gray
<< "] ";
}
}
else {
@@ -382,8 +384,17 @@ void EQEmuLogSys::ProcessConsoleMessage(
else {
(!is_error ? std::cout : std::cerr)
<< (is_error ? rang::fgB::red : rang::fgB::gray)
<< message
<< " ";
<< msg;
}
for (const auto &[key, value]: key_value_map) {
(!is_error ? std::cout : std::cerr)
<< rang::fgB::black
<< " > "
<< key
<< " "
<< rang::fgB::green
<< value;
}
if (!origination_info.zone_short_name.empty()) {
@@ -391,7 +402,7 @@ void EQEmuLogSys::ProcessConsoleMessage(
<<
rang::fgB::black
<<
"-- "
" -- "
<<
fmt::format(
"[{}] ({}) inst_id [{}]",
@@ -403,7 +414,7 @@ void EQEmuLogSys::ProcessConsoleMessage(
(!is_error ? std::cout : std::cerr) << rang::style::reset << std::endl;
m_on_log_console_hook(log_category, message);
m_on_log_console_hook(log_category, msg);
}
/**
@@ -551,7 +562,7 @@ void EQEmuLogSys::StartFileLogs(const std::string &log_name)
return;
}
LogInfo("Starting File Log [{}/zone/{}_{}.log]", GetLogPath(), m_platform_file_name.c_str(), getpid());
LogInfo("Starting File Log [GetLogPath|{}/zone/{}_{}.log]", GetLogPath(), m_platform_file_name.c_str(), getpid());
// Make directory if not exists
EQEmuLogSys::MakeDirectory(fmt::format("{}/zone", GetLogPath()));
@@ -569,7 +580,7 @@ void EQEmuLogSys::StartFileLogs(const std::string &log_name)
return;
}
LogInfo("Starting File Log [{}/{}_{}.log]", GetLogPath(), m_platform_file_name.c_str(), getpid());
LogInfo("Starting File Log [GetLogPath|{}/{}_{}.log]", GetLogPath(), m_platform_file_name.c_str(), getpid());
// Open file pointer
process_log.open(
@@ -687,14 +698,14 @@ EQEmuLogSys *EQEmuLogSys::LoadLogDatabaseSettings()
return this;
}
LogInfo("Loaded [{}] log categories", categories.size());
LogInfo("Loaded [categories.size|{}] log categories", categories.size());
auto webhooks = DiscordWebhooksRepository::GetWhere(*m_database, fmt::format("id < {}", MAX_DISCORD_WEBHOOK_ID));
if (!webhooks.empty()) {
for (auto &w: webhooks) {
m_discord_webhooks[w.id] = {w.id, w.webhook_name, w.webhook_url};
}
LogInfo("Loaded [{}] Discord webhooks", webhooks.size());
LogInfo("Loaded [webhooks.size|{}] Discord webhooks", webhooks.size());
}
// force override this setting
+2 -2
View File
@@ -359,7 +359,7 @@ public:
// gmsay
uint16 GetGMSayColorFromCategory(uint16 log_category);
EQEmuLogSys *SetGMSayHandler(const std::function<void(uint16 log_type, const char *func, const std::string &)>& f)
EQEmuLogSys *SetGMSayHandler(const std::function<void(uint16 log_type, const char *func, const std::string &)> &f)
{
m_on_log_gmsay_hook = f;
return this;
@@ -385,7 +385,7 @@ public:
EQEmuLogSys *SetDatabase(Database *db);
[[nodiscard]] const std::string &GetLogPath() const;
EQEmuLogSys * SetLogPath(const std::string &log_path);
EQEmuLogSys *SetLogPath(const std::string &log_path);
void DisableMySQLErrorLogs();
void EnableMySQLErrorLogs();
@@ -0,0 +1,192 @@
import os
import re
def extract_variable_name(var_expr):
# Remove strings and character literals to avoid interference
var_expr_no_strings = re.sub(r'"[^"]*"|\'[^\']*\'', '', var_expr)
# Replace function calls with their names
var_expr_no_strings = re.sub(r'\b(\w+)\s*\([^()]*\)', r'\1', var_expr_no_strings)
# Extract variable-like tokens, including member access and pointers
tokens = re.findall(r'\b(?:\w+)(?:->\w+|\.\w+)+\b', var_expr_no_strings)
# If no tokens with member access, include standalone variables
if not tokens:
tokens = re.findall(r'\b\w+\b', var_expr_no_strings)
# Prioritize tokens with '->' or '.'
if tokens:
# Choose the longest token
variable_name = max(tokens, key=len)
else:
variable_name = slugify(var_expr)
return variable_name
def slugify(var_expr):
# Remove any quotes
var_expr = var_expr.replace('"', '').replace("'", '')
# Replace non-alphanumeric characters with underscores
var_expr = re.sub(r'\W+', '_', var_expr)
# Remove leading/trailing underscores
var_expr = var_expr.strip('_')
# Optionally limit the length
var_expr = var_expr[:50] # limit to 50 characters
return var_expr
def process_file(file_path):
with open(file_path, 'r') as f:
content = f.read()
original_content = content
# Regular expression to match Log macros
log_macro_pattern = re.compile(r'(Log\w*\s*\()([^\n]*?\))', re.DOTALL)
def replace_log(match):
log_call = match.group(1)
args_content = match.group(2)
# Split arguments, handling nested structures
args = split_arguments(args_content.strip(')'))
if len(args) < 2:
# Not enough arguments to process
return match.group(0)
format_string = args[0].strip()
variables = args[1:]
# Remove quotes from format string
if (format_string.startswith('"') and format_string.endswith('"')) or \
(format_string.startswith("'") and format_string.endswith("'")):
quote_char = format_string[0]
format_string_content = format_string[1:-1]
else:
# Format string is not properly quoted
return match.group(0)
# Find all '{}' placeholders in format string
placeholder_pattern = re.compile(r'(?<!{){(?!{)(?![^}]*:)[^}]*}(?!})')
placeholders = list(placeholder_pattern.finditer(format_string_content))
# Replace '{}' placeholders with '[variable|{}]' or 'variable|{}' depending on context
new_format_string_content = ''
last_index = 0
arg_index = 0
for ph in placeholders:
start, end = ph.span()
preceding_text = format_string_content[max(0, start-1):start]
following_text = format_string_content[end:end+1]
new_format_string_content += format_string_content[last_index:start]
# Only process '{}' placeholders
if format_string_content[start:end] == '{}':
if arg_index < len(variables):
variable = variables[arg_index].strip()
arg_index += 1
# Extract meaningful variable name
variable_name = extract_variable_name(variable)
# Check if '{}' is already inside brackets
inside_brackets = (
(preceding_text == '[' and following_text == ']') or
(preceding_text == '[') or
(following_text == ']')
)
if inside_brackets:
# Replace '{}' with 'variable_name|{}' without adding extra brackets
new_placeholder = f'{variable_name}|{{}}'
else:
# Add brackets around 'variable_name|{}'
new_placeholder = f'[{variable_name}|{{}}]'
new_format_string_content += new_placeholder
else:
# No corresponding variable; leave '{}' as is
new_format_string_content += '{}'
else:
# Keep the original placeholder (e.g., {:#04x})
new_format_string_content += format_string_content[start:end]
last_index = end
new_format_string_content += format_string_content[last_index:]
# Reconstruct the format string with original quotes
new_format_string = quote_char + new_format_string_content + quote_char
# Reconstruct the arguments
new_args_content = ', '.join(args[1:]) # Exclude the format string
# Reconstruct the log call
new_log_call = f'{log_call}{new_format_string}'
if new_args_content.strip():
new_log_call += f', {new_args_content}'
new_log_call += ')'
return new_log_call
def split_arguments(args_str):
# This function splits arguments, handling nested structures
args = []
current_arg = ''
depth = 0
in_string = False
escape = False
i = 0
length = len(args_str)
while i < length:
char = args_str[i]
if escape:
current_arg += char
escape = False
elif char == '\\':
current_arg += char
escape = True
elif char in ('"', "'"):
current_arg += char
if in_string == char:
in_string = False
elif not in_string:
in_string = char
elif not in_string:
if char in '([{':
depth += 1
current_arg += char
elif char in ')]}':
depth -= 1
current_arg += char
elif char == ',' and depth == 0:
args.append(current_arg.strip())
current_arg = ''
else:
current_arg += char
else:
current_arg += char
i += 1
if current_arg.strip():
args.append(current_arg.strip())
return args
# Replace all Log macros in the content
content = log_macro_pattern.sub(replace_log, content)
if content != original_content:
# Write the modified content back to the file without creating backups
with open(file_path, 'w') as f:
f.write(content)
print(f"Processed {file_path}")
def main():
for root, dirs, files in os.walk('.'):
for filename in files:
if filename.endswith('.cpp'):
file_path = os.path.join(root, filename)
process_file(file_path)
if __name__ == '__main__':
main()