OSS(Object Storage Service)是阿里云提供的海量、安全、低成本、高可靠的对象存储服务,提供非常高的可用性、可持久性。由于使用RESTful API 可以在互联网任何位置存储和访问,容量和处理能力弹性扩展等特点,在云场景上OSS被大量使用。常见的场景有:
- 网站的静态数据:存放今天数据
- 多媒体数据处理:例如图片、视频等
- 云端数据处理:例如处理日志、多媒体文件等
- 支持多种存储类型:标准、低频、备份等降低存储成本
由于使用范围广,而存储又是各业务开展的基础,OSS在各场景中扮演了重要的角色。为能够用好OSS,如何了解线上用户的行为和体验变得非常重要。我们需要用到OSS访问日志功能,以下是OSS一条访问日志:
bucket:xxxxoper-img-16 bucket_location: oss-cn-beijing-h bucket_storage_type: standard client_ip: 10.111.23.179 content_length_in: - content_length_out: 21835 delta_data_size: - error_code: - host: xxxoper-img-16.oss-cn-beijing-internal.aliyuncs.com http_method: GET http_status: 200 http_type: http logging_flag: true object: 1526920607501476%xxxx.jpg object_size: 21835 operation: GetObject owner_id: 1020833216692xxxx referer: - request_id: 5B02FCB08293F4BCF409C5A8 request_length: 117 request_uri: /1526920607501xxx/697.jpg HTTP/1.0 requester_id: - response_body_length: 21835 response_time: 6 server_cost_time: 4 sign_type: NotSign sync_request: - time: 22/May/2018:01:06:56 user_agent: - vpc_addr: 121271xxx vpc_id: 7923xxx
熟悉的人应该知道,访问日志和Nginx类似,记录了时间、地点,人物、访问对象、延时以及一些重要附带信息(可参见:OSS访问日志字段描述)。OSS访问日志有两种手段可以获得,在这里,我们主要讲述通过第二种方法:日志服务进行日志查询与分析的用法。
时效性 | 费用(每GB) | 功能 | |
---|---|---|---|
存储OSS | <2 Hour | 存储0.148元/M | OSS处理 |
日志服务(SLS) | <10 S | 存储0.35元/M | 实时查询分析+可视化 |
OSS下的访问日志已和日志服务打通,可以在控制台上开通使用,开通后可以提供:
- 通过关键词、区间、模糊查询等对日志进行筛选排查
- 通过SQL语句进行实时日志分析、可视化、配置告警等
该方案具有如下特点:
除此之外,可以通过日志服务:
- 集成可视化:自定义Dashboard、Grafana,DataV,Jaeger,JDBC等
- 与各种流计算引擎与服务对接:Storm、Spark Streaming、Flink、StreamCompute、Consumer Library (Go、Java)、CloudMonitor、ARMS
- 与数据仓库、数据处理服务打通:OSS、MaxCompute
整体统计
在开通OSS日志分析后,用户对应Logstore下会有如下两类数据:
1. 整体流量(PV、UV等)
PV:一天请求次数是多少?
__topic__: oss_access_log and http_status < 400 | SELECT count(1) AS PV
UV:有多少独立访客来访问资源?
__topic__: oss_access_log and http_status < 400 | SELECT approx_distinct(client_ip) AS UV
吞吐量:
__topic__: oss_access_log and http_status < 400 | SELECT sum(if(content_length_in IS NULL, 0, content_length_in) + if(content_length_out IS NULL, 0, content_length_out))/1024/1024 AS "Total throughput (MB)"
进入流量:根据同样方式我们可以计算出流量。
__topic__: oss_access_log and http_status < 400 | SELECT sum(if(content_length_in IS NULL, 0, content_length_in))/1024/1024 AS "Inbound throughput"
最后关于整体流量的监控如下:
2. 整体业务趋势(PV、UV等跟随时间变化)
对象存储追求大业务吞吐量,如果希望统计吞吐量和时间分布,我们需要用到基于时间窗口函数对每个窗口内的流量进行统计。窗口函数原理如下:
1. 通过时间字段聚合到一个窗口,例如我们以300秒进行聚合:"__time__ - __time__% 300" 作为一个统计时段
2. 根据该时间段对窗口流量进行聚合
3. 根据时间窗口进行排序输出
例如构建以下SQL获得24小时内,每5分钟的流量图
__topic__: oss_access_log and http_status < 400 | select sum(if(content_length_in is null, 0, content_length_in))/1024/1024 + sum(if(content_length_out is null, 0, content_length_out))/1024/1024 as "Total throughut (MB)", sum(content_length_in)/1024/1024 as "Inbound throughut (MB)", sum(content_length_out)/1024/1024 as "Outbound throughut (MB)", date_format(from_unixtime(__time__ - __time__% 300), '%m/%d %H:%i') as "Time per 5 min" group by "Time per 5 min" order by "Time per 5 min" limit 1000
掌握该技能后,统计PV、UV随时间的分布就不在话下了:
__topic__: oss_access_log and http_status < 400 | select count(*) as PV, approx_distinct(client_ip) as UV, date_format(from_unixtime(__time__ - __time__% 300), '%m/%d %H:%i') as "Time per 5 min" group by "Time per 5 min" order by "Time per 5 min" limit 1000
3. 用户来源
每条访问日志中会有IP字段,可以使用IP解析函数来判断国家、地域、来源等。
我们可以用ip_to_country函数结合世界地图拿到分布:
__topic__: oss_access_log and http_status < 400 | select count(*) as PV, ip_to_country(client_ip) as "国家" group by "国家" limit 100
要更细节的分布时,可以使用ip_to_province, ip_to_geo获得更精确的位置,例如省份,地理位置坐标等:
__topic__: oss_access_log and http_status < 400 | select ip_to_geo(client_ip) as geo, count(1) as PV group by geo limit 1000
也可以通过ip_to_provider获得运营商分布:
__topic__: oss_access_log and http_status < 400 | (select round(sum(if(content_length_in is null, 0, content_length_in) + if(content_length_out is null, 0, content_length_out))/1024.0/1024.0, 3) as throughput, ip_to_provider(client_ip) as provider group by provider having ip_to_provider(client_ip) <> '' limit 1000)
也可以根据城市、位置来统计整体的流量分布。
__topic__: oss_access_log and http_status < 400 | select country as "国家", province as "省份", throughput as "总流量 (MB)", round(throughput*100.0/sum(throughput) over(), 2) as "百分比 (%)" from (select round(sum(if(content_length_in is null, 0, content_length_in) + if(content_length_out is null, 0, content_length_out))/1024.0/1024.0, 1) as throughput, sum(if(content_length_in is null, 0, content_length_in))/1024/1024 as throughput_in, sum(if(content_length_out is null, 0, content_length_out))/1024/1024 as "Throughput Out (MB)", ip_to_country(client_ip) as country, ip_to_province(client_ip) as province from log group by country, province having ip_to_country(client_ip) <> '' order by throughput desc limit 1000) order by throughput desc
日志服务提供的完整IP识别函数如下,能够满足绝大部分需求:
函数名 | 含义 | 样例 |
---|---|---|
ip_to_domain(ip) |
判断IP所在的域,是内网还是外网。返回intranet或internet。 | SELECT ip_do_domain(ip) |
ip_to_country(ip) |
判断IP所在的国家。 | SELECT ip_to_country(ip) |
ip_to_province(ip) |
判断IP所在的省份,如果是外国,则返回国家名称。 | SELECT ip_to_province(ip) |
ip_to_city(ip) |
判断IP所在的城市,如果是外国,则返回国家名称。 | SELECT ip_to_city(ip) |
ip_to_geo(ip) |
判断IP所在的经纬度,返回的是高精度经纬度数据,范围结果格式为纬度,经度 。 |
SELECT ip_to_geo(ip) |
ip_to_city_geo(ip) |
判断IP所在的城市的经纬度,返回的是城市经纬度,每个城市只有一个经纬度,范围结果格式为纬度,经度 。 |
SELECT ip_to_city_geo(ip) |
ip_to_provider(ip) |
获取IP对应的网络运营商。 | SELECT ip_to_provider(ip) |
ip_to_country(ip,'en') |
判断IP所在的国家,返回国际码。 | SELECT ip_to_country(ip,'en') |
ip_to_country_code(ip) |
判断IP所在的国家,返回国际码。 | SELECT ip_to_country_code(ip) |
ip_to_province(ip,'en') |
判断IP所在的省份,返回英文省名或者中文拼音。 | SELECT ip_to_province(ip,'en') |
ip_to_city(ip,'en') |
判断IP所在的城市,返回英文城市名或者中文拼音。 | SELECT ip_to_city(ip,'en') |
最后
最后我们可以构建成一张酷炫的实时日志分析仪表盘,是不是很酷炫?对了,如果开通OSS访问日志分析,这张仪表盘已经默认帮你创建好了,可以在此基础上扩展哦。