Python实现带时间戳的YAML格式日志记录及Fallout自建服务器连接信息日志方案咨询
Python实现带时间戳的YAML格式日志记录及Fallout自建服务器连接信息日志方案咨询
现有基础代码
你当前用于创建YAML配置文件的Python代码如下:
import logging import os from pathlib import Path from pydantic import BaseModel, Field, field_validator # Configure logging logging.basicConfig(level=logging.INFO) log = logging.getLogger(__name__) # Get environment variable emvm = os.getenv("Backhole_environment", "").lower() class YamlFileModel(BaseModel): # Fixed class name object_path: Path = Field(..., description="Path to the YAML file") @field_validator('object_path', mode='before') def validate_object_path(cls, v): return Path(v).expanduser().resolve() if not isinstance(v, Path) else v.expanduser().resolve() @staticmethod def setup_yaml_path(): yaml_directory = os.path.dirname(os.path.abspath(__file__)) setting_dir = os.path.join(yaml_directory, 'settings') os.makedirs(setting_dir, exist_ok=True) filename = 'settings.yaml' yaml_settings_path = os.path.join(setting_dir, filename) if not os.path.exists(yaml_settings_path): log.error(f"YAML file not found at {yaml_settings_path}") with open(yaml_settings_path, 'w') as yaml_file: yaml_file.write("# Default YAML settings\n") if os.path.exists(yaml_settings_path) and os.path.getsize(yaml_settings_path) == 0: log.error(f"YAML file at {yaml_settings_path} is empty.") with open(yaml_settings_path, 'w') as yaml_file: yaml_file.write("default_key: default_value\n") if not os.access(yaml_settings_path, os.R_OK): log.error(f"YAML file at {yaml_settings_path} is not readable. Check file permissions.") # Call setup_yaml_path() correctly YamlFileModel.setup_yaml_path()
需求与问题说明
你希望基于这段代码,实现更清晰的YAML格式日志记录,核心目标是记录Fallout自建服务器的连接信息:包括谁连接了服务器、对应的IP、连接来源,同时还要记录错误日志。目前脚本仅能创建YAML文件,需要扩展功能来按照指定格式写入日志。
期望的YAML日志格式
你期望的日志/配置格式如下:
list connections [ server: host: addr: database: user: "admin" password: "securepass" name: "mydatabase" features: enableLogging: true enableDebug: false ]
解决方案与实现建议
1. 引入专业YAML处理库
首先安装pyyaml库(执行pip install pyyaml),它能帮我们规范读写YAML结构,避免手动拼接文本导致的格式错误。
2. 扩展YamlFileModel,添加日志写入方法
修改原类,新增方法来处理连接信息的结构化追加,同时加入时间戳等关键元数据:
import yaml from datetime import datetime # 在YamlFileModel类中添加以下静态方法 @staticmethod def log_connection_info(connection_data): # 获取配置文件路径 yaml_directory = os.path.dirname(os.path.abspath(__file__)) setting_dir = os.path.join(yaml_directory, 'settings') yaml_settings_path = os.path.join(setting_dir, 'settings.yaml') # 读取现有YAML内容(处理空文件或解析错误) with open(yaml_settings_path, 'r') as f: try: yaml_content = yaml.safe_load(f) or {} except yaml.YAMLError as e: log.error(f"Failed to parse YAML file: {e}") yaml_content = {} # 初始化connections列表(不存在则创建) if 'connections' not in yaml_content: yaml_content['connections'] = [] # 构造带时间戳的连接记录 connection_entry = { 'timestamp': datetime.now().isoformat(), 'server': { 'host': connection_data.get('server_host'), 'addr': connection_data.get('server_addr') }, 'player': { 'name': connection_data.get('player_name'), 'ip': connection_data.get('player_ip'), 'location': connection_data.get('player_location') # 可通过IP地理库补充 }, 'status': 'connected' # 可扩展为disconnected、failed等状态 } yaml_content['connections'].append(connection_entry) # 写回YAML文件,保留原格式结构 with open(yaml_settings_path, 'w') as f: yaml.dump(yaml_content, f, sort_keys=False, indent=2) log.info(f"Successfully logged connection for {connection_data.get('player_name')}")
3. 调用日志方法记录连接事件
当你的Fallout服务器检测到新连接时,传入玩家和服务器数据即可:
# 示例:模拟玩家连接数据 new_connection = { 'server_host': 'fallout-vault-76', 'server_addr': '192.168.1.50:27015', 'player_name': 'VaultDweller_42', 'player_ip': '203.0.113.78', 'player_location': 'Capital Wasteland' } YamlFileModel.log_connection_info(new_connection)
4. 错误日志的结构化记录
同样可以扩展方法来记录连接失败等错误:
@staticmethod def log_error(error_data): yaml_directory = os.path.dirname(os.path.abspath(__file__)) setting_dir = os.path.join(yaml_directory, 'settings') yaml_settings_path = os.path.join(setting_dir, 'settings.yaml') with open(yaml_settings_path, 'r') as f: yaml_content = yaml.safe_load(f) or {} if 'errors' not in yaml_content: yaml_content['errors'] = [] error_entry = { 'timestamp': datetime.now().isoformat(), 'error_type': error_data.get('type'), 'message': error_data.get('message'), 'context': error_data.get('context') # 比如失败的玩家IP、服务器状态 } yaml_content['errors'].append(error_entry) with open(yaml_settings_path, 'w') as f: yaml.dump(yaml_content, f, sort_keys=False, indent=2)
Fallout自建服务器日志小贴士
- 捕获服务器事件:多数Fallout自定义服务端会提供事件钩子(比如
PlayerConnected、PlayerDisconnected),通过监听这些钩子可以实时获取连接数据。 - 补充IP地理位置:可以集成
geoip2库(配合MaxMind免费数据库),解析玩家IP对应的真实地理位置,让日志更丰富。 - 日志轮转策略:长期运行的服务器会让YAML文件越来越大,建议定期归档旧日志,或者结合
logging模块的RotatingFileHandler实现自动轮转。 - 权限与性能:确保运行服务器的用户对settings目录有读写权限;如果服务器并发高,可考虑用队列异步写入日志,避免阻塞主线程。
备注:内容来源于stack exchange,提问作者Cthulhu's Rage
相关产品推荐
相关产品推荐

