Download api/syslog.py from dn-scribe/attstore: direct link, hf CLI and curl.
- Browser
- Download file 13 kB
-
https://huggingface.co/spaces/dn-scribe/attstore/resolve/main/api/syslog.py
- Command line
-
hf download hf://spaces/dn-scribe/attstore/api/syslog.py
-
curl -L -o syslog.py https://huggingface.co/spaces/dn-scribe/attstore/resolve/main/api/syslog.py
13 kB
| from flask import Blueprint, request, Response, jsonify | |
| from flask_jwt_extended import get_jwt_identity | |
| import csv | |
| from models import SystemLog, User | |
| from app import db | |
| from auth import jwt_required_with_logging, get_current_user_safe | |
| from api.badges import is_admin_user | |
| from logging_utils import log_event, parse_rfc5424_log | |
| syslog_bp = Blueprint('syslog', __name__) | |
| def receive_syslog(): | |
| """Receive RFC 5424 syslog messages - requires JWT authentication per OpenAPI spec""" | |
| try: | |
| content_type = request.content_type or 'text/plain' | |
| if content_type.startswith('application/json'): | |
| # Handle JSON format | |
| data = request.get_json() | |
| if not data: | |
| return jsonify({'error': 'JSON data required'}), 400 | |
| # Extract log messages from JSON | |
| message = data.get('syslog_message', []) | |
| if not message: | |
| return jsonify({'error': 'syslog_message field required'}), 400 | |
| processed_count = 0 | |
| try: | |
| # Parse RFC 5424 message | |
| parsed = parse_rfc5424_log(message) | |
| # Create log entry | |
| log_entry = SystemLog( | |
| facility=parsed['facility'], | |
| severity=parsed['severity'], | |
| version=parsed['version'], | |
| timestamp=parsed['timestamp'], | |
| hostname=parsed['hostname'], | |
| app_name=parsed['app_name'], | |
| proc_id=parsed['proc_id'], | |
| msg_id=parsed['msg_id'], | |
| structured_data=parsed['structured_data'], | |
| message=parsed['message'], | |
| user_id=int(get_jwt_identity()), | |
| source_ip=request.remote_addr, | |
| event_type='syslog_received' | |
| ) | |
| db.session.add(log_entry) | |
| processed_count += 1 | |
| except Exception as e: | |
| # Log parsing error but continue processing | |
| log_event( | |
| severity=4, | |
| message=f"Failed to parse syslog message: {str(e)}", | |
| event_type="syslog_parse_error", | |
| user_id=int(get_jwt_identity()) | |
| ) | |
| db.session.commit() | |
| return jsonify({ | |
| 'message': f'Processed {processed_count} log messages', | |
| 'processed_count': processed_count | |
| }) | |
| else: | |
| # Handle raw text format (single RFC 5424 message) | |
| message = request.get_data(as_text=True).strip() | |
| if not message: | |
| return jsonify({'error': 'Log message required'}), 400 | |
| try: | |
| # Parse RFC 5424 message | |
| parsed = parse_rfc5424_log(message) | |
| # Create log entry | |
| log_entry = SystemLog( | |
| facility=parsed['facility'], | |
| severity=parsed['severity'], | |
| version=parsed['version'], | |
| timestamp=parsed['timestamp'], | |
| hostname=parsed['hostname'], | |
| app_name=parsed['app_name'], | |
| proc_id=parsed['proc_id'], | |
| msg_id=parsed['msg_id'], | |
| structured_data=parsed['structured_data'], | |
| message=parsed['message'], | |
| user_id=int(get_jwt_identity()), | |
| source_ip=request.remote_addr, | |
| event_type='syslog_received' | |
| ) | |
| db.session.add(log_entry) | |
| db.session.commit() | |
| return jsonify({ | |
| 'message': 'Log message processed successfully' | |
| }) | |
| except Exception as e: | |
| log_event( | |
| severity=4, | |
| message=f"Failed to process syslog message: {str(e)}", | |
| event_type="syslog_error", | |
| user_id=int(get_jwt_identity()) | |
| ) | |
| return jsonify({'error': 'Failed to process log message'}), 500 | |
| except Exception as e: | |
| try: | |
| user_id = int(get_jwt_identity()) | |
| except: | |
| user_id = None | |
| log_event( | |
| severity=3, | |
| message=f"Syslog endpoint error: {str(e)}", | |
| event_type="syslog_endpoint_error", | |
| user_id=user_id | |
| ) | |
| return jsonify({'error': 'Internal server error'}), 500 | |
| def get_logs(): | |
| """Get system logs with filtering""" | |
| try: | |
| # Get query parameters | |
| page = int(request.args.get('page', 1)) | |
| per_page = min(int(request.args.get('per_page', 50)), 100) | |
| severity = request.args.get('severity') | |
| app_name = request.args.get('app_name') | |
| event_type = request.args.get('event_type') | |
| hostname = request.args.get('hostname') | |
| search = request.args.get('search') | |
| # Build query | |
| query = SystemLog.query | |
| # Get current user | |
| current_user = get_current_user_safe() | |
| # Filter by user_id unless user is admin | |
| if current_user: | |
| # Check if user is admin using consistent helper function | |
| is_admin = is_admin_user(current_user) | |
| if not is_admin: | |
| # Only show logs for this user | |
| query = query.filter(SystemLog.user_id == current_user.id) | |
| # Apply filters | |
| if severity is not None: | |
| query = query.filter(SystemLog.severity == int(severity)) | |
| if app_name: | |
| query = query.filter(SystemLog.app_name == app_name) | |
| if event_type: | |
| query = query.filter(SystemLog.event_type == event_type) | |
| if hostname: | |
| query = query.filter(SystemLog.hostname == hostname) | |
| if search: | |
| query = query.filter(SystemLog.message.contains(search)) | |
| # Order by timestamp descending | |
| query = query.order_by(SystemLog.timestamp.desc()) | |
| # Get paginated results | |
| pagination = query.paginate( | |
| page=page, | |
| per_page=per_page, | |
| error_out=False | |
| ) | |
| logs = [] | |
| for log in pagination.items: | |
| log_dict = log.to_dict() | |
| # Add username if user_id exists | |
| if log.user_id: | |
| from models import User | |
| user = User.query.get(log.user_id) | |
| log_dict["username"] = user.username if user else None | |
| else: | |
| log_dict["username"] = None | |
| logs.append(log_dict) | |
| return jsonify({ | |
| 'logs': logs, | |
| 'total': pagination.total, | |
| 'pages': pagination.pages, | |
| 'current_page': page, | |
| 'per_page': per_page | |
| }) | |
| except Exception as e: | |
| log_event( | |
| severity=3, | |
| message=f"Failed to get logs: {str(e)}", | |
| event_type="get_logs_error", | |
| user_id=get_current_user_safe().id if get_current_user_safe() else None | |
| ) | |
| return jsonify({'error': str(e)}), 500 | |
| def get_log_stats(): | |
| """Get log statistics""" | |
| try: | |
| # Get current user | |
| current_user = get_current_user_safe() | |
| # Base query | |
| base_query = SystemLog.query | |
| # Filter by user_id unless user is admin | |
| if current_user: | |
| # Check if user is admin using consistent helper function | |
| is_admin = is_admin_user(current_user) | |
| if not is_admin: | |
| # Only show logs for this user | |
| base_query = base_query.filter(SystemLog.user_id == current_user.id) | |
| # Get log counts by severity | |
| severity_stats = db.session.query( | |
| SystemLog.severity, | |
| db.func.count(SystemLog.id).label('count') | |
| ) | |
| # Apply user filter if not admin | |
| if current_user and not is_admin_user(current_user): | |
| severity_stats = severity_stats.filter(SystemLog.user_id == current_user.id) | |
| severity_stats = severity_stats.group_by(SystemLog.severity).all() | |
| # Get log counts by event type | |
| event_stats = db.session.query( | |
| SystemLog.event_type, | |
| db.func.count(SystemLog.id).label('count') | |
| ) | |
| # Apply user filter if not admin | |
| if current_user and not is_admin_user(current_user): | |
| event_stats = event_stats.filter(SystemLog.user_id == current_user.id) | |
| event_stats = event_stats.group_by(SystemLog.event_type).limit(10).all() | |
| # Get log counts by app name | |
| app_stats = db.session.query( | |
| SystemLog.app_name, | |
| db.func.count(SystemLog.id).label('count') | |
| ) | |
| # Apply user filter if not admin | |
| if current_user and not is_admin_user(current_user): | |
| app_stats = app_stats.filter(SystemLog.user_id == current_user.id) | |
| app_stats = app_stats.group_by(SystemLog.app_name).limit(10).all() | |
| # Total logs | |
| total_logs = base_query.count() | |
| return jsonify({ | |
| 'total_logs': total_logs, | |
| 'severity_stats': [{'severity': s[0], 'count': s[1]} for s in severity_stats], | |
| 'event_stats': [{'event_type': e[0], 'count': e[1]} for e in event_stats], | |
| 'app_stats': [{'app_name': a[0], 'count': a[1]} for a in app_stats] | |
| }) | |
| except Exception as e: | |
| log_event( | |
| severity=3, | |
| message=f"Failed to get log stats: {str(e)}", | |
| event_type="get_stats_error", | |
| user_id=get_current_user_safe().id if get_current_user_safe() else None | |
| ) | |
| return jsonify({'error': str(e)}), 500 | |
| def download_logs_csv(): | |
| """Download all filtered logs as CSV (ignores paging)""" | |
| try: | |
| severity = request.args.get('severity') | |
| app_name = request.args.get('app_name') | |
| event_type = request.args.get('event_type') | |
| hostname = request.args.get('hostname') | |
| search = request.args.get('search') | |
| query = SystemLog.query | |
| current_user = get_current_user_safe() | |
| if current_user: | |
| is_admin = is_admin_user(current_user) | |
| if not is_admin: | |
| query = query.filter(SystemLog.user_id == current_user.id) | |
| if severity is not None: | |
| query = query.filter(SystemLog.severity == int(severity)) | |
| if app_name: | |
| query = query.filter(SystemLog.app_name == app_name) | |
| if event_type: | |
| query = query.filter(SystemLog.event_type == event_type) | |
| if hostname: | |
| query = query.filter(SystemLog.hostname == hostname) | |
| if search: | |
| query = query.filter(SystemLog.message.contains(search)) | |
| logs = query.order_by(SystemLog.timestamp.desc()).all() | |
| # Prepare CSV | |
| output = csv.StringIO() if hasattr(csv, 'StringIO') else __import__('io').StringIO() | |
| writer = csv.writer(output) | |
| headers = [ | |
| 'Timestamp', 'Severity', 'Event Type', 'App Name', 'Hostname', 'Message', 'User', 'Source IP' | |
| ] | |
| writer.writerow(headers) | |
| for log in logs: | |
| username = None | |
| if log.user_id: | |
| user = User.query.get(log.user_id) | |
| username = user.username if user else None | |
| writer.writerow([ | |
| log.timestamp.isoformat() if log.timestamp else '', | |
| log.severity, | |
| log.event_type, | |
| log.app_name, | |
| log.hostname, | |
| log.message, | |
| username or '', | |
| log.source_ip or '' | |
| ]) | |
| output.seek(0) | |
| return Response( | |
| output.getvalue(), | |
| mimetype='text/csv', | |
| headers={ | |
| 'Content-Disposition': 'attachment; filename="logs.csv"' | |
| } | |
| ) | |
| except Exception as e: | |
| log_event( | |
| severity=3, | |
| message=f"Failed to download logs CSV: {str(e)}", | |
| event_type="download_logs_csv_error", | |
| user_id=get_current_user_safe().id if get_current_user_safe() else None | |
| ) | |
| return jsonify({'error': str(e)}), 500 |