---
title: "Debugging"
description: "Comprehensive guide to debugging TracerTM services and applications."
---

## Overview

This guide covers debugging techniques, tools, and configurations for all TracerTM components including the CLI, API server, TUI, and database operations.

## Debug Mode Configuration

### Environment Variables

TracerTM uses environment variables for debug configuration. Create or modify your `.env` file:

```bash
# Logging Configuration
TRACERTM_LOG_LEVEL=DEBUG
TRACERTM_LOG_FORMAT="%(asctime)s - %(name)s - %(levelname)s - %(message)s"

# Database Debugging
TRACERTM_DATABASE__ECHO=true

# Feature Flags for Development
TRACERTM_ENABLE_VALIDATION=true
TRACERTM_ENABLE_CACHE=false  # Disable cache during debugging
```

### Settings Configuration

For persistent debug settings, modify `~/.tracertm/config.yaml`:

```yaml
log_level: DEBUG
database:
  url: sqlite:///tracertm.db
  echo: true
  pool_size: 10
  max_overflow: 20
enable_cache: false
enable_validation: true
```

## Logging Configuration and Levels

### Log Levels

TracerTM uses Loguru for structured logging with the following levels:

- **DEBUG**: Detailed diagnostic information
- **INFO**: General informational messages
- **WARNING**: Warning messages for potentially harmful situations
- **ERROR**: Error messages for serious problems
- **CRITICAL**: Critical errors that may cause system failure

### Log File Locations

Logs are stored in `~/.tracertm/logs/`:

- **tracertm.log**: Main application log (DEBUG level, 7-day retention)
- **tracertm.json**: Structured JSON logs (INFO level, 7-day retention)
- **tracertm_errors.log**: Error-only logs (ERROR level, 30-day retention)

### Configuring Logging

The logging system is configured in `src/tracertm/logging_config.py`:

```python
from tracertm.logging_config import setup_logging, get_logger

# Initialize logging (done automatically by CLI/API)
setup_logging()

# Get a logger for your module
logger = get_logger(__name__)

# Log messages
logger.debug("Detailed debugging information")
logger.info("General information")
logger.warning("Warning message")
logger.error("Error occurred", exc_info=True)
```

### Custom Log Format

To customize the log format for console output:

```python
# In your application initialization
import sys
from loguru import logger

logger.remove()
logger.add(
    sys.stderr,
    format="<green>{time:YYYY-MM-DD HH:mm:ss}</green> | <level>{level: <8}</level> | <cyan>{name}</cyan>:<cyan>{function}</cyan>:<cyan>{line}</cyan> - <level>{message}</level>",
    level="DEBUG",
    colorize=True
)
```

## VS Code Debugging Setup

### Launch Configuration

Create or update `.vscode/launch.json`:

```json
{
  "version": "0.2.0",
  "configurations": [
    {
      "name": "Debug CLI",
      "type": "debugpy",
      "request": "launch",
      "module": "tracertm.cli.app",
      "args": ["list", "--debug"],
      "console": "integratedTerminal",
      "env": {
        "TRACERTM_LOG_LEVEL": "DEBUG",
        "TRACERTM_DATABASE__ECHO": "true"
      },
      "justMyCode": false
    },
    {
      "name": "Debug API Server",
      "type": "debugpy",
      "request": "launch",
      "module": "uvicorn",
      "args": [
        "tracertm.api.main:app",
        "--reload",
        "--host", "0.0.0.0",
        "--port", "8000",
        "--log-level", "debug"
      ],
      "console": "integratedTerminal",
      "env": {
        "TRACERTM_LOG_LEVEL": "DEBUG",
        "TRACERTM_DATABASE__ECHO": "true"
      },
      "justMyCode": false
    },
    {
      "name": "Debug TUI",
      "type": "debugpy",
      "request": "launch",
      "module": "tracertm.cli.app",
      "args": ["dashboard"],
      "console": "integratedTerminal",
      "env": {
        "TRACERTM_LOG_LEVEL": "DEBUG",
        "TEXTUAL_LOG": "textual.log"
      },
      "justMyCode": false
    },
    {
      "name": "Debug Current Test File",
      "type": "debugpy",
      "request": "launch",
      "module": "pytest",
      "args": [
        "${file}",
        "-v",
        "--log-cli-level=DEBUG"
      ],
      "console": "integratedTerminal",
      "env": {
        "TRACERTM_LOG_LEVEL": "DEBUG",
        "TEST_DATABASE_URL": "sqlite+aiosqlite:///:memory:"
      },
      "justMyCode": false
    },
    {
      "name": "Debug Specific Test",
      "type": "debugpy",
      "request": "launch",
      "module": "pytest",
      "args": [
        "${file}::${selectedText}",
        "-v",
        "-s",
        "--log-cli-level=DEBUG"
      ],
      "console": "integratedTerminal",
      "env": {
        "TRACERTM_LOG_LEVEL": "DEBUG"
      },
      "justMyCode": false
    },
    {
      "name": "Attach to Running Process",
      "type": "debugpy",
      "request": "attach",
      "connect": {
        "host": "localhost",
        "port": 5678
      },
      "pathMappings": [
        {
          "localRoot": "${workspaceFolder}",
          "remoteRoot": "."
        }
      ]
    }
  ]
}
```

### VS Code Tasks

Create `.vscode/tasks.json` for common debugging tasks:

```json
{
  "version": "2.0.0",
  "tasks": [
    {
      "label": "Run API with Debug Logging",
      "type": "shell",
      "command": "TRACERTM_LOG_LEVEL=DEBUG uvicorn tracertm.api.main:app --reload --log-level debug",
      "problemMatcher": [],
      "presentation": {
        "reveal": "always",
        "panel": "new"
      }
    },
    {
      "label": "Run Tests with Coverage",
      "type": "shell",
      "command": "pytest --cov=tracertm --cov-report=html --log-cli-level=DEBUG",
      "problemMatcher": [],
      "presentation": {
        "reveal": "always",
        "panel": "new"
      }
    },
    {
      "label": "Clear Log Files",
      "type": "shell",
      "command": "rm -rf ~/.tracertm/logs/*.log ~/.tracertm/logs/*.json",
      "problemMatcher": []
    }
  ]
}
```

## PyCharm Debugging Setup

### Run/Debug Configurations

#### CLI Configuration

1. Go to **Run → Edit Configurations**
2. Click **+** → **Python**
3. Configure:
   - **Name**: Debug CLI
   - **Script path**: (Select module instead)
   - **Module name**: `tracertm.cli.app`
   - **Parameters**: `list --debug`
   - **Environment variables**: `TRACERTM_LOG_LEVEL=DEBUG`
   - **Working directory**: Project root

#### API Server Configuration

1. **Run → Edit Configurations**
2. Click **+** → **Python**
3. Configure:
   - **Name**: Debug API Server
   - **Module name**: `uvicorn`
   - **Parameters**: `tracertm.api.main:app --reload --host 0.0.0.0 --port 8000 --log-level debug`
   - **Environment variables**: `TRACERTM_LOG_LEVEL=DEBUG;TRACERTM_DATABASE__ECHO=true`
   - **Working directory**: Project root

#### TUI Configuration

1. **Run → Edit Configurations**
2. Click **+** → **Python**
3. Configure:
   - **Name**: Debug TUI
   - **Module name**: `tracertm.cli.app`
   - **Parameters**: `dashboard`
   - **Environment variables**: `TRACERTM_LOG_LEVEL=DEBUG;TEXTUAL_LOG=textual.log`
   - **Emulate terminal in output console**: ✓ (checked)

#### Pytest Configuration

1. **Run → Edit Configurations**
2. Click **+** → **Python tests → pytest**
3. Configure:
   - **Name**: Debug Tests
   - **Target**: Script path or Custom
   - **Additional Arguments**: `-v --log-cli-level=DEBUG`
   - **Environment variables**: `TRACERTM_LOG_LEVEL=DEBUG`

## Debugging the CLI

### Enable Debug Mode

```bash
# Using --debug flag
rtm --debug list

# Using environment variable
TRACERTM_LOG_LEVEL=DEBUG rtm list

# Verbose output with tracebacks
rtm --debug list 2>&1 | tee debug.log
```

### Debugging Specific Commands

```bash
# Debug project commands
TRACERTM_LOG_LEVEL=DEBUG rtm project create "Test Project"

# Debug import operations
TRACERTM_LOG_LEVEL=DEBUG rtm import --file requirements.csv --debug

# Debug sync operations
TRACERTM_LOG_LEVEL=DEBUG rtm sync pull --verbose
```

### Common CLI Debugging Scenarios

**1. Command Not Found**

```bash
# List all available commands
rtm --help

# Check specific command
rtm project --help
```

**2. Database Connection Issues**

```bash
# Test database connectivity
TRACERTM_DATABASE__ECHO=true rtm db status

# Reset database
rtm db reset --confirm
```

**3. Configuration Problems**

```bash
# Show current configuration
rtm config show

# Validate configuration
rtm config validate
```

## Debugging the API Server

### Running with Debug Mode

```bash
# Start API with debug logging
TRACERTM_LOG_LEVEL=DEBUG uvicorn tracertm.api.main:app --reload --log-level debug

# Start with specific host/port
uvicorn tracertm.api.main:app --host 0.0.0.0 --port 8000 --reload --log-level debug
```

### FastAPI Debug Features

#### Interactive API Documentation

Access the interactive API docs:

- **Swagger UI**: http://localhost:8000/docs
- **ReDoc**: http://localhost:8000/redoc
- **OpenAPI Schema**: http://localhost:8000/openapi.json

#### Request/Response Logging

Add middleware for request logging:

```python
from fastapi import Request
import time

@app.middleware("http")
async def log_requests(request: Request, call_next):
    start_time = time.time()

    # Log request
    logger.debug(f"Request: {request.method} {request.url}")

    response = await call_next(request)

    # Log response
    process_time = time.time() - start_time
    logger.debug(f"Response: {response.status_code} (took {process_time:.3f}s)")

    return response
```

### Using httpie for API Debugging

```bash
# Install httpie
pip install httpie

# Test endpoints
http GET localhost:8000/health
http GET localhost:8000/api/v1/projects
http POST localhost:8000/api/v1/items project_id="123" title="Test Item"

# With authentication
http GET localhost:8000/api/v1/items Authorization:"Bearer TOKEN"
```

### Debugging Database Queries

Enable SQLAlchemy echo mode:

```bash
TRACERTM_DATABASE__ECHO=true uvicorn tracertm.api.main:app --reload
```

This will print all SQL queries to the console:

```sql
INFO:sqlalchemy.engine.Engine:SELECT items.id, items.title, items.view
FROM items WHERE items.project_id = ?
INFO:sqlalchemy.engine.Engine:[cached since 0.001s ago] ('proj-123',)
```

## Debugging the TUI

### Textual Debugging

Textual (the TUI framework) has built-in debugging tools:

```bash
# Enable Textual console logging
TEXTUAL_LOG=textual.log rtm dashboard

# View Textual console in real-time
tail -f textual.log
```

### Textual DevTools

Run the TUI with DevTools (if installed):

```bash
# Install textual-dev
pip install textual-dev

# Run with DevTools
textual run --dev tracertm.cli.app:dashboard

# Access DevTools at http://localhost:8081
```

### TUI Event Debugging

Add debug logging to TUI widgets:

```python
from textual.widget import Widget
from loguru import logger

class MyWidget(Widget):
    async def on_mount(self) -> None:
        logger.debug(f"Widget {self.id} mounted")

    async def on_key(self, event) -> None:
        logger.debug(f"Key pressed: {event.key}")

    async def on_click(self, event) -> None:
        logger.debug(f"Click at {event.x}, {event.y}")
```

### TUI State Inspection

Use Textual's built-in inspection:

```python
from textual.app import App

class DebugApp(App):
    def key_d(self) -> None:
        """Press 'd' to dump widget tree"""
        self.console.print(self.tree)

    def key_s(self) -> None:
        """Press 's' to show state"""
        logger.debug(f"App state: {self.state}")
```

## Database Query Debugging

### SQLAlchemy Echo Mode

Enable query logging:

```python
from sqlalchemy import create_engine

engine = create_engine(
    "postgresql://user:pass@localhost/tracertm",
    echo=True,  # Enable query logging
    echo_pool=True  # Enable connection pool logging
)
```

### Using Environment Variables

```bash
# Enable database echo
TRACERTM_DATABASE__ECHO=true rtm list
```

### Query Profiling

Profile slow queries:

```python
from sqlalchemy import event
from sqlalchemy.engine import Engine
import time

@event.listens_for(Engine, "before_cursor_execute")
def before_cursor_execute(conn, cursor, statement, parameters, context, executemany):
    conn.info.setdefault('query_start_time', []).append(time.time())

@event.listens_for(Engine, "after_cursor_execute")
def after_cursor_execute(conn, cursor, statement, parameters, context, executemany):
    total = time.time() - conn.info['query_start_time'].pop(-1)
    if total > 0.1:  # Log queries taking > 100ms
        logger.warning(f"Slow query ({total:.3f}s): {statement}")
```

### Debugging Transactions

Add transaction logging:

