Skip to content

Develop#12

Open
Insality wants to merge 8 commits intomainfrom
develop
Open

Develop#12
Insality wants to merge 8 commits intomainfrom
develop

Conversation

@Insality
Copy link
Copy Markdown
Owner

No description provided.

Copilot AI review requested due to automatic review settings December 23, 2025 17:39
Copy link
Copy Markdown

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR refactors the Defold logging module by extracting functionality into separate internal modules (config, formatter, file_writter), adds file logging capabilities with callback support, and reorganizes documentation into dedicated files.

Key Changes:

  • Refactored monolithic log.lua into modular structure with internal/config.lua, internal/formatter.lua, and internal/file_writter.lua
  • Added file logging functionality with write_nearby_this_file() and callback system for custom log handlers
  • Moved configuration and use case documentation from README.md to separate CONFIGURATION.md and USE_CASES.md files

Reviewed changes

Copilot reviewed 8 out of 10 changed files in this pull request and generated 20 comments.

Show a summary per file
File Description
log/log.lua Major refactoring to extract formatting and configuration logic; added file logging support and callback system
log/internal/config.lua New module containing all configuration constants and system detection logic
log/internal/formatter.lua New module containing log formatting and table serialization logic
log/internal/file_writter.lua New module providing file writing functionality with state management
docs/USE_CASES.md New documentation file with practical examples of log module usage
docs/CONFIGURATION.md New documentation file detailing configuration options (moved from README)
README.md Simplified by moving detailed configuration docs to separate files; updated API documentation
example/example.gui_script Updated example to demonstrate file logging and callback features
game.project Enabled write_log_file and updated log format configuration
.gitignore Added log.txt to ignored files
Comments suppressed due to low confidence (1)

log/log.lua:254

  • The metatable no longer has an '__index' metamethod pointing to a default logger instance. This means that when the log module is used directly (e.g., 'log:trace()'), it will try to call methods on the M table which only has the name and level fields set. The _last_gc_memory and _last_message_time fields are not initialized for the default logger, which could cause issues with tracking features. Consider either restoring the __index to a properly initialized default logger, or initializing all necessary fields on M directly.
return setmetatable(M, {
	__call = function(self, name, force_logger_level_in_debug)
		return M.get_logger(name, force_logger_level_in_debug)
	end
})

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

@@ -0,0 +1,114 @@
local config = require("log.internal.config")
local formatter = require("log.internal.formatter")

Copy link

Copilot AI Dec 23, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The filename 'file_writter.lua' contains a spelling error. It should be 'file_writer.lua' (single 't'). This affects the module name and all references to it.

Copilot uses AI. Check for mistakes.
Comment thread log/log.lua
Comment on lines 148 to +149
---@param data any
---@param message string Message to log
Copy link

Copilot AI Dec 23, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The function parameter order for 'message' and 'data' annotations is inconsistent. Line 140 shows 'message' as nullable (string?) while line 141 shows 'data', but line 149 has them in reverse order (data before message). This inconsistency could confuse API consumers. The parameter order in the actual function signature should match the documentation order.

Suggested change
---@param data any
---@param message string Message to log
---@param message string Message to log
---@param data any

Copilot uses AI. Check for mistakes.
Comment thread log/log.lua
end
---Clear all callbacks
function M.clear_callbacks()
log_callbacks = {}
Copy link

Copilot AI Dec 23, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

After clearing callbacks with 'log_callbacks = {}', the file_writter.log_callback (which was in the original array at line 21) is lost and won't be restored. This will break file logging functionality since the internal callback is removed. Consider using a different approach, such as only removing user-added callbacks while preserving internal ones, or documenting that this clears ALL callbacks including internal file writing.

Suggested change
log_callbacks = {}
-- Preserve internal callbacks such as the file writer while
-- removing any user-added callbacks.
log_callbacks = { file_writter.log_callback }

Copilot uses AI. Check for mistakes.


function init(self)
log.clear_log_files()
Copy link

Copilot AI Dec 23, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Calling 'log.clear_log_files()' before any logging occurs will try to delete files that may not exist yet, which could produce error messages. Additionally, calling it in the 'final' function (line 103) right after 'close_log_files()' (line 102) will delete all log files that were just created during the game session. Consider removing the call from 'init' and documenting that 'clear_log_files' is typically used for maintenance rather than normal operation.

Copilot uses AI. Check for mistakes.
Comment on lines +167 to +168
if config.IS_FORMAT_MESSAGE and message then
string_message_block = string_m.gsub(string_message_block, "%%message", message)
Copy link

Copilot AI Dec 23, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

When message is nil and IS_FORMAT_MESSAGE is true, the %message placeholder in the format string won't be replaced (line 167 guards against this). This will leave '%message' literally in the output string, which looks like a formatting error. Consider either: (1) replacing %message with an empty string or a placeholder like "(no message)" when message is nil, or (2) ensuring that the check at line 71 of log.lua prevents calling format when message is nil.

