零基础学习java------29---------网络日志数据session案例,runtime

一. 网络日志数据session案例

部分数据

零基础学习java------29---------网络日志数据session案例,runtime

 

 

 数据中的字段分别为:

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

需求:

(1)  

  需要为从访问日志中梳理出每一个session(如果一个用户两次相邻请求之间的时间差<30分钟,则该两次请求都属于同一个session(不考虑不同的URL),否则分属不同的session),并为session中的历次请求打上序号,示意如下:

  零基础学习java------29---------网络日志数据session案例,runtime

 

 

 (2) 将每次session进行汇总,得出用户每次session的浏览起、止页面,每次session会话总时长等,示意如下:

  零基础学习java------29---------网络日志数据session案例,runtime

 

 

 步骤分析:

  1 读取日志文件,获取用户请求数据,会根据用户的ip进行分组 (Map)

  2 将用户的url按照时间排序

  3. 判断两个相邻的url的时间差值是否是在30分钟内来确定是否是同一个session

  4. 判断为每个url生成sessionId并打上运行顺序标签

  5. 第二问,获取sessionId相同的url,得出最先请求和最终请求的两个url和之间的时间差值

写代码时犯的一些错误

(1)写正则时,忽视了空格的存在,空格也会进行正则的匹配(),自己将第一个写成(\\d{1,3}\\.)(此处自己无意间加了一个空格){3}\\d{1,3},导致匹配失败

零基础学习java------29---------网络日志数据session案例,runtime

 

(2)代码写的位置出现问题

  将2处的代码块写在1处,导致打印结果出现问题

零基础学习java------29---------网络日志数据session案例,runtime

 

 

 说明:此处只写第一问的代码

工具类(SessionUtils):

零基础学习java------29---------网络日志数据session案例,runtime
public class SessionUtils {
    /**
     * 正则获取需要的子串
     * @param str
     * @param regex
     * @return
     */
    public static String getStrByRegex(String str,String regex) {
        String res = null;
        Pattern p = Pattern.compile(regex);
        Matcher matcher = p.matcher(str);
        while(matcher.find()) {
            res = matcher.group();
        }
        return res;
    }
    
    /**
     * 将字符串形式的时间转为date形式的时间
     * @param strDate
     * @return
     */
    public static Date parseStrToDate(String strDate) {
        Date date = null;
        try {
            if(strDate != null) {
                String str = strDate.substring(1, strDate.length() - 1);
                SimpleDateFormat sdf = new SimpleDateFormat("dd/MMM/yyyy:hh:mm:ss",Locale.US);
                date = sdf.parse(str);
            }
        } catch (ParseException e) {
            e.printStackTrace();
        }
        return date;
    }
    
    
    /**
     * 获取唯一的sessionId
     * @return
     */
    public static String getSessionId() {
        UUID uuid = UUID.randomUUID();
        String str = uuid.toString();
        String sessionId = str.replaceAll("-","");
        return sessionId;
    }
    
    /**
     * 将map中的list以date的形式排序
     * @param map
     */
    public static void sortDate(Map<String, List<SessionBean>> map) {
        Set<Entry<String,List<SessionBean>>> entrySet = map.entrySet();
        for (Entry<String, List<SessionBean>> entry : entrySet) {
            List<SessionBean> list = entry.getValue();
            Collections.sort(list, new Comparator<SessionBean>() {
                @Override
                public int compare(SessionBean o1, SessionBean o2) {
                    return o1.getDate().before(o2.getDate())?-1:1;
                }
            });
        }
    }
    /**
     * 判断两个相邻的sessionBean是否是同一个sessionId
     * @param bean1
     * @param bean2
     * @return
     */
    public static boolean isSameSession(SessionBean bean1, SessionBean bean2) {
        boolean res = false;
        //
        if (bean1 != null && bean2 != null) {
            Date d1 = bean1.getDate();
            Date d2 = bean2.getDate();
            long l = d2.getTime() - d1.getTime();
            if (l >= 0 && l <= 30 * 60 * 1000) {
                res = true;
            }
        }
        return res;
    }
}
View Code

SessionBean

零基础学习java------29---------网络日志数据session案例,runtime
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 + "]";
    }
    
    
}
View Code

主程序(main)

