Beispiel #1
0
 @Override
 public void updateUserStats(List<UserStatisticsVO> userStats) {
   Transaction txn = Transaction.currentTxn();
   try {
     txn.start();
     String sql = UPDATE_USER_STATS;
     PreparedStatement pstmt = null;
     pstmt =
         txn.prepareAutoCloseStatement(
             sql); // in reality I just want CLOUD_USAGE dataSource connection
     for (UserStatisticsVO userStat : userStats) {
       pstmt.setLong(1, userStat.getNetBytesReceived());
       pstmt.setLong(2, userStat.getNetBytesSent());
       pstmt.setLong(3, userStat.getCurrentBytesReceived());
       pstmt.setLong(4, userStat.getCurrentBytesSent());
       pstmt.setLong(5, userStat.getAggBytesReceived());
       pstmt.setLong(6, userStat.getAggBytesSent());
       pstmt.setLong(7, userStat.getId());
       pstmt.addBatch();
     }
     pstmt.executeBatch();
     txn.commit();
   } catch (Exception ex) {
     txn.rollback();
     s_logger.error("error saving user stats to cloud_usage db", ex);
     throw new CloudRuntimeException(ex.getMessage());
   }
 }
Beispiel #2
0
 @Override
 public void saveUserStats(List<UserStatisticsVO> userStats) {
   Transaction txn = Transaction.currentTxn();
   try {
     txn.start();
     String sql = INSERT_USER_STATS;
     PreparedStatement pstmt = null;
     pstmt =
         txn.prepareAutoCloseStatement(
             sql); // in reality I just want CLOUD_USAGE dataSource connection
     for (UserStatisticsVO userStat : userStats) {
       pstmt.setLong(1, userStat.getId());
       pstmt.setLong(2, userStat.getDataCenterId());
       pstmt.setLong(3, userStat.getAccountId());
       pstmt.setString(4, userStat.getPublicIpAddress());
       if (userStat.getDeviceId() != null) {
         pstmt.setLong(5, userStat.getDeviceId());
       } else {
         pstmt.setNull(5, Types.BIGINT);
       }
       pstmt.setString(6, userStat.getDeviceType());
       if (userStat.getNetworkId() != null) {
         pstmt.setLong(7, userStat.getNetworkId());
       } else {
         pstmt.setNull(7, Types.BIGINT);
       }
       pstmt.setLong(8, userStat.getNetBytesReceived());
       pstmt.setLong(9, userStat.getNetBytesSent());
       pstmt.setLong(10, userStat.getCurrentBytesReceived());
       pstmt.setLong(11, userStat.getCurrentBytesSent());
       pstmt.setLong(12, userStat.getAggBytesReceived());
       pstmt.setLong(13, userStat.getAggBytesSent());
       pstmt.addBatch();
     }
     pstmt.executeBatch();
     txn.commit();
   } catch (Exception ex) {
     txn.rollback();
     s_logger.error("error saving user stats to cloud_usage db", ex);
     throw new CloudRuntimeException(ex.getMessage());
   }
 }
    private boolean collectDirectNetworkUsage(HostVO host) {
      s_logger.debug("Direct Network Usage stats collector is running...");

      long zoneId = host.getDataCenterId();
      DetailVO lastCollectDetail = _detailsDao.findDetail(host.getId(), "last_collection");
      if (lastCollectDetail == null) {
        s_logger.warn(
            "Last collection time not available. Skipping direct usage collection for Traffic Monitor: "
                + host.getId());
        return false;
      }
      Date lastCollection = new Date(new Long(lastCollectDetail.getValue()));

      // Get list of IPs currently allocated
      List<IPAddressVO> allocatedIps = listAllocatedDirectIps(zoneId);
      Calendar rightNow = Calendar.getInstance();

      // Allow 2 hours for traffic sentinel to populate historical traffic
      // This coule be made configurable

      rightNow.add(Calendar.HOUR_OF_DAY, -2);
      Date now = rightNow.getTime();

      if (lastCollection.after(now)) {
        s_logger.debug(
            "Current time is less than 2 hours after last collection time : "
                + lastCollection.toString()
                + ". Skipping direct network usage collection");
        return false;
      }

      // Get IP Assign/Release events from lastCollection time till now
      List<UsageEventVO> IpEvents = _eventDao.listDirectIpEvents(lastCollection, now, zoneId);

      Map<String, Date> ipAssigment = new HashMap<String, Date>();
      List<UsageIPAddressVO> IpPartialUsage =
          new ArrayList<
              UsageIPAddressVO>(); // Ips which were allocated only for the part of collection
                                   // duration
      List<UsageIPAddressVO> fullDurationIpUsage =
          new ArrayList<
              UsageIPAddressVO>(); // Ips which were allocated only for the entire collection
                                   // duration

      // Use UsageEvents to track the IP assignment
      // Add them to IpUsage list with account_id , ip_address, alloc_date, release_date

      for (UsageEventVO IpEvent : IpEvents) {
        String address = IpEvent.getResourceName();
        if (EventTypes.EVENT_NET_IP_ASSIGN.equals(IpEvent.getType())) {
          ipAssigment.put(address, IpEvent.getCreateDate());
        } else if (EventTypes.EVENT_NET_IP_RELEASE.equals(IpEvent.getType())) {
          if (ipAssigment.containsKey(address)) {
            Date assigned = ipAssigment.get(address);
            ipAssigment.remove(address);
            IpPartialUsage.add(
                new UsageIPAddressVO(
                    IpEvent.getAccountId(), address, assigned, IpEvent.getCreateDate()));
          } else {
            // Ip was assigned prior to lastCollection Date
            IpPartialUsage.add(
                new UsageIPAddressVO(
                    IpEvent.getAccountId(), address, lastCollection, IpEvent.getCreateDate()));
          }
        }
      }

      List<String> IpList = new ArrayList<String>();
      for (IPAddressVO ip : allocatedIps) {
        if (ip.getAllocatedToAccountId() == AccountVO.ACCOUNT_ID_SYSTEM) {
          // Ignore usage for system account
          continue;
        }
        String address = (ip.getAddress()).toString();
        if (ipAssigment.containsKey(address)) {
          // Ip was assigned during the current period but not release till Date now
          IpPartialUsage.add(
              new UsageIPAddressVO(
                  ip.getAllocatedToAccountId(), address, ipAssigment.get(address), now));
        } else {
          // Ip was not assigned or released during current period. Consider entire duration for
          // usage calculation (lastCollection to now)
          fullDurationIpUsage.add(
              new UsageIPAddressVO(ip.getAllocatedToAccountId(), address, lastCollection, now));
          // Store just the Ips to send the list as part of DirectNetworkUsageCommand
          IpList.add(address);
        }
      }

      List<UserStatisticsVO> collectedStats = new ArrayList<UserStatisticsVO>();

      // Get usage for Ips which were assigned for the entire duration
      if (fullDurationIpUsage.size() > 0) {
        DirectNetworkUsageCommand cmd =
            new DirectNetworkUsageCommand(IpList, lastCollection, now, _TSinclZones, _TSexclZones);
        DirectNetworkUsageAnswer answer =
            (DirectNetworkUsageAnswer) _agentMgr.easySend(host.getId(), cmd);
        if (answer == null || !answer.getResult()) {
          String details = (answer != null) ? answer.getDetails() : "details unavailable";
          String msg =
              "Unable to get network usage stats from "
                  + host.getId()
                  + " due to: "
                  + details
                  + ".";
          s_logger.error(msg);
          return false;
        } else {
          for (UsageIPAddressVO usageIp : fullDurationIpUsage) {
            String publicIp = usageIp.getAddress();
            long[] bytesSentRcvd = answer.get(publicIp);
            Long bytesSent = bytesSentRcvd[0];
            Long bytesRcvd = bytesSentRcvd[1];
            if (bytesSent == null || bytesRcvd == null) {
              s_logger.debug("Incorrect bytes for IP: " + publicIp);
              continue;
            }
            if (bytesSent == 0L && bytesRcvd == 0L) {
              s_logger.trace("Ignore zero bytes for IP: " + publicIp);
              continue;
            }
            UserStatisticsVO stats =
                new UserStatisticsVO(usageIp.getAccountId(), zoneId, null, null, null, null);
            stats.setCurrentBytesSent(bytesSent);
            stats.setCurrentBytesReceived(bytesRcvd);
            collectedStats.add(stats);
          }
        }
      }

      // Get usage for Ips which were assigned for part of the duration period
      for (UsageIPAddressVO usageIp : IpPartialUsage) {
        IpList = new ArrayList<String>();
        IpList.add(usageIp.getAddress());
        DirectNetworkUsageCommand cmd =
            new DirectNetworkUsageCommand(
                IpList, usageIp.getAssigned(), usageIp.getReleased(), _TSinclZones, _TSexclZones);
        DirectNetworkUsageAnswer answer =
            (DirectNetworkUsageAnswer) _agentMgr.easySend(host.getId(), cmd);
        if (answer == null || !answer.getResult()) {
          String details = (answer != null) ? answer.getDetails() : "details unavailable";
          String msg =
              "Unable to get network usage stats from "
                  + host.getId()
                  + " due to: "
                  + details
                  + ".";
          s_logger.error(msg);
          return false;
        } else {
          String publicIp = usageIp.getAddress();
          long[] bytesSentRcvd = answer.get(publicIp);
          Long bytesSent = bytesSentRcvd[0];
          Long bytesRcvd = bytesSentRcvd[1];
          if (bytesSent == null || bytesRcvd == null) {
            s_logger.debug("Incorrect bytes for IP: " + publicIp);
            continue;
          }
          if (bytesSent == 0L && bytesRcvd == 0L) {
            s_logger.trace("Ignore zero bytes for IP: " + publicIp);
            continue;
          }
          UserStatisticsVO stats =
              new UserStatisticsVO(usageIp.getAccountId(), zoneId, null, null, null, null);
          stats.setCurrentBytesSent(bytesSent);
          stats.setCurrentBytesReceived(bytesRcvd);
          collectedStats.add(stats);
        }
      }

      if (collectedStats.size() == 0) {
        s_logger.debug("No new direct network stats. No need to persist");
        return false;
      }
      // Persist all the stats and last_collection time in a single transaction
      Transaction txn = Transaction.open(Transaction.CLOUD_DB);
      try {
        txn.start();
        for (UserStatisticsVO stat : collectedStats) {
          UserStatisticsVO stats =
              _statsDao.lock(
                  stat.getAccountId(),
                  stat.getDataCenterId(),
                  0L,
                  null,
                  host.getId(),
                  "DirectNetwork");
          if (stats == null) {
            stats =
                new UserStatisticsVO(
                    stat.getAccountId(), zoneId, null, host.getId(), "DirectNetwork", 0L);
            stats.setCurrentBytesSent(stat.getCurrentBytesSent());
            stats.setCurrentBytesReceived(stat.getCurrentBytesReceived());
            _statsDao.persist(stats);
          } else {
            stats.setCurrentBytesSent(stats.getCurrentBytesSent() + stat.getCurrentBytesSent());
            stats.setCurrentBytesReceived(
                stats.getCurrentBytesReceived() + stat.getCurrentBytesReceived());
            _statsDao.update(stats.getId(), stats);
          }
        }
        lastCollectDetail.setValue("" + now.getTime());
        _detailsDao.update(lastCollectDetail.getId(), lastCollectDetail);
        txn.commit();
      } finally {
        txn.close();
      }

      return true;
    }