Skip to main content

Overview

Activity logs provide a complete audit trail of all system changes. This guide covers how to access, filter, and analyze activity data for compliance, troubleshooting, and monitoring.

Activity Log System

What is Logged?

The system automatically tracks:

CREATE Events

New records added to the system

UPDATE Events

Modifications to existing records

DELETE Events

Record deletions (usually logical)

Status Changes

Workflow status transitions

Activity Log Model

operaciones/models/registro_actividad_models.py
class RegistroActividad(models.Model):
    registro_id = models.IntegerField(null=True, blank=True)
    evento = models.TextField(null=True, blank=True)  # CREATE, UPDATE, DELETE
    campo = models.TextField(blank=True, null=True)   # Changed field
    valor_anterior = models.TextField(blank=True, null=True)  # Old value
    valor_actual = models.TextField(blank=True, null=True)    # New value
    afectacion = models.TextField(blank=True, null=True)      # Affected module
    fecha = models.DateTimeField(blank=True, null=True)       # Timestamp
    usuario_id = models.ForeignKey(User, on_delete=models.CASCADE)  # Who made change
    tabla_log = models.IntegerField(blank=True, null=True)    # Module identifier
    detalle = models.TextField(blank=True, null=True)         # Additional details
    
    class Meta:
        db_table = 'registro_actividad'

Accessing Activity Logs

1

Navigate to Logs

Go to Configuración > Registro de Actividad
2

View All Activity

Default view shows all recent activity
3

Use Filters

Narrow down results (see Filtering section below)

Activity Log Interface

The activity log view provides:
operaciones/views/registro_actividad.py
@login_required(login_url='/accounts/login/')
def registro_actividad(request):
    """Index de registro de actividad"""
    return render(request, 'operaciones/registro_actividad/registro_actividad.html')

Log Display Columns

  • ID: Unique log entry identifier
  • Evento: Action type (CREATE, UPDATE, DELETE)
  • Afectación: Module/table affected
  • Detalle: Description of what changed
  • Fecha: Date and time of change
  • Usuario: User who made the change
  • Valor Anterior: Old value (for updates)
  • Valor Actual: New value (for updates)

Filtering Activity Logs

By User

1

Load User List

operaciones/views/registro_actividad.py
@login_required(login_url='/accounts/login/')
def obtener_usuarios(request):
    usuarios = User.objects.filter(is_active=True).values(
        'id', 'username', 'first_name', 'last_name', 'email'
    )
    
    # Format for display
    usuarios_list.append({
        'id': usuario['id'],
        'descripcion': f"{usuario['first_name']} {usuario['last_name']} ({usuario['username']})"
    })
2

Select User

Choose from dropdown to see only that user’s actions

By Event Type

Filter by action:
  • CREATE: New record creation
  • UPDATE: Record modification
  • DELETE: Record deletion
  • STATUS_CHANGE: Workflow transitions

By Module (Afectación)

Filter by system module:

PTEs

tabla_log = 1

Work Orders

tabla_log = 2

Production

tabla_log = 3

Catalogs

tabla_log = 4

Users

tabla_log = 5

Permissions

tabla_log = 6

By Search Term

Full-text search across:
  • Valor anterior
  • Valor actual
  • Evento
  • Afectación
  • Detalle
  • User name and email
operaciones/views/registro_actividad.py
search_value = request.GET.get('filtro', '')

if search_value:
    registros = registros.filter(
        Q(valor_anterior__icontains=search_value) |
        Q(valor_actual__icontains=search_value) |
        Q(evento__icontains=search_value) |
        Q(afectacion__icontains=search_value) |
        Q(detalle__icontains=search_value) |
        Q(fecha__icontains=search_value) |
        Q(campo__icontains=search_value) |
        Q(usuario_id__first_name__icontains=search_value) |
        Q(usuario_id__last_name__icontains=search_value) |
        Q(usuario_id__email__icontains=search_value)
    )

DataTable API

Activity logs use server-side DataTables:
operaciones/views/registro_actividad.py
@login_required
def datatable_registro_actividad(request):
    draw = int(request.GET.get('draw', 1))
    start = int(request.GET.get('start', 0))
    length = int(request.GET.get('length', 10))
    
    # Apply filters
    usuario_id = request.GET.get('usuario_id')
    evento = request.GET.get('evento')
    afectacion = request.GET.get('afectacion')
    
    registros = RegistroActividad.objects.select_related('usuario_id').all()
    
    if usuario_id:
        registros = registros.filter(usuario_id_id=usuario_id)
    if evento:
        registros = registros.filter(evento=evento)
    if afectacion:
        registros = registros.filter(tabla_log=afectacion)
    
    # Sorting
    order_column = request.GET.get('order[0][column]', '0')
    order_dir = request.GET.get('order[0][dir]', 'desc')
    
    column_map = {
        '0': 'id',
        '1': 'evento',
        '2': 'afectacion',
        '3': 'detalle',
        '4': 'fecha',
        '5': 'usuario__first_name',
    }
    
    order_field = column_map.get(order_column, 'fecha')
    if order_dir == 'desc':
        order_field = f'-{order_field}'
    
    registros = registros.order_by(order_field)
    
    # Pagination
    total_records = registros.count()
    registros_paginados = registros[start:start + length]

