摘要: 日志服务提供 30 多种数据采集方式, 针对服务器移动端嵌入式设备及各种开发语言都提供完整的接入方案对 Java 开发者而言, 没有什么比熟悉的日志框架 Log4jLog4j2Logback Appender 更好使的了
日志中心化之路
近几年来, 无状态编程容器 Serverless 编程方式的诞生极大提升了软件交付与部署的效率在架构的演化过程中, 可以看到两个变化:
应用架构开始从单体系统逐步转变微服务, 其中的业务逻辑随之而来就会变成微服务之间调用与请求
资源角度来看, 传统服务器这个物理单位也逐渐淡化, 变成了看不见摸不到的虚拟资源模式
从以上两个变化可以看到这种弹性标准化架构背后, 原先运维与诊断的需求也变得越来越复杂在 10 年前我们可以快速登陆到服务器上捞取日志, Attach 进程的模式已再也不存在, 面对我们的更多是一个标准化的黑盒
为了应对这种变化趋势, 诞生一系列面向 DevOps 诊断与分析的工具例如集中式监控集中式日志系统以及 SaaS 化的各种部署监控等服务
日志中心化解决的是以上这个问题, 既应用产生日志后实时 (或准实时) 传输到中心化的节点服务器, 例如 Syslog,Kafka,ELK,Hbase 进行集中式存储是一些常见的模式
中心化四个好处
使用方便: 在无状态应用中最麻烦的要属 Grep 日志了, 集中式存储只要运行一个 Search 命令就能够替代原先漫长的过程
存储与计算分离: 定制机器硬件时无需为日志存储考虑空间大小
更低成本: 集中式日志存储可以削峰填谷, 预留更高水位
安全: 当发生黑客入侵以及灾难时, 关键数据留作取证
采集端 (Java 系列)
日志服务提供 30 + 数据采集方式, 针对服务器移动端嵌入式设备及各种开发语言都提供完整的接入方案对 Java 开发者而言, 没有什么比熟悉的日志框架 Log4jLog4j2Logback Appender 更好使的了
对 Java 应用而言, 目前有两种主流的日志采集方案:
Java 程序将日志落盘, 通过 Logtail 进行实时采集
Java 程序直接配置日志服务提供的 Appender, 当程序运行时, 实时将日志发完服务端
两者的差别如下:
通过 Appender 可以在不改任何代码情况下, 通过 Config 就能够非常容易完成日志实时采集工作, 日志服务提供的 Java 系列 Appender 有如下几大优势:
无需修改程序, 修改配置即生效
异步化 + 断点续传: IO 不影响主线程, 支持一定网络和服务容错
高并发设计: 满足海量日志写入需求
支持上下文查询功能: 写入支持支持在服务端还原原始进程中精确上下文(前后 N 条日志)
Appender 介绍与使用
目前提供 Appender 如下, 底层均使用 aliyun-log-producer-java 完成数据的写入
- aliyun-log-log4j-appender
- aliyun-log-log4j2-appender
- aliyun-log-logback-appender
这四者的差别如下:
接入 Appender
可参考 aliyun-log-log4j-appender 的配置步骤部分接入 appender
配置文件 log4j.properties 的内容如下:
查询与分析
通过上述方式配置好 appender 后, Java 应用产生的日志会被自动发往日志服务可以通过 LogSearch/Analytics 对这些日志实时查询和分析本文提供的样例的日志格式如下:
记录用户登录行为的日志
记录用户购买行为的日志
开启查询分析
若要对数据进行查询和分析, 需要首先开启查询分析功能开启步骤如下:
登录 日志服务管理控制台
选择目标项目, 单击项目名称或者单击右侧的 管理
选择目标日志库并单击日志索引列下的 查询
单击右上角的 设置查询分析 > 设置
进入设置菜单, 为下列字段开启查询
分析实例
以下视频包含了下述 5 个分析实例
视频地址: http://cloud.video.taobao.com//play/u/2450842572/p/1/e/6/t/1/50073510333.mp4
1. 统计过去 1 小时发生 Error 最多的 3 个位置
语法示例: level: ERROR |selectlocation ,count(*)ascountGROUPBYlocationORDERBYcountDESCLIMIT3
2. 统计过去 15 分钟各种日志级别产生的日志条数
语法示例:
3. 日志上下文查询
对于任意一条日志, 能够精确还原原始日志文件上下文日志信息
参阅: 上下文查询
4. 统计过去 1 小时, 登录次数最多的三个用户
语法示例: login |SELECTregexp_extract(message,'userID=(?[a-zA-Z\d]+)',1)ASuserID,count(*)ascountGROUPBYuserIDORDERBYcountDESCLIMIT3
5. 统计过去 15 分钟, 每个用户的付款总额
语法示例: order |SELECTregexp_extract(message,'userID=(?[a-zA-Z\d]+)',1)ASuserID,sum(cast(regexp_extract(message,'amount=(?[a-zA-Z\d]+)',1)ASdouble))ASamountGROUPBYuserID
来源: http://www.jianshu.com/p/96500e12d075