Volver a la wiki

Descripción

Modelo Django que almacena entradas de auditoría del sistema: quién hizo qué, cuándo, en qué organización y con qué detalles. Trazabilidad completa de mutaciones sensibles.

Tabla: core_systemlog
Ubicación: core.models.SystemLog
Disponible desde: v1.0.73 (con categorías ITSM y OBSERVATORY desde PR #71; CREDENTIAL desde v1.103.0 / commit d14ebb58)

Campos

CampoTipoNuleableDescripción
idAutoFieldNoClave primaria
timestampDateTimeFieldNoInstante del evento (siempre timezone.now())
userForeignKey(User)SíOperador que realizó la acción. None si anónimo o token sin identidad
organizationForeignKey(Organization)SíOrg afectada. None si a nivel de sistema (raro)
levelCharField(max_length=10)NoSeveridad: INFO, WARN, ERROR
categoryCharField(max_length=50)NoCategoría de la acción (ver tabla abajo)
actionCharField(max_length=200)NoIdentificador de la acción (ej: channel.create, alert.delete)
detailsTextFieldSíPayload libre — JSON, texto plano o URL-encoded (sin restricción de formato)

Categorías (CATEGORY_CHOICES)

ClaveEtiquetaUsoIntroducido
AUTHAuthenticationLogins, logouts, cambios de contraseñav1.0.0
RACKRack ManagementCRUD de racks, cambios de estadov1.0.0
BLUEPRINTBlueprint ManagementCambios en blueprintsv1.0.0
SYSTEMSystemJobs, rebalances, maintenance internov1.0.0
NETWORKNetwork ManagementCambios en topología de red (CNS)v1.0.0
ITSMITSM ManagementCanales, escalados, SLA, mantenimiento, runbooksPR #71 (2026-06-07)
OBSERVATORYObservatory ManagementAlertas, wireless, UPS, descubrimientosPR #71 (2026-06-07)
CREDENTIALCredential StoreAlta/edición/borrado/desencriptado de credenciales guardadasv1.103.0 / commit d14ebb58 (2026-09-03)

Acciones por categoría (no exhaustivo)

ITSM:

OBSERVATORY:

CREDENTIAL:

Índices

CREATE TABLE core_systemlog (
    id BIGINT PRIMARY KEY,
    timestamp TIMESTAMP NOT NULL,
    user_id BIGINT NULL REFERENCES core_user(id),
    organization_id BIGINT NULL REFERENCES core_organization(id),
    level VARCHAR(10) NOT NULL,
    category VARCHAR(50) NOT NULL,
    action VARCHAR(200) NOT NULL,
    details TEXT NULL,
    created_at TIMESTAMP DEFAULT NOW()
);

CREATE INDEX idx_systemlog_org_category_action_ts 
  ON core_systemlog(organization_id, category, action, timestamp DESC);

CREATE INDEX idx_systemlog_org_user_ts 
  ON core_systemlog(organization_id, user_id, timestamp DESC);

CREATE INDEX idx_systemlog_level 
  ON core_systemlog(level, timestamp DESC);

Relaciones

Métodos y propiedades

__str__()

def __str__(self) -> str:
    """Retorna representación humana: '<2026-06-07 10:55 user=operator org=acme action=channel.create>'"""

Migración reciente: 0034

Cambio: Extensión de CATEGORY_CHOICES con CREDENTIAL (cola de auditoría, task #286).

# core/migrations/0034_systemlog_category_credential.py
# Generated: 2026-09-03

migrations.AlterField(
    model_name='systemlog',
    name='category',
    field=models.CharField(
        choices=[
            ('AUTH', 'Authentication'),
            ('RACK', 'Rack Management'),
            ('BLUEPRINT', 'Blueprint Management'),
            ('SYSTEM', 'System'),
            ('NETWORK', 'Network Management'),
            ('ITSM', 'ITSM Management'),
            ('OBSERVATORY', 'Observatory Management'),
            ('CREDENTIAL', 'Credential Store'),          # NEW
        ],
        max_length=50,
    ),
)

Motivo: core/credential_api.py gestionaba credenciales (crear/editar/borrar/desencriptar) sin dejar rastro en SystemLog — un operador podía leer el secreto de un dispositivo sin que quedara registro alguno. La cola de auditoría (task #286, 14 hallazgos MEDIA) lo detectó y añadió el rastro completo, sin loguear nunca el valor del secreto.

Impacto: No-op para datos existentes. Las nuevas mutaciones de credenciales quedan auditadas.

Migración anterior: 0023

Cambio: Extensión de CATEGORY_CHOICES con ITSM y OBSERVATORY.

# core/migrations/0023_alter_systemlog_category.py
# Generated: 2026-06-07

migrations.AlterField(
    model_name='systemlog',
    name='category',
    field=models.CharField(
        choices=[
            ('AUTH', 'Authentication'),
            ('RACK', 'Rack Management'),
            ('BLUEPRINT', 'Blueprint Management'),
            ('SYSTEM', 'System'),
            ('NETWORK', 'Network Management'),
            ('ITSM', 'ITSM Management'),           # NEW
            ('OBSERVATORY', 'Observatory Management'),  # NEW
        ],
        max_length=50,
    ),
)

Impacto: No-op para datos existentes. Las nuevas mutaciones pueden usar las nuevas categorías.

Lectura de auditoría

API: GET /api/core/logs/ (si existe)

Típicamente expuesto via core/api/logs.py → SystemLogSchema (readonly):

class SystemLogSchema(Schema):
    id: int
    timestamp: datetime
    level: str
    category: str
    action: str
    details: str
    user_id: Optional[int]
    username: str  # derived

Django admin

Registrado en core/admin.py para navegación manual (solo superusers).

Queries comunes

# Auditoría de un operador en una org
SystemLog.objects.filter(
    organization=org,
    user=operator,
    timestamp__gte=start_date
).order_by('-timestamp')

# Todas las mutaciones de un tipo
SystemLog.objects.filter(
    organization=org,
    category='ITSM',
    action='channel.delete'
)

# Logs de error
SystemLog.objects.filter(level='ERROR')

Retención y archivado

Integración con observabilidad

Las entradas de SystemLog pueden ingerirse en Prometheus/Grafana vía:

  1. Endpoint expuesto (lectura filtrada por org)
  2. Exporter custom (convierte rows a métricas)
  3. ELK/Splunk (dump periódico a datawarehouse)

RLS

Performance

Cambios futuros

Véase también

Subir