diff --git a/config.def.h b/config.def.h index 563ed9555d..5164432321 100644 --- a/config.def.h +++ b/config.def.h @@ -438,6 +438,12 @@ static bool menu_swap_ok_cancel_buttons = false; static bool quit_press_twice = false; +#if defined(ANDROID) +static bool default_log_to_file = true; +#else +static bool default_log_to_file = false; +#endif + /* Crop overscanned frames. */ static const bool crop_overscan = true; @@ -915,4 +921,6 @@ static char buildbot_assets_server_url[] = "http://buildbot.libretro.com/assets/ static char default_discord_app_id[] = "475456035851599874"; +static char default_log_file[] = "retroarch.log"; + #endif diff --git a/configuration.c b/configuration.c index 8aecd689c3..e779600a69 100644 --- a/configuration.c +++ b/configuration.c @@ -1310,6 +1310,9 @@ static struct config_path_setting *populate_settings_path(settings_t *settings, global->record.config_dir, false, NULL, true); } + SETTING_ARRAY("log_file", settings->paths.log_file, true, default_log_file, true); + SETTING_ARRAY("log_dir", settings->paths.log_dir, true, "", true); + *size = count; return tmp; @@ -1592,6 +1595,7 @@ static struct config_bool_setting *populate_settings_bool(settings_t *settings, #ifdef HAVE_OZONE SETTING_BOOL("ozone_collapse_sidebar", &settings->bools.ozone_collapse_sidebar, true, ozone_collapse_sidebar, false); #endif + SETTING_BOOL("log_to_file", &settings->bools.log_to_file, true, default_log_to_file, false); *size = count; @@ -1956,6 +1960,12 @@ void config_set_defaults(void) strlcpy(settings->arrays.discord_app_id, default_discord_app_id, sizeof(settings->arrays.discord_app_id)); + strlcpy(settings->paths.log_file, + default_log_file, sizeof(settings->paths.log_file)); + + strlcpy(settings->paths.log_dir, + g_defaults.dirs[DEFAULT_DIR_LOGS], sizeof(settings->paths.log_dir)); + #ifdef HAVE_MATERIALUI if (g_defaults.menu.materialui.menu_color_theme_enable) settings->uints.menu_materialui_color_theme = g_defaults.menu.materialui.menu_color_theme; @@ -2253,6 +2263,11 @@ void config_set_defaults(void) g_defaults.dirs[DEFAULT_DIR_CONTENT_HISTORY], sizeof(settings->paths.directory_content_history)); + if (!string_is_empty(g_defaults.dirs[DEFAULT_DIR_LOGS])) + strlcpy(settings->paths.log_dir, + g_defaults.dirs[DEFAULT_DIR_LOGS], + sizeof(settings->paths.log_dir)); + if (!string_is_empty(g_defaults.path.config)) { char *temp_str = (char*)malloc(PATH_MAX_LENGTH * sizeof(char)); @@ -2832,7 +2847,9 @@ static bool config_load_file(const char *path, bool set_defaults, if (config_get_bool(conf, "log_verbosity", &tmp_bool)) { if (tmp_bool) + { verbosity_enable(); + } else verbosity_disable(); } @@ -3244,7 +3261,6 @@ static bool config_load_file(const char *path, bool set_defaults, recording_driver_update_streaming_url(); ret = true; - end: if (conf) config_file_free(conf); diff --git a/configuration.h b/configuration.h index f1ea2f6b3b..6e8cd1ad2c 100644 --- a/configuration.h +++ b/configuration.h @@ -320,6 +320,8 @@ typedef struct settings #ifdef HAVE_OZONE bool ozone_collapse_sidebar; #endif + + bool log_to_file; } bools; struct @@ -589,6 +591,9 @@ typedef struct settings char directory_menu_config[PATH_MAX_LENGTH]; char directory_menu_content[PATH_MAX_LENGTH]; char streaming_title[PATH_MAX_LENGTH]; + + char log_dir[PATH_MAX_LENGTH]; + char log_file[PATH_MAX_LENGTH]; } paths; bool modified; diff --git a/defaults.h b/defaults.h index 117e14a39a..6ffd885498 100644 --- a/defaults.h +++ b/defaults.h @@ -54,6 +54,7 @@ enum default_dirs DEFAULT_DIR_CHEATS, DEFAULT_DIR_RECORD_CONFIG, DEFAULT_DIR_RECORD_OUTPUT, + DEFAULT_DIR_LOGS, DEFAULT_DIR_LAST }; diff --git a/dirs.c b/dirs.c index aa253ceb8e..ee2c980861 100644 --- a/dirs.c +++ b/dirs.c @@ -314,6 +314,8 @@ void dir_check_defaults(void) */ #ifdef ORBIS if (filestream_exists("host0:app/custom.ini")) +#elif defined(ANDROID) + if (filestream_exists("host0:app/custom.ini")) #else if (filestream_exists("custom.ini")) #endif diff --git a/frontend/drivers/platform_unix.c b/frontend/drivers/platform_unix.c index 2f9e41e6b2..2fd9914449 100644 --- a/frontend/drivers/platform_unix.c +++ b/frontend/drivers/platform_unix.c @@ -1660,6 +1660,10 @@ static void frontend_unix_get_env(int *argc, sizeof(g_defaults.dirs[DEFAULT_DIR_CORE_ASSETS])); } + fill_pathname_join(g_defaults.dirs[DEFAULT_DIR_LOGS], + internal_storage_app_path, "logs", + sizeof(g_defaults.dirs[DEFAULT_DIR_LOGS])); + break; /* only the internal app dir is writable, this should never happen*/ @@ -1722,6 +1726,10 @@ static void frontend_unix_get_env(int *argc, sizeof(g_defaults.dirs[DEFAULT_DIR_CORE_ASSETS])); } + fill_pathname_join(g_defaults.dirs[DEFAULT_DIR_LOGS], + app_dir, "logs", + sizeof(g_defaults.dirs[DEFAULT_DIR_LOGS])); + break; /* sdcard is writable, this should be the case most of the time*/ case INTERNAL_STORAGE_WRITABLE: @@ -1742,6 +1750,10 @@ static void frontend_unix_get_env(int *argc, internal_storage_path, "RetroArch/downloads", sizeof(g_defaults.dirs[DEFAULT_DIR_CORE_ASSETS])); + fill_pathname_join(g_defaults.dirs[DEFAULT_DIR_LOGS], + internal_storage_path, "RetroArch/logs", + sizeof(g_defaults.dirs[DEFAULT_DIR_LOGS])); + fill_pathname_join(g_defaults.dirs[DEFAULT_DIR_MENU_CONFIG], internal_storage_path, "RetroArch/config", sizeof(g_defaults.dirs[DEFAULT_DIR_MENU_CONFIG])); diff --git a/frontend/drivers/platform_win32.c b/frontend/drivers/platform_win32.c index da5142956d..35bd1f0a2e 100644 --- a/frontend/drivers/platform_win32.c +++ b/frontend/drivers/platform_win32.c @@ -465,7 +465,8 @@ static void frontend_win32_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) snprintf(g_defaults.settings.menu, diff --git a/intl/msg_hash_us.h b/intl/msg_hash_us.h index 7bb269143e..ec89eef333 100644 --- a/intl/msg_hash_us.h +++ b/intl/msg_hash_us.h @@ -3976,7 +3976,7 @@ MSG_HASH( ) MSG_HASH( MENU_ENUM_SUBLABEL_LOG_VERBOSITY, - "Log events to the terminal." + "Log events to a terminal or file." ) MSG_HASH( MENU_ENUM_SUBLABEL_NETPLAY, diff --git a/pkg/android/phoenix/jni/Android.mk b/pkg/android/phoenix/jni/Android.mk index 0c63486e0e..542acad1a6 100644 --- a/pkg/android/phoenix/jni/Android.mk +++ b/pkg/android/phoenix/jni/Android.mk @@ -8,6 +8,7 @@ HAVE_NEON := 1 HAVE_LOGGER := 0 HAVE_VULKAN := 1 HAVE_CHEEVOS := 1 +HAVE_FILE_LOGGER := 1 INCFLAGS := DEFINES := diff --git a/pkg/android/phoenix/src/com/retroarch/browser/preferences/util/UserPreferences.java b/pkg/android/phoenix/src/com/retroarch/browser/preferences/util/UserPreferences.java index 2e1ec9ed61..d19cef2643 100644 --- a/pkg/android/phoenix/src/com/retroarch/browser/preferences/util/UserPreferences.java +++ b/pkg/android/phoenix/src/com/retroarch/browser/preferences/util/UserPreferences.java @@ -140,7 +140,6 @@ public final class UserPreferences Log.i(TAG, "dst dir is: " + dst_path); Log.i(TAG, "dst subdir is: " + dst_path_subdir); - config.setBoolean("log_verbosity", true); config.setString("bundle_assets_src_path", ctx.getApplicationInfo().sourceDir); config.setString("bundle_assets_dst_path", dst_path); config.setString("bundle_assets_dst_path_subdir", dst_path_subdir); diff --git a/retroarch.c b/retroarch.c index e7afc9bfff..5b882e08d3 100644 --- a/retroarch.c +++ b/retroarch.c @@ -1759,6 +1759,20 @@ static void retroarch_parse_input_and_config(int argc, char *argv[]) } } + + if (verbosity_is_enabled()) + { + settings_t *settings = config_get_ptr(); + if (settings->bools.log_to_file && + !string_is_empty(settings->paths.log_dir) && !string_is_empty(settings->paths.log_file)) + { + char buf[PATH_MAX_LENGTH]; + fill_pathname_join(buf, settings->paths.log_dir, settings->paths.log_file, sizeof(buf)); + RARCH_LOG("Logging to file: %s\n", buf); + retro_main_log_file_init(buf); + } + } + #ifdef HAVE_GIT_VERSION RARCH_LOG("RetroArch %s (Git %s)\n", PACKAGE_VERSION, retroarch_git_version); diff --git a/runtime_file.c b/runtime_file.c index 7139b56c38..b2125a1bbb 100644 --- a/runtime_file.c +++ b/runtime_file.c @@ -370,7 +370,7 @@ runtime_log_t *runtime_log_init(const char *content_path, const char *core_path, if(!path_is_directory(log_file_dir)) { - RARCH_ERR("Failed to create directory for runtime log: %s.\n", log_file_dir); + RARCH_ERR("[runtime] failed to create directory for runtime log: %s.\n", log_file_dir); return NULL; } } @@ -415,7 +415,7 @@ runtime_log_t *runtime_log_init(const char *content_path, const char *core_path, if (string_is_empty(log_file_path)) return NULL; - + /* Phew... If we get this far then all is well. * > Create 'runtime_log' object */ runtime_log = (runtime_log_t*)calloc(1, sizeof(*runtime_log)); diff --git a/verbosity.c b/verbosity.c index 55a155a34c..662198dee0 100644 --- a/verbosity.c +++ b/verbosity.c @@ -96,6 +96,11 @@ bool verbosity_is_enabled(void) return main_verbosity; } +bool is_logging_to_file(void) +{ + return log_file_initialized; +} + bool *verbosity_get_ptr(void) { return &main_verbosity; @@ -190,10 +195,14 @@ void RARCH_LOG_V(const char *tag, const char *fmt, va_list ap) else if (string_is_equal(file_path_str(FILE_PATH_LOG_ERROR), tag)) prio = ANDROID_LOG_ERROR; } - __android_log_vprint(prio, - file_path_str(FILE_PATH_PROGRAM_NAME), - fmt, - ap); + + if (log_file_initialized) + vfprintf(log_file_fp, fmt, ap); + else + __android_log_vprint(prio, + file_path_str(FILE_PATH_PROGRAM_NAME), + fmt, + ap); } #else diff --git a/verbosity.h b/verbosity.h index 42ae964f58..546066af61 100644 --- a/verbosity.h +++ b/verbosity.h @@ -41,6 +41,8 @@ void retro_main_log_file_deinit(void); void retro_main_log_file_init(const char *path); +bool is_logging_to_file(void); + #if defined(HAVE_LOGGER) void logger_init (void);