一、For Beginner

日志系统主要是一组记录引擎底层及应用逻辑层系统状态变化过程的接口。几乎所有的游戏服务器框架都会有一组操作日志的接口,当然最简单的就是大家所熟悉的printf格式化到标准输出,日志系统的复杂度有高有低,具体目的主要是为调试及运营数据查询需要。可以说日志系统实现是否易用、简洁,将直接影响到开发及运营效率。

二、文件VS数据库

是写文件还是写数据库,这是一个问题。数据库的优势是查询/统计/排序很方便,一旦建立好所有的日志表及其操作以后,后期运营会比较舒服,可以轻松应对策划无休止的BT日志统计需求。但为每个日志建立数据库的表项及其索引是需要有很强前瞻性的,对程序员的经验要求较高,大数据量的数据库数据库表项及其索引的变更所需要的时间比较长, 而日志本身的内容变更应随需而变,这是一个矛盾。写文件的最大好处是简单,方便人工阅读,文件更容易做备份,备份的拆分与合并也更容易,即使要查找若干年以前的数据也不需要很复杂的恢复过程。但文件的数据搜集与统计的成本是很高的,往往不能适应策划的快速响应需求,后期在运营上面支撑不足。 现在很多项目也逐步采用文件与数据库相结合的方式,日志首先写到文件中,然后根据日常统计收集需要将指定的日志定时增量load到数据库中,然后对数据库进行查询,这无疑结合了两种载体的优势,值得尝试。

三、日志文件格式建议

日志文件应该采用文本格式,这是unix工具集的标准格式,任何尝试自定义日志格式的行为都将付出代价--你将不得不为自己写一堆的配套工具,服务器磁盘容量及IO消耗并没紧要到如此这般的程度。
通常每一条日志可以概括为: [datetime]log desc:key1=value1,key2=value2,key3=value3...,无论如何选定日志的格式,有一个基本的前提就是,项目内必须保持严格一致,可以在debug模式下对日志的输入信息进行正则匹配,如果不满足需要就报错。日志格式的统一,为项目后期运营工具的单一化带来了可能,如果每个系统都是按照自己的格式任意书写日志,那么所有的日志扫描工具都差不多要自己重写,模块的可重用性大大降低,这实在是很令人恼怒的事情,我们不应该把时间浪费到这样的事情上面。
建议设置单条日志长度上限,这主要是为方便人工阅读,设置为80的可能性很小,废话稍微多一点就超过了,一般设置为256,大概主流显示器在终端上面字体合理的情况下可以显示完一行。
单行日志记录完整事件,切忌换行,以交易系统为例,应该在一行里面把交易双方的个人信息/物品/金钱信息一起记录下来,如果换行的话,后期扫描日志的工具会相当难写。

四、日志分级

多数日志都是废话,特别是当系统一切正常的时候,你可能会关闭掉许多输出速度很快又没啥价值的日志...但关键时候你可能又需要启用这些日志。如果在日志系统设计之初就提供日志的分级策略,将为这种需求提供便利。 日志分级可以做两种设计,一种是静态的即编译期决定的,比如设置一个LOG_LEVEL的宏,所有小于等于此级别的日志都将被输出。 另外也可以作为服务器的启动参数, 比如-D 3,这跟apache配置文件的LogLevel比较类似,一般地,当系统收到SIGHUP信号的时候,可以重设一次LogLevel,这样就可以实时的在生产环境中改变日志分级。常见的日志分级层次有

LOG_EMERG 7
system is unusable
LOG_ALERT  6
action must be taken immediately
LOG_CRIT  5
critical conditions
LOG_ERR 4
error conditions
LOG_WARNING 3
warning conditions
LOG_NOTICE 2
normal, but significant, condition
LOG_INFO 1
informational message
LOG_DEBUG  0
debug-level message

当然实际游戏环境中可能并不需要这么多的级别,一般情况下缩减一半都足够了。实际项目中,写游戏逻辑的程序员对日志分级是非常不感冒,反正只要IO还支撑得了,谁又愿意花那么一点点时间定义一下自己的日志Level呢?

五、基于文件日志系统实现细节

基于本地文件的日志系统几乎都要面对一个问题,写日志是用buffered io(fopen/fwrite/fclose) 还是系统调用unbuffered io(open/write/close),如果你的日志系统会缓存文件操作的handler,并且测试表明日志系统占用了不小的开销,那么你可以选用buffered io,否则还是使用unbuffered io会比较靠谱。在系统异常退出的情况下,丢失日志的可能性小非常多。
在日志大量重复写同一组文件的情况下,我们很容易想到把日志文件handler缓存起来,通常的做法是做一个日志的class。这个方法看似完美,节省了大量的open/close操作,经过笔者的反复测试,在写小数据量(24-48字节)的情况下,cpu消耗几乎减少一半左右。但考虑到实际服务器生产环境会定期move/tar日志文件,而日志class得不到任何通知,这会导致将日志写到并不期望的地方,甚至丢失日志。当然我们可以建立一种通知机制,让系统管理员的shell运行的时候顺带通过signal通知一下服务器进程,然后进程内显式的reload所有的日志对象。甚至,我们还可以用一种更优雅一点的做法,使用系统kernel提供的inotify机制去监控这些日志文件,当他们发生改变时候reload对应的日志文件。 但wait...这真的有此必要么? 过早的优化是魔鬼,还是让你的系统统计数据来说话吧!
日志系统是同步写还是异步写? 相信经历过游戏运营的同学都不会陌生以下场景,某日深夜,运维同学急电:“服务器卡机啦,卡得不得了啊,走三步退一步,赶紧上线看看吧”,结果上去一看,每日文件全备份,IO卡到死,游戏中所有的IO操作都阻塞了,不卡才怪呢...这就是同步io读写的悲剧场景。基本上应该说,游戏服务器的所有操作都不应该是同步阻塞的(关于sync,block,unblock,async的话题另外再说吧),除了内存以外我们不能假想任何设备的速度是足够的快的,这是一个基本前提。否则,游戏服务器莫名的卡机那是早迟的事情。对于异步IO读写来说,有两个可选方案,一个是叫做非阻塞读写/带阻塞通知的异步io模型比如,epoll/kq/select/poll等等,但似乎悲剧的是在linux下面epoll并不支持文件的异步读写,另外一个就是真正的正宗的async io - AIO,关于AIO的资料网络上面已经相当丰富了,使用起来也非常简单。重点是AIO跟libevent的结合还不是特别好,需要做一定工作,并且忍受一下在多个AIO并发时的性能损失,但无论如何都不要尝试直接操纵AIO的signal或者thread callback func,除非你觉得你以及你的团队可以写出漂亮的“信号可重入函数”以及“线程安全的函数”。 
日志系统写本地还是写远程? 为了实现简洁及运营方便,对于单服结构的游戏服务器都应该写本地日志,但对于多服结构的则最好是固定写到一个物理服务器上面,否则日志的收集/合并/排序是个抓狂的工作。

*unix syslog

相信有很多人考虑过syslog作为日志系统的底层框架,我目前对这部分了解有限。有时间了再补课

六、其他

呃,部分新手有时候会犯傻,当日志系统出错以后想要log下来,结果却习惯性的使用了自己定义的日志函数,于是...悲剧了。

