diff --git a/code/__helpers/_logging.dm b/code/__helpers/_logging.dm index cbfaf6cb44a..cbc514d7232 100644 --- a/code/__helpers/_logging.dm +++ b/code/__helpers/_logging.dm @@ -1,4 +1,5 @@ -//print an error message to world.log +//location of the rust-g library +#define RUST_G "rust_g" // On Linux/Unix systems the line endings are LF, on windows it's CRLF, admins that don't use notepad++ // will get logs that are one big line if the system is Linux and they are using notepad. This solves it by adding CR to every line ending @@ -11,7 +12,7 @@ #define SEND_SOUND(target, sound) DIRECT_OUTPUT(target, sound) #define SEND_TEXT(target, text) DIRECT_OUTPUT(target, text) #define WRITE_FILE(file, text) DIRECT_OUTPUT(file, text) -#define WRITE_LOG(log, text) DIRECT_OUTPUT(log, text) +#define WRITE_LOG(log, text) call(RUST_G, "log_write")(log, text) /proc/error(msg) log_world("## ERROR: [msg]") @@ -31,11 +32,11 @@ /proc/log_admin(text) admin_log.Add(text) if(config.log_admin) - WRITE_LOG(GLOB.world_game_log, "\[[time_stamp()]]ADMIN: [text][log_end]") + WRITE_LOG(GLOB.world_game_log, "ADMIN: [text][log_end]") /proc/log_debug(text) if(config.log_debug) - WRITE_LOG(GLOB.world_game_log, "\[[time_stamp()]]DEBUG: [text][log_end]") + WRITE_LOG(GLOB.world_game_log, "DEBUG: [text][log_end]") for(var/client/C in admins) if(check_rights(R_DEBUG, 0, C.mob) && (C.prefs.toggles & CHAT_DEBUGLOGS)) @@ -43,85 +44,85 @@ /proc/log_game(text) if(config.log_game) - WRITE_LOG(GLOB.world_game_log, "\[[time_stamp()]]GAME: [text][log_end]") + WRITE_LOG(GLOB.world_game_log, "GAME: [text][log_end]") /proc/log_vote(text) if(config.log_vote) - WRITE_LOG(GLOB.world_game_log, "\[[time_stamp()]]VOTE: [text][log_end]") + WRITE_LOG(GLOB.world_game_log, "VOTE: [text][log_end]") /proc/log_access_in(client/new_client) if(config.log_access) var/message = "[key_name(new_client)] - IP:[new_client.address] - CID:[new_client.computer_id] - BYOND v[new_client.byond_version]" - WRITE_LOG(GLOB.world_game_log, "\[[time_stamp()]]ACCESS IN: [message][log_end]") + WRITE_LOG(GLOB.world_game_log, "ACCESS IN: [message][log_end]") /proc/log_access_out(mob/last_mob) if(config.log_access) var/message = "[key_name(last_mob)] - IP:[last_mob.lastKnownIP] - CID:[last_mob.computer_id] - BYOND Logged Out" - WRITE_LOG(GLOB.world_game_log, "\[[time_stamp()]]ACCESS OUT: [message][log_end]") + WRITE_LOG(GLOB.world_game_log, "ACCESS OUT: [message][log_end]") /proc/log_say(text, mob/speaker) if(config.log_say) - WRITE_LOG(GLOB.world_game_log, "\[[time_stamp()]]SAY: [speaker.simple_info_line()]: [html_decode(text)][log_end]") + WRITE_LOG(GLOB.world_game_log, "SAY: [speaker.simple_info_line()]: [html_decode(text)][log_end]") /proc/log_whisper(text, mob/speaker) if(config.log_whisper) - WRITE_LOG(GLOB.world_game_log, "\[[time_stamp()]]WHISPER: [speaker.simple_info_line()]: [html_decode(text)][log_end]") + WRITE_LOG(GLOB.world_game_log, "WHISPER: [speaker.simple_info_line()]: [html_decode(text)][log_end]") /proc/log_ooc(text, client/user) if(config.log_ooc) - WRITE_LOG(GLOB.world_game_log, "\[[time_stamp()]]OOC: [user.simple_info_line()]: [html_decode(text)][log_end]") + WRITE_LOG(GLOB.world_game_log, "OOC: [user.simple_info_line()]: [html_decode(text)][log_end]") /proc/log_aooc(text, client/user) if(config.log_ooc) - WRITE_LOG(GLOB.world_game_log, "\[[time_stamp()]]AOOC: [user.simple_info_line()]: [html_decode(text)][log_end]") + WRITE_LOG(GLOB.world_game_log, "AOOC: [user.simple_info_line()]: [html_decode(text)][log_end]") /proc/log_looc(text, client/user) if(config.log_ooc) - WRITE_LOG(GLOB.world_game_log, "\[[time_stamp()]]LOOC: [user.simple_info_line()]: [html_decode(text)][log_end]") + WRITE_LOG(GLOB.world_game_log, "LOOC: [user.simple_info_line()]: [html_decode(text)][log_end]") /proc/log_emote(text, mob/speaker) if(config.log_emote) - WRITE_LOG(GLOB.world_game_log, "\[[time_stamp()]]EMOTE: [speaker.simple_info_line()]: [html_decode(text)][log_end]") + WRITE_LOG(GLOB.world_game_log, "EMOTE: [speaker.simple_info_line()]: [html_decode(text)][log_end]") /proc/log_attack(attacker, defender, message) if(config.log_attack) - WRITE_LOG(GLOB.world_game_log, "\[[time_stamp()]]ATTACK: [attacker] against [defender]: [message][log_end]") //Seperate attack logs? Why? + WRITE_LOG(GLOB.world_game_log, "ATTACK: [attacker] against [defender]: [message][log_end]") //Seperate attack logs? Why? /proc/log_adminsay(text, mob/speaker) if(config.log_adminchat) - WRITE_LOG(GLOB.world_game_log, "\[[time_stamp()]]ADMINSAY: [speaker.simple_info_line()]: [html_decode(text)][log_end]") + WRITE_LOG(GLOB.world_game_log, "ADMINSAY: [speaker.simple_info_line()]: [html_decode(text)][log_end]") /proc/log_mentorsay(text, mob/speaker) if(config.log_adminchat) - WRITE_LOG(GLOB.world_game_log, "\[[time_stamp()]]MENTORSAY: [speaker.simple_info_line()]: [html_decode(text)][log_end]") + WRITE_LOG(GLOB.world_game_log, "MENTORSAY: [speaker.simple_info_line()]: [html_decode(text)][log_end]") /proc/log_ghostsay(text, mob/speaker) if(config.log_say) - WRITE_LOG(GLOB.world_game_log, "\[[time_stamp()]]DEADCHAT: [speaker.simple_info_line()]: [html_decode(text)][log_end]") + WRITE_LOG(GLOB.world_game_log, "DEADCHAT: [speaker.simple_info_line()]: [html_decode(text)][log_end]") /proc/log_ghostemote(text, mob/speaker) if(config.log_emote) - WRITE_LOG(GLOB.world_game_log, "\[[time_stamp()]]DEADEMOTE: [speaker.simple_info_line()]: [html_decode(text)][log_end]") + WRITE_LOG(GLOB.world_game_log, "DEADEMOTE: [speaker.simple_info_line()]: [html_decode(text)][log_end]") /proc/log_adminwarn(text) if(config.log_adminwarn) - WRITE_LOG(GLOB.world_game_log, "\[[time_stamp()]]ADMINWARN: [html_decode(text)][log_end]") + WRITE_LOG(GLOB.world_game_log, "ADMINWARN: [html_decode(text)][log_end]") /proc/log_pda(text, mob/speaker) if(config.log_pda) - WRITE_LOG(GLOB.world_game_log, "\[[time_stamp()]]PDA: [speaker.simple_info_line()]: [html_decode(text)][log_end]") + WRITE_LOG(GLOB.world_game_log, "PDA: [speaker.simple_info_line()]: [html_decode(text)][log_end]") /proc/log_chat(text, mob/speaker) if(config.log_pda) - WRITE_LOG(GLOB.world_game_log, "\[[time_stamp()]]CHAT: [speaker.simple_info_line()] [html_decode(text)][log_end]") + WRITE_LOG(GLOB.world_game_log, "CHAT: [speaker.simple_info_line()] [html_decode(text)][log_end]") /proc/log_misc(text) - WRITE_LOG(GLOB.world_game_log, "\[[time_stamp()]]MISC: [text][log_end]") + WRITE_LOG(GLOB.world_game_log, "MISC: [text][log_end]") /proc/log_world(text) SEND_TEXT(world.log, text) if(config && config.log_world_output) - WRITE_LOG(GLOB.world_game_log, "\[[time_stamp()]]WORLD: [text][log_end]") + WRITE_LOG(GLOB.world_game_log, "WORLD: [html_decode(text)][log_end]") /proc/log_runtime_txt(text) // different from /tg/'s log_runtime because our error handler has a log_runtime proc already that does other stuff GLOB.world_runtime_log << text @@ -130,6 +131,9 @@ WRITE_LOG(GLOB.config_error_log, text) SEND_TEXT(world.log, text) +/proc/log_href(text) + WRITE_LOG(GLOB.world_href_log, "HREF: [html_decode(text)]") + /** * Standardized method for tracking startup times. */ @@ -144,6 +148,14 @@ to_chat(world, "[message]") log_world(message) +/* For logging round startup. */ +/proc/start_log(log) + WRITE_LOG(log, "Starting up.\n-------------------------") + +/* Close open log handles. This should be called as late as possible, and no logging should hapen after. */ +/proc/shutdown_logging() + call(RUST_G, "log_close_all")() + // Helper procs for building detailed log lines /proc/datum_info_line(var/datum/d) @@ -167,4 +179,7 @@ return "[key_name(src)] ([x],[y],[z])" /client/proc/simple_info_line() - return "[key_name(src)] ([mob.x],[mob.y],[mob.z])" \ No newline at end of file + return "[key_name(src)] ([mob.x],[mob.y],[mob.z])" + +//this is only used here (for now) +#undef RUST_G \ No newline at end of file diff --git a/code/controllers/master.dm b/code/controllers/master.dm index 7af487c815f..ddde5460cef 100644 --- a/code/controllers/master.dm +++ b/code/controllers/master.dm @@ -64,7 +64,7 @@ GLOBAL_REAL(Master, /datum/controller/master) = new /datum/controller/master/New() makeDatumRefLists() //temporary file used to record errors with loading config, moved to log directory once logging is set up - GLOB.config_error_log = GLOB.world_game_log = GLOB.world_runtime_log = file("data/logs/config_error.log") + GLOB.config_error_log = GLOB.world_game_log = GLOB.world_runtime_log = "data/logs/config_error.log" load_configuration() // Highlander-style: there can only be one! Kill off the old and replace it with the new. diff --git a/code/game/world.dm b/code/game/world.dm index f2ed1ef9c9e..f7cf1a758b7 100644 --- a/code/game/world.dm +++ b/code/game/world.dm @@ -285,6 +285,7 @@ var/world_topic_spam_protect_time = world.timeofday log_admin("[key_name(usr)] has requested an immediate world restart via client side debugging tools") spawn(0) to_chat(world, "Rebooting world immediately due to host request") + shutdown_logging() // Past this point, no logging procs can be used, at risk of data loss. if(config && config.shutdown_on_reboot) sleep(0) if(shutdown_shell_command) @@ -321,6 +322,7 @@ var/world_topic_spam_protect_time = world.timeofday //kick_clients_in_lobby("The round came to an end with you in the lobby.", 1) processScheduler.stop() + shutdown_logging() // Past this point, no logging procs can be used, at risk of data loss. if(config && config.shutdown_on_reboot) sleep(0) @@ -435,12 +437,12 @@ var/failed_old_db_connections = 0 /world/proc/SetupLogs() GLOB.log_directory = "data/logs/[time2text(world.realtime, "YYYY/MM-Month/DD-Day")]" - GLOB.world_game_log = file("[GLOB.log_directory]/game.log") - GLOB.world_href_log = file("[GLOB.log_directory]/hrefs.log") - GLOB.world_runtime_log = file("[GLOB.log_directory]/runtime.log") - WRITE_FILE(GLOB.world_game_log, "\n\nStarting up. [time_stamp()]\n---------------------") - WRITE_FILE(GLOB.world_href_log, "\n\nStarting up. [time_stamp()]\n---------------------") - WRITE_FILE(GLOB.world_runtime_log, "\n\nStarting up. [time_stamp()]\n---------------------") + GLOB.world_game_log = "[GLOB.log_directory]/game.log" + GLOB.world_href_log = "[GLOB.log_directory]/hrefs.log" + GLOB.world_runtime_log = "[GLOB.log_directory]/runtime.log" + start_log(GLOB.world_game_log) + start_log(GLOB.world_href_log) + start_log(GLOB.world_runtime_log) if(fexists(GLOB.config_error_log)) fcopy(GLOB.config_error_log, "[GLOB.log_directory]/config_error.log") diff --git a/code/modules/admin/admin_investigate.dm b/code/modules/admin/admin_investigate.dm index 42c7866dceb..4623a46d7d1 100644 --- a/code/modules/admin/admin_investigate.dm +++ b/code/modules/admin/admin_investigate.dm @@ -41,7 +41,7 @@ if("hrefs") //persistant logs and stuff if(config && config.log_hrefs) if(GLOB.world_href_log) - src << browse(GLOB.world_href_log,"window=investigate[subject];size=800x300") + src << browse(file(GLOB.world_href_log), "window=investigate[subject];size=800x300") else to_chat(src, "Error: admin_investigate: No href logfile found.") return diff --git a/code/modules/admin/admin_verbs.dm b/code/modules/admin/admin_verbs.dm index 383557bf0a6..43652f0784d 100644 --- a/code/modules/admin/admin_verbs.dm +++ b/code/modules/admin/admin_verbs.dm @@ -19,15 +19,13 @@ var/list/admin_verbs_admin = list( /client/proc/resetcolorooc, /*allows us to set a reset our ooc color*/ /client/proc/admin_ghost, /*allows us to ghost/reenter body at will*/ /client/proc/toggle_view_range, /*changes how far we can see*/ - /datum/admins/proc/view_txt_log, /*shows the server log (diary) for today*/ - /datum/admins/proc/view_atk_log, /*shows the server combat-log, doesn't do anything presently*/ /client/proc/cmd_admin_pm_context, /*right-click adminPM interface*/ /client/proc/cmd_admin_pm_panel, /*admin-pm list*/ /client/proc/cmd_admin_pm_by_key_panel, /*admin-pm list by key*/ /client/proc/cmd_admin_subtle_message, /*send an message to somebody as a 'voice in their head'*/ /client/proc/cmd_admin_delete, /*delete an instance/object/mob/etc*/ /client/proc/cmd_admin_check_contents, /*displays the contents of an instance*/ - /client/proc/getserverlog, /*allows us to fetch server logs (diary) for other days*/ + /client/proc/getserverlogs, /*allows us to fetch server logs (diary) for other days*/ /client/proc/jumptocoord, /*we ghost and jump to a coordinate*/ /client/proc/Getmob, /*teleports a mob to our location*/ /client/proc/Getkey, /*teleports a mob with a certain ckey to our location*/ diff --git a/code/modules/admin/verbs/getlogs.dm b/code/modules/admin/verbs/getlogs.dm index f27f1ab7ed6..22c6d778733 100644 --- a/code/modules/admin/verbs/getlogs.dm +++ b/code/modules/admin/verbs/getlogs.dm @@ -15,11 +15,10 @@ //This proc allows download of past server logs saved within the data/logs/ folder. -//It works similarly to show-server-log. -/client/proc/getserverlog() - set name = ".getserverlog" - set desc = "Fetch logfiles from data/logs" - set category = null +/client/proc/getserverlogs() + set name = "Get Server Logs" + set desc = "View/retrieve logfiles." + set category = "Admin" var/path = browse_files("data/logs/") if(!path) @@ -29,44 +28,14 @@ return message_admins("[key_name_admin(src)] accessed file: [path]") - src << ftp(file(path)) - - to_chat(src, "Attempting to send file, this may take a fair few minutes if the file is very large.") - return - - -//Other log stuff put here for the sake of organisation - -//Shows today's server log -/datum/admins/proc/view_txt_log() - set category = "Admin" - set name = "Show Server Log" - set desc = "Shows today's server log." - - var/path = "[GLOB.log_directory]/game.log" - if( fexists(path) ) - src << ftp(file(path)) - - else - to_chat(src, "Error: view_txt_log(): File not found/Invalid path([path]).") - return - feedback_add_details("admin_verb","VTL") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc! - return - -//Shows today's attack log -/datum/admins/proc/view_atk_log() - set category = "Admin" - set name = "Show Server Attack Log" - set desc = "Shows today's server attack log." - - var/path = "[GLOB.log_directory]/attack.log" - if(fexists(path)) - src << ftp(file(path)) - - else - to_chat(src, "Error: view_atk_log(): File not found/Invalid path([path]).") - return - usr << run(file(path)) - - feedback_add_details("admin_verb","SSAL") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc! - return + switch(alert("View (in game), Open (in your system's text editor), or Download?", path, "View", "Open", "Download")) + if ("View") + src << browse("
[html_encode(file2text(file(path)))]", list2params(list("window" = "viewfile.[path]"))) + if ("Open") + src << run(file(path)) + if ("Download") + src << ftp(file(path)) + else + return + to_chat(src, "Attempting to send [path], this may take a fair few minutes if the file is very large.") + return \ No newline at end of file diff --git a/code/modules/client/client procs.dm b/code/modules/client/client procs.dm index 9e84720ef82..838670221ad 100644 --- a/code/modules/client/client procs.dm +++ b/code/modules/client/client procs.dm @@ -95,7 +95,7 @@ //Logs all hrefs if(config && config.log_hrefs) - WRITE_LOG(GLOB.world_href_log, "[time2text(world.timeofday,"hh:mm")] [src] (usr:[usr]) || [hsrc ? "[hsrc] " : ""][href]