Automatic Activity Logging

The @registrar_actividad decorator automatically logs changes:

Decorator Usage

operaciones/views/pte.py
@require_http_methods(["POST"])
@login_required
@registrar_actividad  # Automatically logs this action
def crear_pte(request):
    # Create PTE
    pte_header = PTEHeader.objects.create(...)
This decorator:
  • Captures the action (CREATE, UPDATE, DELETE)
  • Records changed fields
  • Stores old and new values
  • Associates with current user
  • Timestamps the action

Common Use Cases

Audit Trail Investigation

1

Identify Record

Note the ID of the record in question (e.g., PTE #123)
2

Filter by Record ID

Use search to find all changes to that record
3

Review Timeline

Sort by date to see chronological changes
4

Identify Users

See who made each modification
5

Export Results

Export filtered logs for documentation

Security Investigation

1

Suspicious Activity Detected

User reports unusual changes
2

Filter by Time Range

Narrow to when issue occurred
3

Filter by Module

Focus on affected module
4

Review User Actions

Check what each user did during period
5

Identify Source

Determine if issue was:
  • User error
  • Unauthorized access
  • System error

Compliance Reporting

1

Define Period

Select reporting period (month, quarter, year)
2

Export All Activity

Export complete log for period
3

Generate Statistics

Count by:
  • User
  • Module
  • Event type
4

Document Findings

Create compliance report with:
  • Total activity count
  • Active users
  • Critical changes
  • Access patterns

Troubleshooting Data Issues

When Data Looks Wrong

Example: Production volumes suddenly changedInvestigation Steps:
  1. Find the production record ID
  2. Filter logs by that record
  3. Review all UPDATE events
  4. Check:
    • What changed (campo)
    • Old value (valor_anterior)
    • New value (valor_actual)
    • Who changed it (usuario_id)
    • When it changed (fecha)
  5. Determine if change was:
    • Intentional correction
    • User error
    • System issue
  6. Take appropriate action (revert, train user, fix bug)

Exporting Activity Logs

Export logs for offline analysis:
1

Apply Desired Filters

Narrow down to relevant records
2

Use DataTable Export

Available formats:
  • Excel (full data with formatting)
  • CSV (for database import)
  • PDF (for documentation)
  • Print (hard copy)
3

Verify Export

Check that all required columns are included

Log Retention

Activity logs are permanent. They are never automatically deleted to maintain complete audit trail.

Archiving Old Logs

For very old logs (if database grows too large):
1

Export Historical Data

Export logs older than retention period (e.g., >5 years)
2

Archive Securely

Store export in secure, backed-up location
3

Document Archive

Record where archived data is stored
4

Optional: Database Cleanup

Consult with IT before deleting any log data

Understanding Log Entries

CREATE Event

{
  "evento": "CREATE",
  "registro_id": 456,
  "afectacion": "PTE",
  "detalle": "Created PTE: PTE-2026-123",
  "usuario": "juan.perez",
  "fecha": "2026-03-09 14:30:00"
}

UPDATE Event

{
  "evento": "UPDATE",
  "registro_id": 456,
  "campo": "estatus",
  "valor_anterior": "1 (PENDIENTE)",
  "valor_actual": "2 (EN PROCESO)",
  "afectacion": "PTE",
  "detalle": "Status changed for PTE-2026-123",
  "usuario": "maria.lopez",
  "fecha": "2026-03-10 09:15:00"
}

DELETE Event

{
  "evento": "DELETE",
  "registro_id": 789,
  "afectacion": "Work Order",
  "valor_anterior": "OT-2026-045 (Active)",
  "valor_actual": "Deleted (estatus=0)",
  "detalle": "Logical deletion of OT-2026-045",
  "usuario": "admin",
  "fecha": "2026-03-11 11:00:00"
}
Most “deletions” are logical (estatus=0) not physical, so data remains accessible.

Best Practices

Regular Reviews

Review logs weekly for unusual activity

Monitor Sensitive Changes

Watch for permission changes and user modifications

Document Investigations

Keep notes on major findings

Train Users

Use logs to identify training needs

Secure Access

Limit log access to administrators

Never Delete

Preserve complete audit trail

Performance Considerations

Activity logs can grow large. For better performance:
  • Use specific filters instead of viewing all logs
  • Export and analyze offline for complex queries
  • Consider database indexing on frequently filtered columns

Managing Users

User account administration

User Permissions

Understanding permission system

Build docs developers (and LLMs) love