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

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 "http://cos.name/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 "http://www.angularjs.cn/A00n" "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 String sessionId;
    private String ip;
    private String url;
    private Date date;
    private int order;**

    public String getSessionId() {
        return sessionId;
    }
    public void setSessionId(String sessionId) {
        this.sessionId = sessionId;
    }
    public String getIp() {
        return ip;
    }
    public void setIp(String ip) {
        this.ip = ip;
    }
    public String getUrl() {
        return url;
    }
    public void setUrl(String url) {
        this.url = url;
    }
    public Date getDate() {
        return date;
    }
    public void setDate(Date date) {
        this.date = date;
    }
    public int getOrder() {
        return order;
    }
    public void setOrder(int order) {
        this.order =order;
    }
    @Override
    public String toString() {
        return "SessionBean [sessionId=" + sessionId + ", ip=" + ip + ", url="
                + url + ", date=" + date + ", order=" + order + "]";
    }

}

读取用户数据并且存在map中

try(
            BufferedReader br = new BufferedReader(new FileReader("f:/access.log.fensi"));
            ) {
        Map<String,List<SessionBean>> map=new HashMap<>();
        String line=null;
        String ipRex = "(\\d{1,3}+\\.){3}\\d{1,3}";
        String timeRex = "\\[.+\\d\\]";
        String urlRegex = "(GET|POST){1}\\s(\\S)*\\s";
        while((line=br.readLine())!=null){
        //在一行里面获取制定规则的数据(调用方法据正则表达式获取内容)
        String ip = Myutils.getStrByRex(line, ipRex);
        String timestr = Myutils.getStrByRex(line, timeRex);
        String url = Myutils.getStrByRex(line,urlRegex);
        List<SessionBean> list = map.getOrDefault(ip, new ArrayList<>());
        //创建sessionBean 【sessionId order】
        SessionBean sessionBean = new SessionBean();
        sessionBean.setIp(ip);
        sessionBean.setUrl(url);
        //将字符串转换为时间对象
        //[18/Sep/2013:06:49:42 +0000] 时间格式不是我需要的
        //对字符串进行parse
        Date date = Myutils.parseDate(timestr);
        sessionBean.setDate(date);
        list.add(sessionBean);//sessionBean添加到list中去 
        //更新map数据
        map.put(ip, list);//list作为value传入map中
        }



**使用正则表达式获取字段的方法:**
public static String getStrByRex(String line,String rex){
    String res=null;
    Pattern pattern = Pattern.compile(rex);//获取一个pattern对象  并编译正则表达式
    Matcher m = pattern.matcher(line);//获取一个macher:匹配器  在这个对象中包含了匹配的结果
    //获取匹配的内容
    while(m.find()){//返回  boolean类型  判断是否找到
        res=m.group();//取内容    不能直接使用     必须要再find方法之后进行执行
    }
    return res;
}

**将字符串转换成时间对象**
@SuppressWarnings("null")
public static Date parseDate(String dateStr) throws ParseException{
    Date d  = null ;
    /*long t1 = d.getTime();
    long t2 = d.getTime();*/
    if(dateStr!=null){
        String str = dateStr.substring(1, dateStr.length()-1);//截取时间对象
        //将字符串  转换成时间对象
        SimpleDateFormat format = new SimpleDateFormat("dd/MMM/yyyy:HH:mm:ss" ,Locale.US) ;
         d = format.parse(str);
    }
    return d;
}

对map的value(list)进行排序
Myutils.sortMap(map);//直接调用

List中的SessionBean按照时间先后顺序排列
public static void sortMap(Map<String,List<SessionBean>>map){
    Set<Entry<String, List<SessionBean>>> entrySet = map.entrySet();
    for (Entry<String, List<SessionBean>> entry : entrySet) {
        String ip = entry.getKey();
        List<SessionBean> list = entry.getValue();
        //对list排序
        if(list!=null&&list.size()>0){
            Collections.sort(list,new Comparator<SessionBean>() {

                @Override
                public int compare(SessionBean o1, SessionBean o2) {
                    return o1.getDate().compareTo(o2.getDate());
                }
            });
                for (SessionBean entry1 : list) {
                    //System.out.println(entry1);

                }
            }
        }

    }

//生成sessionID和序号并判断结果条件
createdSessionId(map);//调用方法

private static void createdSessionId(Map<String, List<SessionBean>> map) {
    Set<Entry<String, List<SessionBean>>> entrySet = map.entrySet();
    for (Entry<String, List<SessionBean>> entry : entrySet) {
        String ip = entry.getKey();   
        List<SessionBean> list = entry.getValue();
    //  1 list中只有一个数据    sessionid  1 
    //  2 list中有多条数据    前一个和后一个时间比较 来判断是否是同一个session
        if(list.size()==1){
            SessionBean bean = list.get(0);
            bean.setSessionId(Myutils.createsessionId());//sessionId不能重复(调用方法)
            bean.setOrder(1);
        }
        if(list.size()>1){
            for(int i=0;i<list.size()-1;i++){
                //判断相邻的数据  判断这个数据是不是同一个session  时间
                SessionBean presession = list.get(i);
                SessionBean aftersession = list.get(i+1);
                //判断是否为同一session
                if(Myutils.issamesession(presession, aftersession)){//相同session
                    //给两条数据设置sessionid和编号
                    //前面的数据没有sessionId
                    if(presession.getSessionId()==null){//如果为空直接创建sessionId
                        presession.setSessionId(Myutils.createsessionId());
                    }//如果有的话 则直接赋值给后一个数(他两相等)
                    aftersession.setSessionId(presession.getSessionId());
                if(presession.getOrder()==0){
                    presession.setOrder(1);//定义前一个序号为1
                }//有的话  后一个为前一个+1;
                aftersession.setOrder(presession.getOrder()+1);
            }else{//不同session
                if(presession.getSessionId()==null){
                    presession.setSessionId(Myutils.createsessionId());
                }
                aftersession.setSessionId(Myutils.createsessionId());
                if(presession.getOrder()==0){
                    presession.setOrder(1);
                }
                aftersession.setOrder(1);
            }
        }
    }
}
}
**生成SessionID 获取不重复的字符串**
public static String createsessionId(){
    UUID uid = UUID.randomUUID();
    String idstr = uid.toString();
    String sessionId = idstr.replace("-", "");//把"-"替换掉 
    return sessionId;

}
**//判断两个sessionBean是否是同一个session**
public static boolean issamesession(SessionBean presession,SessionBean aftersession){
        boolean flag=false;
        Date d1 = presession.getDate();
        Date d2 = aftersession.getDate();
        //判断两个时间间隔是否在30分钟之内
        long res=d2.getTime()-d1.getTime();
        if(res>=0&&res<=(30*60*1000)){
            flag=true; 
        }
            return flag;
}

遍历结果并打印

Set<Entry<String, List<SessionBean>>> entrySet = map.entrySet();
        for (Entry<String, List<SessionBean>> entry : entrySet) {
            String ip = entry.getKey();
            List<SessionBean> value = entry.getValue();
            for (SessionBean sessionBean2 : value) {
                //System.out.println(ip+" "+sessionBean2.getSessionId()+" "+sessionBean2.getDate()+" "+sessionBean2.getOrder());
            }

        }
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值