From 2c65068be09458e0935a892850df21bf3ce48df9 Mon Sep 17 00:00:00 2001 From: jdgleaver Date: Mon, 25 Mar 2019 17:22:59 +0000 Subject: [PATCH] More 'Log to File' Additions: - Add optional timestamped log files - Handle errors if log file cannot be opened - Android: flush log file immediately - 3DS: log to file tested and fully working - Default log paths added for all platforms --- config.def.h | 1 + configuration.c | 1 + configuration.h | 1 + frontend/drivers/platform_ctr.c | 33 ++++++++-------- frontend/drivers/platform_darwin.m | 1 + frontend/drivers/platform_emscripten.c | 2 + frontend/drivers/platform_gx.c | 53 +++++++------------------- frontend/drivers/platform_orbis.c | 2 + frontend/drivers/platform_ps2.c | 2 + frontend/drivers/platform_ps3.c | 3 ++ frontend/drivers/platform_psp.c | 4 ++ frontend/drivers/platform_qnx.c | 2 + frontend/drivers/platform_switch.c | 3 ++ frontend/drivers/platform_uwp.c | 2 + frontend/drivers/platform_wiiu.c | 2 + frontend/drivers/platform_xdk.c | 6 +++ intl/msg_hash_lbl.h | 2 + intl/msg_hash_us.h | 8 ++++ menu/cbs/menu_cbs_sublabel.c | 4 ++ menu/menu_displaylist.c | 3 ++ menu/menu_setting.c | 16 ++++++++ msg_hash.h | 1 + retroarch.c | 21 +++++++++- tasks/task_content.c | 4 -- verbosity.c | 13 ++++++- 25 files changed, 128 insertions(+), 62 deletions(-) diff --git a/config.def.h b/config.def.h index 97a95dacb1..efdb68a691 100644 --- a/config.def.h +++ b/config.def.h @@ -440,6 +440,7 @@ static bool menu_swap_ok_cancel_buttons = false; static bool quit_press_twice = false; static bool default_log_to_file = false; +static bool log_to_file_timestamp = false; /* Crop overscanned frames. */ static const bool crop_overscan = true; diff --git a/configuration.c b/configuration.c index 07af9cdc0a..fb82023d53 100644 --- a/configuration.c +++ b/configuration.c @@ -1595,6 +1595,7 @@ static struct config_bool_setting *populate_settings_bool(settings_t *settings, #endif SETTING_BOOL("log_to_file", &settings->bools.log_to_file, true, default_log_to_file, false); + SETTING_BOOL("log_to_file_timestamp", &settings->bools.log_to_file_timestamp, true, log_to_file_timestamp, false); *size = count; diff --git a/configuration.h b/configuration.h index 4919a22c14..a6099c2198 100644 --- a/configuration.h +++ b/configuration.h @@ -321,6 +321,7 @@ typedef struct settings #endif bool log_to_file; + bool log_to_file_timestamp; } bools; struct diff --git a/frontend/drivers/platform_ctr.c b/frontend/drivers/platform_ctr.c index 6db1865dbb..41254ef7ea 100644 --- a/frontend/drivers/platform_ctr.c +++ b/frontend/drivers/platform_ctr.c @@ -93,14 +93,6 @@ static void frontend_ctr_get_environment_settings(int* argc, char* argv[], { (void)args; -#ifndef IS_SALAMANDER -#if defined(HAVE_LOGGER) - logger_init(); -#elif defined(HAVE_FILE_LOGGER) - retro_main_log_file_init("sdmc:/retroarch/retroarch-log.txt"); -#endif -#endif - fill_pathname_basedir(g_defaults.dirs[DEFAULT_DIR_PORT], elf_path_cst, sizeof(g_defaults.dirs[DEFAULT_DIR_PORT])); RARCH_LOG("port dir: [%s]\n", g_defaults.dirs[DEFAULT_DIR_PORT]); @@ -125,11 +117,13 @@ static void frontend_ctr_get_environment_settings(int* argc, char* argv[], fill_pathname_join(g_defaults.dirs[DEFAULT_DIR_REMAP], g_defaults.dirs[DEFAULT_DIR_PORT], "config/remaps", sizeof(g_defaults.dirs[DEFAULT_DIR_REMAP])); fill_pathname_join(g_defaults.dirs[DEFAULT_DIR_VIDEO_FILTER], g_defaults.dirs[DEFAULT_DIR_PORT], - "filters", sizeof(g_defaults.dirs[DEFAULT_DIR_REMAP])); + "filters", sizeof(g_defaults.dirs[DEFAULT_DIR_VIDEO_FILTER])); fill_pathname_join(g_defaults.dirs[DEFAULT_DIR_DATABASE], g_defaults.dirs[DEFAULT_DIR_PORT], "database/rdb", sizeof(g_defaults.dirs[DEFAULT_DIR_DATABASE])); fill_pathname_join(g_defaults.dirs[DEFAULT_DIR_CURSOR], g_defaults.dirs[DEFAULT_DIR_PORT], "database/cursors", sizeof(g_defaults.dirs[DEFAULT_DIR_CURSOR])); + fill_pathname_join(g_defaults.dirs[DEFAULT_DIR_LOGS], g_defaults.dirs[DEFAULT_DIR_PORT], + "logs", sizeof(g_defaults.dirs[DEFAULT_DIR_LOGS])); fill_pathname_join(g_defaults.path.config, g_defaults.dirs[DEFAULT_DIR_PORT], file_path_str(FILE_PATH_MAIN_CONFIG), sizeof(g_defaults.path.config)); } @@ -145,11 +139,18 @@ static void frontend_ctr_deinit(void* data) (void)data; #ifndef IS_SALAMANDER + /* Note: frontend_ctr_deinit() is normally called when + * forking to load new content. When this happens, the + * log messages generated in frontend_ctr_exec() *must* + * be printed to screen (provided bottom screen is not + * turned off...), since the 'first core launch' warning + * can prevent sdcard corruption. We therefore close any + * existing log file, enable verbose logging and revert + * to console output. (Normal logging will be resumed + * once retroarch.cfg has been re-read) */ + retro_main_log_file_deinit(); verbosity_enable(); - -#ifdef HAVE_FILE_LOGGER - command_event(CMD_EVENT_LOG_FILE_DEINIT, NULL); -#endif + retro_main_log_file_init(NULL, false); if ((gfxBottomFramebuffers[0] == (u8*)currentConsole->frameBuffer) && (ctr_fork_mode == FRONTEND_FORK_NONE)) @@ -203,9 +204,9 @@ static void frontend_ctr_exec(const char* path, bool should_load_game) if (should_load_game && !path_is_empty(RARCH_PATH_CONTENT)) { strcpy(game_path, path_get(RARCH_PATH_CONTENT)); - arg_data[args] = game_path; - arg_data[args + 1] = NULL; - args++; + arg_data[args] = game_path; + arg_data[args + 1] = NULL; + args++; RARCH_LOG("content path: [%s].\n", path_get(RARCH_PATH_CONTENT)); } #endif diff --git a/frontend/drivers/platform_darwin.m b/frontend/drivers/platform_darwin.m index 00125d96cd..ab3cbdb6b2 100644 --- a/frontend/drivers/platform_darwin.m +++ b/frontend/drivers/platform_darwin.m @@ -401,6 +401,7 @@ static void frontend_darwin_get_environment_settings(int *argc, char *argv[], fill_pathname_join(g_defaults.dirs[DEFAULT_DIR_SAVESTATE], home_dir_buf, "states", sizeof(g_defaults.dirs[DEFAULT_DIR_SAVESTATE])); fill_pathname_join(g_defaults.dirs[DEFAULT_DIR_RECORD_CONFIG], home_dir_buf, "records_config", sizeof(g_defaults.dirs[DEFAULT_DIR_RECORD_CONFIG])); fill_pathname_join(g_defaults.dirs[DEFAULT_DIR_RECORD_OUTPUT], home_dir_buf, "records", sizeof(g_defaults.dirs[DEFAULT_DIR_RECORD_OUTPUT])); + fill_pathname_join(g_defaults.dirs[DEFAULT_DIR_LOGS], home_dir_buf, "logs", sizeof(g_defaults.dirs[DEFAULT_DIR_LOGS])); #if defined(IOS) fill_pathname_join(g_defaults.dirs[DEFAULT_DIR_PLAYLIST], home_dir_buf, "playlists", sizeof(g_defaults.dirs[DEFAULT_DIR_PLAYLIST])); #endif diff --git a/frontend/drivers/platform_emscripten.c b/frontend/drivers/platform_emscripten.c index 4aaf6a7d13..df4dad555c 100644 --- a/frontend/drivers/platform_emscripten.c +++ b/frontend/drivers/platform_emscripten.c @@ -198,6 +198,8 @@ static void frontend_emscripten_get_env(int *argc, char *argv[], "system", sizeof(g_defaults.dirs[DEFAULT_DIR_SYSTEM])); fill_pathname_join(g_defaults.dirs[DEFAULT_DIR_THUMBNAILS], user_path, "thumbnails", sizeof(g_defaults.dirs[DEFAULT_DIR_THUMBNAILS])); + fill_pathname_join(g_defaults.dirs[DEFAULT_DIR_LOGS], user_path, + "logs", sizeof(g_defaults.dirs[DEFAULT_DIR_LOGS])); /* cache dir */ fill_pathname_join(g_defaults.dirs[DEFAULT_DIR_CACHE], "/tmp/", diff --git a/frontend/drivers/platform_gx.c b/frontend/drivers/platform_gx.c index 47e983cf6d..5fb04661e9 100644 --- a/frontend/drivers/platform_gx.c +++ b/frontend/drivers/platform_gx.c @@ -20,6 +20,7 @@ #include #include #include +#include #include #include @@ -65,17 +66,6 @@ extern void system_exec_wii(const char *path, bool should_load_game); static enum frontend_fork gx_fork_mode = FRONTEND_FORK_NONE; #endif -#ifndef IS_SALAMANDER -#include "../../paths.h" - -enum -{ - GX_DEVICE_SD = 0, - GX_DEVICE_USB, - GX_DEVICE_END -}; - -#if defined(HAVE_LOGGER) || defined(HAVE_FILE_LOGGER) static devoptab_t dotab_stdout = { "stdout", /* device name */ 0, /* size of file structure */ @@ -101,7 +91,16 @@ static devoptab_t dotab_stdout = { NULL, /* device fsync_r */ NULL, /* deviceData; */ }; -#endif + +#ifndef IS_SALAMANDER +#include "../../paths.h" + +enum +{ + GX_DEVICE_SD = 0, + GX_DEVICE_USB, + GX_DEVICE_END +}; #ifdef HW_RVL static struct @@ -151,22 +150,6 @@ static void gx_devthread(void *a) } #endif -#ifdef HAVE_LOGGER -static int gx_logger_net(struct _reent *r, int fd, const char *ptr, size_t len) -{ -#ifdef HAVE_LOGGER - static char temp[4000]; - size_t l = (len >= 4000) ? 3999 : len - 1; - memcpy(temp, ptr, l); - temp[l] = 0; - logger_send("%s", temp); -#elif defined(HAVE_FILE_LOGGER) - fwrite(ptr, 1, len, retro_main_log_file()); -#endif - return len; -} -#endif - #endif #ifdef IS_SALAMANDER @@ -180,11 +163,6 @@ static void frontend_gx_get_environment_settings( char *last_slash = NULL; char *device_end = NULL; #ifndef IS_SALAMANDER -#if defined(HAVE_LOGGER) - logger_init(); -#elif defined(HAVE_FILE_LOGGER) - retro_main_log_file_init("/retroarch-log.txt"); -#endif /* This situation can happen on some loaders so we really need some fake args or else retroarch will just crash on parsing NULL pointers */ @@ -253,6 +231,8 @@ static void frontend_gx_get_environment_settings( "savefiles", sizeof(g_defaults.dirs[DEFAULT_DIR_SAVESTATE])); fill_pathname_join(g_defaults.dirs[DEFAULT_DIR_PLAYLIST], g_defaults.dirs[DEFAULT_DIR_PORT], "playlists", sizeof(g_defaults.dirs[DEFAULT_DIR_PLAYLIST])); + fill_pathname_join(g_defaults.dirs[DEFAULT_DIR_LOGS], g_defaults.dirs[DEFAULT_DIR_PORT], + "logs", sizeof(g_defaults.dirs[DEFAULT_DIR_LOGS])); #ifdef IS_SALAMANDER if (*argc > 2 && argv[1] != NULL && argv[2] != NULL) @@ -326,15 +306,8 @@ static void frontend_gx_init(void *data) fatInitDefault(); -#ifdef HAVE_LOGGER devoptab_list[STD_OUT] = &dotab_stdout; devoptab_list[STD_ERR] = &dotab_stdout; - dotab_stdout.write_r = gx_logger_net; -#elif defined(HAVE_FILE_LOGGER) && !defined(IS_SALAMANDER) - devoptab_list[STD_OUT] = &dotab_stdout; - devoptab_list[STD_ERR] = &dotab_stdout; - dotab_stdout.write_r = gx_logger_file; -#endif #if defined(HW_RVL) && !defined(IS_SALAMANDER) gx_devices[GX_DEVICE_SD].interface = &__io_wiisd; diff --git a/frontend/drivers/platform_orbis.c b/frontend/drivers/platform_orbis.c index b46d11f4e9..f284dbf898 100644 --- a/frontend/drivers/platform_orbis.c +++ b/frontend/drivers/platform_orbis.c @@ -169,6 +169,8 @@ static void frontend_orbis_get_environment_settings(int *argc, char *argv[], "overlays", sizeof(g_defaults.dirs[DEFAULT_DIR_OVERLAY])); fill_pathname_join(g_defaults.dirs[DEFAULT_DIR_THUMBNAILS], user_path, "thumbnails", sizeof(g_defaults.dirs[DEFAULT_DIR_THUMBNAILS])); + fill_pathname_join(g_defaults.dirs[DEFAULT_DIR_LOGS], user_path, + "logs", sizeof(g_defaults.dirs[DEFAULT_DIR_LOGS])); strlcpy(g_defaults.dirs[DEFAULT_DIR_CONTENT_HISTORY], user_path, sizeof(g_defaults.dirs[DEFAULT_DIR_CONTENT_HISTORY])); fill_pathname_join(g_defaults.path.config, user_path, diff --git a/frontend/drivers/platform_ps2.c b/frontend/drivers/platform_ps2.c index fc07094e28..1ac58934d2 100644 --- a/frontend/drivers/platform_ps2.c +++ b/frontend/drivers/platform_ps2.c @@ -77,6 +77,8 @@ static void create_path_names(void) "SCREENSHOTS", sizeof(g_defaults.dirs[DEFAULT_DIR_SCREENSHOT])); fill_pathname_join(g_defaults.dirs[DEFAULT_DIR_SYSTEM], user_path, "SYSTEM", sizeof(g_defaults.dirs[DEFAULT_DIR_SYSTEM])); + fill_pathname_join(g_defaults.dirs[DEFAULT_DIR_LOGS], user_path, + "LOGS", sizeof(g_defaults.dirs[DEFAULT_DIR_LOGS])); /* cache dir */ fill_pathname_join(g_defaults.dirs[DEFAULT_DIR_CACHE], user_path, diff --git a/frontend/drivers/platform_ps3.c b/frontend/drivers/platform_ps3.c index 656d1e604b..c796b6f07f 100644 --- a/frontend/drivers/platform_ps3.c +++ b/frontend/drivers/platform_ps3.c @@ -263,6 +263,9 @@ static void frontend_ps3_get_environment_settings(int *argc, char *argv[], fill_pathname_join(g_defaults.dirs[DEFAULT_DIR_AUTOCONFIG], g_defaults.dirs[DEFAULT_DIR_CORE], "autoconfig", sizeof(g_defaults.dirs[DEFAULT_DIR_AUTOCONFIG])); + fill_pathname_join(g_defaults.dirs[DEFAULT_DIR_LOGS], + g_defaults.dirs[DEFAULT_DIR_CORE], + "logs", sizeof(g_defaults.dirs[DEFAULT_DIR_LOGS])); } #ifndef IS_SALAMANDER diff --git a/frontend/drivers/platform_psp.c b/frontend/drivers/platform_psp.c index fa8e86e472..25045be15c 100644 --- a/frontend/drivers/platform_psp.c +++ b/frontend/drivers/platform_psp.c @@ -147,6 +147,8 @@ static void frontend_psp_get_environment_settings(int *argc, char *argv[], "overlays", sizeof(g_defaults.dirs[DEFAULT_DIR_OVERLAY])); fill_pathname_join(g_defaults.dirs[DEFAULT_DIR_THUMBNAILS], user_path, "thumbnails", sizeof(g_defaults.dirs[DEFAULT_DIR_THUMBNAILS])); + fill_pathname_join(g_defaults.dirs[DEFAULT_DIR_LOGS], user_path, + "logs", sizeof(g_defaults.dirs[DEFAULT_DIR_LOGS])); strlcpy(g_defaults.dirs[DEFAULT_DIR_CONTENT_HISTORY], user_path, sizeof(g_defaults.dirs[DEFAULT_DIR_CONTENT_HISTORY])); fill_pathname_join(g_defaults.path.config, user_path, @@ -177,6 +179,8 @@ static void frontend_psp_get_environment_settings(int *argc, char *argv[], "SCREENSHOTS", sizeof(g_defaults.dirs[DEFAULT_DIR_SCREENSHOT])); fill_pathname_join(g_defaults.dirs[DEFAULT_DIR_SYSTEM], user_path, "SYSTEM", sizeof(g_defaults.dirs[DEFAULT_DIR_SYSTEM])); + fill_pathname_join(g_defaults.dirs[DEFAULT_DIR_LOGS], user_path, + "LOGS", sizeof(g_defaults.dirs[DEFAULT_DIR_LOGS])); /* cache dir */ fill_pathname_join(g_defaults.dirs[DEFAULT_DIR_CACHE], user_path, diff --git a/frontend/drivers/platform_qnx.c b/frontend/drivers/platform_qnx.c index 168a7462ca..eb2bd40857 100644 --- a/frontend/drivers/platform_qnx.c +++ b/frontend/drivers/platform_qnx.c @@ -130,6 +130,8 @@ static void frontend_qnx_get_environment_settings(int *argc, char *argv[], "thumbnails", sizeof(g_defaults.dirs[DEFAULT_DIR_THUMBNAIL])); fill_pathname_join(g_defaults.dirs[DEFAULT_DIR_WALLPAPERS], user_path, "wallpapers", sizeof(g_defaults.dirs[DEFAULT_DIR_WALLPAPERS])); + fill_pathname_join(g_defaults.dirs[DEFAULT_DIR_LOGS], user_path, + "logs", sizeof(g_defaults.dirs[DEFAULT_DIR_LOGS])); /* tmp */ strlcpy(g_defaults.dirs[DEFAULT_DIR_CACHE], diff --git a/frontend/drivers/platform_switch.c b/frontend/drivers/platform_switch.c index d3927eff84..98cb62d335 100644 --- a/frontend/drivers/platform_switch.c +++ b/frontend/drivers/platform_switch.c @@ -223,6 +223,9 @@ static void frontend_switch_get_environment_settings(int *argc, char *argv[], vo fill_pathname_join(g_defaults.dirs[DEFAULT_DIR_THUMBNAILS], g_defaults.dirs[DEFAULT_DIR_PORT], "thumbnails", sizeof(g_defaults.dirs[DEFAULT_DIR_THUMBNAILS])); + fill_pathname_join(g_defaults.dirs[DEFAULT_DIR_LOGS], g_defaults.dirs[DEFAULT_DIR_PORT], + "logs", sizeof(g_defaults.dirs[DEFAULT_DIR_LOGS])); + int i = 0; for (i; i < DEFAULT_DIR_LAST; i++) { diff --git a/frontend/drivers/platform_uwp.c b/frontend/drivers/platform_uwp.c index 7859f8ac5b..ce33bfcd7e 100644 --- a/frontend/drivers/platform_uwp.c +++ b/frontend/drivers/platform_uwp.c @@ -374,6 +374,8 @@ static void frontend_uwp_environment_get(int *argc, char *argv[], "~\\states", sizeof(g_defaults.dirs[DEFAULT_DIR_SAVESTATE])); fill_pathname_expand_special(g_defaults.dirs[DEFAULT_DIR_SYSTEM], "~\\system", sizeof(g_defaults.dirs[DEFAULT_DIR_SYSTEM])); + fill_pathname_expand_special(g_defaults.dirs[DEFAULT_DIR_LOGS], + "~\\logs", sizeof(g_defaults.dirs[DEFAULT_DIR_LOGS])); #ifdef HAVE_MENU #if defined(HAVE_OPENGL) || defined(HAVE_OPENGLES) diff --git a/frontend/drivers/platform_wiiu.c b/frontend/drivers/platform_wiiu.c index f3a6831019..5559deca3b 100644 --- a/frontend/drivers/platform_wiiu.c +++ b/frontend/drivers/platform_wiiu.c @@ -104,6 +104,8 @@ static void frontend_wiiu_get_environment_settings(int *argc, char *argv[], "database/rdb", sizeof(g_defaults.dirs[DEFAULT_DIR_DATABASE])); fill_pathname_join(g_defaults.dirs[DEFAULT_DIR_CURSOR], g_defaults.dirs[DEFAULT_DIR_PORT], "database/cursors", sizeof(g_defaults.dirs[DEFAULT_DIR_CURSOR])); + fill_pathname_join(g_defaults.dirs[DEFAULT_DIR_LOGS], g_defaults.dirs[DEFAULT_DIR_CORE], + "logs", sizeof(g_defaults.dirs[DEFAULT_DIR_LOGS])); fill_pathname_join(g_defaults.path.config, g_defaults.dirs[DEFAULT_DIR_PORT], file_path_str(FILE_PATH_MAIN_CONFIG), sizeof(g_defaults.path.config)); diff --git a/frontend/drivers/platform_xdk.c b/frontend/drivers/platform_xdk.c index 73b1e978eb..8fb2e5ebc7 100644 --- a/frontend/drivers/platform_xdk.c +++ b/frontend/drivers/platform_xdk.c @@ -132,6 +132,9 @@ static void frontend_xdk_get_environment_settings(int *argc, char *argv[], fill_pathname_join(g_defaults.dirs[DEFAULT_DIR_PLAYLIST], g_defaults.dirs[DEFAULT_DIR_CORE], "playlists", sizeof(g_defaults.dirs[DEFAULT_DIR_PLAYLIST])); + fill_pathname_join(g_defaults.dirs[DEFAULT_DIR_LOGS], + g_defaults.dirs[DEFAULT_DIR_CORE], + "logs", sizeof(g_defaults.dirs[DEFAULT_DIR_LOGS])); #elif defined(_XBOX360) strlcpy(g_defaults.dirs[DEFAULT_DIR_CORE], "game:", @@ -152,6 +155,9 @@ static void frontend_xdk_get_environment_settings(int *argc, char *argv[], sizeof(g_defaults.dirs[DEFAULT_DIR_SRAM])); strlcpy(g_defaults.dirs[DEFAULT_DIR_SYSTEM], "game:\\system", sizeof(g_defaults.dirs[DEFAULT_DIR_SYSTEM])); + strlcpy(g_defaults.dirs[DEFAULT_DIR_LOGS], + "game:\\logs", + sizeof(g_defaults.dirs[DEFAULT_DIR_LOGS])); #endif fill_pathname_join(g_defaults.dirs[DEFAULT_DIR_CORE_INFO], g_defaults.dirs[DEFAULT_DIR_CORE], diff --git a/intl/msg_hash_lbl.h b/intl/msg_hash_lbl.h index a0f0b92e35..939158c0c7 100644 --- a/intl/msg_hash_lbl.h +++ b/intl/msg_hash_lbl.h @@ -649,6 +649,8 @@ MSG_HASH(MENU_ENUM_LABEL_LOG_VERBOSITY, "log_verbosity") MSG_HASH(MENU_ENUM_LABEL_LOG_TO_FILE, "log_to_file") +MSG_HASH(MENU_ENUM_LABEL_LOG_TO_FILE_TIMESTAMP, + "log_to_file_timestamp") MSG_HASH(MENU_ENUM_LABEL_MAIN_MENU, "main_menu") MSG_HASH(MENU_ENUM_LABEL_MANAGEMENT, diff --git a/intl/msg_hash_us.h b/intl/msg_hash_us.h index 85f8d5e911..38c0fc9d83 100644 --- a/intl/msg_hash_us.h +++ b/intl/msg_hash_us.h @@ -1624,6 +1624,14 @@ MSG_HASH( MENU_ENUM_SUBLABEL_LOG_TO_FILE, "Redirects system event log messages to file. Requires 'Logging Verbosity' to be enabled." ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_LOG_TO_FILE_TIMESTAMP, + "Timestamped Log Files" + ) +MSG_HASH( + MENU_ENUM_SUBLABEL_LOG_TO_FILE_TIMESTAMP, + "When logging to file, redirects the output from each RetroArch session to a new timestamped file. If disabled, log is overwritten each time RetroArch is restarted." + ) MSG_HASH( MENU_ENUM_LABEL_VALUE_MAIN_MENU, "Main Menu" diff --git a/menu/cbs/menu_cbs_sublabel.c b/menu/cbs/menu_cbs_sublabel.c index de341c3a1e..a5b70b6583 100644 --- a/menu/cbs/menu_cbs_sublabel.c +++ b/menu/cbs/menu_cbs_sublabel.c @@ -144,6 +144,7 @@ default_sublabel_macro(action_bind_sublabel_toggle_gamepad_combo, MENU_ default_sublabel_macro(action_bind_sublabel_show_hidden_files, MENU_ENUM_SUBLABEL_SHOW_HIDDEN_FILES) default_sublabel_macro(action_bind_sublabel_log_verbosity, MENU_ENUM_SUBLABEL_LOG_VERBOSITY) default_sublabel_macro(action_bind_sublabel_log_to_file, MENU_ENUM_SUBLABEL_LOG_TO_FILE) +default_sublabel_macro(action_bind_sublabel_log_to_file_timestamp, MENU_ENUM_SUBLABEL_LOG_TO_FILE_TIMESTAMP) default_sublabel_macro(action_bind_sublabel_log_dir, MENU_ENUM_SUBLABEL_LOG_DIR) default_sublabel_macro(action_bind_sublabel_video_monitor_index, MENU_ENUM_SUBLABEL_VIDEO_MONITOR_INDEX) default_sublabel_macro(action_bind_sublabel_video_refresh_rate_auto, MENU_ENUM_SUBLABEL_VIDEO_REFRESH_RATE_AUTO) @@ -2134,6 +2135,9 @@ int menu_cbs_init_bind_sublabel(menu_file_list_cbs_t *cbs, case MENU_ENUM_LABEL_LOG_TO_FILE: BIND_ACTION_SUBLABEL(cbs, action_bind_sublabel_log_to_file); break; + case MENU_ENUM_LABEL_LOG_TO_FILE_TIMESTAMP: + BIND_ACTION_SUBLABEL(cbs, action_bind_sublabel_log_to_file_timestamp); + break; case MENU_ENUM_LABEL_LOG_DIR: BIND_ACTION_SUBLABEL(cbs, action_bind_sublabel_log_dir); break; diff --git a/menu/menu_displaylist.c b/menu/menu_displaylist.c index c2038ea153..4c827c366f 100644 --- a/menu/menu_displaylist.c +++ b/menu/menu_displaylist.c @@ -5492,6 +5492,9 @@ bool menu_displaylist_ctl(enum menu_displaylist_ctl_state type, menu_displaylist menu_displaylist_parse_settings_enum(menu, info, MENU_ENUM_LABEL_LOG_TO_FILE, PARSE_ONLY_BOOL, false); + menu_displaylist_parse_settings_enum(menu, info, + MENU_ENUM_LABEL_LOG_TO_FILE_TIMESTAMP, + PARSE_ONLY_BOOL, false); { settings_t *settings = config_get_ptr(); diff --git a/menu/menu_setting.c b/menu/menu_setting.c index 3b03386ba5..ad3de63362 100644 --- a/menu/menu_setting.c +++ b/menu/menu_setting.c @@ -3342,6 +3342,7 @@ void general_write_handler(rarch_setting_t *setting) } break; case MENU_ENUM_LABEL_LOG_DIR: + case MENU_ENUM_LABEL_LOG_TO_FILE_TIMESTAMP: if (verbosity_is_enabled() && is_logging_to_file()) { rarch_log_file_deinit(); @@ -4975,6 +4976,21 @@ static bool setting_append_list( general_read_handler, SD_FLAG_ADVANCED); + CONFIG_BOOL( + list, list_info, + &settings->bools.log_to_file_timestamp, + MENU_ENUM_LABEL_LOG_TO_FILE_TIMESTAMP, + MENU_ENUM_LABEL_VALUE_LOG_TO_FILE_TIMESTAMP, + log_to_file_timestamp, + MENU_ENUM_LABEL_VALUE_OFF, + MENU_ENUM_LABEL_VALUE_ON, + &group_info, + &subgroup_info, + parent_group, + general_write_handler, + general_read_handler, + SD_FLAG_ADVANCED); + END_SUB_GROUP(list, list_info, parent_group); START_SUB_GROUP(list, list_info, "Performance Counters", &group_info, &subgroup_info, diff --git a/msg_hash.h b/msg_hash.h index 89c58939c1..0973f9946a 100644 --- a/msg_hash.h +++ b/msg_hash.h @@ -1394,6 +1394,7 @@ enum msg_hash_enums MENU_LABEL(LOG_VERBOSITY), MENU_LABEL(LOG_TO_FILE), + MENU_LABEL(LOG_TO_FILE_TIMESTAMP), MENU_ENUM_LABEL_OVERLAY_NEXT, diff --git a/retroarch.c b/retroarch.c index 50252741e7..a1308602a7 100644 --- a/retroarch.c +++ b/retroarch.c @@ -292,6 +292,7 @@ static char runtime_content_path[PATH_MAX_LENGTH] = {0}; static char runtime_core_path[PATH_MAX_LENGTH] = {0}; static bool log_file_created = false; +static char timestamped_log_file_name[64] = {0}; extern bool input_driver_flushing_input; @@ -5282,6 +5283,22 @@ void rarch_log_file_init(void) FILE *fp = NULL; bool success = false; + /* If this is the first run, generate a timestamped log + * file name (do this even when not outputting timestamped + * log files, since user may decide to switch at any moment...) */ + if (string_is_empty(timestamped_log_file_name)) + { + char format[256]; + time_t cur_time = time(NULL); + + format[0] = '\0'; + + strftime(format, sizeof(format), "retroarch__%Y_%m_%d__%H_%M_%S", localtime(&cur_time)); + + fill_pathname_noext(timestamped_log_file_name, format, + file_path_str(FILE_PATH_EVENT_LOG_EXTENSION), sizeof(timestamped_log_file_name)); + } + /* If nothing has changed, do nothing */ if ((!settings->bools.log_to_file && !is_logging_to_file()) || (settings->bools.log_to_file && is_logging_to_file())) @@ -5312,7 +5329,9 @@ void rarch_log_file_init(void) if (!string_is_empty(settings->paths.log_dir)) { char buf[PATH_MAX_LENGTH]; - fill_pathname_join(buf, settings->paths.log_dir, file_path_str(FILE_PATH_DEFAULT_EVENT_LOG), sizeof(buf)); + fill_pathname_join(buf, settings->paths.log_dir, + settings->bools.log_to_file_timestamp ? timestamped_log_file_name : file_path_str(FILE_PATH_DEFAULT_EVENT_LOG), + sizeof(buf)); if (!string_is_empty(buf)) { /* When RetroArch is launched, log file is overwritten. diff --git a/tasks/task_content.c b/tasks/task_content.c index ec809fa14f..d1c9c03fd0 100644 --- a/tasks/task_content.c +++ b/tasks/task_content.c @@ -188,9 +188,7 @@ static void content_load_init_wrap( const struct rarch_main_wrap *args, int *argc, char **argv) { -#ifdef HAVE_FILE_LOGGER int i; -#endif *argc = 0; argv[(*argc)++] = strdup("retroarch"); @@ -238,10 +236,8 @@ static void content_load_init_wrap( if (args->verbose) argv[(*argc)++] = strdup("-v"); -#ifdef HAVE_FILE_LOGGER for (i = 0; i < *argc; i++) RARCH_LOG("arg #%d: %s\n", i, argv[i]); -#endif } /** diff --git a/verbosity.c b/verbosity.c index 8c05d20055..267f6193f6 100644 --- a/verbosity.c +++ b/verbosity.c @@ -126,6 +126,14 @@ void retro_main_log_file_init(const char *path, bool append) return; log_file_fp = (FILE*)fopen_utf8(path, append ? "ab" : "wb"); + + if (!log_file_fp) + { + log_file_fp = stderr; + RARCH_ERR("Failed to open system event log file: %s\n", path); + return; + } + log_file_initialized = true; #if !defined(PS2) /* TODO: PS2 IMPROVEMENT */ @@ -137,7 +145,7 @@ void retro_main_log_file_init(const char *path, bool append) void retro_main_log_file_deinit(void) { - if (log_file_fp && log_file_fp != stderr) + if (log_file_fp && log_file_initialized) { fclose(log_file_fp); log_file_fp = NULL; @@ -199,7 +207,10 @@ void RARCH_LOG_V(const char *tag, const char *fmt, va_list ap) } if (log_file_initialized) + { vfprintf(log_file_fp, fmt, ap); + fflush(log_file_fp); + } else __android_log_vprint(prio, file_path_str(FILE_PATH_PROGRAM_NAME),