本文目录导读:

我来详细介绍Python操作数据库审计日志的方法。
MySQL审计日志
开启MySQL审计日志
-- 安装审计插件 INSTALL PLUGIN audit_log SONAME 'audit_log.so'; -- 开启审计日志 SET GLOBAL audit_log_policy = 'ALL'; SET GLOBAL audit_log_format = 'JSON';
Python读取MySQL审计日志
import json
import re
from datetime import datetime
import mysql.connector
from pathlib import Path
class MySQLAuditLogReader:
def __init__(self, log_path="/var/log/mysql/audit.log"):
self.log_path = Path(log_path)
def parse_audit_log(self):
"""解析MySQL审计日志"""
audit_entries = []
with open(self.log_path, 'r') as f:
for line in f:
try:
entry = json.loads(line.strip())
# 提取关键审计信息
audit_info = {
'timestamp': entry.get('time', ''),
'user': entry.get('user', ''),
'host': entry.get('host', ''),
'query': entry.get('query', ''),
'status': entry.get('status', ''),
'rows_examined': entry.get('rows_examined', 0),
'thread_id': entry.get('thread_id', '')
}
audit_entries.append(audit_info)
except json.JSONDecodeError:
continue
return audit_entries
def filter_by_user(self, entries, username):
"""按用户筛选审计日志"""
return [e for e in entries if e['user'] == username]
def filter_by_time_range(self, entries, start_time, end_time):
"""按时间范围筛选"""
filtered = []
for entry in entries:
try:
entry_time = datetime.strptime(
entry['timestamp'],
'%Y-%m-%d %H:%M:%S'
)
if start_time <= entry_time <= end_time:
filtered.append(entry)
except ValueError:
continue
return filtered
# 使用示例
reader = MySQLAuditLogReader()
all_logs = reader.parse_audit_log()
# 查询特定用户的日志
user_logs = reader.filter_by_user(all_logs, 'admin')
# 查询时间范围内的日志
from datetime import datetime, timedelta
now = datetime.now()
start = now - timedelta(hours=1)
recent_logs = reader.filter_by_time_range(all_logs, start, now)
PostgreSQL审计日志
配置PostgreSQL审计
-- 修改postgresql.conf log_destination = 'csvlog' logging_collector = on log_statement = 'all' log_line_prefix = '%t %u %d %p %r '
Python读取PostgreSQL审计日志
import csv
from datetime import datetime
import psycopg2
from pathlib import Path
class PostgreSQLAuditLogReader:
def __init__(self, log_directory="/var/log/postgresql"):
self.log_directory = Path(log_directory)
def parse_csv_logs(self, log_file):
"""解析PostgreSQL CSV格式审计日志"""
audit_entries = []
with open(log_file, 'r') as f:
reader = csv.reader(f)
for row in reader:
if len(row) >= 12:
entry = {
'timestamp': row[0],
'user': row[3],
'database': row[4],
'process_id': row[5],
'remote_host': row[7],
'session_id': row[8],
'command_tag': row[10],
'statement': row[11],
'error_severity': row[9] if len(row) > 12 else ''
}
audit_entries.append(entry)
return audit_entries
def detect_anomalies(self, entries):
"""检测异常操作"""
anomalies = []
for entry in entries:
statement = entry.get('statement', '').upper()
# 检测敏感操作
if any(keyword in statement for keyword in [
'DROP', 'TRUNCATE', 'DELETE', 'ALTER SYSTEM'
]):
anomalies.append({
'type': 'dangerous_operation',
'entry': entry
})
# 检测批量删除
if 'DELETE' in statement and 'WHERE' not in statement:
anomalies.append({
'type': 'mass_deletion',
'entry': entry
})
return anomalies
# 使用示例
pg_reader = PostgreSQLAuditLogReader()
logs = pg_reader.parse_csv_logs('/var/log/postgresql/postgresql-2023-01-01.csv')
anomalies = pg_reader.detect_anomalies(logs)
print(f"发现 {len(anomalies)} 个异常操作")
使用PyAudit进行通用审计
import pyaudit
import logging
from datetime import datetime
class DatabaseAuditor:
"""数据库审计管理器"""
def __init__(self, db_config):
self.db_config = db_config
self.setup_audit_logging()
def setup_audit_logging(self):
"""设置审计日志系统"""
# 创建审计日志记录器
self.audit_logger = logging.getLogger('database_audit')
self.audit_logger.setLevel(logging.INFO)
# 文件处理器
file_handler = logging.FileHandler(
f'audit_{datetime.now().strftime("%Y%m%d")}.log'
)
file_handler.setLevel(logging.INFO)
# 格式化
formatter = logging.Formatter(
'%(asctime)s - %(levelname)s - %(message)s'
)
file_handler.setFormatter(formatter)
self.audit_logger.addHandler(file_handler)
def log_query_audit(self, user, query, status="success"):
"""记录查询审计"""
audit_entry = {
'timestamp': datetime.now().isoformat(),
'user': user,
'query': query,
'status': status,
'ip': self.get_client_ip()
}
self.audit_logger.info(json.dumps(audit_entry))
def get_client_ip(self):
"""获取客户端IP"""
# 实际实现会根据数据库连接信息获取
return "192.168.1.100"
def query_audit_logs(self, start_date=None, end_date=None):
"""查询审计日志"""
logs = []
log_file = f'audit_{datetime.now().strftime("%Y%m%d")}.log'
try:
with open(log_file, 'r') as f:
for line in f:
log_entry = json.loads(
line.split(' - ')[-1].strip()
)
if start_date and end_date:
log_time = datetime.fromisoformat(
log_entry['timestamp']
)
if start_date <= log_time <= end_date:
logs.append(log_entry)
else:
logs.append(log_entry)
except FileNotFoundError:
pass
return logs
# 使用示例
auditor = DatabaseAuditor({
'host': 'localhost',
'port': 3306,
'user': 'admin',
'password': 'password'
})
# 记录审计
auditor.log_query_audit(
user='john_doe',
query='SELECT * FROM users WHERE id = 1'
)
# 查询审计日志
recent_logs = auditor.query_audit_logs(
start_date=datetime.now().replace(hour=0, minute=0, second=0)
)
实时审计监控系统
import asyncio
import asyncpg
from watchdog.observers import Observer
from watchdog.events import FileSystemEventHandler
import time
class RealTimeAuditSystem:
"""实时审计监控系统"""
def __init__(self, log_path, db_config):
self.log_path = log_path
self.db_config = db_config
self.observers = []
async def start_monitoring(self):
"""开始实时监控"""
# 设置文件监控
event_handler = AuditLogHandler(self.process_audit_entry)
observer = Observer()
observer.schedule(event_handler, self.log_path, recursive=False)
observer.start()
# 启动异步处理
await self.process_audit_queue()
async def process_audit_entry(self, entry):
"""处理审计条目"""
async with asyncpg.create_pool(**self.db_config) as pool:
async with pool.acquire() as conn:
await conn.execute(
"""
INSERT INTO audit_logs
(timestamp, user, query, status)
VALUES ($1, $2, $3, $4)
""",
entry['timestamp'],
entry['user'],
entry['query'],
entry['status']
)
async def process_audit_queue(self):
"""处理审计队列"""
queue = asyncio.Queue()
while True:
if not queue.empty():
entry = await queue.get()
await self.process_audit_entry(entry)
await asyncio.sleep(0.1)
class AuditLogHandler(FileSystemEventHandler):
"""审计日志文件事件处理器"""
def __init__(self, callback):
self.callback = callback
self.last_position = 0
def on_modified(self, event):
if event.src_path.endswith('.log'):
self.process_new_entries(event.src_path)
def process_new_entries(self, file_path):
"""处理新写入的日志条目"""
with open(file_path, 'r') as f:
f.seek(self.last_position)
new_lines = f.readlines()
self.last_position = f.tell()
for line in new_lines:
try:
entry = json.loads(line.strip())
self.callback(entry)
except json.JSONDecodeError:
continue
审计日志分析工具
import pandas as pd
import matplotlib.pyplot as plt
from collections import Counter
import re
class AuditLogAnalyzer:
"""审计日志分析器"""
def __init__(self, logs):
self.logs = logs
self.df = pd.DataFrame(logs)
def analyze_user_activity(self):
"""分析用户活动"""
user_activity = self.df['user'].value_counts()
print("\n用户活动统计:")
print("-" * 30)
for user, count in user_activity.items():
print(f"{user}: {count} 次操作")
# 可视化
plt.figure(figsize=(10, 6))
user_activity.plot(kind='bar')
plt.title('用户操作频率统计')
plt.xlabel('用户')
plt.ylabel('操作次数')
plt.xticks(rotation=45)
plt.tight_layout()
plt.savefig('user_activity.png')
def analyze_query_types(self):
"""分析查询类型"""
query_types = Counter()
for log in self.logs:
query = log.get('query', '').upper().strip()
if query.startswith('SELECT'):
query_types['SELECT'] += 1
elif query.startswith('INSERT'):
query_types['INSERT'] += 1
elif query.startswith('UPDATE'):
query_types['UPDATE'] += 1
elif query.startswith('DELETE'):
query_types['DELETE'] += 1
elif query.startswith('DROP'):
query_types['DROP'] += 1
else:
query_types['OTHER'] += 1
print("\n查询类型分布:")
print("-" * 30)
for qtype, count in query_types.most_common():
percentage = (count / len(self.logs)) * 100
print(f"{qtype}: {count} ({percentage:.1f}%)")
# 饼图
plt.figure(figsize=(8, 8))
plt.pie(query_types.values(),
labels=query_types.keys(),
autopct='%1.1f%%')
plt.title('查询类型分布')
plt.savefig('query_types.png')
def detect_security_risks(self):
"""检测安全风险"""
risks = []
for log in self.logs:
query = log.get('query', '').upper()
# SQL注入尝试检测
if re.search(r"'.*OR.*1.*=.*1|--|;.*DROP", query):
risks.append({
'type': 'sql_injection',
'user': log.get('user'),
'time': log.get('timestamp'),
'query': log.get('query')
})
# 敏感数据访问检测
sensitive_tables = ['password', 'credit_card', 'ssn', 'secret']
for table in sensitive_tables:
if table.upper() in query:
risks.append({
'type': 'sensitive_data_access',
'user': log.get('user'),
'time': log.get('timestamp'),
'table': table,
'query': log.get('query')
})
return risks
# 使用示例
analyzer = AuditLogAnalyzer(all_logs)
analyzer.analyze_user_activity()
analyzer.analyze_query_types()
risks = analyzer.detect_security_risks()
print(f"发现 {len(risks)} 个安全问题")
这些方法涵盖了:
- 读取不同数据库的审计日志
- 解析和分析审计数据
- 实时监控审计事件
- 异常检测和报警
- 可视化和报表生成
根据你的具体需求选择合适的方案。
版权声明:NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
足球直播
足球直播
足球直播
篮球直播
篮球直播
篮球直播
NBA直播
NBA直播
NBA直播
CBA直播
CBA直播
CBA直播
亚冠直播
亚冠直播
亚冠直播
欧冠直播
欧冠直播
欧冠直播
英超直播
英超直播
英超直播
西甲直播
西甲直播
西甲直播
中超直播
中超直播
中超直播
足球直播
足球直播
足球直播
篮球直播
篮球直播
篮球直播
NBA直播
NBA直播
NBA直播
CBA直播
CBA直播
CBA直播
亚冠直播
亚冠直播
亚冠直播
欧冠直播
欧冠直播
欧冠直播
英超直播
英超直播
英超直播
西甲直播
西甲直播
西甲直播
中超直播
中超直播
中超直播
足球直播
足球直播
足球直播
篮球直播
篮球直播
篮球直播
NBA直播
NBA直播
NBA直播
CBA直播
CBA直播
CBA直播
亚冠直播
亚冠直播
亚冠直播
欧冠直播
欧冠直播
欧冠直播
英超直播
英超直播
英超直播
西甲直播
西甲直播
西甲直播
中超直播
中超直播
中超直播
足球直播
足球直播
足球直播
篮球直播
篮球直播
篮球直播
NBA直播
NBA直播
NBA直播
CBA直播
CBA直播
CBA直播
亚冠直播
亚冠直播
亚冠直播
欧冠直播
欧冠直播
欧冠直播
英超直播
英超直播
英超直播
西甲直播
西甲直播
西甲直播
中超直播
中超直播
中超直播
曼联直播
曼联直播
曼联直播
日职联直播
日职联直播
日职联直播
澳超直播
澳超直播
澳超直播
阿森纳直播
阿森纳直播
阿森纳直播
足球直播
足球直播
足球直播
NBA直播
NBA直播
NBA直播
曼联直播
曼联直播
曼联直播
日职联直播
日职联直播
日职联直播
澳超直播
澳超直播
澳超直播
阿森纳直播
阿森纳直播
阿森纳直播
足球直播
足球直播
足球直播
NBA直播
NBA直播
NBA直播
曼联直播
曼联直播
曼联直播
日职联直播
日职联直播
日职联直播
澳超直播
澳超直播
澳超直播
阿森纳直播
阿森纳直播
阿森纳直播
足球直播
足球直播
足球直播
NBA直播
NBA直播
NBA直播
曼联直播
曼联直播
曼联直播
日职联直播
日职联直播
日职联直播
澳超直播
澳超直播
澳超直播
阿森纳直播
阿森纳直播
阿森纳直播
足球直播
足球直播
足球直播
NBA直播
NBA直播
NBA直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
足球直播
足球直播
足球直播
足球直播
足球直播
英超直播
英超直播
英超直播
英超直播
英超直播
篮球直播
篮球直播
篮球直播
篮球直播
篮球直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
中超直播
中超直播
中超直播
中超直播
中超直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
足球直播
足球直播
足球直播
足球直播
足球直播
英超直播
英超直播
英超直播
英超直播
英超直播
篮球直播
篮球直播
篮球直播
篮球直播
篮球直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
中超直播
中超直播
中超直播
中超直播
中超直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播