Skip to main content

A complete logging solution with console, database, and Discord notification support

Project description

Hibiki Core

A production-ready logging system with console, database, and Discord notification support.

Python 3.10+ License: MIT

AI Coding Assistant Support

If you use an AI coding assistant (Cursor, GitHub Copilot, ChatGPT, Claude, etc.), provide LLMGUIDE.md as context. It contains a complete reference for the package's API, initialization sequence, async behavior, and common pitfalls -- everything the model needs to generate correct integration code.

Features

  • Console Logging - Human-readable or JSON-formatted output
  • Database Logging - Store logs in PostgreSQL (or any SQLAlchemy-supported DB)
  • Discord Notifications - Automatic webhook notifications for errors
  • Non-blocking - All DB and Discord operations are async
  • Encrypted Storage - Discord webhook URLs encrypted at rest
  • Context Support - Attach user_id, request path, HTTP method to logs
  • Configurable Levels - Separate thresholds for console, DB, and Discord

Installation

pip install hibiki-core

# With PostgreSQL support
pip install hibiki-core[postgres]

Quick Start

Console-only (no database)

from hibiki_core import configure_logging, get_logger

configure_logging(namespace="myapp")

logger = get_logger("myapp.service")
logger.info("Ready")
logger.error("Something broke", exc_info=True)

With database and Discord

from sqlalchemy.ext.asyncio import create_async_engine, async_sessionmaker
from sqlalchemy.orm import declarative_base
from hibiki_core import configure_logging, setup_db_logging, get_logger
from hibiki_core.models import create_log_model, create_discord_config_model

# Define models
Base = declarative_base()
Log = create_log_model(Base)
DiscordNotificationConfig = create_discord_config_model(Base)

# Create async engine and session
engine = create_async_engine("postgresql+asyncpg://user:pass@localhost/db")
session_maker = async_sessionmaker(engine, expire_on_commit=False)

# Initialize logging (call once at startup)
configure_logging(namespace="myapp")
setup_db_logging(
    session_maker=session_maker,
    log_model=Log,
    namespace="myapp",
    discord_config_model=DiscordNotificationConfig,  # optional
)

logger = get_logger("myapp.module")
logger.error("Something went wrong", exc_info=True)

Alternatively, create tables directly with raw SQL:

from hibiki_core.models import LOG_TABLE_SQL, DISCORD_CONFIG_TABLE_SQL

Configuration

Environment Variables

Variable Default Description
ENCRYPTION_KEY (none) Required if using Discord webhook encryption. Generate with: python -c "from hibiki_core.encryption import generate_key; print(generate_key())"
LOG_DB_MIN_LEVEL WARNING Minimum level saved to database. Options: DEBUG, INFO, WARNING, ERROR, CRITICAL
LOG_DISCORD_MIN_LEVEL ERROR Minimum level sent to Discord. Same options as above.
ENV development Set to production for JSON console output and ERROR-only console log level. Leave unset for human-readable output at INFO level.

Namespace

The namespace parameter controls which loggers receive DB and Discord handlers. Only loggers whose names start with the namespace will log to the database and Discord.

configure_logging(namespace="myapp")
setup_db_logging(session_maker=..., log_model=..., namespace="myapp")

logger = get_logger("myapp.api")     # Gets DB + Discord handlers
logger = get_logger("other.module")  # Console only

Use extra_loggers to include third-party loggers:

configure_logging(namespace="myapp", extra_loggers=["uvicorn", "fastapi"])

Logging with Context

from hibiki_core import get_logger, add_context_to_logger

logger = get_logger("myapp.users")
context_logger = add_context_to_logger(logger, user_id="123", path="/api/users", method="POST")
context_logger.error("User creation failed")

Discord Setup

  1. Create a webhook in your Discord server.
  2. Encrypt the URL and store it in the discord_notification_config table with notification_type = 'log' and is_enabled = true.
from hibiki_core.encryption import encrypt
encrypted_url = encrypt("https://discord.com/api/webhooks/...")

Discord error messages include the logger name, message, traceback, and any attached context (user_id, path, method).

API Reference

Core Functions

configure_logging(namespace="app", extra_loggers=None)

Configure console logging. Call once at app startup.

setup_db_logging(session_maker, log_model, discord_config_model=None, namespace="app")