零基础学习java------29---------网络日志数据session案例,runtime
public class TestMain {
    public static void main(String[] args) {
        
        // 读取数据并使用正则获取相应的子串
//        List<SessionBean> list = new ArrayList<SessionBean>();
        Map<String, List<SessionBean>> map = new HashMap<>();
        try (
                BufferedReader br = new BufferedReader(new FileReader("E:\\javafile\\session.txt"));
                ){
            String line = null;
            while((line = br.readLine())!= null) {
                // 正则获取相应的字段
                String ipRegex = "(\\d{1,3}\\.){3}\\d{1,3}";
                String timeRegex = "\\[.+\\d\\]";
                String urlRegex = "(GET|POST){1}\\s(\\S)*\\s";
                String ip = SessionUtils.getStrByRegex(line, ipRegex);
                String strDate = SessionUtils.getStrByRegex(line, timeRegex);
                String url = SessionUtils.getStrByRegex(line, urlRegex);
                // 将字符串形式的时间转为date形式的时间
                Date date = SessionUtils.parseStrToDate(strDate);
                SessionBean bean = new SessionBean();
                bean.setIp(ip);
                bean.setDate(date);
                bean.setUrl(url);
                List<SessionBean> list = map.getOrDefault(ip, new ArrayList<SessionBean>());
                list.add(bean);
                map.put(ip, list);
                
            }
            //map的list按照时间的先后顺序排列
            SessionUtils.sortDate(map);
            // 生成sessionId以及编号
            getResult(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();
                for(SessionBean sessionBean:list) {
                    System.out.println(ip+"==="+sessionBean.getSessionId()+"=="+sessionBean.getOrder());
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    private static void getResult(Map<String, List<SessionBean>> map) {
        Set<Entry<String, List<SessionBean>>> entrySet = map.entrySet();
        for (Entry<String, List<SessionBean>> entry : entrySet) {
            List<SessionBean> list2 = entry.getValue();
            // list内只有一个SessionBean的情况
            if(list2.size() == 1) {
                SessionBean sb = list2.get(0);
                String sessionId = SessionUtils.getSessionId();
                sb.setSessionId(sessionId);
                sb.setOrder(1);
            }
            // list内超过两个SessionBean的情况
            if(list2.size() >=2) {
                for (int i = 0; i < list2.size()-1; i++) {
                    SessionBean sb1 = list2.get(i);
                    SessionBean sb2 = list2.get(i+1);
                    // 当两个SessionBean的sessionId相同时,设置sessionId和编号
                    if(SessionUtils.isSameSession(sb1, sb2)) {
                        if(sb1.getSessionId() == null) {
                            String sessionId = SessionUtils.getSessionId();
                            sb1.setSessionId(sessionId);
                        }
                        sb2.setSessionId(sb1.getSessionId());
                        if(sb1.getOrder() == 0) {
                            sb1.setOrder(1);
                        }
                        sb2.setOrder(sb1.getOrder()+1);
                    // 当两个SessionBean的sessionId不同时,设置sessionId和编号
                    }else {
                        if(sb1.getSessionId() == null) {
                            String sessionId = SessionUtils.getSessionId();
                            sb1.setSessionId(sessionId);
                        }
                        String sessionId = SessionUtils.getSessionId();
                        sb2.setSessionId(sessionId);
                        if(sb1.getOrder() == 0) {
                            sb1.setOrder(1);
                        }
                        sb2.setOrder(1);
                    }
                }
            }
        }
    }
}
View Code

 

 二.  runtime

在java中Runtime类表示运行时操作类,是一个封装了JVM进程的类,每一个JVM都对应着一个Runtime类的实例,此实例由JVM运行时为其实例化。所以在JDK文档中读者不会发现任何有关Runtime类中构造方法的定义,这是因为Runtime类本身的构造方法是私有化的(单例设计),如果想要得到一个Runtime实例,只有以下方法:
Runtime run=Runtime.getRuntime();

也就是说在Runtime类中提供了一个静态的getRuntime()方法,此类可以取得Runtime类的实例,然后通过Runtime就可以取得一些系统的信息。如,getRuntime(),取得Runtime实例;freeMemory()返回java虚拟机中的空闲内存量;maxMemory()返回JVM的最大内存量;gc()运行垃圾回收器,释放空间;exec(command)执行本机命令

 

上一篇:apache——(OS 10048)通常每个套接字地址(协议/网络地址/端口)只允许使用一次。 : AH00072: make_sock: could not bind to address [::]:443


下一篇:用python计算lda语言模型的困惑度并作图