diff --git a/README.md b/README.md index a304514..00f46e1 100644 --- a/README.md +++ b/README.md @@ -1 +1,113 @@ -# Godot-SimpleLogger \ No newline at end of file +# LoggerAddon Documentation + +A comprehensive logging system for Godot that provides multiple log levels, timestamps, and file persistence. + +## Features + +- Multiple log levels (TRACE, DEBUG, INFO, WARN, ERROR) +- Optional timestamps for each log message +- File logging with automatic directory creation +- Both full and abbreviated function names +- Configurable log filtering by level + +## Configuration + +### Inspector Properties + +| Property | Type | Default | Description | +| --- | --- | --- | --- | +| `current_log_level` | LogLevel | DEBUG | Minimum log level to display | +| `enable_timestamp` | bool | true | Add timestamp to log messages | +| `save_log` | bool | false | Save logs to file | +| `folder` | String | "" | Directory for log files | +| `log_filename` | String | "addons/Logs/data.log" | Log file path | + +## Log Levels + +From lowest to highest priority: + +- **TRACE**: Detailed debugging information +- **DEBUG**: General debugging information +- **INFO**: Informational messages +- **WARN**: Warning messages (displayed in yellow) +- **ERROR**: Error messages (displayed in red) + +## Usage + +### Full Function Names +```gdscript +Logger.trace("Detailed trace message", variable1, variable2) +Logger.debug("Debug information", value) +Logger.info("Application started") +Logger.warning("This is a warning") +Logger.error("An error occurred", error_code) +``` + +### Abbreviated Function Names +```gdscript +Logger.t("Trace", data) +Logger.d("Debug", data) +Logger.i("Info", data) +Logger.w("Warning", data) +Logger.e("Error", data) +``` + +## Log Output Format + +**With timestamp:** +``` +[HH:MM:SS]|[LEVEL ]: Message content +``` + +**Without timestamp:** +``` +[LEVEL ]: Message content +``` + +## File Logging + +When `save_log` is enabled: + +1. Logs are saved to the specified file path +2. Directories are created automatically if they don't exist +3. Messages are appended to the file (not overwritten) +4. File operations are handled safely with error checking + +### Example Configuration +```gdscript +Logger.current_log_level = LogLevel.DEBUG +Logger.enable_timestamp = true +Logger.save_log = true +Logger.folder = "user://logs/" +Logger.log_filename = "game.log" +``` + +## Tips + +- Set `current_log_level` to `LogLevel.ERROR` in production to reduce console spam +- Use TRACE and DEBUG for development, remove them before shipping +- Combine multiple arguments in a single call for cleaner logs +- File logging automatically creates missing directories + + +## MIT License + +Copyright (c) 2025 Vincenzo Gavioli + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/logger.gd b/logger.gd new file mode 100644 index 0000000..7191a04 --- /dev/null +++ b/logger.gd @@ -0,0 +1,108 @@ +class_name SimpleLogger extends Node + + +enum LogLevel { + TRACE, + DEBUG, + INFO, + WARN, + ERROR +} + + +@export var current_log_level:LogLevel = LogLevel.DEBUG +@export var enable_timestamp:bool = true +@export var save_log:bool = false +@export var folder:String = "" +@export var log_filename:String = "addons/Logs/data.log" + +const TIMESTAMP_FORMAT:String = "%H:%M:%S" +const LOG_FORMAT_TIMESTAMP:String = "[%s]|[%-6s]: %s" +const LOG_FORMAT:String = "[%-6s]: %s" + +var log_file_path = folder + log_filename + + +#region Logger main stuff + +func _print(level: LogLevel, ...args: Array) -> void: + if level < current_log_level: return + + var level_str:String = LogLevel.keys()[level] + var timestamp := Time.get_time_string_from_system() + var text: String = "" + for arg:Variant in args: + for arg2 in arg: + text += str(arg2) + + var message:String = LOG_FORMAT_TIMESTAMP % [ + timestamp, + level_str, + text, + ] if self.enable_timestamp else LOG_FORMAT % [ + level_str, + text, + ] + + match level: + LogLevel.ERROR: push_error(message) + LogLevel.WARN: push_warning(message) + _: print(message) + + if self.save_log: self._save_logs_to_file(message) + + +func _save_logs_to_file(message: String) -> bool: + var file := FileAccess.open(self.log_file_path, FileAccess.READ_WRITE) + if file == null: + DirAccess.make_dir_recursive_absolute(self.folder) + var tmp_file = FileAccess.open(self.log_file_path, FileAccess.WRITE) + if tmp_file == null: + push_error("Failed to create file %s" % self.log_file_path) + return false + file = tmp_file + file.seek_end() + file.store_line(message) + return true + +#endregion + + +#region level functions + +func trace(...args: Array) -> void: + _print(LogLevel.TRACE, args) + +func debug(...args: Array) -> void: + _print(LogLevel.DEBUG, args) + +func info(...args: Array) -> void: + _print(LogLevel.INFO, args) + +func warning(...args: Array) -> void: + _print(LogLevel.WARN, args) + +func error(...args: Array) -> void: + _print(LogLevel.ERROR, args) + +#endregion + + +#region abbreviated functions + +func t(...args: Array) -> void: + _print(LogLevel.TRACE, args) + +func d(...args: Array) -> void: + _print(LogLevel.DEBUG, args) + +func i(...args: Array) -> void: + _print(LogLevel.INFO, args) + +func w(...args: Array) -> void: + _print(LogLevel.WARN, args) + +func e(...args: Array) -> void: + _print(LogLevel.ERROR, args) + +#endregion diff --git a/logger.gd.uid b/logger.gd.uid new file mode 100644 index 0000000..11d3691 --- /dev/null +++ b/logger.gd.uid @@ -0,0 +1 @@ +uid://cxnqi0viadnaq diff --git a/plugin.cfg b/plugin.cfg new file mode 100644 index 0000000..ca8bfa4 --- /dev/null +++ b/plugin.cfg @@ -0,0 +1,7 @@ +[plugin] + +name="Logger" +description="A simple godot 4 logger" +author="Arctia" +version="0.1.0" +script="logger.gd"