网络日志数据session案例(上)

编程入门 行业动态 更新时间:2024-10-24 17:26:19

<a href=https://www.elefans.com/category/jswz/34/1630058.html style=网络日志数据session案例(上)"/>

网络日志数据session案例(上)

转载自www.51doit.com培训班的课程案例

194.237.142.21 - - [18/Sep/2013:06:49:18 +0000] "GET /wp-content/uploads/2013/07/rstudio-git3.png HTTP/1.1" 304 0 "-" "Mozilla/4.0 (compatible;)"
183.49.46.228 - - [18/Sep/2013:06:49:23 +0000] "-" 400 0 "-" "-"
163.177.71.12 - - [18/Sep/2013:06:49:33 +0000] "HEAD / HTTP/1.1" 200 20 "-" "DNSPod-Monitor/1.0"
163.177.71.12 - - [18/Sep/2013:06:49:36 +0000] "HEAD / HTTP/1.1" 200 20 "-" "DNSPod-Monitor/1.0"
101.226.68.137 - - [18/Sep/2013:06:49:42 +0000] "HEAD / HTTP/1.1" 200 20 "-" "DNSPod-Monitor/1.0"
101.226.68.137 - - [18/Sep/2013:06:49:45 +0000] "HEAD / HTTP/1.1" 200 20 "-" "DNSPod-Monitor/1.0"
60.208.6.156 - - [18/Sep/2013:06:49:48 +0000] "GET /wp-content/uploads/2013/07/rcassandra.png HTTP/1.0" 200 185524 "/category/software/packages/" "Mozilla/5.0 (Windows NT 6.1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/29.0.1547.66 Safari/537.36"
222.68.172.190 - - [18/Sep/2013:06:49:57 +0000] "GET /images/my.jpg HTTP/1.1" 200 19939 "" "Mozilla/5.0 (Windows NT 6.1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/29.0.1547.66 Safari/537.36"
222.68.172.190 - - [18/Sep/2013:06:50:08 +0000] "-" 400 0 "-" "-"

数据中的字段分别为:
访客ip地址
访客访问时间
访客请求的url及协议
网站响应码
网站返回数据量
访客的referral url
访客的客户端操作系统及浏览器信息

需求:

1)需要为从访问日志中梳理出每一个session(如果一个用户两次相邻请求之间的时间差<30分钟,则该两次请求都属于同一个session(不考虑不同的URL),否则分属不同的session),并为session中的历次请求打上序号,示意如下:
session号 ip地址 请求时间 请求url 请求次序 其他字段……
session1 ip1 2017-10-11 08:10:30 /a 1 ……
session1 ip1 2017-10-11 08:11:20 /b 2 ……
session2 ip1 2017-10-11 09:10:30 /c 1 ……

步骤分析:

1 读取日志文件,获取用户请求数据,会根据用户的ip进行分组 (Map)
2 将用户的url按照时间排序
3 判断两个相邻的url的时间差值是否是在30分钟内来确定是否是同一个session
4 判断为每个url生成sessionId并打上运行顺序标签