Initialize database and optional Discord logging. Call after your database is ready.

get_logger(name) -> logging.Logger

Get a logger. If name matches the configured namespace, DB/Discord handlers are attached automatically.

add_context_to_logger(logger, user_id=None, path=None, method=None) -> logging.LoggerAdapter

Wrap a logger with request context that is included in DB and Discord log entries.

async log_to_db(level, message, logger_name, user_id=None, path=None, method=None, trace=None)

Manually log a message to the database (respects LOG_DB_MIN_LEVEL).

async log_to_discord(level, message, logger_name, trace=None, user_id=None, path=None, method=None)

Manually send a notification to Discord (respects LOG_DISCORD_MIN_LEVEL).

async log_error(error, logger_name, message=None, user_id=None, path=None, method=None)

Log an exception to the database with its traceback automatically extracted.

Encryption Utilities

from hibiki_core.encryption import encrypt, decrypt, generate_key

key = generate_key()
encrypted = encrypt("https://discord.com/api/webhooks/...")
original = decrypt(encrypted)

Models

from hibiki_core.models import (
    create_log_model,              # Factory: Log model bound to your Base
    create_discord_config_model,   # Factory: DiscordNotificationConfig model
    LOG_TABLE_SQL,                 # Raw SQL for logs table (PostgreSQL)
    DISCORD_CONFIG_TABLE_SQL,      # Raw SQL for discord_notification_config table
)

Framework Integration

FastAPI

from contextlib import asynccontextmanager
from fastapi import FastAPI
from hibiki_core import configure_logging, setup_db_logging, get_logger

@asynccontextmanager
async def lifespan(app: FastAPI):
    configure_logging(namespace="app", extra_loggers=["uvicorn", "fastapi"])
    setup_db_logging(
        session_maker=async_session_maker,
        log_model=Log,
        namespace="app",
        discord_config_model=DiscordNotificationConfig,
    )
    yield

app = FastAPI(lifespan=lifespan)
logger = get_logger("app.routes")

Django

# settings.py
from hibiki_core import configure_logging
configure_logging(namespace="myproject")

# views.py
from hibiki_core import get_logger
logger = get_logger("myproject.views")

Flask

from hibiki_core import configure_logging, get_logger

configure_logging(namespace="myapp")
logger = get_logger("myapp.routes")

Troubleshooting

Logs not appearing in database - Verify setup_db_logging() was called, your logger name matches the namespace, and LOG_DB_MIN_LEVEL allows the level.

Discord notifications not sending - Check that a row exists in discord_notification_config with notification_type = 'log' and is_enabled = true, and that LOG_DISCORD_MIN_LEVEL allows the level.

Encryption errors - Ensure ENCRYPTION_KEY is set. If you rotate the key, re-encrypt all stored webhook URLs.

License

MIT

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

hibiki_core-2.1.0.tar.gz (18.3 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

hibiki_core-2.1.0-py3-none-any.whl (13.4 kB view details)

Uploaded Python 3

File details

Details for the file hibiki_core-2.1.0.tar.gz.

File metadata

  • Download URL: hibiki_core-2.1.0.tar.gz
  • Upload date:
  • Size: 18.3 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.13.7

File hashes

Hashes for hibiki_core-2.1.0.tar.gz
Algorithm Hash digest
SHA256 c726d60bc4d674558acb1b9e8fa19e058802dfba574598c154f92b6146ce0972
MD5 282f286b6017e1fd01694f09b5bb239a
BLAKE2b-256 8a2aeec0b416df50f71d282c17798f16e27814ecc2ecb3af57c955d10c9510d5

See more details on using hashes here.

File details

Details for the file hibiki_core-2.1.0-py3-none-any.whl.

File metadata

  • Download URL: hibiki_core-2.1.0-py3-none-any.whl
  • Upload date:
  • Size: 13.4 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.13.7

File hashes

Hashes for hibiki_core-2.1.0-py3-none-any.whl
Algorithm Hash digest
SHA256 c662d8dec1b708e03f18d77ef1af06a842537164035d8c9df99919fc39a01e03
MD5 edc329b605b1e7bdffcae9d1cf9da00d
BLAKE2b-256 59a34c5b439f5d4696abe88a617621b09a89d4af687c6f592d3d952bc39fdc9b

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page