系列文章:
- 游戏日志分析(1):概览
- 游戏日志分析(2):全方位数据采集
- 游戏日志分析(3):程序日志规范与埋点
- 游戏日志分析(4):线上问题定位与排查
- 游戏日志分析(5):数据库与日志关联分析
- 游戏日志分析(6):CDN/对象存储日志分析
- 游戏日志分析(7):网络日志查询与分析
- 游戏日志分析(8):数据库日志分析
- 游戏日志分析(9):安全日志分析
- 游戏日志分析(10):数据可视化与报表
- 游戏日志分析(11):数仓建设
- 游戏日志分析(12):实时数据处理与流计算
前言
在上一篇文章中,我们介绍了日志数据对游戏的重要性,这一篇我们来讨论下如何高效地实施全方位无死角的日志采集。
游戏日志数据
日志来源
游戏日志数据有很多的来源,例如:
- 在推广期,我们需要采集广告流量和点击的数据,以确定新用户转化率
- 在用户端,如果是手游,我们需要采集移动端Android、IOS上游戏运行及操作日志
- 如果是页游,除了服务端日志之外,静态页面JS对我们也很重要
- 如果是客户端游戏,需要跨平台采集客户端运行数据
- 服务端各模块打点记录,包括请求、用户操作
日志分类
以上这些也只是部分而已,在阿里集团和支撑业务中,涉及到采集的日志如下:
- 程序日志
- 中间件日志
- 前端服务器日志
- Tomcat等日志
-
主机日志
- syslog
- var/log/message
- H5页面日志
- 云产品日志:云服务商提供的日志数据
-
移动端埋点日志
- IOS 日志
- Android 日志
- WAP 页面
-
数据库日志
- Binlog
- Slow Log
- SQL Log
-
硬件设备
- X86
- ARMS
- RTOS
日志采集的作用就是把这些分布在全球各地域,多个渠道和终端,异构网络的数据统一,以适应后期各种角色(研发、运维、客服、运营、产品、总监等)对数据处理的各种需求。
数据采集方法
1. 硬件设备日志采集
随着VR游戏的流行,一部分业务会使用嵌入式设备,例如传感器、摄像头、交互大屏等。这类设备一般会有如下特点:
- 硬件架构、系统类型多样,例如ARM、X86、PPC等硬件架构,Linux、RTOS、嵌入式Windows等系统
- 设备端资源紧张,可分配给日志采集的资源较少
- 全球化部署,设备部署具有全球化、边缘化特点
日志服务提供C Producer系列日志库,用于采集各种硬件设备的日志。优势如下: - 客户端高并发写入:可配置的发送线程池,支持每秒数十万条日志写入,详情参见性能测试。
- 低资源消耗:每秒20W日志写入只消耗70% CPU;同时在低性能硬件(例如树莓派)上,每秒产生100条日志对资源基本无影响。详情参见性能测试。
- 客户端日志不落盘:既数据产生后直接通过网络发往服务端。
- 客户端计算与 I/O 逻辑分离:日志异步输出,不阻塞工作线程。
- 支持多优先级:不通客户端可配置不同的优先级,保证高优先级日志最先发送。
- 本地调试:支持设置本地调试,便于您在网络不通的情况下本地测试应用程序。
- 全球化动态加速:利用阿里云全球化部署能力和静态带宽资源,为全球部署的设备进行采集加速。
根据不同设备类型以及资源限制,我们推荐使用以下方式进行日志采集:
- C Producer : 适用于C++游戏服务器、路由器/交换机、平板类设备采集,占用资源1MB左右。
- C Producer Lite : 适用于智能设备(例如智能音箱、摄像头等)日志采集,占用资源80KB左右。
- C Producer Bricks : 适用于IOT设备(例如传感器、RTOS设备等)日志采集,占用资源8KB左右。
2. 移动端日志采集
在移动互联网时代,手游已经成为游戏中最热点的类目,对于手游APP的日志采集场景,我们希望将APP的日志直接上传到日志服务中,而不需要通过APP服务端中转,这样用户就能专注在自己的业务逻辑开发。
普通模式下,日志写入日志服务需要开启主账号的访问秘钥,用于鉴权以及防篡改。移动APP如果通过此模式接入日志服务,需要将您的AK信息保存在移动端,存在AK泄漏的数据安全风险。一旦发生AK泄漏,需要升级移动APP,并替换AK,代价太大。另一种移动端日志接入日志服务的方式为通过用户服务器中转,但是该种模式下,如果移动APP数量较大,用户的应用服务器需要承载所有的移动端数据,对服务器的规模有较高的要求。
为了避免以上问题,日志服务为您提供能更安全、更便捷的移动APP日志数据采集方案,即通过RAM搭建一个基于移动服务的移动应用数据直传服务。相较于直接使用AK访问日志服务,用户不需要在APP端保存AK,不存在AK泄露的风险。使用临时Token访问,更加安全,Token有生命周期,并且可以针对Token定制更加复杂的权限控制,比如限制IP段的访问权限等。成本低,用户不需要准备很多服务器,移动应用直联云平台,只有控制流走用户自己的应用服务器。
手游日志直传服务搭建可参考:搭建移动端日志直传服务。该方案可搭配以下SDK进行接入:
- 移动端:可以使用移动端 SDK IOS, Android 接入。
- ARM 设备:ARM 平台可以使用 Native C 交叉编译。
- 商家平台设备:X86 平台设备可以用 SDK、ARM 平台可以使用 Native C 交叉编译。
3. H5静态页面采集
页面用户行为收集可以分为两类:
- 页面与后台服务器交互:例如下单,登陆、退出等。
- 页面无后台服务器交互:请求直接在前端处理,例如滚屏,关闭页面等。
实施方法:
- 第一种可以参考服务端采集方法。
- 第二种可以使用 Tracking Pixel/JS Library 收集页面行为,参考 Tracking Web 接口。
Web Tracking只需一个http get请求即可将数据传输至日志服务Logstore端,适应各种无需任何验证的静态网页、广告投放、宣传资料和移动端数据采集。相比其他日志采集方案,特点如下:
- 便捷:支持浏览器、JS、Image等标签埋点,无需签名即可发送
- 高并发:服务端百万级QPS,全国+全球20个以上接入点
- 无运维成本:无服务器开销,无运维负担
- 按量付费:成本低廉,按照使用量付费
4. 服务端-服务器采集
服务器日志一般通过Agent进行采集,相对应用直发,Agent采集具备以下优势:只要应用可以将日志输出(以文件形式保存到磁盘、syslog等)或者支持通用的接口拉取,Agent即可将日志采集到。大部分场景下松耦合、可扩展性、可维护性相比Agent额外开销更具优势。
日志采集Agent选型一般需要关注功能、性能、稳定性、运维代价4个方面:
- 功能:作为选择Agent最基本需求,主要分为输入源、数据处理(除日志解析外,还包括过滤、压缩等)、数据输出。
- 性能:不同类型Agent之间会有数十倍的性能差距。当日志产生速率较低且资源充足时,此项可以忽略;但大部分情况下采集Agent是作为整个集群的基础软件,在集群规模庞大的情况下,即使每台机器节省1%的CPU、10MB的内存也是很大一笔资金节省。
- 稳定性:稳定的重要性无需多言,除保证自身运行的稳定外,Agent还需保证不能超出限定的资源使用Quota,以免对应用产生影响。
- 运维代价:日志采集的运维主要包括:Agent部署、动态伸缩、配置管理、Agent升级、Agent异常监控。当只有数台主机时,Agent可以使用人肉的方式进行管理,但当集群规模扩大到数百及以上时,运维必须依赖有效的机制。
目前阿里云日志服务logtail采集Agent已承载阿里云全站、所有云产品服务、全球各Region部署、阿里巴巴集团(淘宝、天猫、菜鸟等)上重要服务的数据采集。每天采集接近百万服务器上数PB的实时数据,对接数千个应用与消费者。之所以使用Logtail作为采集Agent也是经过上述四个方面的综合考虑。由于采集Agent数量众多,这里我们选择目前最主流的3款Agent进行对比:
Logtail | Logstash | Fluentd | Beats系列 | ||
---|---|---|---|---|---|
功能 | 文本文件采集 | 支持 | 支持 | 支持 | 支持 |
syslog | 支持 | 支持 | 支持 | 不支持 | |
处理方式 | 正则、anchor、分隔符、json任意组合 | 插件扩展 | 插件扩展 | 只支持multiline | |
过滤 | 正则 | 插件扩展 | 插件扩展 | 不支持 | |
压缩 | lz4 | 插件扩展 | 插件扩展 | 支持 | |
功能扩展 | 支持插件 | 支持插件 | 支持插件 | 支持(修改源码) | |
性能 | 采集性能 | 极简单核160M/s、正则20M/s | 单核2M/s左右 | 单核3-5M/s | 极简单核15M/s |
资源消耗 | 平均CPU 2%、内存 40M | 10倍以上性能消耗 | 10倍以上性能消耗 | 内存消耗较低 | |
稳定性 | 多租户隔离 | 自实现的隔离 | 线程级隔离 | 线程级隔离 | goroutine隔离 |
硬性资源限制 | 支持 | 支持 | 支持 | 不支持 | |
资源动态调整 | 支持 | 不支持 | 不支持 | 不支持 | |
数据保存 | 支持 | 插件支持 | 插件支持 | 不支持 | |
进程守护 | 支持 | 辅助软件支持 | 辅助软件支持 | 辅助软件支持 | |
采集点位保存 | 所有均支持 | 只支持文件 | 插件支持 | 只支持文件 | |
运维代价 | 本地监控 | 支持 | 支持 | 支持 | |
服务端监控 | 支持 | Beta版本支持简单功能 | 辅助监控软件扩展 | 不支持 | |
集群自动缩扩容 | 自定义标识机器组 | 不支持 | 不支持 | 不支持 | |
运行时配置变更 | 支持 | 支持 | 支持 | 支持 | |
服务端配置管理 | 支持 | Beta版本支持简单功能 | 辅助软件扩展 | 不支持 | |
自动升级 | 支持 | 辅助软件扩展 | 辅助软件扩展 | 不支持 |
相对主流的采集Agent,Logtail在采集功能上有一定的不足,对于输入源、处理方式等支持没有开源软件的多,但从目前的功能来看,可以满足95%以上的日志采集需求。但日志采集并不是能够采集到就可以。相对开源软件,Logtail的优势是有集团百万服务器、上万应用的练兵环境,很多问题纯粹从Agent和开源社区的角度并不会考虑到。因此经历了数年的迭代优化,在性能、稳定性、运维代价上,Logtail相对更加成熟,在性价比上具有绝对的优势。
因此建议使用Logtail进行数据采集,针对不同格式的日志配置方法如下:
5. 服务端-K8S采集
在K8S中,日志采集并没有很好的解决方案,主要原因如下:
- __采集目标多__:需要采集宿主机日志、容器内日志、容器stdout。针对每种数据源都有对应的采集软件,但缺乏一站式解决方案。
- __弹性伸缩难__:K8S是一个分布式的集群,服务、环境的弹性伸缩对于日志采集带来了很大的困难,采集的动态性以及数据完整性是非常大的挑战。
- __运维成本大__:现有的方案只能使用多种软件组合采集,各个软件组装起来的系统稳定性难以保障,且缺乏中心化的管理、配置、监控手段,运维负担巨大。
- __侵入性高__:Docker Driver扩展需要修改底层引擎;一个Container对应一个采集Agent又会产生资源竞争和浪费。
- __采集性能低__:正常情况下一个Docker Engine会运行数十个甚至数百个Container,此时开源Agent日志采集性能以及资源消耗十分堪忧。
基于阿里巴巴多年来容器服务日志采集的经验积累,并结合阿里云Kubernetes广大用户的反馈与诉求,日志服务推出了Kubernetes日志采集方案,支持容器文件 、容器stdout 、宿主机文件 的全方位采集。相比其他容器日志采集方案优势如下:
- 全方位数据采集:支持metric、event、容器stdout、容器日志文件、宿主机日志文件
- Kubernetes无缝集成:支持原生Kubernetes配置方式,与应用发布、管理无缝集成
- 高性能:c&c++&go实现的高性能客户端,相比开源方案数倍、数十倍性能优势
- 稳定可靠:百万级规模,经历多次双11双12考验
- 中心化配置管理:所有配置管理均在控制台配置,支持配置动态加载
- 详细采集监控:详细的采集监控信息,支持数据采集状态查询与自定义报警
6. 程序日志采集
日志服务提供多种语言的SDK,支持各种语言程序直发日志服务:
针对高性能应用场景,我们推荐使用Producer Library(Java Producer Library 、 C Producer Library)。Producer Library 会简化您程序开发的步骤,帮助您批量聚合写请求,通过异步的方式发往LogHub服务端。在整个过程中,您可以配置批量聚合的参数、服务端异常处理的逻辑等。该方式具备以下特点:
- 客户端日志不落盘:既数据产生后直接通过网络发往服务端。
- 客户端高并发写入:例如一秒钟会有百次以上写操作。
- 客户端计算与 I/O 逻辑分离:打印日志不影响计算耗时。
若您的Java程序使用Log4J库进行日志输出,可直接使用日志服务Log4j Appender 进行日志采集。该方式具备以下特点:
- 日志不落盘:产生数据实时通过网络发给服务端。
- 无需改造:对已使用Log4J应用,只需简单配置即可采集。
- 异步高吞吐:高并发设计,后台异步发送,适合高并发写入。
- 上下文查询:服务端除了通过关键词检索外,给定日志能够精确还原原始日志文件上下文日志信息。
此外若您的程序日志已经打到本地,可直接通过Logtail 进行采集。
7. 数据库日志采集
ChangeLog-Binlog
Logtail binlog 支持以MySQL slave的形式基于Binlog进行同步,支持Insert、Update、Delete以及DDL采集。相比传统数据库采集方式,Logtail binlog方式具备以下优势:
- 采集性能高:Logtail binlog实现了Mysql master slave同步协议,以slave的形式同步数据,对数据库压力极小。
- 增量采集:只采集变化的数据,且对于Update类型数据可以看到更改前后数据对比。
- 丰富过滤规则:支持正则表达式设置采集的table黑白名单,配置极其灵活。
- 采集成本低:Logtail完全免费,部署一个Logtail可以采集多个数据库日志,成本极低。
数据库中的增量数据
Logtail JDBC 支持以SQL形式定期采集数据库中的数据,根据SQL可实现各种自定义采集方式。可根据自增ID或时间等标志进行增量数据同步,也可根据业务需求进行自定义筛选同步。Logtail JDBC功能如下:
- 支持提供MySQL接口的数据库,包括RDS
- 支持分页设置
- 支持时区设置
- 支持超时设置
- 支持checkpoint状态保存
- 支持SSL
- 支持每次最大采集数量限制
8. 自定义数据采集
Logtail HTTP输入 可根据您的配置定期请求指定URL,将请求返回body值作为输入源上传到日志服务。通过该方式可采集各类以OpenApi方式提供接口的应用,例如Nginx status、kafka status、flink等。Logtail HTTP功能如下:
- 支持配置多个URL。
- 支持请求间隔配置。
- 支持HTTP方法配置。
- 支持自定义header。
- 支持设置method。
- 支持HTTPS。
- 支持检测body是否匹配固定pattern。
日志记录注意事项
在程序日志输出时,为了保证后续处理,有一些通用的原则:
1. 通用日志原则
- 可追溯:记录必要的信息,例如发起人、请求id、处理IP、处理结果、错误ID等
- 可分析:字段表达清晰,不需要过多的清洗即可分析结果
- 可建模:每个字段有明确含义,避免歧义性
- 可诊断:包含明确错误信息与上下文
2. 分文件
对于简单的系统,可以将所有的日志输出到同一个日志文件中,并通过不同的关键字进行区分。而对于复杂的系统,将不同需求的日志输出到不同的日志文件中是必要的,通过对不同类型的文件采用不同的日志格式(例如对于计费日志可以直接输出为Json格式),可以方便接入其他的子系统。
对于应用而言,可以分3个日志文件
/worker/app.log <-- 程序逻辑相关
/worker/access.log <-- 用户请求和访问相关
/worker/error.log <-- 错误日志
3. 动态日志控制
DEBUG日志和INFO日志的一个重要的区别是:INFO日志用于记录常规的系统运行状态,请求的基本的输入和输出等,对定位一般的问题已经足够了。而DEBUG日志则详细的记录了一个请求的处理过程,甚至是每一个函数的输入和输出结果,遇到一些隐藏比较深的问题时,必须要依赖DEBUG日志。
然而,由于DEBUG级别的日志数量比INFO级别的数量多很多(通常差一个数量级),如果长期在线上服务器开启DEBUG级别的日志输出,日志量太大。再比如,有时候仅仅是由于某一个用户的访问模式比较特殊导致了问题,如果将整个服务(特别是一个服务部署了很多台节点时)都临时调整为DEBUG级别日志输出,也非常不方便。
下面介绍集中动态日志控制技术:
-
根据请求控制
在业务处理层的Proxy中,实现如下逻辑:当接收到的HTTP请求的QueryString中包含"Level=Debug"参数时,就将所有的DEBUG级别的日志也输出: 在负载均衡层的Openresty中,实现如下接口:管理员可以配置将哪个用户的哪个桶的哪个对象的哪种操作(注:这是对象存储中的几个概念)输出为DEBUG日志,Openresty会对每个请求进行过滤,当发现请求和配置的DEBUG日志输出条件相匹配时,则在请求的QueryString中新增"Level=Debug"参数。 通过这种方式,管理员可以随时配置哪些请求需要输出为DEBUG级别的日志,可以大大提高线上定位问题的效率。
-
主动监控配置文件
进程通过Inotify等技术监控日志配置文件,例如Log4J.property,当配置文件有更新时(例如LogLevel发生变动),即可感知。 该方案可以在进程不重启的情况下完成配置更改与生效。 > 如果用户使用 spring,可以使用 org.springframework.web.util.Log4jConfigListener[http://www.cnblogs.com/Irving/archive/2013/02/28/2936810.html](http://www.cnblogs.com/Irving/archive/2013/02/28/2936810.html) > 否则,使用 Log4j DOMConfigurator类的configureAndWatch方法[http://489291468.iteye.com/blog/1895471](http://489291468.iteye.com/blog/1895471)
-
动态配置服务器
例如所有服务器都实时与配置管理服务器(ConfigServer)互通,当配置有改动时会实时生效。