Logging fixes and catches (#79621)

THIS IS A REDO BECAUSE GITHUB SUCKS ASS

## About The Pull Request

Hardens logging against sudden and unexpected cases where we try to log
to a category that is not initialized or the file goes missing.

## Why It's Good For The Game

Logging needs to be robust and bullet proof
This commit is contained in:
Zephyr
2023-12-10 02:46:05 +00:00
committed by GitHub
parent 8a0d46faa5
commit f2d9e84f36
7 changed files with 77 additions and 17 deletions
+41 -6
View File
@@ -107,7 +107,7 @@ GENERAL_PROTECT_DATUM(/datum/log_holder)
return
switch(action)
if("refresh")
if("re-render")
cache_ui_data()
SStgui.update_uis(src)
return TRUE
@@ -206,6 +206,42 @@ GENERAL_PROTECT_DATUM(/datum/log_holder)
return category_tree
/// Log entry header used to mark a file is being reset
#define LOG_CATEGORY_RESET_FILE_MARKER "{\"LOG FILE RESET -- THIS IS AN ERROR\"}"
#define LOG_CATEGORY_RESET_FILE_MARKER_READABLE "LOG FILE RESET -- THIS IS AN ERROR"
/// Gets a recovery file for the given path. Caches the last known recovery path for each path.
/datum/log_holder/proc/get_recovery_file_for(path)
var/static/cache
if(isnull(cache))
cache = list()
var/count = cache[path] || 0
while(fexists("[path].rec[count]"))
count++
cache[path] = count
return "[path].rec[count]"
/// Sets up the given category's file and header.
/datum/log_holder/proc/init_category_file(datum/log_category/category)
var/file_path = category.get_output_file(null)
if(fexists(file_path)) // already exists? implant a reset marker
rustg_file_append(LOG_CATEGORY_RESET_FILE_MARKER, file_path)
fcopy(file_path, get_recovery_file_for(file_path))
rustg_file_write("[json_encode(category.category_header)]\n", file_path)
if(!human_readable_enabled)
return
file_path = category.get_output_file(null, "log")
if(fexists(file_path))
rustg_file_append(LOG_CATEGORY_RESET_FILE_MARKER_READABLE, file_path)
fcopy(file_path, get_recovery_file_for(file_path))
rustg_file_write("\[[human_readable_timestamp()]\] Starting up round ID [round_id].\n - -------------------------\n", file_path)
#undef LOG_CATEGORY_RESET_FILE_MARKER
#undef LOG_CATEGORY_RESET_FILE_MARKER_READABLE
/// Initializes the given log category and populates the list of contained categories based on the sub category list
/datum/log_holder/proc/init_log_category(datum/log_category/category_type, list/datum/log_category/sub_categories)
var/datum/log_category/category_instance = new category_type
@@ -239,9 +275,8 @@ GENERAL_PROTECT_DATUM(/datum/log_holder)
LOG_HEADER_CATEGORY = category_instance.category,
)
rustg_file_write("[json_encode(category_header)]\n", category_instance.get_output_file(null))
if(human_readable_enabled)
rustg_file_write("\[[human_readable_timestamp()]\] Starting up round ID [round_id].\n - -------------------------\n", category_instance.get_output_file(null, "log"))
category_instance.category_header = category_header
init_category_file(category_instance, category_header)
/datum/log_holder/proc/human_readable_timestamp(precision = 3)
var/start = time2text(world.timeofday, "YYYY-MM-DD hh:mm:ss")
@@ -270,7 +305,7 @@ GENERAL_PROTECT_DATUM(/datum/log_holder)
stack_trace("Logging with a non-text message")
if(!category)
category = LOG_CATEGORY_NOT_FOUND
category = LOG_CATEGORY_INTERNAL_CATEGORY_NOT_FOUND
stack_trace("Logging with a null or empty category")
if(data && !islist(data))
@@ -286,7 +321,7 @@ GENERAL_PROTECT_DATUM(/datum/log_holder)
var/datum/log_category/log_category = log_categories[category]
if(!log_category)
Log(LOG_CATEGORY_NOT_FOUND, message, data)
Log(LOG_CATEGORY_INTERNAL_CATEGORY_NOT_FOUND, message, data)
CRASH("Attempted to log to a category that doesn't exist! [category]")
var/list/semver_store = null