短链接监控

   private void shortLinkStats(String fullShortUrl,String gid,HttpServletRequest request,HttpServletResponse response){


        /**
         * uv,pv,ip监控
        **/
        AtomicBoolean uvFirstFlag =new AtomicBoolean();
        Cookie[] cookies = request.getCookies();




       try {

           AtomicReference<String> uv =new AtomicReference<>();
           Runnable addResponseCookieTask =()->{
               uv.set( cn.hutool.core.lang.UUID.fastUUID().toString());
               Cookie uvCookie = new Cookie("uv", uv.get());
               uvCookie.setMaxAge(60*60*24*30);
               //为什么要设置路径
               uvCookie.setPath(StrUtil.sub(fullShortUrl,fullShortUrl.indexOf("/"),fullShortUrl.length()));
               response.addCookie(uvCookie);
               uvFirstFlag.set(Boolean.TRUE);
               stringRedisTemplate.opsForSet().add("short-link-status:uv:"+fullShortUrl,uv.get());
           };

           if(ArrayUtil.isNotEmpty(cookies)){
               //过滤流中cookie的名字是"uv"的
               //找到第一个就不再遍历其他的元素
               //将流中的所有元素用自己的的value代替
               //ifPresentOrElse,如果找到了名字是"uv"的,就存redis的set,存成功了就给uvFirstFlag赋值true,否则就是false,如果没有找到名字是"uv"的,就执行addResponseCookieTask任务
               Arrays.stream(cookies)
                       .filter(each -> Objects.equals(each.getName(),"uv"))
                       .findFirst()
                       .map(Cookie::getValue)
                       .ifPresentOrElse(each->{
                           uv.set(each);
                           Long added =stringRedisTemplate.opsForSet().add("short-link-status:uv:"+fullShortUrl,each);
                           uvFirstFlag.set(added!=null&&added>0L);
                       },addResponseCookieTask);
           }else {
               addResponseCookieTask.run();
           }

           //判断ip是否重复
           String remoteAddr = LinkUtil.getIp(request);
           Long uipAdded = stringRedisTemplate.opsForSet().add("short-link:stats:uip:" + fullShortUrl, remoteAddr);
           boolean uipFirstFlag =uipAdded!=null&&uipAdded>0L;

           //如果gid是空的就查一下路由表
           if(StrUtil.isBlank(gid)){
               LambdaQueryWrapper<ShortLinkGotoDO> eq = Wrappers.lambdaQuery(ShortLinkGotoDO.class)
                       .eq(ShortLinkGotoDO::getFullShortUrl, fullShortUrl);
               ShortLinkGotoDO shortLinkGotoDO = shortLinkGotoMapper.selectOne(eq);
               gid =shortLinkGotoDO.getGid();
           }

           int hour  = DateUtil.hour(new Date(),true);
           Week week = DateUtil.dayOfWeekEnum(new Date());
           int weekValue = week.getIso8601Value();
           LinkAccessStatsDO linkAccessStatsDO =LinkAccessStatsDO.builder()
                   .pv(1)
                   .uv(uvFirstFlag.get()?1:0)
                   .uip(uipFirstFlag?1:0)
                   .hour(hour)
                   .weekday(weekValue)
                   .fullShortUrl(fullShortUrl)
                   .gid(gid)
                   .date(new Date())
                   .build();
           linkAccessStatsMapper.shortLinkStats(linkAccessStatsDO);


           /**
            * 地区信息监控
           **/
           //调用高德地图API获取地区信息
           HashMap<String, Object> requestMap = new HashMap<>();

           requestMap.put("key", statsLocaleAmapKey);
           requestMap.put("ip",remoteAddr);
           String result = HttpUtil.get(AMAP_REMOTE_URL, requestMap);
           JSONObject localeResultObj= JSON.parseObject(result);
           String infocode = localeResultObj.getString("infocode");

           String province=null;
           String city=null;
           LinkLocaleStatsDO linkLocaleStatsDO;
           if(StrUtil.isNotBlank(infocode)&&StrUtil.equals(infocode,"10000")){
               province = StrUtil.equals("[]",localeResultObj.getString("province"))?"未知":localeResultObj.getString("province");
               city = StrUtil.equals("[]",localeResultObj.getString("city"))?"未知":localeResultObj.getString("city");
               String adcode = localeResultObj.getString("adcode");
              linkLocaleStatsDO  = LinkLocaleStatsDO.builder()
                       .city(city)
                       .province(province)
                       .adcode( StrUtil.isBlank(adcode)?"未知":adcode)
                       .country("中国")
                       .cnt(1)
                       .fullShortUrl(fullShortUrl)
                       .gid(gid)
                       .date(new Date())
                       .build();
               linkLocaleStatsMapper.shortLinkLocaleStats(linkLocaleStatsDO);
           }

           /**
            * 操作系统信息监控
           **/

           String os = LinkUtil.getOs(request);
           LinkOsStatsDO linkOsStatsDO = LinkOsStatsDO.builder()
                   .cnt(1)
                   .fullShortUrl(fullShortUrl)
                   .os(os)
                   .gid(gid)
                   .date(new Date())
                   .build();
           linkOsStatsMapper.shortLinkOsStats(linkOsStatsDO);

           /**
            * 浏览器监控
           **/

           String browser = LinkUtil.getBrowser(request);
           LinkBrowserStatsDO linkBrowserStatsDO =LinkBrowserStatsDO.builder()
                   .cnt(1)
                   .fullShortUrl(fullShortUrl)
                   .browser(browser)
                   .gid(gid)
                   .date(new Date())
                   .build();

           linkBrowserStatsMapper.shortLinkBrowserStats(linkBrowserStatsDO);


           /**
            * 访问设备监控
           **/

           String device = LinkUtil.getDevice(request);
           LinkDeviceStatsDO linkDeviceStatsDO = LinkDeviceStatsDO.builder()
                   .device(device)
                   .cnt(1)
                   .fullShortUrl(fullShortUrl)
                   .date(new Date())
                   .build();
           linkDeviceStatsMapper.shortLinkDeviceState(linkDeviceStatsDO);

           /**
            * 访问网络监控
           **/
           String network = LinkUtil.getNetwork(request);
           LinkNetworkStatsDO linkNetworkStatsDO = LinkNetworkStatsDO.builder()
                   .network(network)
                   .cnt(1)
                   .gid(gid)
                   .fullShortUrl(fullShortUrl)
                   .date(new Date())
                   .build();
           linkNetworkStatsMapper.shortLinkNetworkState(linkNetworkStatsDO);

           /**
            * 访问日志
           **/

           LinkAccessLogsDO linkAccessLogsDO = LinkAccessLogsDO.builder()
                   .ip(remoteAddr)
                   .user(uv.get())
                   .os(os)
                   .browser(browser)
                   .fullShortUrl(fullShortUrl)
                   .gid(gid)
                   .device(device)
                   .locale(StrUtil.join("-","中国",province,city))
                   .network(network)
                   .build();
           linkAccessLogsMapper.insert(linkAccessLogsDO);

           //增加该短链接的总访问数
           baseMapper.incrementStats(gid, fullShortUrl, 1, uvFirstFlag.get() ? 1 : 0, uipFirstFlag ? 1 : 0);

           LinkStatsTodayDO linkStatsTodayDO = LinkStatsTodayDO.builder()
                   .todayPv(1)
                   .todayUv(uvFirstFlag.get() ? 1 : 0)
                   .todayUip(uipFirstFlag ? 1 : 0)
                   .gid(gid)
                   .fullShortUrl(fullShortUrl)
                   .date(new Date())
                   .build();
           linkStatsTodayMapper.shortLinkTodayState(linkStatsTodayDO);
       }catch (Throwable e){
           log.error("短链接访问统计异常",e);
       }


    }

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值