Suggested change
if config.IS_FORMAT_MESSAGE and message then
string_message_block = string_m.gsub(string_message_block, "%%message", message)
if config.IS_FORMAT_MESSAGE then
local formatted_message = message ~= nil and tostring(message) or ""
string_message_block = string_m.gsub(string_message_block, "%%message", formatted_message)

Copilot uses AI. Check for mistakes.
Comment thread README.md
Comment on lines +108 to +137
**log.set_callback**
---
```lua
log.set_callback(callback)
```
Set a custom handler for log messages. This allows you to intercept and process log messages for additional purposes such as file logging, remote logging, or custom formatting. The callback is called in addition to the default console output.

- **Parameters:**
- `callback`: A function that receives `(logger, level, message, context, log_message)` parameters, or `nil` to remove the callback.
- `logger`: The logger instance that generated the log
- `level`: The log level (TRACE, DEBUG, INFO, WARN, ERROR, FATAL)
- `message`: The original message string
- `context`: Any additional context data passed to the log function
- `log_message`: The formatted log message string (as it appears in console)

- **Usage Example:**

```lua
-- Set up file logging
log.set_callback(function(logger, level, message, context, log_message)
local file = io.open("game.log", "a")
if file then
file:write(log_message .. "\n")
file:close()
end
end)

-- Remove callback
log.set_callback(nil)
```
Copy link

Copilot AI Dec 23, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The documentation describes 'log.set_callback(callback)' with a single callback parameter that can be nil to remove the callback. However, the actual implementation uses 'log.add_callback(callback)' which adds callbacks to an array, not replaces them. The documented behavior of passing nil to remove callbacks doesn't match the implementation. Update the documentation to reflect the actual API: add_callback, remove_callback, and clear_callbacks.

Copilot uses AI. Check for mistakes.
Comment on lines +95 to +97
function update(self, dt)
logger:info("Update", dt)
end
Copy link

Copilot AI Dec 23, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The 'update' function will log every frame (line 96), which could generate an enormous number of log entries very quickly (60+ logs per second). This will rapidly fill disk space and likely cause performance issues. This is probably intended as an example to demonstrate file logging, but it should include a warning comment or use a less aggressive logging pattern (e.g., log every N frames or every second).

Copilot uses AI. Check for mistakes.
Comment on lines +22 to +30
if logger.file then
if not FILE_HANDLERS[logger.file] then
FILE_HANDLERS[logger.file] = io.open(logger.file, "a")
end

local handler = FILE_HANDLERS[logger.file]
if handler then
handler:write(log_message .. "\n")
handler:flush()
Copy link

Copilot AI Dec 23, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If io.open() fails at line 24 (e.g., due to invalid path, permissions, or disk full), the FILE_HANDLERS entry is never set, but the code will retry opening the file on every subsequent log message. This creates repeated failed open attempts. Consider either: (1) caching the failure (set FILE_HANDLERS[logger.file] = false on failure), or (2) logging a warning when the file cannot be opened so the user knows file logging has failed.

Copilot uses AI. Check for mistakes.
handler:close()
end

FILE_HANDLERS = {}
Copy link

Copilot AI Dec 23, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Assigning 'FILE_HANDLERS = {}' at line 111 creates a new empty table but doesn't update the module's reference to it. Any code that cached a reference to the old FILE_HANDLERS table will still have stale file handlers. While this may not be an issue in the current implementation, it's better practice to clear the existing table contents with a loop (for k in pairs(FILE_HANDLERS) do FILE_HANDLERS[k] = nil end) to maintain the same table reference.

Suggested change
FILE_HANDLERS = {}
for k in pairs(FILE_HANDLERS) do
FILE_HANDLERS[k] = nil
end

Copilot uses AI. Check for mistakes.
Comment thread docs/CONFIGURATION.md
|----------------------|-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| **%logger** | The name of the logger instance producing the log message. Helps in identifying the source of the log message. |
| **%levelname** | The name of the log level (e.g., DEBUG, INFO, WARN, etc.). Provides clarity on the severity or nature of the log message. Should be placed at the beginning of the log message for color highlighting in the Defold Console. |
| **%levelshort** | The short name of the log level (e.g., D, I, W, E). Provides a compact representation of the log level. But Defold Console will be not able to highlight it. |
Copy link

Copilot AI Dec 23, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Grammar issue: "But Defold Console will be not able" should be "But Defold Console will not be able" (word order - 'not' should come before 'be').

Suggested change
| **%levelshort** | The short name of the log level (e.g., D, I, W, E). Provides a compact representation of the log level. But Defold Console will be not able to highlight it. |
| **%levelshort** | The short name of the log level (e.g., D, I, W, E). Provides a compact representation of the log level. But Defold Console will not be able to highlight it. |

Copilot uses AI. Check for mistakes.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants