Skip to content

Add debug logging for troubleshooting #29

@coreyleavitt

Description

@coreyleavitt

Summary

Add structured debug logging throughout the codebase to aid in troubleshooting issues with corrupt databases, authentication failures, and potential bugs.

Requirements

Follow Python standard practices for library logging:

  1. Use logging.getLogger(__name__) in each module - Creates hierarchical loggers under kdbxtool.*

  2. Add NullHandler to root logger - Prevents "No handler found" warnings when logging is not configured:

    # In kdbxtool/__init__.py
    import logging
    logging.getLogger('kdbxtool').addHandler(logging.NullHandler())
  3. Never add handlers or configure levels in library code - Let applications configure logging

  4. Use appropriate log levels:

    • DEBUG - Detailed troubleshooting (parsing offsets, field values, stages)
    • INFO - General operations (file opened, database saved)
    • WARNING - Potential issues (weak KDF parameters, deprecated features)
    • ERROR - Failures that are caught and re-raised
  5. Sanitize sensitive data - Even at DEBUG level, never log:

    • Passwords or password hashes
    • Key material (master key, cipher keys, HMAC keys)
    • Decrypted content
    • Log safe metadata only (lengths, offsets, field types, UUIDs)

Suggested log points

Parsing (parsing/header.py, parsing/kdbx4.py)

  • Header field types and lengths (not values for sensitive fields)
  • Version detected
  • KDF type and parameters
  • Compression type
  • Parsing offsets for debugging truncation issues

Crypto (security/crypto.py, security/kdf.py)

  • Cipher type being used
  • KDF type and iteration counts
  • Key derivation stages (without key material)
  • HMAC verification attempts (pass/fail, not the values)

Database (database.py)

  • File open/save operations
  • XML parsing stages
  • Entry/group counts
  • Protected value encryption/decryption (counts, not content)

Usage example

import logging

# Enable debug logging for kdbxtool
logging.basicConfig(level=logging.DEBUG)
# Or more targeted:
logging.getLogger('kdbxtool.parsing').setLevel(logging.DEBUG)

# Now operations produce detailed logs
db = Database.open("problem.kdbx", password="test")

References

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions