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:

  1. Increase verbosity: Launch with invidious --log-level=debug or set log_level: Trace in the config file.
  2. Reproduce the issue: Interact with the UI while monitoring output via tail -f /var/log/invidious.log or the terminal.
  3. Identify the component: Search for file paths (e.g., youtube_api.cr or channels.cr) to pinpoint the failing subsystem.
  4. Inspect background activity: Look for interleaved timestamps from job fibers—errors here often indicate feed refresh failures.
  5. Add temporary instrumentation: If gaps remain, insert LOGGER.debug("State: #{variable.inspect}") in the relevant source file, recompile with shards build, and rerun.
  6. Verify connections: Check for YT_POOL connection failures if API calls timeout—these appear at info level.

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.cr that filters messages based on the configured LogLevel.
  • Levels range from All (0) to Off (7), with Info (3) as the default; use Debug (2) or Trace (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.cr for API issues, channels.cr/parser.cr for content extraction, and src/invidious/jobs/* for background task failures.
  • Add temporary LOGGER.debug calls in source files and recompile with shards build to 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:

Share the following with your agent to get started:
curl -s "https://instagit.com/install.md"

Works with
Claude Codex Cursor VS Code OpenClaw Any MCP Client

Maintain an open-source project? Get it listed too →