You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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自建服务器日志小贴士

  1. 捕获服务器事件:多数Fallout自定义服务端会提供事件钩子(比如PlayerConnected、PlayerDisconnected),通过监听这些钩子可以实时获取连接数据。
  2. 补充IP地理位置:可以集成geoip2库(配合MaxMind免费数据库),解析玩家IP对应的真实地理位置,让日志更丰富。
  3. 日志轮转策略:长期运行的服务器会让YAML文件越来越大,建议定期归档旧日志,或者结合logging模块的RotatingFileHandler实现自动轮转。
  4. 权限与性能:确保运行服务器的用户对settings目录有读写权限;如果服务器并发高,可考虑用队列异步写入日志,避免阻塞主线程。

备注:内容来源于stack exchange,提问作者Cthulhu's Rage

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.04.13 19:39:29