RefresherTowel

Custom Debugging Log File Generator in GML

Nov 13th, 2020 (edited)
2,489
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. /*** Custom Debugging Log File Generator ***
  2. This set of scripts replaces show_debug_message() in GML and creates a custom log file that holds a lot more information than a simple show_debug_message(). Here's an example output of a log file:
  3.  
  4.  
  5.  
  6.  
  7.  
  8. ********* THE LOG FILE *********/
  9.  
  10. -- SPECS START --
  11.  
  12. Logfile Name: Y:\Spaceslingers_Steam_Version_6AE9EECB_YYC\\Log\log_14112020133855.logfile
  13. Log Time: 14-11-2020(13h-38m-55s)
  14. Game Version: 0.95 // This is the game version you've entered under the Options settings in GMS
  15. OS Version: 655360
  16. OS Language: en
  17. OS Region: AU
  18. OS Data: // Read this page for info on the below numbers: http://127.0.0.1:51290/index.html?page=source%2f_build/3_scripting%2f4_gml_reference%2fmiscellaneous%2fos_get_info.html
  19. 838866018
  20. bd496841-475e-4ff4-8ce2-da95a970930e
  21. 4318
  22. 072B1308
  23. 072B04FC
  24. 5121
  25. 2189754368
  26. 161
  27. NVIDIA GeForce GTX 960
  28. 0
  29. Working Dir: Y:\Spaceslingers_Steam_Version_6AE9EECB_YYC\
  30. Steam User: euphoria_syndrome
  31. Steam User ID: 111111111111111
  32. Steam Account Cloud Enabled: 1
  33. Steam Game Cloud Enabled: 1
  34. Steam Cloud Quota Available: 4992948
  35. Steam Available Languages: english
  36. Steam Current Game Language: english
  37. Steam User Logged On: 1
  38.  
  39. -- SPECS END --
  40.  
  41.  
  42. --- LOG START ---
  43.  
  44. ** Running Time 418 ** // 418 milliseconds since the game was booted
  45. This is an info log. // INFO -- Callstack:
  46. >>gml_Object_master_Create_0:159 // Called from an object called master, in the Create Event at line 159
  47.  
  48. ** Running Time 423 **
  49. This is an error log. // ERROR -- Callstack:
  50. >>gml_Object_master_Create_0:160 // Called from an object called master, in the Create Event at line 160
  51.  
  52. ** Running Time 428 **
  53. This is an error log inside a script named load_steam_save(). // ERROR -- Callstack:
  54. >>>>gml_Script_load_steam_save:5 // Called from inside a script called load_steam_save at line 5
  55. >>gml_Object_master_Create_0:162 // load_steam_save script was called from an object called master, in the Create Event at line 162
  56.  
  57. ** Running Time 591 **
  58. This is a log in another object called obj_title. // ERROR -- Callstack:
  59. >>gml_Object_obj_title_Create_0:4 // Called from an object called obj_title, in the Create Event at line 4
  60.  
  61. --- LOG END ---
  62.  
  63. /********* END OF LOG FILE *********
  64.  
  65.  
  66.  
  67.  
  68.  
  69. As you can see, it gathers information about the computer itself so you can see what specs the player is running, and it gives you the error/info message you were asking for alongside the callstack where it was generated. It requires 3 scripts to function properly, log_ini(), log() [which is the replacement for show_debug_message()] and log_quit() [this one is not entirely necessary, but it'll show you if the user quit the game on purpose or if the game completed crashed].
  70.  
  71. The log_ini() script takes a single argument, which is whether to turn a global boolean called global.debug on or off. If global.debug is set to true, then alongside the log file, GMS will also output a show_debug_message() with the same info to your console. If it's false, the only the log file will be created. Run log_ini in whatever object is first created in the game.
  72.  
  73.  
  74.  
  75.  
  76.  
  77. ********* START OF log_ini() SCRIPT *********/
  78.  
  79. ///@function log_ini(debug_mode);
  80. ///@description Initialises the log file
  81. ///@param {bool} debug_mode
  82.  
  83. global.debug = argument0;
  84.  
  85. var _time = string(current_day)+"-"+string(current_month)+"-"+string(current_year)+"("+string(current_hour)+"h-"+string(current_minute)+"m-"+string(current_second)+"s)"; // The time the log file was generated
  86. var _filekey = string(current_day)+string(current_month)+string(current_year)+string(current_hour)+string(current_minute)+string(current_second);
  87. var _fname = "log_"+string(_filekey)+".logfile"; // The logfile name is based off what time it was created.
  88. global.logfile_name = working_directory+"\\Log\\"+_fname; // Change this if you want the logfile to be stored somewhere other than a folder called Log
  89. var _game_version = global.version;
  90. var _os_version = os_version;
  91. var _os_lang = os_get_language();
  92. var _os_region = os_get_region();
  93. var _os_map = os_get_info();
  94. var _map_data = [];
  95. if (_os_map != -1) {
  96.     var size, key, i;
  97.     size = ds_map_size(_os_map);
  98.     key = ds_map_find_first(_os_map);
  99.    for (i = 0; i < size - 1; i++;) {
  100.         _map_data[i] = ds_map_find_value(_os_map, key);
  101.         key = ds_map_find_next(_os_map, key);
  102.     }
  103.     ds_map_destroy(_os_map);
  104. }
  105. var _str =  "-- SPECS START --\n\n"+
  106.             "Logfile Name: "+string(global.logfile_name)+"\n"+
  107.             "Log Time: "+string(_time)+"\n"+
  108.             "Game Version: "+string(_game_version)+"\n"+
  109.             "OS Version: "+string(_os_version)+"\n"+
  110.             "OS Language: "+string(_os_lang)+"\n"+
  111.             "OS Region: "+string(_os_region)+"\n"+
  112.             "OS Data: \n";
  113.  
  114. for (var i=0;i<array_length_1d(_map_data);i++) {
  115.     _str += string(_map_data[i])+"\n";
  116. }
  117.  
  118. _str += "Working Dir: "+string(working_directory)+"\n";
  119.  
  120. // This next section is only necessary if you are using Steam and need info on the Steam player
  121.  
  122. if (steam_initialised()) {
  123.     _str +=     "Steam User: "+string(steam_get_persona_name())+"\n"+
  124.                 "Steam User ID: "+string(steam_get_user_steam_id())+"\n"+
  125.                 "Steam Account Cloud Enabled: "+string(steam_is_cloud_enabled_for_account())+"\n"+
  126.                 "Steam Game Cloud Enabled: "+string(steam_is_cloud_enabled_for_app())+"\n"+
  127.                 "Steam Cloud Quota Available: "+string(steam_get_quota_free())+"\n"+
  128.                 "Steam Available Languages: "+string(steam_available_languages())+"\n"+
  129.                 "Steam Current Game Language: "+string(steam_current_game_language())+"\n"+
  130.                 "Steam User Logged On: "+string(steam_is_user_logged_on());
  131. }
  132.  
  133. // Steam info section ended
  134.  
  135. _str += "\n\n-- SPECS END --\n\n\n--- LOG START ---\n";
  136.  
  137. var file = file_text_open_write(global.logfile_name);
  138. file_text_write_string(file,_str);
  139. file_text_writeln(file);
  140. file_text_close(file);
  141.  
  142. /********* END OF log_ini(debug_mode) SCRIPT *********
  143.  
  144.  
  145.  
  146.  
  147.  
  148. The next script is the log(text,log_type) script, which is the meat and potatoes of the script set. Use it in place of show_debug_message(). It takes two arguments, text, which is the text you want displayed for this log line and log_type, which is an enum and lets you differentiate between actual errors and things you want to keep track of. By default the enum has two values: log_type.INFO and log_type.ERROR but you could add more to the enum if you wanted. Call it like this: log("This is the text you want saved to the log",log_type.INFO) from anywhere you want after log_ini(debug_mode) has been called. If debug_mode is true, this will also trigger a show_debug_message() with the contents, but if not it won't.
  149.  
  150.  
  151.  
  152.  
  153.  
  154. ********* START OF log(text,log_type) SCRIPT *********/
  155.  
  156. ///@function log(msg,type);
  157. ///@description Logs an entry into the debug list
  158. ///@param {string} msg The message to log
  159. ///@param {enum} type The type of entry
  160.  
  161. enum log_type { // Add enums below if you want to have different log_types
  162.     INFO,
  163.     ERROR
  164. }
  165.  
  166. var msg = argument0;
  167. var type = argument1;
  168. var type_str = "";
  169. var log_str = "";
  170. var _ctime = string(current_time);
  171.  
  172. switch (type) { // If you've added enums, then also add a case for the enum with what text to call it
  173.     case log_type.INFO:
  174.         type_str = "INFO";
  175.     break;
  176.     case log_type.ERROR:
  177.         type_str = "ERROR";
  178.     break;
  179. }
  180.  
  181. log_str = "** Running Time "+string(_ctime)+" **\n"+msg+"
  182. log_str += " -- Callstack:";
  183. var _stack = debug_get_callstack();
  184. var _stacklen = array_length_1d(_stack)-1;
  185. for (var i=1;i<_stacklen;i++) {
  186.     log_str += "\n";
  187.     repeat ((_stacklen)-i) {
  188.         log_str += ">>";
  189.     }
  190.     log_str += string(_stack[i]);
  191. }
  192.  
  193. log_str += "\n";
  194. var file = file_text_open_append(global.logfile_name);
  195. if (file_exists(global.logfile_name)) {
  196.     file_text_write_string(file,log_str);
  197.     file_text_writeln(file);
  198.     file_text_close(file);
  199.     if (global.debug) {
  200.         show_debug_message(log_str);
  201.     }
  202. }
  203. else { // This only triggers if the log file is not writeable for some reason. Never happened to me
  204.     file = file_text_open_write(working_directory+"\\Logfile_not_found.logfile");
  205.     if (file_exists(working_directory+"\\Logfile_not_found.logfile")) {
  206.         file_text_write_string(file,"Tried to write to "+string(global.logfile_name)+" and file was not accessible. Original log error was:\n\n"+log_str);
  207.     }
  208.     file_text_close(file);
  209. }
  210.  
  211. /********* END OF log(text,log_type) SCRIPT *********
  212.  
  213.  
  214.  
  215.  
  216.  
  217. Then finally we have the log_quit() script, which is simply a closer to the log file so that you know if the game ended naturally through the Game End Event or if it crashed to desktop. Call it from a persistent object in the Game End Event.
  218.  
  219.  
  220.  
  221.  
  222.  
  223. ********* START OF log_quit() SCRIPT *********/
  224.  
  225. ///@function log_quit();
  226. ///@description Adds a closer to the log file
  227.  
  228. var _str = "--- LOG END ---";
  229.  
  230. var file = file_text_open_append(global.logfile_name);
  231. file_text_write_string(file,_str);
  232. file_text_writeln(file);
  233. file_text_close(file);
  234.  
  235. /********* END OF log_quit() SCRIPT *********
  236.  
  237.  
  238.  
  239.  
  240. That's it. Add these files as scripts named appropriately and start using log() instead of show_debug_message() and you'll be able to store much more information about anything potentially going wrong that you're checking for. */
RAW Paste Data

Adblocker detected! Please consider disabling it...

We've detected AdBlock Plus or some other adblocking software preventing Pastebin.com from fully loading.

We don't have any obnoxious sound, or popup ads, we actively block these annoying types of ads!

Please add Pastebin.com to your ad blocker whitelist or disable your adblocking software.

×