SessionBean
public class SessionBean {private long session;//sessionIDprivate String ip;private Date time;//时间private String url;private int order;//请求次序

读取用户数据并且存在map中
Map<String, List<SessionBean>> map = new HashMap<>();//ip 时间 url 的正则表达式String ipRex = "(\\d{1,3}+\\.){3}\\d{1,3}";String timeRex = "\\[.+\\d\\]";String urlRegex = "(GET|POST){1}\\s(\\S)*\\s";BufferedReader br = new BufferedReader(new FileReader("d:/data/fensi.log"));String line;while((line=br.readLine())!=null) {//获取ip  time urlString ip = MyUtils.getStrByRegex(line,ipRex);String date = MyUtils.getStrByRegex(line,timeRex);String url = MyUtils.getStrByRegex(line,urlRegex);//[18/Sep/2013:06:49:42 +0000] 时间格式不是我需要的//对date进行formatDate time = MyUtils.formatDate(date);//创建bean,session默认1,order默认1SessionBean bean = new SessionBean(1, ip, time, url, 1);List<SessionBean> list = map.getOrDefault(ip, new ArrayList<>());list.add(bean);//得到mapmap.put(ip, list);}
使用正则表达式获取字段的方法:
public static String getStrByRegex(String line, String regex) {String res = null;Pattern p = Pattern.compile(regex);Matcher m = p.matcher(line);while (m.find()) {res = m.group();}return res;}
日期格式化:
public static Date formatDate(String date) {Date date2 = null;// [18/Sep/2013:06:49:18 +0000]if (date != null) {try {// 18/Sep/2013:06:49:18 +0000String str = date.substring(1, date.length() - 1);SimpleDateFormat sdf = new SimpleDateFormat("dd/MMM/yyyy:HH:mm:ss", Locale.US);date2 = sdf.parse(str);} catch (ParseException e) {e.printStackTrace();}}return date2;}

对map中的value按时间排序:
public static Map<String, List<SessionBean>> sortMapByTime(Map<String, List<SessionBean>> map) {Map<String, List<SessionBean>> sortMap = new HashMap<>();Set<Entry<String, List<SessionBean>>> set = map.entrySet();// 遍历setfor (Entry<String, List<SessionBean>> entry : set) {String key = entry.getKey();List<SessionBean> value = entry.getValue();// 对value排序,按时间顺序if(value.size()>1) {Collections.sort(value, (o1, o2) -> o1.getTime().compareTo(o2.getTime()));}sortMap.put(key, value);}return sortMap;}

对sortMap遍历
  1. value元素只有一个就设置session为唯一的值(纳秒值),order已经默认1,不要设置
  2. value里面的元素大于1个,前后元素按时间做减法

    1. 第一个元素的session直接设置唯一的值,order默认1

    2. 时间小于30分钟,这两个就是同一session,将前一个session值赋给后面,order+1

    3. 时间大于30分钟,这两个不是同一个session,后一个session设置唯一纳秒值,order默认1
  3. 遍历结束实现需求
Set<Entry<String, List<SessionBean>>> set = sortMap.entrySet();for (Entry<String, List<SessionBean>> entry : set) {List<SessionBean> list = entry.getValue();if(list.size()==1) {//只有一个元素,不用比较,直接赋值,order在创建bean时已经默认1,这里不用重赋值list.get(0).setSession(System.nanoTime());}else {//元素2个以上,比较前后是否在30分钟内,for循环嵌套for (int i = 0; i < list.size()-1; i++) {//给第一个sessionBean的session赋值if(i==0) {//唯一的纳秒值list.get(0).setSession(System.nanoTime());}for (int j = i+1; j < list.size(); j++) {SessionBean sessionBean1 = list.get(i);SessionBean sessionBean2 = list.get(j);//true->同一个session,false->不同的sessionboolean flag = MyUtils.compareSessionBeanByTime(sessionBean1,sessionBean2);if(flag) {//相差不到30分钟,同一个session ,oder设置sessionBean2.setSession(sessionBean1.getSession());sessionBean2.setOrder(sessionBean1.getOrder()+1);}else {//超过30分钟,设置不同的session,前bean不设置 后一个bean 给session赋值,order默认1不用赋值sessionBean2.setSession(System.nanoTime());}}}}//打印得到结果list.forEach(System.out::println);

判断两个SessionBean是否是同一个Session:
public static boolean compareSessionBeanByTime(SessionBean sessionBean1, SessionBean sessionBean2) {long t1 = sessionBean1.getTime().getTime();long t2 = sessionBean2.getTime().getTime();long tem = t2-t1;if(tem<30*60*1000) {//小于30分钟return true;}return false;}

更多推荐

网络日志数据session案例(上)

本文发布于:2023-07-28 21:05:30,感谢您对本站的认可!
本文链接:https://www.elefans.com/category/jswz/34/1318625.html
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。
本文标签:网络日志   案例   数据   session

发布评论

评论列表 (有 0 条评论)
草根站长

>www.elefans.com

编程频道|电子爱好者 - 技术资讯及电子产品介绍!