```python
from sqlalchemy.ext.asyncio import AsyncSession

async def debug_transaction(session: AsyncSession):
    logger.debug("Starting transaction")
    try:
        async with session.begin():
            logger.debug("Transaction begun")
            # Your operations here
            logger.debug("Committing transaction")
    except Exception as e:
        logger.error(f"Transaction failed: {e}")
        raise
```

### Inspecting Database State

```bash
# Connect to database
psql -h localhost -U tracertm -d tracertm

# Or for SQLite
sqlite3 ~/.tracertm/tracertm.db

# Show all tables
\dt

# Describe table structure
\d items

# Run queries
SELECT * FROM items LIMIT 10;
```

## Remote Debugging

### Using debugpy

For remote debugging (e.g., Docker containers):

```python
# Add to application entry point
import debugpy

# Start debug server
debugpy.listen(("0.0.0.0", 5678))
print("Waiting for debugger attach...")
debugpy.wait_for_client()
print("Debugger attached!")
```

Run the application:

```bash
# In Docker or remote server
python -m tracertm.api.main
```

Attach from VS Code using the "Attach to Running Process" configuration.

### SSH Tunneling for Remote Debug

```bash
# Create SSH tunnel
ssh -L 5678:localhost:5678 user@remote-server

# Now attach debugger to localhost:5678
```

### Docker Debugging

```dockerfile
# Dockerfile with debug support
FROM python:3.12-slim

# Install debugpy
RUN pip install debugpy

# Expose debug port
EXPOSE 5678

# Run with debugpy
CMD ["python", "-m", "debugpy", "--listen", "0.0.0.0:5678", "--wait-for-client", "-m", "tracertm.api.main"]
```

## Performance Profiling

### Using cProfile

```bash
# Profile CLI command
python -m cProfile -o profile.stats -m tracertm.cli.app list

# View results
python -m pstats profile.stats
> sort cumulative
> stats 20
```

### Using py-spy

```bash
# Install py-spy
pip install py-spy

# Profile running process
py-spy record -o profile.svg --pid <PID>

# Profile command
py-spy record -o profile.svg -- python -m tracertm.cli.app list
```

### Memory Profiling

```bash
# Install memory_profiler
pip install memory_profiler

# Profile memory usage
python -m memory_profiler tracertm/api/main.py
```

### Async Profiling

For async code profiling:

```python
import asyncio
import time

async def profile_async_function():
    start = time.perf_counter()
    try:
        result = await your_async_function()
        return result
    finally:
        duration = time.perf_counter() - start
        logger.info(f"Function took {duration:.3f}s")
```

## Common Debugging Scenarios

### 1. Application Won't Start

**Check logs:**
```bash
# View latest error logs
tail -100 ~/.tracertm/logs/tracertm_errors.log
```

**Verify configuration:**
```bash
# Check config file
cat ~/.tracertm/config.yaml

# Validate environment
env | grep TRACERTM
```

**Test database connection:**
```bash
# Try connecting to database
psql -h localhost -U tracertm -d tracertm

# Or for SQLite
sqlite3 ~/.tracertm/tracertm.db ".tables"
```

### 2. Import Errors

**Check Python path:**
```bash
python -c "import sys; print('\n'.join(sys.path))"
```

**Verify package installation:**
```bash
pip list | grep tracertm
pip show tracertm
```

**Reinstall in development mode:**
```bash
pip uninstall tracertm
pip install -e .
```

### 3. Database Migration Issues

**Check migration status:**
```bash
rtm db status
```

**View migration history:**
```bash
rtm db history
```

**Reset and remigrate:**
```bash
rtm db reset --confirm
rtm db upgrade head
```

### 4. Async/Await Issues

**Common async debugging patterns:**

```python
# Enable asyncio debug mode
import asyncio
asyncio.set_event_loop_policy(asyncio.DefaultEventLoopPolicy())
asyncio.get_event_loop().set_debug(True)

# Log slow callbacks (> 100ms)
import warnings
warnings.filterwarnings('default', category=ResourceWarning)
```

**Debugging hanging coroutines:**

```python
import asyncio

# List all tasks
tasks = asyncio.all_tasks()
for task in tasks:
    logger.debug(f"Task: {task.get_name()}, done: {task.done()}")

# Cancel stuck tasks
for task in tasks:
    if not task.done():
        task.cancel()
```

### 5. Performance Issues

**Enable profiling:**
```bash
# Profile specific command
TRACERTM_LOG_LEVEL=DEBUG python -m cProfile -o profile.stats -m tracertm.cli.app list

# Analyze results
python -m pstats profile.stats
```

**Check query performance:**
```bash
# Enable query timing
TRACERTM_DATABASE__ECHO=true rtm list 2>&1 | grep -i "took"
```

