Files
IT_Ticket_System/app/services/log_service.py
T
2026-03-25 11:37:46 -04:00

91 lines
3.1 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
import logging
from flask import request
from app import db
from app.models import ActivityLog
logger = logging.getLogger(__name__)
def _get_real_ip():
"""
Return the genuine client IP address when Flask sits behind an nginx
reverse proxy.
nginx forwards the original client IP in two headers:
- X-Forwarded-For: <client>, <proxy1>, <proxy2>, ...
- X-Real-IP: <client>
request.remote_addr is always 127.0.0.1 in a proxied setup, so we
must read the headers instead. We take the leftmost (first) value in
X-Forwarded-For because that is the original client; subsequent values
are intermediate proxies appended by each hop.
Falls back to X-Real-IP, then remote_addr as a last resort.
"""
try:
xff = request.headers.get('X-Forwarded-For')
if xff:
# Strip any port appended by some proxies and take first entry
return xff.split(',')[0].strip()
xri = request.headers.get('X-Real-IP')
if xri:
return xri.strip()
return request.remote_addr
except RuntimeError:
return None
def log_action(user_id, action, entity_type=None, entity_id=None, details=None):
"""
Persist an activity log entry for create / edit / delete actions.
Parameters
----------
user_id : int | None the acting user (None for system actions)
action : str e.g. 'ticket_create', 'ticket_update', 'comment_delete'
entity_type : str | None 'ticket', 'comment', 'user', etc.
entity_id : int | None primary key of the affected entity
details : str | None free-form JSON or human-readable details
"""
ip = _get_real_ip()
try:
entry = ActivityLog(
user_id = user_id,
action = action,
entity_type = entity_type,
entity_id = entity_id,
details = details,
ip_address = ip,
)
db.session.add(entry)
db.session.commit()
logger.info(
f'[ACTIVITY] action={action} entity={entity_type}:{entity_id} '
f'user_id={user_id} ip={ip}'
)
except Exception as exc:
db.session.rollback()
logger.error(f'[ACTIVITY LOG ERROR] {exc}')
def log_ticket_history(ticket, field_name, old_value, new_value, changed_by_id):
"""Record a granular field-level change on a ticket."""
from app.models import TicketHistory
try:
entry = TicketHistory(
ticket_id = ticket.id,
changed_by = changed_by_id,
field_name = field_name,
old_value = str(old_value) if old_value is not None else None,
new_value = str(new_value) if new_value is not None else None,
)
db.session.add(entry)
db.session.commit()
logger.info(
f'[TICKET HISTORY] ticket_id={ticket.id} field={field_name} '
f'"{old_value}" -> "{new_value}" by user_id={changed_by_id}'
)
except Exception as exc:
db.session.rollback()
logger.error(f'[TICKET HISTORY ERROR] {exc}')