This guide covers logging, debugging techniques, and troubleshooting for the godot-torrent library.
extends Node
var session: TorrentSession
var logger: TorrentLogger
func _ready():
# Create logger
logger = TorrentLogger.new()
logger.enable_logging(true)
logger.set_log_level(TorrentLogger.INFO)
# Attach logger to session
session = TorrentSession.new()
session.set_logger(logger)
session.start_session()
The logging system provides five log levels, each including all levels below it:
Level | Value | Description | Use Case |
---|---|---|---|
NONE |
0 | Logging disabled | Production (no logging overhead) |
ERROR |
1 | Errors only | Production (critical issues only) |
WARNING |
2 | Warnings + Errors | Production (potential issues) |
INFO |
3 | Info + Warning + Error | Development (general information) |
DEBUG |
4 | Debug + above | Development (detailed debugging) |
TRACE |
5 | Trace + above | Development (verbose logging) |
# Set log level
logger.set_log_level(TorrentLogger.DEBUG)
# Or via session
session.set_log_level(TorrentLogger.DEBUG)
Filter logs by category for focused debugging:
Category | Description |
---|---|
ALL |
All categories (default) |
SESSION |
Session lifecycle and configuration |
TORRENT |
Torrent operations |
PEER |
Peer connections and communication |
TRACKER |
Tracker announces and responses |
DHT |
DHT operations |
PORT_MAPPING |
UPnP/NAT-PMP port mapping |
STORAGE |
File storage operations |
PERFORMANCE |
Performance metrics |
ALERT |
Libtorrent alerts |
# Enable specific categories only
logger.disable_all_categories()
logger.enable_category(TorrentLogger.TORRENT, true)
logger.enable_category(TorrentLogger.TRACKER, true)
# Or enable all (default)
logger.enable_all_categories()
Save logs to a file for later analysis:
# Enable file logging
logger.set_log_file("user://torrent_debug.log")
# Logs are written to both console and file
# Close file when done
logger.close_log_file()
Log file location:
%APPDATA%\Godot\app_userdata\<project_name>\torrent_debug.log
~/.local/share/godot/app_userdata/<project_name>/torrent_debug.log
~/Library/Application Support/Godot/app_userdata/<project_name>/torrent_debug.log
Log custom messages at any level:
logger.log_error("Critical error occurred", "CUSTOM")
logger.log_warning("Potential issue detected", "CUSTOM")
logger.log_info("Download started", "CUSTOM")
logger.log_debug("Piece verified", "CUSTOM")
logger.log_trace("Detailed trace info", "CUSTOM")
# Or use generic log method
logger.log(TorrentLogger.INFO, "Custom message", "CATEGORY")
Monitor logging activity:
var stats = logger.get_log_stats()
print("Errors: ", stats["error_count"])
print("Warnings: ", stats["warning_count"])
print("Info: ", stats["info_count"])
print("Total: ", stats["total_count"])
# Reset statistics
logger.reset_log_stats()
Symptoms:
start_session()
returns falseDebug Steps:
# Enable detailed logging
logger.set_log_level(TorrentLogger.DEBUG)
logger.enable_category(TorrentLogger.SESSION, true)
# Check for port conflicts
session.set_listen_port_range(6881, 6891)
# Check console for specific error
var success = session.start_session()
if not success:
print("Check console for error details")
Common Causes:
Symptoms:
add_torrent_file()
returns null handleDebug Steps:
logger.set_log_level(TorrentLogger.DEBUG)
logger.enable_category(TorrentLogger.TORRENT, true)
logger.enable_category(TorrentLogger.STORAGE, true)
var handle = session.add_torrent_file(data, save_path)
if handle == null or not handle.is_valid():
# Check console for error:
# - "Session not running"
# - "Save path cannot be empty"
# - "Invalid torrent file"
# - "libtorrent error: ..."
pass
Common Causes:
Symptoms:
num_peers
stays at 0Debug Steps:
logger.set_log_level(TorrentLogger.DEBUG)
logger.enable_category(TorrentLogger.PEER, true)
logger.enable_category(TorrentLogger.TRACKER, true)
logger.enable_category(TorrentLogger.DHT, true)
# Check DHT status
if not session.is_dht_running():
session.start_dht()
# Check tracker status
var status = handle.get_status()
print("Announce: ", status.get_next_announce())
# Check peer info
var peers = handle.get_peer_info()
print("Peer count: ", peers.size())
Common Causes:
Symptoms:
Debug Steps:
logger.set_log_level(TorrentLogger.DEBUG)
logger.enable_category(TorrentLogger.PERFORMANCE, true)
logger.enable_category(TorrentLogger.PEER, true)
# Check current rates
var status = handle.get_status()
print("Download rate: ", status.get_download_rate() / 1024.0, " KB/s")
print("Upload rate: ", status.get_upload_rate() / 1024.0, " KB/s")
print("Peers: ", status.get_num_peers())
print("Seeds: ", status.get_num_seeds())
# Adjust limits
session.set_download_rate_limit(0) # Unlimited
session.set_upload_rate_limit(0) # Unlimited
session.set_max_connections(200)
Common Causes:
Symptoms:
handle.is_valid()
returns falseDebug Steps:
logger.set_log_level(TorrentLogger.DEBUG)
logger.enable_category(TorrentLogger.TORRENT, true)
# Always check handle validity
if not handle.is_valid():
print("Handle is invalid - was torrent removed?")
return
# Store handle reference
var stored_handles = []
stored_handles.append(handle) # Prevent GC
Common Causes:
func _process(_delta):
if not session.is_running():
return
var stats = session.get_session_stats()
# Monitor statistics
logger.log_debug("Session stats: " + str(stats), "PERFORMANCE")
func monitor_torrent(handle: TorrentHandle):
if not handle.is_valid():
return
var status = handle.get_status()
var info = "Torrent: %s\n" % handle.get_name()
info += "Progress: %.2f%%\n" % (status.get_progress() * 100)
info += "Download: %.2f KB/s\n" % (status.get_download_rate() / 1024.0)
info += "Upload: %.2f KB/s\n" % (status.get_upload_rate() / 1024.0)
info += "Peers: %d (%d seeds)\n" % [status.get_num_peers(), status.get_num_seeds()]
info += "State: %d" % status.get_state()
logger.log_debug(info, "PERFORMANCE")
Development:
logger.enable_logging(true)
logger.set_log_level(TorrentLogger.DEBUG)
logger.set_log_file("user://debug.log")
Production:
logger.enable_logging(true)
logger.set_log_level(TorrentLogger.WARNING) # Errors and warnings only
# No file logging (performance)
When logging is disabled (NONE
), there is zero performance overhead.
Tips for minimal overhead:
WARNING
or ERROR
level in productionAll logs follow this format:
[YYYY-MM-DD HH:MM:SS] [LEVEL] [CATEGORY] Message
Example:
[2025-10-04 15:30:45] [INFO] [SESSION] Logger attached to TorrentSession
[2025-10-04 15:30:45] [ERROR] [TORRENT] Failed to add torrent: invalid file
Use categories to focus on specific areas:
# Debug tracker issues only
logger.disable_all_categories()
logger.enable_category(TorrentLogger.TRACKER, true)
logger.set_log_level(TorrentLogger.DEBUG)
# Debug peer connection issues
logger.disable_all_categories()
logger.enable_category(TorrentLogger.PEER, true)
logger.enable_category(TorrentLogger.DHT, true)
logger.set_log_level(TorrentLogger.DEBUG)
Before reporting issues, check:
session.is_running()
returns truehandle.is_valid()
returns true[ClassName::method]
formatextends Node
var session: TorrentSession
var logger: TorrentLogger
var handle: TorrentHandle
func _ready():
setup_logging()
setup_session()
load_torrent()
func setup_logging():
logger = TorrentLogger.new()
logger.enable_logging(true)
logger.set_log_level(TorrentLogger.DEBUG)
logger.set_log_file("user://torrent_debug.log")
# Focus on torrent and tracker issues
logger.disable_all_categories()
logger.enable_category(TorrentLogger.SESSION, true)
logger.enable_category(TorrentLogger.TORRENT, true)
logger.enable_category(TorrentLogger.TRACKER, true)
logger.log_info("=== Debug session started ===", "APP")
func setup_session():
session = TorrentSession.new()
session.set_logger(logger)
if not session.start_session():
logger.log_error("Failed to start session", "APP")
return
logger.log_info("Session started successfully", "APP")
# Start DHT
session.start_dht()
func load_torrent():
var file = FileAccess.open("res://test.torrent", FileAccess.READ)
if file == null:
logger.log_error("Failed to open torrent file", "APP")
return
var torrent_data = file.get_buffer(file.get_length())
file.close()
var save_path = "downloads"
handle = session.add_torrent_file(torrent_data, save_path)
if handle == null or not handle.is_valid():
logger.log_error("Failed to add torrent", "APP")
return
logger.log_info("Torrent added: " + handle.get_name(), "APP")
func _process(_delta):
if handle != null and handle.is_valid():
var status = handle.get_status()
logger.log_debug("Progress: %.2f%%" % (status.get_progress() * 100), "APP")
func _exit_tree():
if logger != null:
var stats = logger.get_log_stats()
logger.log_info("=== Debug session ended ===", "APP")
logger.log_info("Total logs: " + str(stats["total_count"]), "APP")
logger.close_log_file()
if session != null:
session.stop_session()
error-handling.md
for error codes and recoveryuser://
directory for log filesThe logging system provides:
Enable logging during development, use appropriate levels in production, and leverage categories to focus on specific issues.