How to Debug Invidious: Log-Level Configuration and Troubleshooting Guide
To debug Invidious, configure the log_level setting in config/config.yml or launch with --log-level=debug to expose granular diagnostic data from the Kemal HTTP server, YouTube API backend, and background job processors.
Invidious uses a centralized logging architecture where every component—from database migrations to video parsing—funnels through a single global LOGGER instantiated at startup. Understanding how to manipulate this logging system allows you to trace errors across the entire Crystal-based application stack without modifying source code.
Understanding the Centralized Logging Architecture
At startup, the Config struct defined in src/invidious/config.cr reads log_level and colorize_logs values from config/config.yml or corresponding environment variables. The application entry point in src/invidious.cr then instantiates the global LOGGER constant using these values, directing output to either STDOUT or a specified file:
# src/invidious.cr
OUTPUT = CONFIG.output.upcase == "STDOUT" ? STDOUT : File.open(CONFIG.output, mode: "a")
LOGGER = Invidious::LogHandler.new(OUTPUT, CONFIG.log_level, CONFIG.colorize_logs)
This Invidious::LogHandler class, implemented in src/invidious/helpers/logger.cr, provides the standard methods trace, debug, info, warn, error, and fatal. Each method checks the configured LogLevel before printing, ensuring minimal performance overhead when verbose logging is disabled.
Log Level Hierarchy
Invidious recognizes eight distinct log levels defined in src/invidious/helpers/logger.cr. The numeric values determine verbosity:
| Level | Value | Purpose |
|---|---|---|
All |
0 | Capture every message including internal traces |
Trace |
1 | Function entry/exit and state dumps |
Debug |
2 | Diagnostic data for bug hunting |
Info |
3 | Normal operational events (default) |
Warn |
4 | Potential issues requiring attention |
Error |
5 | Request-breaking failures |
Fatal |
6 | Critical errors causing shutdown |
Off |
7 | Disable all logging |
The default log_level is Info (3), which masks lower-priority messages.
Configuring Debug Output
You can elevate log verbosity through three mechanisms, all feeding into the OptionParser logic in src/invidious.cr.
Command-Line Flags
Override the config file for a single execution:
invidious --log-level=debug
For maximum verbosity showing every YouTube API payload:
invidious --log-level=trace
Environment Variables
Set INVIDIOUS_LOG_LEVEL before launching the binary:
INVIDIOUS_LOG_LEVEL=trace invidious
Configuration File
For persistent changes, edit config/config.yml:
log_level: Debug
colorize_logs: true
output: "STDOUT"
Locating Relevant Log Output
Every major subsystem emits standardized log statements that respect the global level.
HTTP Server and Routing
The Invidious::LogHandler integrates with Kemal to log incoming requests at info level. Routing errors and 404/500 handlers in src/invidious/routes/errors.cr automatically forward exceptions to LOGGER.error. The before_all hook in src/invidious/routes/before_all.cr logs any pre-route failures at error level.
YouTube Backend Debugging
When videos fail to load, examine src/invidious/yt_backend/youtube_api.cr. This file emits debug logs for endpoint usage and trace logs for full request payloads around lines 618-620. Connection pool health for YT_POOL (instantiated in invidious.cr line 89) is logged at info level in connection_pool.cr.
Content Parsing and Background Jobs
Channel fetching logic in src/invidious/channels/channels.cr and video parsing in src/invidious/videos/parser.cr emit debug and trace messages during each fetch step. Background jobs in src/invidious/jobs/* log their start and completion at debug and info levels, with retry failures surfacing at error.
Database Integrity
Startup integrity checks performed by Invidious::Database.check_integrity in src/invidious/database/base.cr log migration errors and schema issues during initialization.
Step-by-Step Debugging Workflow
Follow this systematic approach to isolate issues:
- Increase verbosity: Launch with
invidious --log-level=debugor setlog_level: Tracein the config file. - Reproduce the issue: Interact with the UI while monitoring output via
tail -f /var/log/invidious.logor the terminal. - Identify the component: Search for file paths (e.g.,
youtube_api.crorchannels.cr) to pinpoint the failing subsystem. - Inspect background activity: Look for interleaved timestamps from job fibers—errors here often indicate feed refresh failures.
- Add temporary instrumentation: If gaps remain, insert
LOGGER.debug("State: #{variable.inspect}")in the relevant source file, recompile withshards build, and rerun. - Verify connections: Check for
YT_POOLconnection failures if API calls timeout—these appear atinfolevel.
Adding Custom Debug Statements
When existing logs prove insufficient, add custom statements directly to the Crystal source. For example, to inspect video ID handling:
# src/invidious/yt_backend/youtube_api.cr
LOGGER.debug("Fetching video ID #{video_id} with client #{client_config.client_type}")
After inserting the statement, rebuild:
shards build
The debug message will appear in your logs whenever that code path executes at or above the Debug log level.
Summary
- Invidious uses a centralized LogHandler instantiated in
src/invidious.crthat filters messages based on the configuredLogLevel. - Levels range from
All(0) toOff(7), withInfo(3) as the default; useDebug(2) orTrace(1) for troubleshooting. - Override logging via CLI flags (
--log-level=debug), environment variables (INVIDIOUS_LOG_LEVEL), or the config file (config/config.yml). - Key diagnostic sources include
youtube_api.crfor API issues,channels.cr/parser.crfor content extraction, andsrc/invidious/jobs/*for background task failures. - Add temporary
LOGGER.debugcalls in source files and recompile withshards buildto inspect specific variable states during execution.
Frequently Asked Questions
How do I enable trace logging in Invidious?
Set the log level to Trace using invidious --log-level=trace or by setting log_level: Trace in config/config.yml. This exposes function-level entry/exit points and raw YouTube API payloads in src/invidious/yt_backend/youtube_api.cr.
Where are Invidious log files stored?
By default, Invidious logs to STDOUT. To use a file, set output: "/var/log/invidious.log" in config/config.yml. The file handle is opened once at startup in src/invidious.cr and written to by the global LOGGER instance.
Why don't I see debug messages after changing the config file?
Ensure you have restarted the Invidious process after modifying config/config.yml. Unlike environment variables or CLI flags that apply at startup, file changes require a full restart to reload the Config struct and reinstantiate the logger.
How do I debug YouTube API connection failures?
Enable trace level logging and examine the output from src/invidious/yt_backend/youtube_api.cr around lines 618-620. Look for LOGGER.error entries indicating API response failures, and check connection_pool.cr logs for YT_POOL connectivity issues at info level.
Have a question about this repo?
These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →