Skynet 日志轮转实战:一个 SIGHUP 搞定切割
Skynet 日志轮转实战一个 SIGHUP 搞定切割【免费下载链接】skynetA lightweight online game framework项目地址: https://gitcode.com/GitHub_Trending/sk/skynetSkynet 游戏服半夜把 3GB 日志改名归档后磁盘占用纹丝不动新文件里一行日志都没有。服务没崩日志却失踪了。说白了进程还握着旧文件的句柄在写。Skynet 的日志轮转log rotation方案不复杂值得花两分钟看懂这条链路。一条 skynet.error 消息的旅程此处建议插入从 skynet_error.c 到 logger 服务的消息投递流程图Skynet 没让每个服务各自打开日志文件。任何服务调用skynet.errorC 层都会把消息投给一个名为 logger 的服务。投递逻辑在 skynet-src/skynet_error.c按名字查 handle然后 push 进它的消息队列。默认服务是 C 写的 logger代码在 service-src/service_logger.c。这条链路有两个直接好处。其一全服日志串行落盘不会出现两个服务写同一文件时错行的情况。其二写盘发生在 logger 自己的消息循环里业务服务发完消息立刻继续跑IO 不占游戏逻辑线程。轮转的钥匙是 SIGHUP不是配置项别急先别改配置。Skynet 没有内置 log_maxsize 一类的轮转参数。rotation轮转被拆成两步外部改名内部重开。启动时 skynet-src/skynet_start.c 注册了 SIGHUP 处理。收到信号后它给 logger 发一条 SYSTEM 消息logger_cb里对 PTYPE_SYSTEM 的分支会freopen同一个文件名以追加模式重开。所以切割动作长这样外部把旧文件改名再给进程发 HUPlogger 就在原路径新建文件继续写。全程不重启正在写的行也不丢。mv skynet.log skynet.log.$(date %F) kill -HUP $(cat skynet.pid)这两行就是 Skynet 日志切割的完整操作skynet.pid 来自配置里的 daemon 项。挂进 crontab 定时执行定时轮转就有了。此处建议插入rename 前后 ls -li 对比 inode 变化的终端截图端到端跑一遍先让日志落盘 动手前对照 examples/config 理解两个键。logger 是 C logger 的文件名参数不写或写 nil 就打印到 stdoutlogservice 指定用哪个服务当日志服务默认是 C 的 logger。thread 8 logger skynet.log start main cpath ./cservice/?.so luaservice ./service/?.lua -- …其余初始化逻辑省略这份最小配置让 Skynet 启动后把日志追加写进 skynet.log。对照 examples/config_log 会发现它是集群从节点配置logger nilC 层日志走 stdout业务日志另由 examples/main_log.lua 拉起的 examples/globallog.lua 集中处理。⚠️ 如果日志没出现在文件里别急。先确认 logger 没被写成 nil否则日志只能去 stdout 找。再确认 daemon 模式没有终端时 stdout 会直接蒸发必须显式给文件名。还有 harbor大于 1 的从节点有自己独立的 logger别只盯 master 节点的文件。单条 fflush 的账高并发下要不要换 Lua 日志服务service_logger.c 每写一行就fflush一次。好处是进程被 kill -9 时写完的行都在内核缓冲区里最多丢正在写的那行。坏处是每条日志一次系统调用。战斗场景日志量大时logger 队列的 backpressure队列反压会先在skynet.stat mqlen里露头。一个现成的替代模板是 examples/userlog.lua。它注册 text 协议自己处理日志方便你改成批量缓冲、按级别分流skynet.register_protocol { name text, id skynet.PTYPE_TEXT, unpack skynet.tostring, dispatch function(_, address, msg) print(string.format(:%08x(%.2f): %s, address, skynet.time(), msg)) end } -- …SYSTEM 信号处理与 skynet.start 省略把配置里的 logservice 指到这个服务名即可接管日志。以上示例代码仅供参考以仓库最新源码为准。临时排查问题时不用动 loggerlualib/skynet/debug.lua 里的 TRACELOG 调试命令可以对单个协议开 trace查完关掉生产环境少留一双手。上生产前先让测试机跑满 24 小时 轮转脚本上线前把三件事做完再谈稳定性。把 crontab 和 HUP 命令在测试机连跑一天确认 rename 后新文件立即出日志、旧文件完整。用 du -sh 记录每天的磁盘增量对照 logger 的 mqlen确认没有积压。关键操作日志单独打一个带前缀的文件归档时和访问日志分开。把这段配置贴进生产环境前先在测试机压 24 小时盯住磁盘占用和 mqlen 曲线再上。【免费下载链接】skynetA lightweight online game framework项目地址: https://gitcode.com/GitHub_Trending/sk/skynet创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
上一篇/下一篇内容由系统自动关联
返回资讯列表 →