网络游戏服务器之 日志系统相关推荐

  1. notes服务器日志文件,邮件服务器之日志分析(五)

    ### 邮件服务器(mail.unotes.co)收到 test01\@unotes.co 发送给 test.redhat\@gmail.com 邮件的日志 ```bash $ tail -f /va ...

  2. 阿里云自动java和mysql数据库_阿里云服务器之基于Linux系统部署上线JavaWeb项目和连接MySQL数据库(从购买云服务器到发布JavaWeb项目全套详细流程)...

    阿里云服务器之基于Linux系统部署上线JavaWeb项目和连接MySQL数据库(从购买云服务器到发布JavaWeb项目全套详细流程) (仅此纪念人生第一篇学习博客) 前阵子接了一个小小的JavaWe ...

  3. 创业公司 互联网架构方案 整体技术栈 基础设施 数据库 服务治理 消息中间件 日志系统 ELK 自动化部署

    欢迎关注博主公众号:[矿洞程序员]文章由陈晓阳原创. 本人微信:chenxiaoyangzxy. 免费提供本人大量学习资料. 从零开始搭建创业公司后台技术栈 原创: 潘锦 说到后台技术栈,脑海中是不是 ...

  4. python2.7.3怎么安装_Linux系统如何编译安装python 2.7.3 - Python - 服务器之家

    Linux系统如何编译安装python 2.7.3 发布时间:2014-04-14 来源:服务器之家 下载了linux版的python 2.7.3的安装包,解压缩,./configure make和m ...

  5. 重装xshell的系统_xshell恢复默认设置 如何还原系统 - Linux - 服务器之家

    xshell恢复默认设置 如何还原系统 发布时间:2017-05-24 来源:服务器之家 电脑在使用过程中可能会遇到各种各样的问题,当我们询问这些问题的解决办法时候相信得到的答案很多都是还原系统,其实 ...

  6. Linux日志系统_syslog服务详解

    Linux日志系统_syslog服务详解 参考链接:https://blog.csdn.net/weixin_42569329/article/details/116609984 一台服务器的日志对系 ...

  7. shell 调用securecrt_securecrt导入xshell 解决xshell、SecureCRT中文乱码 - Linux - 服务器之家...

    securecrt导入xshell 解决xshell.SecureCRT中文乱码 发布时间:2017-04-14 来源:服务器之家 一.解决xshell 中文乱码 在xshell命令行里面 输入: l ...

  8. java 连接OPC服务器之 utgard 连接 KepServer

    java 连接OPC服务器之 utgard 连接 KepServer 我要做一个java开发的项目, 这个在网上很少案例, 大家基本都是做web开发的, 我其实之前也是.但是现在有这个需求, 就干了. ...

  9. linux 任务计划 权限设置,Linux系统 文件权限+计划任务+日志系统

    实验目的:熟练掌握权限相关概念和具体操作 实验环境:Red Hat Enterprise Linux Server 5.3 实验步骤: 一.文件权限 二.计划任务 三.日志 一.文件权限 (一)基本权 ...

最新文章

  1. 博问问题内容页面的前端优化
  2. linux玩我的世界java版_Linux下安装我的世界(Minecraft)
  3. 进阶第四课 Python模块之os
  4. ActionForm类及表单数据验证
  5. 站在巨人肩膀上的意思就是拒绝重复造轮子,分享12个常见的js插件
  6. 基于xilinx vivado的XDMA IP的使用详解
  7. 使用Java EE 7,WildFly和Docker进行连续部署–(第1部分)
  8. Eclipse如何新建TOMCAT并配置Server Locations和Publishing属性
  9. c语言字符马图案,C语言实现马踏棋盘
  10. linux ip地址本地缓存,ip-address – 如何解析组织的IP地址(使用缓存)
  11. servlet3异步 例子_异步Servlet示例
  12. [LeetCode]Trapping Rain Water
  13. 小米首页html代码,小米首页小功能案例.html
  14. 申请被拒模板 (三)
  15. 永远无法实现的“诚实“
  16. 国产哈希算法WJLHA(六):自定义哈希长度的WJLHA3开源(JAVASCRIPT)
  17. (附源码)springboot菠萝大学课室预约系统分析与设 毕业设计 641656
  18. calloc()函数
  19. Bugku-web-秋名山老司机
  20. html5中的td tr,html5 表格标签 table tr td

热门文章

  1. 20135323符运锦期中总结----Linux系统的理解及学习心得
  2. 【题解】P1979 [NOIP2013 提高组] 华容道(SPFA,BFS,常数优化)
  3. RCEP正式生效,对东南亚的跨境电商将带来哪些影响?
  4. 采购关税及税相关配置
  5. OpenGL 游戏开发: 熟悉练习【《OpenGL超级宝典》第二章】
  6. 一份大厂出来的创业公司cto的创业心得
  7. 【系统分析师之路】系统分析师必知必会(需求分析篇)
  8. 关于springmvc项目一加入validation-api包就报错的解决方法
  9. git lfs的安装和使用
  10. raid卷构建实操(raid0、raid1、raid5、raid6以及raid10),可跟做