一、日志(Log)
日志(Log)是系统在运行过程中变化的一种抽象,其内容为指定对象的某些操作和其操作结果按时间的有序集合。文件日志(LogFile)、事件(Event)、数据库日志(BinLog)、度量(Metric)数据都是日志的不同载体。在文件日志中,每个日志文件由一条或多条日志组成,每条日志描述了一次单独的系统事件,是日志服务中处理的最小数据单元。
二、日志服务
Log Service是针对日志类数据的一站式服务。
1.实时采集与消费(LogHub)
用途:数据清洗(ETL)、流计算(Stream Compute)、监控与报警、 机器学习与迭代计算。
2.查询与实时分析(Search/Analytics)
用途:DevOps/线上运维,日志实时数据分析,安全诊断与分析,运营与客服系统
3.投递数仓(LogShipper)
用途:数据仓库 + 数据分析、审计、推荐系统与用户画像。
三、概念
日志库(Logstore)是日志服务中日志数据的收集、存储和查询单元。每个日志库隶属于一个项目,且每个项目可以创建多个日志库。
分区(Shard每个日志库分若干个分区(Shard),每个分区由MD5左闭右开区间组成,每个区间范围不会相互覆盖,并且所有的区间的范围是MD5整个取值范围。
文件日志(LogFile)、事件(Event)、数据库日志(BinLog)、度量(Metric)数据都是日志的不同载体。
日志服务采用半结构数据模式定义一条日志。该模式中包含主题(Topic)、时间(Time)、内容(Content)、来源(Source)和标签(Tags)五个数据域。
日志组(LogGroup)是一组日志的集合,是API/SDK写入与读取数据的基本单位。一个LogGroup中的数据包含相同Meta(IP、Source等信息)。
通过日志服务API/SDK写入数据时,多条日志会打包成一个LogGroup,以LogGroup为单位发往日志服务。相对于以日志为单位读写数据,LogGroup的读写方式可以最大限度地减少读取与写入次数,提高业务效率。日志组的限制为:5 MB空间。
服务器上有三种日志:操作日志(operation_log)、应用程序日志(application_log)以及访问日志(access_log)
日志框架 Log4j、Log4j2、Logback Appender
对Java应用而言,目前有两种主流的日志采集方案:
Java程序将日志落盘,通过Logtail进行实时采集。
Java程序直接配置日志服务提供的Appender,当程序运行时,实时将日志发往服务端。
四、采集并分析Nginx访问日志
Nginx日志内容
字段 | 含义 |
---|---|
remote_addr | 客户端地址 |
remote_user | 客户端用户名 |
time_local | 服务器时间 |
request | 请求内容,包括方法名、地址和http协议 |
http_host | 用户请求时使用的http地址 |
status | 返回的http状态码 |
request_length | 请求大小 |
body_bytes_sent | 返回的大小 |
http_referer | 来源页 |
http_user_agent | 客户端名称 |
request_time | 整体请求延时 |
upstream_response_time | 上游服务的处理延时 |
1.使用SQL语句分析Nginx访问日志
统计最近一天的PV数和UV数
select approx_distinct(remote_addr) as uv ,
count(1) as pv ,
date_format(date_trunc('hour', __time__), '%m-%d %H:%i') as time
group by date_format(date_trunc('hour', __time__), '%m-%d %H:%i')
order by time
limit 1000
统计访问IP来源情况
select count(1) as c,
ip_to_province(remote_addr) as address
group by ip_to_province(remote_addr) limit 10
统计最近一天各种请求方法的占比
select count(1) as pv,
request_method
group by request_method
统计最近一天各种http状态码的占比
select count(1) as pv,
status
group by status
统计最近一天各种浏览器的占比
select count(1) as pv,
case when http_user_agent like '%Chrome%' then 'Chrome'
when http_user_agent like '%Firefox%' then 'Firefox'
when http_user_agent like '%Safari%' then 'Safari'
else 'unKnown' end as http_user_agent
group by http_user_agent
order by pv desc
limit 10
五、Nginx访问日志诊断及优化
-
通过每5分钟的平均延时和最大延时,从整体上了解延时情况。
* | select from_unixtime(__time__ -__time__% 300) as time, avg(request_time) as avg_latency , max(request_time) as max_latency group by __time__ -__time__% 300
- 统计最大延时对应的请求页面。
知道了最大延时之后,需要明确最大延时对应的请求页面,以方便进一步优化页面响应。
* | select from_unixtime(__time__ - __time__% 60) , max_by(request_uri,request_time) group by __time__ - __time__%60
- 统计请求延时的分布。
统计网站的所有请求的延时的分布,把延时分布在十个桶里面,看每个延时区间的请求个数。
* |select numeric_histogram(10,request_time)
- 统计最大的十个延时。
除最大的延时之外,还需要统计最大的十个延时及其对应值。
统计语句:
* | select max(request_time,10)
- 对延时最大的页面调优。
假如
/url2
这个页面的访问延时最大,为了对/url2
页面进行调优,接下来需要统计/url2
这个页面的访问PV、UV、各种method次数、各种status次数、各种浏览器次数、平均延时和最大延时。request_uri:"/url2" | select count(1) as pv, approx_distinct(remote_addr) as uv, histogram(method) as method_pv, histogram(status) as status_pv, histogram(user_agent) as user_agent_pv, avg(request_time) as avg_latency, max(request_time) as max_latency
七、Logtail采集原理
Logtail采集日志的流程为:监听文件、读取文件、处理日志、过滤日志、聚合日志和发送数据6个步骤 。Logtail支持极简模式、完整正则模式、分隔符模式、JSON模式、NGINX配置模式 、IIS配置模式、APACHE配置模式等方式收集日志
八、Nginx日志
Nginx日志格式和目录通常在配置文件/etc/nginx/nginx.conf中
配置文件中定义了Nginx日志的打印格式,即main格式:
log_format main '$remote_addr - $remote_user [$time_local] "$request" '
'$request_time $request_length '
'$status $body_bytes_sent "$http_referer" '
'"$http_user_agent"';
声明使用了main这种日志格式和写入的文件名。
access_log /var/logs/nginx/access.log main
日志样例
192.168.1.2 - - [10/Jul/2015:15:51:09 +0800] "GET /ubuntu.iso HTTP/1.0" 0.000 129 404 168 "-" "Wget/1.11.4 Red Hat modified"
字段说明
字段名称 | 含义 |
---|---|
remoteaddr | 表示客户端IP地址。 |
remote_user | 表示客户端用户名称。 |
request | 表示请求的URL和HTTP协议。 |
status | 表示请求状态。 |
bodybytessent | 表示发送给客户端的字节数,不包括响应头的大小;该变量与Apache模块modlogconfig里的bytes_sent发送给客户端的总字节数相同。 |
connection | 表示连接的序列号。 |
connection_requests | 表示当前通过一个连接获得的请求数量。 |
msec | 表示日志写入的时间。单位为秒,精度是毫秒。 |
pipe | 表示请求是否通过HTTP流水线(pipelined)发送。通过HTTP流水线发送则pipe值为p ,否则为. 。 |
httpreferer | 表示从哪个页面链接访问过来的。 |
“http_user_agent” | 表示客户端浏览器相关信息,前后必须加上双引号。 |
requestlength | 表示请求的长度。包括请求行,请求头和请求正文。 |
request_time | 表示请求处理时间,单位为秒,精度为毫秒。从读入客户端的第一个字节开始,直到把最后一个字符发送给客户端后进行日志写入为止。 |
[$time_local] | 表示通用日志格式下的本地时间,前后必须加上中括号。 |
九、Systemd日志输入源
Systemd是专用于 Linux 操作系统的系统与服务管理器。当作为启动进程(PID=1)运行时,它将作为初始化系统运行,启动并维护各种用户空间的服务。 Systemd统一管理所有Unit的日志(包括内核和应用日志),配置文件一般在/etc/systemd/journald.conf中。
功能
- 支持设置初始同步位置,后续采集会自动保存checkpoint,应用重启时不影响进程。
- 支持过滤指定的Unit。
- 支持采集内核日志。
- 支持自动解析日志等级。
- 支持以容器方式采集宿主机上的Journal日志,适用于Docker/Kubernetes场景。