零基础学习java------29---------网络日志数据session案例,runtime
Posted jj1106
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了零基础学习java------29---------网络日志数据session案例,runtime相关的知识,希望对你有一定的参考价值。
一. 网络日志数据session案例
部分数据
数据中的字段分别为:
访客ip地址,访客访问时间,访客请求的url及协议,网站响应码,网站返回数据量,访客的referral url,访客的客户端操作系统及浏览器信息
需求:
(1)
需要为从访问日志中梳理出每一个session(如果一个用户两次相邻请求之间的时间差<30分钟,则该两次请求都属于同一个session(不考虑不同的URL),否则分属不同的session),并为session中的历次请求打上序号,示意如下:
(2) 将每次session进行汇总,得出用户每次session的浏览起、止页面,每次session会话总时长等,示意如下:
步骤分析:
1 读取日志文件,获取用户请求数据,会根据用户的ip进行分组 (Map)
2 将用户的url按照时间排序
3. 判断两个相邻的url的时间差值是否是在30分钟内来确定是否是同一个session
4. 判断为每个url生成sessionId并打上运行顺序标签
5. 第二问,获取sessionId相同的url,得出最先请求和最终请求的两个url和之间的时间差值
写代码时犯的一些错误
(1)写正则时,忽视了空格的存在,空格也会进行正则的匹配(),自己将第一个写成(\\\\d1,3\\\\.)(此处自己无意间加了一个空格)3\\\\d1,3,导致匹配失败
(2)代码写的位置出现问题
将2处的代码块写在1处,导致打印结果出现问题
说明:此处只写第一问的代码
工具类(SessionUtils):
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;
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 + "]";
主程序(main)
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 = "(\\\\d1,3\\\\.)3\\\\d1,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);
二. 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)执行本机命令
以上是关于零基础学习java------29---------网络日志数据session案例,runtime的主要内容,如果未能解决你的问题,请参考以下文章