## Debugging Tips and Tricks

### 1. Enable Verbose Logging Temporarily

```bash
# Quick debug without changing config
TRACERTM_LOG_LEVEL=DEBUG rtm [command]
```

### 2. Use Rich Console for Better Output

```python
from rich.console import Console
from rich.traceback import install

# Install rich tracebacks
install(show_locals=True)

console = Console()
console.print("[bold red]Error occurred![/bold red]")
console.print_exception()
```

### 3. Breakpoint Debugging

```python
# Use built-in breakpoint()
def problematic_function():
    data = fetch_data()
    breakpoint()  # Execution will pause here
    process_data(data)
```

### 4. Context Managers for Timing

```python
from contextlib import contextmanager
import time

@contextmanager
def timer(name: str):
    start = time.perf_counter()
    try:
        yield
    finally:
        duration = time.perf_counter() - start
        logger.info(f"{name} took {duration:.3f}s")

# Usage
with timer("Database query"):
    results = await session.execute(query)
```

### 5. Logging Decorators

```python
from functools import wraps
from loguru import logger

def log_calls(func):
    @wraps(func)
    async def wrapper(*args, **kwargs):
        logger.debug(f"Calling {func.__name__} with args={args}, kwargs={kwargs}")
        try:
            result = await func(*args, **kwargs)
            logger.debug(f"{func.__name__} returned {result}")
            return result
        except Exception as e:
            logger.error(f"{func.__name__} raised {e}")
            raise
    return wrapper

@log_calls
async def my_function(x: int) -> int:
    return x * 2
```

### 6. Environment-Specific Debug Configs

Create environment-specific config files:

```bash
# development.env
TRACERTM_LOG_LEVEL=DEBUG
TRACERTM_DATABASE__ECHO=true
TRACERTM_ENABLE_CACHE=false

# production.env
TRACERTM_LOG_LEVEL=INFO
TRACERTM_DATABASE__ECHO=false
TRACERTM_ENABLE_CACHE=true
```

Load with:
```bash
# Load environment
set -a; source development.env; set +a

# Run application
rtm list
```

### 7. Quick Database Inspection

```python
# Add this helper function
async def inspect_db_state(session: AsyncSession):
    """Quick database state inspection"""
    from sqlalchemy import text

    result = await session.execute(text("SELECT COUNT(*) FROM items"))
    count = result.scalar()
    logger.info(f"Total items in database: {count}")

    result = await session.execute(text("SELECT status, COUNT(*) FROM items GROUP BY status"))
    for status, count in result:
        logger.info(f"Items with status '{status}': {count}")
```

### 8. Test Data Debugging

```python
# Create debug test data
from tracertm.testing_factories import create_test_project, create_test_item

async def create_debug_data(session: AsyncSession):
    project = await create_test_project(session, name="Debug Project")
    for i in range(10):
        await create_test_item(
            session,
            project_id=project.id,
            title=f"Debug Item {i}",
            status="todo"
        )
    await session.commit()
    logger.info(f"Created debug project: {project.id}")
```

### 9. Capture Request IDs for Tracing

```python
# Add request ID to logs
from uuid import uuid4

async def process_request():
    request_id = str(uuid4())
    logger = logger.bind(request_id=request_id)

    logger.info("Processing request")
    # All subsequent logs will include request_id
```

### 10. Debug Mode Flag

```python
# Global debug flag
import os
DEBUG = os.getenv("TRACERTM_DEBUG", "false").lower() == "true"

if DEBUG:
    logger.setLevel("DEBUG")
    # Enable additional debugging features
```

## Additional Resources

- [Loguru Documentation](https://loguru.readthedocs.io/)
- [FastAPI Debugging](https://fastapi.tiangolo.com/tutorial/debugging/)
- [Textual Debugging Guide](https://textual.textualize.io/guide/devtools/)
- [SQLAlchemy Debugging](https://docs.sqlalchemy.org/en/20/core/engines.html#configuring-logging)
- [Python Debugging with pdb](https://docs.python.org/3/library/pdb.html)

## Summary

Effective debugging requires:

1. **Proper logging configuration** - Use appropriate log levels and formats
2. **IDE integration** - Set up launch configurations for common scenarios
3. **Database visibility** - Enable query logging when needed
4. **Remote debugging capabilities** - For production issues
5. **Performance monitoring** - Profile slow operations
6. **Structured approach** - Follow systematic debugging workflows

With these tools and techniques, you can efficiently diagnose and resolve issues in all TracerTM components.
