"""Docker container logs table Adds docker_logs — one row per container log line, pushed by the host agent and folded into its metrics push. Time-series, host-scoped (container names are only unique within a host). Bounded by a per-container size+age ring in retention, so a chatty container keeps a shorter window rather than growing without limit. Additive create_table + twin indexes (viewer lookup by (host, container, ts); age-cutoff prune by ts). Revision ID: docker_009_container_logs Revises: docker_008_bigint_mem Create Date: 2026-07-19 """ from typing import Sequence, Union from alembic import op import sqlalchemy as sa revision: str = "docker_009_container_logs" down_revision: Union[str, None] = "docker_008_bigint_mem" branch_labels: Union[str, Sequence[str], None] = None depends_on: Union[str, Sequence[str], None] = None def upgrade() -> None: op.create_table( "docker_logs", sa.Column("id", sa.String(length=36), nullable=False), sa.Column("host_id", sa.String(length=36), nullable=False), sa.Column("container_name", sa.String(length=255), nullable=False), sa.Column("ts", sa.DateTime(timezone=True), nullable=False), sa.Column("stream", sa.String(length=8), nullable=False, server_default="stdout"), sa.Column("line", sa.Text(), nullable=False, server_default=""), sa.ForeignKeyConstraint(["host_id"], ["hosts.id"], ondelete="CASCADE"), sa.PrimaryKeyConstraint("id"), ) op.create_index("ix_docker_logs_host_id", "docker_logs", ["host_id"]) op.create_index("ix_docker_logs_container_name", "docker_logs", ["container_name"]) op.create_index("ix_docker_logs_host_container_time", "docker_logs", ["host_id", "container_name", "ts"]) op.create_index("ix_docker_logs_ts", "docker_logs", ["ts"]) def downgrade() -> None: op.drop_index("ix_docker_logs_ts", table_name="docker_logs") op.drop_index("ix_docker_logs_host_container_time", table_name="docker_logs") op.drop_index("ix_docker_logs_container_name", table_name="docker_logs") op.drop_index("ix_docker_logs_host_id", table_name="docker_logs") op.drop_table("docker_logs")