阿里云开放实验室
https://edu.aliyun.com/lab/courses
选择一个日志分析项目为例:
实验详情:
- 实验概述:网站访问日志是用户在访问网站服务器时产生的日志,它包含了各种原始信息,一般以.log结尾。通过它就可以清楚的知道用户的IP,访问时间,请求链接,请求状态,请求字节数,来源链接,用户操作系统,浏览器内核,浏览器名称,浏览器版本等等信息。对网站日志的分析统计可以使我们了解网站当前的一些状况,为网站的各种优化升级甚至公司营销策略提供依据。
- 该实验提供实验手册,包含实验资源(MaxCompute,阿里云账户等),附件下载
- 主要技术:大数据计算服务MaxCompute,DataWorks,QuickBI
- 实验目的:
- 学习统计网站日志分析的一些常见指标
- 掌握MaxCompute对数据进行分析处理
- 掌握使用QuickBI以图表方式展示分析
实操记录:
MaxCompute
输入密码即可。
本实验的数据压缩包data.zip包含了两个文本文件:网站访问日志文件access.log和IP地址库文件ip.txt。
下载客户端 odpscmd 后编辑配置文件:
(下载链接:https://help.aliyun.com/document_detail/27971.html?spm=a2c4g.11174283.2.3.33e0590eSUhpg1)
运行客户端:(Mac运行 odpscmd)
创建表:
编写 Java 程序处理log:
import java.io.*;
public class LogParser {
/**
* 日志文件预处理
*
* @param inPath 日志文件输入地址
* @param outPath 输出地址
* @throws IOException
*/
public void accessLogId(String inPath, String outPath) throws IOException {
String line = "";
long index = 0;
BufferedReader bufferedReader = null;
FileWriter fileWriter = null;
try {
bufferedReader = new BufferedReader(new FileReader(inPath));
File outFile = new File(outPath);
if (outFile.exists()) {
outFile.delete();
}
outFile.createNewFile();
fileWriter = new FileWriter(outFile);
while ((line = bufferedReader.readLine()) != null) {
index++;
String newLine = String.valueOf(index) + " " + line + "\r\n";
fileWriter.write(newLine);
}
} finally {
if (bufferedReader != null) {
bufferedReader.close();
}
if (fileWriter != null) {
fileWriter.close();
}
}
}
public static void main(String[] args) {
try {
LogParser logParser = new LogParser();
//日志文件预处理 传入输入和输出地址
logParser.accessLogId("/Users/cxf/IT/project/aliyun/mooc_log/data/access.log", "/Users/cxf/IT/project/aliyun/mooc_log/data/log.txt");
} catch (IOException e) {
e.printStackTrace();
}
}
}
运行main方法后生成新的log.txt文件:(在原有的每行log前多加一个数字)
上传文件:
查看表:
DataWorks
进入数据开发
DataStudio 数据开发欢迎界面可清楚看到整个流程:
在 DataStudio 里新建业务流程:
新建节点:
双击对应节点可编辑:
两个虚拟节点和所有 ODPS SQL 创建完成如下:
双击每个节点指定每个ODPS_SQL节点的脚本。
首先是日志文件属性提取,脚本如下:
--初始化临时表
DROP TABLE IF EXISTS t_web_access_log_tmp1;
CREATE TABLE t_web_access_log_tmp1 (
id BIGINT,
ip STRING,
ip_num BIGINT,
ip_1 BIGINT,
access_time STRING,
url STRING,
status STRING,
traffic STRING,
referer STRING,
c_info STRING
);
--使用正则表达式提取并向临时表插入数据
INSERT OVERWRITE TABLE t_web_access_log_tmp1
SELECT CAST(regexp_replace(regexp_substr(content,'[[].*?[]] |".*?" |.*? ', 1, 1), ' $', '') AS BIGINT) AS id
,regexp_replace(regexp_substr(content, '[[].*?[]] |".*?" |.*? ', 1,2), ' $', '') AS ip
,CAST(regexp_substr(content, '\\d+', 1, 2) AS BIGINT) * 255 * 255 * 255 +CAST(regexp_substr(content, '\\d+', 1, 3) AS BIGINT) * 255 * 255 + CAST(regexp_substr(content,'\\d+', 1, 4) AS BIGINT) * 255 + CAST(regexp_substr(content, '\\d+', 1, 5) AS BIGINT) AS ip_num
,regexp_substr(content, '\\d+', 1, 2) AS ip_1
,regexp_replace(regexp_substr(content, '[[].*?[]] |".*?" |.*? ', 1,5), '^[[]|[]] $', '') AS access_time
,regexp_replace(regexp_substr(content, '[[].*?[]] |".*?" |.*? ', 1,6), '^"|" $', '') AS url
,regexp_replace(regexp_substr(content, '[[].*?[]] |".*?" |.*? ', 1,7), ' $', '') AS status
,regexp_replace(regexp_substr(content, '[[].*?[]] |".*?" |.*? ', 1,8), ' $', '') AS traffic
,regexp_replace(regexp_substr(content, '[[].*?[]] |".*?" |.*? ', 1,9), '^"|" $', '') AS referer
,regexp_replace(regexp_substr(content, '".*?"', 1, 3),'^"|"$', '') AS c_info
FROM t_web_access_log_content;
ip信息提取,脚本如下:
--初始化IP表
DROP TABLE IF EXISTS t_cz_ip;
CREATE TABLE t_cz_ip (
ip_start BIGINT,
ip_start_1 STRING,
ip_end BIGINT,
city STRING,
isp STRING
);
--使用正则表达式提取并向IP表插入数据
INSERT OVERWRITE TABLE t_cz_ip
SELECT CAST(regexp_substr(content, '\\d+', 1, 1) AS BIGINT) * 255 * 255 * 255 + CAST(regexp_substr(content, '\\d+', 1, 2) AS BIGINT) * 255 * 255 + CAST(regexp_substr(content, '\\d+', 1, 3) AS BIGINT) *255 + CAST(regexp_substr(content, '\\d+', 1, 4) AS BIGINT) AS ip_start
,regexp_substr(content, '\\d+', 1, 1) AS ip_start_1
,CAST(regexp_substr(content, '\\d+', 1, 5) AS BIGINT) * 255 * 255 * 255 +CAST(regexp_substr(content, '\\d+', 1, 6) AS BIGINT) * 255 * 255 +CAST(regexp_substr(content, '\\d+', 1, 7) AS BIGINT) * 255 +CAST(regexp_substr(content, '\\d+', 1, 8) AS BIGINT) AS ip_end
,regexp_replace(regexp_substr(content, ' +[^ ]+', 1, 2), '^ +', '') AS city
,regexp_replace(regexp_substr(content, ' +[^ ]+', 1, 3), '^ +', '') AS isp
FROM t_cz_ip_content;
地域及运营商信息提取,脚本如下:
--初始化临时表
DROP TABLE IF EXISTS t_web_access_log_tmp2;
CREATE TABLE t_web_access_log_tmp2 (
id BIGINT,
ip STRING,
city STRING,
isp STRING,
access_time STRING,
url STRING,
status STRING,
traffic STRING,
referer STRING,
c_info STRING
);
--从ip表中查询城市和运营商信息
INSERT OVERWRITE TABLE t_web_access_log_tmp2
SELECT /*+ mapjoin(b) */ a.id, a.ip, b.city, b.isp,a.access_time
, a.url, a.status,a.traffic, a.referer, a.c_info
FROM t_web_access_log_tmp1 a
JOIN t_cz_ip b
ON a.ip_1 = b.ip_start_1
AND a.ip_num >=b.ip_start
AND a.ip_num <=b.ip_end;
用户所在省和访问链接,脚本如下:
--初始化临时表
DROP TABLE IF EXISTS t_web_access_log_tmp3;
CREATE TABLE t_web_access_log_tmp3 (
id BIGINT,
ip STRING,
province STRING,
city STRING,
isp STRING,
access_time STRING,
url STRING,
status STRING,
traffic STRING,
referer STRING,
c_info STRING
);
--提取省信息使用正则表达式提取访问链接的实际地址并向临时表插入数据
INSERT OVERWRITE TABLE t_web_access_log_tmp3
SELECT id, ip
, CASE
WHEN INSTR(city, '省') >0 THEN SUBSTR(city, 1, INSTR(city, '省') - 1)
WHEN INSTR(city, '内蒙古')> 0 THEN '内蒙古'
WHEN INSTR(city, '西藏') >0 THEN '西藏'
WHEN INSTR(city, '广西') >0 THEN '广西'
WHEN INSTR(city, '宁夏') >0 THEN '宁夏'
WHEN INSTR(city, '新疆') >0 THEN '新疆'
WHEN INSTR(city, '北京') >0 THEN '北京'
WHEN INSTR(city, '上海') >0 THEN '上海'
WHEN INSTR(city, '天津') >0 THEN '天津'
WHEN INSTR(city, '重庆') >0 THEN '重庆'
WHEN INSTR(city, '香港') >0 THEN '香港'
WHEN INSTR(city, '澳门') >0 THEN '澳门'
ELSE city
END AS province,city, isp, access_time
,regexp_replace(regexp_substr(url, ' .*?(\\.mooc| )', 1, 1), '^ | $', '') AS url
, status, traffic,referer, c_info
FROM t_web_access_log_tmp2;
访问时间和referer处理,脚本如下:
--初始化临时表
DROP TABLE IF EXISTS t_web_access_log_tmp4;
CREATE TABLE t_web_access_log_tmp4 (
id BIGINT,
ip STRING,
province STRING,
city STRING,
isp STRING,
access_time STRING,
access_hour STRING,
url STRING,
status STRING,
traffic STRING,
referer STRING,
ref_type STRING,
c_info STRING
);
--使用正则表达式提取访问时间和来源分类并向临时表插入数据
INSERT OVERWRITE TABLE t_web_access_log_tmp4
SELECT id, ip, province, city, isp
,regexp_replace(regexp_substr(access_time, ':\\d.*? ', 1, 1), ':|$', '') ASaccess_time
,regexp_replace(regexp_substr(access_time, ':\\d\\d:', 1, 1), '^:|:$', '') ASaccess_hour
, url, status,traffic, referer
, CASE
WHEN INSTR(referer, 'www.chinamoocs.com') > 0
OR LENGTH(referer)< 5 THEN 'self'
WHEN INSTR(referer, 'www.google.com') > 0 THEN 'google'
WHEN INSTR(referer, 'www.baidu.com') > 0 THEN 'baidu'
WHEN INSTR(referer, 'www.bing.com') > 0 THEN 'bing'
WHEN INSTR(referer, 'www.so.com') > 0 THEN '360'
ELSE 'other'
END AS ref_type,c_info
FROM t_web_access_log_tmp3;
用户信息处理,脚本如下:
--初始化访问日志表
DROP TABLE IF EXISTS t_web_access_log;
CREATE TABLE t_web_access_log (
id BIGINT,
ip STRING,
province STRING,
city STRING,
isp STRING,
access_time STRING,
access_hour STRING,
url STRING,
status STRING,
traffic STRING,
referer STRING,
ref_type STRING,
c_info STRING,
client_type STRING,
client_browser STRING
);
--使用正则表达式提取客户端信息中的操作系统和浏览器信息并向表插入数据
INSERT OVERWRITE TABLE t_web_access_log
SELECT id, ip, province, city, isp
, access_time,access_hour, url, status, traffic
, referer,ref_type, c_info
, CASE
WHEN INSTR(c_info,'iPhone;') > 0 THEN 'IOS'
WHEN INSTR(c_info,'iPad;') > 0 THEN 'IOS'
WHEN INSTR(c_info,'Mac OS X ') > 0 THEN 'OS X'
WHEN INSTR(c_info,'X11;') > 0 THEN 'Linux'
WHEN INSTR(c_info,'Android ') > 0 THEN 'Android'
WHEN INSTR(c_info,'Windows NT ') > 0 THEN 'Windows'
ELSE 'other'
END AS client_type
, CASE
WHEN INSTR(c_info,' QQBrowser') > 0 THEN 'QQBrowser'
WHEN INSTR(c_info,' UCBrowser') > 0 THEN 'UCBrowser'
WHEN INSTR(c_info,' Edge') > 0 THEN 'Edge'
WHEN INSTR(c_info,' LBBROWSER') > 0 THEN 'LBBROWSER'
WHEN INSTR(c_info,' Maxthon') > 0 THEN 'Maxthon'
WHEN INSTR(c_info,' Firefox') > 0 THEN 'Firefox'
WHEN INSTR(c_info,' Chrome') > 0 THEN 'Chrome'
WHEN INSTR(c_info,' Mac OS X') > 0
AND INSTR(c_info,' Safari') > 0 THEN 'Safari'
WHEN INSTR(c_info,' MSIE') > 0 THEN 'IE'
ELSE 'other'
END ASclient_browser
FROM t_web_access_log_tmp4;
TopN数据采集,脚本如下:
--初始化访问链接TopN表
DROP TABLE IF EXISTS t_web_access_log_url_top;
CREATE TABLE t_web_access_log_url_top (
url STRING,
times INT
);
INSERT OVERWRITE TABLE t_web_access_log_url_top
SELECT top.url, top.times
FROM (
SELECT url,COUNT(1) AS times
FROM t_web_access_log
WHERE INSTR(url,'.mooc') > 0
GROUP BY url
) top
ORDER BY top.times DESC
LIMIT 10;
获取每个访客的第一条访问日志,脚本如下
--初始化每个访客的第一个访问日志
DROP TABLE IF EXISTS t_web_access_log_first;
CREATE TABLE t_web_access_log_first (
id BIGINT,
ip STRING,
province STRING,
city STRING,
isp STRING,
access_time STRING,
access_hour STRING,
url STRING,
status STRING,
traffic STRING,
referer STRING,
ref_type STRING,
c_info STRING,
client_type STRING,
client_browser STRING
);
INSERT OVERWRITE TABLE t_web_access_log_first
SELECT a.id, a.ip, a.province, a.city, a.isp
, a.access_time, a.access_hour,a.url, a.status, a.traffic
, a.referer,a.ref_type, a.c_info, a.client_type, a.client_browser
FROM t_web_access_log a
JOIN (
SELECT c.ip,MIN(c.id) AS id
FROM t_web_access_log c
GROUP BY c.ip,
c.c_info
) b
ON a.ip = b.ip
AND a.id = b.id;
ip黑名单处理,脚本如下:
--初始化访问IP黑名单表
DROP TABLE IF EXISTS t_web_access_log_ip_black;
CREATE TABLE t_web_access_log_ip_black (
ip STRING,
times INT
);
INSERT OVERWRITE TABLE t_web_access_log_ip_black
SELECT ip, COUNT(1) AS times
FROM t_web_access_log
WHERE status = '404'
GROUP BY ip
HAVING COUNT(1) > 10;
运行,等所有都打钩就代表所有都执行完:
可验证结果:
(也可以通过 Web UI 去查看所有表)
玩玩Quick BI
统计pv,即页面浏览量
在数据图表选择指标看板
以下参照实验手册:
选中生成后的图表,左上角选择数据集为t_web_access_log:
然后将度量中的访问人次拖入数据下的看板指标/度量:
然后在样式中修改标题为PV:
点击更新(图表可以自行拖拽控制大小):
结果如下:
统计UV,即独立访客
新建指标看板,选择数据集为t_web_access_log_first,将度量中的访问人数拖入指标看板/度量,然后在样式中修改标题为UV。
点击更新,结果如下:
统计独立IP
双击新建指标看板,选择数据集为t_web_access_log_first,将度量中的独立IP拖入指标看板/度量,然后在样式中修改标题为IP。
点击更新,结果如下:
访问趋势图
双击新建线图,选择数据集为t_web_access_log,将维度中的访问时间拖入类别轴/维度,将度量中的访问人次拖入值轴/度量,然后在样式中修改标题为一天访问趋势。
点击更新,结果如下:
访问来源分析
双击新建饼图,选择数据集为t_web_access_log_first,将维度访问来源拖入扇区标签/维度,将度量访问人数拖入扇区角度/度量,然后在样式中修改标题为访问来源占比。
点击更新,结果如下:
搜索引擎来源
双击新建饼图,选择数据集为t_web_access_log_first,将维度搜索引擎拖入扇区标签/维度,将度量访问人数拖入扇区角度/度量,将维度搜索引擎拖入过滤器下,编辑枚举选择所有搜索引擎项:
点击确定,然后在样式中修改标题为搜索引擎占比。
点击更新,结果如下:
用户访问链接Top10
双击新建饼图,选择数据集为t_web_access_log_url_top,将维度访问链接拖入扇区标签/维度,将度量访问次数拖入扇区角度/度量,然后在样式中修改标题为访问链接Top10。
点击更新,结果如下:
恶意攻击IP
双击新建柱图,选择数据集为t_web_access_log_ip_black,将维度IP地址拖入类别轴/维度,将度量攻击次数拖入值轴/度量,然后在样式中修改标题为IP黑名单。
点击更新,结果如下:
访客地域分布
双击新建色彩地图,选择数据集为t_web_access_log_first,将所在省份拖入地理区域/维度,将度量访问人数拖入色彩饱和度/度量,然后在样式中修改标题为访客地域分布。
点击更新,结果如下:
访客浏览器
双击新建饼图,选择数据集为t_web_access_log_first,将维度浏览器拖入扇区标签/维度,将度量访问人数拖入扇区角度/度量,然后在样式中修改标题为访客浏览器。
点击更新,结果如下:
访客操作系统
双击新建极坐标图,选择数据集为t_web_access_log_first,将维度操作系统拖入扇区标签/维度,将度量访问人数拖入扇区长度/度量,然后在样式中修改标题为访客操作系统。
点击更新,结果如下:
访客网络运营商
双击新建饼图,选择数据集为t_web_access_log_first,将维度运营商拖入扇区标签/维度,将度量访问人数拖入扇区角度/度量,然后在样式中修改标题为访客网络运营商。
点击更新,结果如下:
最后再次保存仪表板,预览效果如下(可以根据自己喜好排列)。
仪表板保存好后,可以点击左侧的作品,然后找刚刚保存的仪表板,在展开操作。
选择分享,即分享给其他阿里云用户
选择公开,即生成仪表板的链接,任何人都可以通过这个链接来访问。
如果有兴趣可以创建数据门户,它可以将多个仪表板组件成一个门户网站。