diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..d9aac21 --- /dev/null +++ b/.gitignore @@ -0,0 +1,15 @@ +# Godot 4+ specific ignores +.godot/ + +# Godot-specific ignores +.import/ +export.cfg +export_presets.cfg + +# Imported translations (automatically generated from CSV files) +*.translation + +# Mono-specific ignores +.mono/ +data_*/ +mono_crash.*.json diff --git a/Logger.gd b/Logger.gd new file mode 100644 index 0000000..058c275 --- /dev/null +++ b/Logger.gd @@ -0,0 +1,8 @@ +tool +extends EditorPlugin + +func _enter_tree(): + add_custom_type("Logger", "Node", preload("log_base.gd"), preload("Logging.png")) + +func _exit_tree(): + remove_custom_type("Logger") diff --git a/Logging.png b/Logging.png new file mode 100644 index 0000000..7228148 Binary files /dev/null and b/Logging.png differ diff --git a/Logging.png.import b/Logging.png.import new file mode 100644 index 0000000..f6d3011 --- /dev/null +++ b/Logging.png.import @@ -0,0 +1,34 @@ +[remap] + +importer="texture" +type="StreamTexture" +path="res://.import/Logging.png-4515a13ab4998ab99f08b72db994dc6b.stex" +metadata={ +"vram_texture": false +} + +[deps] + +source_file="res://addons/Logger/Logging.png" +dest_files=[ "res://.import/Logging.png-4515a13ab4998ab99f08b72db994dc6b.stex" ] + +[params] + +compress/mode=0 +compress/lossy_quality=0.7 +compress/hdr_mode=0 +compress/bptc_ldr=0 +compress/normal_map=0 +flags/repeat=0 +flags/filter=true +flags/mipmaps=false +flags/anisotropic=false +flags/srgb=2 +process/fix_alpha_border=true +process/premult_alpha=false +process/HDR_as_SRGB=false +process/invert_color=false +stream=false +size_limit=0 +detect_3d=true +svg/scale=1.0 diff --git a/README.md b/README.md new file mode 100644 index 0000000..2bb5c4d --- /dev/null +++ b/README.md @@ -0,0 +1,65 @@ +# Logger + +A filebased logging plugin, for [Godot](https://godotengine.org/) game engine. + +## Setup + +Assuming you have this plugin installed into Godot. + +> Need help installing a plugin? Try [HERE](https://docs.godotengine.org/en/stable/tutorials/plugins/editor/installing_plugins.html) + +From there simply active the plugin, then add a Logger node to your scene or create a new Logger instance via code. + +```gdscript +var Log + +func _ready(): + Log = Logger.new() + # Don't forget to configure the Logger node too! +``` + +## Configuration + +If you've used the Godot editor to create the Logger node then you can simply use the inspector. + +| Value | Type | Description | +|------------|------------|-----------| +| Persist Debug | Bool | Does the log file get cleared on start of the scene/instance/use of logging? | +| File Dir | String | The path to store the log file. | +| File Name | String | The name of the log file. (See Format Template section for help on what {dt} means) | +| File Name Time Format | String | Defines {dt} in File Name. (See Format Template section for help on what {dt} means) | +| Formatting | String | The format of all logging lines (I.E. `09-01-2020 01:00:00 PM DEBUG A Debug Statement.`) | +| Time Format | String | The format of {dt} for in Formatting. | +| Debug | Bool | Do we log debug statements/calls. | +| Info | Bool | Do we log info statements/calls. | +| Warn | Bool | Do we log warn/warning statements/calls. | +| error | Bool | Do we log error statements/calls. | +| Crit | Bool | Do we log crit/critical statements/calls. | + +## Format Template + +This allows fully customised log files. + +| Value | Description | +|-------|-------------| +| dt | Typically used to indicate date time stamp. (Once defined) +| level | The logging level (DEBUG, INFO, WARN, ERROR, CRITICAL) +| msg | The message passed to one of the logging statements/calls. +| month | The current month as 2 digits. (I.E. January is `01`) +| day | The current day as 2 digits. (I.E. First day of the month is `01`) +| year | The current year as 4 digits. (I.E. 2000 is `2000`) +| 24hour | The current hour as 24 hour (Millitary time), as 2 digits. (I.E. 1 PM is `13`) +| 12hour | The current hour as 12 hour (Use `ampm` to add the AM/PM), as 2 digits. (I.E. 1 PM is `01`) +| min | The current minute as 2 digits. (I.E. 5 minutes is `05`) +| sec | The current second as 2 digits. (I.E. 2 seconds is `02`) +| ampm | A string describing if it's AM or PM. (Only use with `12hour`) + +> dt is used to abreviate date time in File Name, and Formatting. + +## Contact me + +Please leave an issue/bug report if anything goes wrong or you come up with some other suggestions/feature requests. + +## Credits + +* `Logging.png` was based off of [Node](https://github.com/godotengine/godot/blob/master/editor/icons/Node.svg) from the Godot game engine. diff --git a/log_base.gd b/log_base.gd new file mode 100644 index 0000000..f6ff062 --- /dev/null +++ b/log_base.gd @@ -0,0 +1,111 @@ +tool +extends Node + +var log_file = null +export var persist_debug = true +var logy = null + +export var file_dir = "res://" +export var file_name = "{dt}.log" +export var file_name_time_format = "{month}-{year}" +export var formatting = "{dt} {level} {msg}" +export var time_format = "{month}/{day}/{year} {24hour}:{min}:{sec}" + +# Allow toggling what you want +export var DEBUG = true +export var INFO = true +export var WARN = true +export var ERROR = true +export var CRIT = true + +func _enter_tree(): + logy = self + editor_description = "Logger V1.0 ApolloX" + logy.editor_description = "Logger V1.0 ApolloX" + logy.setup() + return logy + +func setup(): + log_file = File.new() + var dtnow = timestamp(file_name_time_format) + if !log_file.file_exists(file_dir + file_name.format({"dt": dtnow})) or !persist_debug: + log_file.open(file_dir + file_name.format({"dt": dtnow}), File.WRITE) + log_file.close() + log_file.open(file_dir + file_name.format({"dt": dtnow}), File.READ_WRITE) + log_file.seek_end() + else: + log_file.open(file_dir + file_name.format({"dt": dtnow}), File.READ_WRITE) + log_file.seek_end() + +# Assistant Functions +func pos2str(pos: Vector2 = Vector2(0, 0)) -> String: + return "(" + str(pos.x) + ", " + str(pos.y) + ")" + +func timestamp(fmat="{month}/{day}/{year} {24hour}:{min}:{sec}", in_utc: bool = false): + var t = OS.get_datetime(in_utc) + var hour12 = t.hour + var ampm = "AM" + if hour12 > 12: + hour12 -= 12 + ampm = "PM" + var result = fmat.format({"month": str(t.month).pad_zeros(2), "day": str(t.day).pad_zeros(2), "year": str(t.year).pad_zeros(4), "24hour": str(t.hour).pad_zeros(2), "12hour": str(hour12).pad_zeros(2), "min": str(t.minute).pad_zeros(2), "sec": str(t.second).pad_zeros(2), "ampm": str(ampm)}) + return result + +func debug(msg): + if DEBUG: + var dt = timestamp(time_format) + var line = formatting.format({"dt": dt, "level": "DEBUG", "msg": msg}) + if log_file != null: + log_file.seek_end() + log_file.store_string(line + "\n") + log_file.flush() + +func info(msg): + if INFO: + var dt = timestamp(time_format) + var line = formatting.format({"dt": dt, "level": "INFO", "msg": msg}) + if log_file != null: + log_file.seek_end() + log_file.store_string(line + "\n") + log_file.flush() + +func warn(msg): + if WARN: + var dt = timestamp(time_format) + var line = formatting.format({"dt": dt, "level": "WARN", "msg": msg}) + if log_file != null: + log_file.seek_end() + log_file.store_string(line + "\n") + log_file.flush() + +func warning(msg): + if WARN: + warn(msg) + +func error(msg, and_exit: bool = false): + if ERROR: + var dt = timestamp(time_format) + var line = formatting.format({"dt": dt, "level": "ERROR", "msg": msg}) + if log_file != null: + log_file.seek_end() + log_file.store_string(line + "\n") + log_file.flush() + if and_exit: + var my_pid = OS.get_process_id() + var _ec = OS.kill(my_pid) + +func crit(msg, and_exit: bool = true): + if CRIT: + var dt = timestamp(time_format) + var line = formatting.format({"dt": dt, "level": "CRITICAL", "msg": msg}) + if log_file != null: + log_file.seek_end() + log_file.store_string(line + "\n") + log_file.flush() + if and_exit: + var my_pid = OS.get_process_id() + var _ec = OS.kill(my_pid) + +func critical(msg, and_exit: bool = true): + if CRIT: + crit(msg, and_exit) diff --git a/plugin.cfg b/plugin.cfg new file mode 100644 index 0000000..577d66c --- /dev/null +++ b/plugin.cfg @@ -0,0 +1,7 @@ +[plugin] + +name="Logger" +description="A filebased logging plugin." +author="ApolloX" +version="1.0-dev" +script="Logger.gd"