mirror of
https://github.com/jhd3197/ServerKit.git
synced 2026-11-09 13:35:12 +09:00
RunLogStream accepts any RunLike (__run_kind__ + id + to_dict, optional result/step members): one room grammar run_<kind>_<id>, one batched persisted run_log/run_status event pair, and a GET /api/v1/runs/<kind>/<id>/logs?after_id polling twin over the new run_log_entries table (migration 087). Deploys keep DeploymentJobLog and dual-emit the legacy deploy_log/deploy_status during the migration window. The unified Job runtime — which had NO live channel — adopts it in the consumer (start/succeeded/failed frames; handlers can log via stream_for(job)). The dead pipeline_* scaffolding was retired in E2. Gate: emit -> persisted row -> after_id resync contract test; consumer adoption test. MIGRATION_INVENTORY.md regenerated (census moved). Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
42 lines
1.5 KiB
Python
42 lines
1.5 KiB
Python
"""Generic run-scoped log rows (plan 77 E1).
|
|
|
|
``DeploymentJobLog`` predates this table and stays the store for the deploy
|
|
kind; every OTHER run kind (unified jobs, sandbox runs, site imports,
|
|
backups) persists its stream lines here, keyed by ``(run_kind, run_id)`` —
|
|
the same key the ``run_<kind>_<id>`` socket room and the
|
|
``GET /api/v1/runs/<kind>/<id>/logs?after_id`` polling twin use, so a client
|
|
can always resync after a dropped socket.
|
|
"""
|
|
from datetime import datetime
|
|
|
|
from app import db
|
|
|
|
|
|
class RunLogEntry(db.Model):
|
|
__tablename__ = 'run_log_entries'
|
|
|
|
id = db.Column(db.Integer, primary_key=True)
|
|
run_kind = db.Column(db.String(40), nullable=False)
|
|
run_id = db.Column(db.String(64), nullable=False)
|
|
step_index = db.Column(db.Integer, nullable=True)
|
|
level = db.Column(db.String(10), default='info', nullable=False)
|
|
message = db.Column(db.Text, nullable=False, default='')
|
|
data = db.Column(db.Text, nullable=True)
|
|
created_at = db.Column(db.DateTime, default=datetime.utcnow)
|
|
|
|
__table_args__ = (
|
|
# The one access pattern: a run's lines in id order, optionally after a
|
|
# known id (the resync cursor).
|
|
db.Index('ix_run_log_entries_kind_run_id', 'run_kind', 'run_id', 'id'),
|
|
)
|
|
|
|
def to_dict(self):
|
|
return {
|
|
'id': self.id,
|
|
'step_index': self.step_index,
|
|
'level': self.level,
|
|
'message': self.message,
|
|
'data': self.data,
|
|
'ts': self.created_at.isoformat() if self.created_at else None,
|
|
}
|