diff --git a/engine/schema/src/com/cloud/usage/dao/UsageDao.java b/engine/schema/src/com/cloud/usage/dao/UsageDao.java index 8a806553112..f571b63ce40 100644 --- a/engine/schema/src/com/cloud/usage/dao/UsageDao.java +++ b/engine/schema/src/com/cloud/usage/dao/UsageDao.java @@ -38,6 +38,7 @@ public interface UsageDao extends GenericDao { Long getLastUserStatsId(); List listPublicTemplatesByAccount(long accountId); Long getLastVmDiskStatsId(); - void updateVmDiskStats(List vmNetStats); - void saveVmDiskStats(List vmNetStats); + void updateVmDiskStats(List vmDiskStats); + void saveVmDiskStats(List vmDiskStats); + void saveUsageRecords(List usageRecords); } diff --git a/engine/schema/src/com/cloud/usage/dao/UsageDaoImpl.java b/engine/schema/src/com/cloud/usage/dao/UsageDaoImpl.java index f7d5069eef9..2237d56dd72 100644 --- a/engine/schema/src/com/cloud/usage/dao/UsageDaoImpl.java +++ b/engine/schema/src/com/cloud/usage/dao/UsageDaoImpl.java @@ -18,6 +18,7 @@ package com.cloud.usage.dao; import java.sql.PreparedStatement; import java.sql.ResultSet; +import java.sql.Timestamp; import java.sql.Types; import java.util.ArrayList; import java.util.Date; @@ -63,6 +64,8 @@ public class UsageDaoImpl extends GenericDaoBase implements Usage " VALUES (?,?,?,?,?,?,?,?,?,?, ?, ?, ?, ?,?, ?, ?)"; private static final String UPDATE_VM_DISK_STATS = "UPDATE cloud_usage.vm_disk_statistics SET net_io_read=?, net_io_write=?, current_io_read=?, current_io_write=?, agg_io_read=?, agg_io_write=?, " + "net_bytes_read=?, net_bytes_write=?, current_bytes_read=?, current_bytes_write=?, agg_bytes_read=?, agg_bytes_write=? WHERE id=?"; + private static final String INSERT_USGAE_RECORDS = "INSERT INTO cloud_usage.cloud_usage (zone_id, account_id, domain_id, description, usage_display, usage_type, raw_usage, vm_instance_id, vm_name, offering_id, template_id, " + + "usage_id, type, size, network_id, start_date, end_date) VALUES (?,?,?,?,?,?,?,?,?, ?, ?, ?,?,?,?,?,?)"; protected final static TimeZone s_gmtTimeZone = TimeZone.getTimeZone("GMT"); @@ -375,4 +378,65 @@ public class UsageDaoImpl extends GenericDaoBase implements Usage } } + + @Override + public void saveUsageRecords(List usageRecords) { + Transaction txn = Transaction.currentTxn(); + try { + txn.start(); + String sql = INSERT_USGAE_RECORDS; + PreparedStatement pstmt = null; + pstmt = txn.prepareAutoCloseStatement(sql); // in reality I just want CLOUD_USAGE dataSource connection + for (UsageVO usageRecord : usageRecords) { + pstmt.setLong(1, usageRecord.getZoneId()); + pstmt.setLong(2, usageRecord.getAccountId()); + pstmt.setLong(3, usageRecord.getDomainId()); + pstmt.setString(4, usageRecord.getDescription()); + pstmt.setString(5, usageRecord.getUsageDisplay()); + pstmt.setInt(6, usageRecord.getUsageType()); + pstmt.setDouble(7, usageRecord.getRawUsage()); + if(usageRecord.getVmInstanceId() != null){ + pstmt.setLong(8, usageRecord.getVmInstanceId()); + } else { + pstmt.setNull(8, Types.BIGINT); + } + pstmt.setString(9, usageRecord.getVmName()); + if(usageRecord.getOfferingId() != null){ + pstmt.setLong(10, usageRecord.getOfferingId()); + } else { + pstmt.setNull(10, Types.BIGINT); + } + if(usageRecord.getTemplateId() != null){ + pstmt.setLong(11, usageRecord.getTemplateId()); + } else { + pstmt.setNull(11, Types.BIGINT); + } + if(usageRecord.getUsageId() != null){ + pstmt.setLong(12, usageRecord.getUsageId()); + } else { + pstmt.setNull(12, Types.BIGINT); + } + pstmt.setString(13, usageRecord.getType()); + if(usageRecord.getSize() != null){ + pstmt.setLong(14, usageRecord.getSize()); + } else { + pstmt.setNull(14, Types.BIGINT); + } + if(usageRecord.getNetworkId() != null){ + pstmt.setLong(15, usageRecord.getNetworkId()); + } else { + pstmt.setNull(15, Types.BIGINT); + } + pstmt.setTimestamp(16, new Timestamp(usageRecord.getStartDate().getTime())); + pstmt.setTimestamp(17, new Timestamp(usageRecord.getEndDate().getTime())); + pstmt.addBatch(); + } + pstmt.executeBatch(); + txn.commit(); + } catch (Exception ex) { + txn.rollback(); + s_logger.error("error saving usage records to cloud_usage db", ex); + throw new CloudRuntimeException(ex.getMessage()); + } + } } diff --git a/server/src/com/cloud/api/ApiResponseHelper.java b/server/src/com/cloud/api/ApiResponseHelper.java index bcc1605d8b9..0c98abc9400 100755 --- a/server/src/com/cloud/api/ApiResponseHelper.java +++ b/server/src/com/cloud/api/ApiResponseHelper.java @@ -3404,8 +3404,8 @@ public class ApiResponseHelper implements ResponseGenerator { //Device Type usageRecResponse.setType(usageRecord.getType()); //VM Instance Id - VMInstanceVO vm = _entityMgr.findByIdIncludingRemoved(VMInstanceVO.class, usageRecord.getUsageId().toString()); - usageRecResponse.setUsageId(vm.getUuid()); + VMInstanceVO vm = _entityMgr.findByIdIncludingRemoved(VMInstanceVO.class, usageRecord.getVmInstanceId().toString()); + usageRecResponse.setVirtualMachineId(vm.getUuid()); //Volume ID VolumeVO volume = _entityMgr.findByIdIncludingRemoved(VolumeVO.class, usageRecord.getUsageId().toString()); usageRecResponse.setUsageId(volume.getUuid()); diff --git a/usage/src/com/cloud/usage/parser/NetworkUsageParser.java b/usage/src/com/cloud/usage/parser/NetworkUsageParser.java index 3da6854d11b..f2f24e460c9 100644 --- a/usage/src/com/cloud/usage/parser/NetworkUsageParser.java +++ b/usage/src/com/cloud/usage/parser/NetworkUsageParser.java @@ -16,6 +16,7 @@ // under the License. package com.cloud.usage.parser; +import java.util.ArrayList; import java.util.Date; import java.util.HashMap; import java.util.List; @@ -89,6 +90,7 @@ public static final Logger s_logger = Logger.getLogger(NetworkUsageParser.class. networkUsageByZone.put(key, new NetworkInfo(zoneId, usageNetwork.getHostId(), usageNetwork.getHostType(), usageNetwork.getNetworkId(), bytesSent, bytesReceived)); } + List usageRecords = new ArrayList(); for (String key : networkUsageByZone.keySet()) { NetworkInfo networkInfo = networkUsageByZone.get(key); long totalBytesSent = networkInfo.getBytesSent(); @@ -110,7 +112,7 @@ public static final Logger s_logger = Logger.getLogger(NetworkUsageParser.class. } UsageVO usageRecord = new UsageVO(networkInfo.getZoneId(), account.getId(), account.getDomainId(), usageDesc, totalBytesSent + " bytes sent", UsageTypes.NETWORK_BYTES_SENT, new Double(totalBytesSent), hostId, networkInfo.getHostType(), networkInfo.getNetworkId(), startDate, endDate); - m_usageDao.persist(usageRecord); + usageRecords.add(usageRecord); // Create the usage record for bytes received usageDesc = "network bytes received"; @@ -119,7 +121,7 @@ public static final Logger s_logger = Logger.getLogger(NetworkUsageParser.class. } usageRecord = new UsageVO(networkInfo.getZoneId(), account.getId(), account.getDomainId(), usageDesc, totalBytesReceived + " bytes received", UsageTypes.NETWORK_BYTES_RECEIVED, new Double(totalBytesReceived), hostId, networkInfo.getHostType(), networkInfo.getNetworkId(), startDate, endDate); - m_usageDao.persist(usageRecord); + usageRecords.add(usageRecord); } else { // Don't charge anything if there were zero bytes processed if (s_logger.isDebugEnabled()) { @@ -127,6 +129,11 @@ public static final Logger s_logger = Logger.getLogger(NetworkUsageParser.class. } } } + try { + m_usageDao.saveUsageRecords(usageRecords); + } catch (Exception ex) { + s_logger.error("Exception in usage manager", ex); + } return true; } diff --git a/usage/src/com/cloud/usage/parser/VmDiskUsageParser.java b/usage/src/com/cloud/usage/parser/VmDiskUsageParser.java index b8a5f98c99b..74fa214324e 100644 --- a/usage/src/com/cloud/usage/parser/VmDiskUsageParser.java +++ b/usage/src/com/cloud/usage/parser/VmDiskUsageParser.java @@ -16,6 +16,7 @@ // under the License. package com.cloud.usage.parser; +import java.util.ArrayList; import java.util.Date; import java.util.HashMap; import java.util.List; @@ -93,6 +94,7 @@ public static final Logger s_logger = Logger.getLogger(VmDiskUsageParser.class.g vmDiskUsageByZone.put(key, new VmDiskInfo(zoneId, usageVmDisk.getVmId(), usageVmDisk.getVolumeId(), ioRead, ioWrite, bytesRead, bytesWrite)); } + List usageRecords = new ArrayList(); for (String key : vmDiskUsageByZone.keySet()) { VmDiskInfo vmDiskInfo = vmDiskUsageByZone.get(key); long ioRead = vmDiskInfo.getIORead(); @@ -107,44 +109,45 @@ public static final Logger s_logger = Logger.getLogger(VmDiskUsageParser.class.g } Long vmId = null; + Long volumeId = null; // Create the usage record for bytes read String usageDesc = "disk bytes read"; - if(vmDiskInfo.getVmId() != 0){ + if ((vmDiskInfo.getVmId() != 0) && (vmDiskInfo.getVolumeId() != 0)){ vmId = vmDiskInfo.getVmId(); - usageDesc += " for Vm: "+vmDiskInfo.getVmId()+" and Volume: "+ vmDiskInfo.getVolumeId(); + volumeId = vmDiskInfo.getVolumeId(); + usageDesc += " for Vm: " + vmId + " and Volume: " + volumeId; } UsageVO usageRecord = new UsageVO(vmDiskInfo.getZoneId(), account.getId(), account.getDomainId(), usageDesc, ioRead + " io read", - UsageTypes.VM_DISK_IO_READ, new Double(ioRead), vmId, "VirtualMachine", vmDiskInfo.getVolumeId(), startDate, endDate); - m_usageDao.persist(usageRecord); + UsageTypes.VM_DISK_IO_READ, new Double(ioRead), vmId, null, null, null, vmDiskInfo.getVolumeId(), startDate, endDate, "VirtualMachine"); + usageRecords.add(usageRecord); // Create the usage record for bytes write usageDesc = "disk bytes write"; - if(vmDiskInfo.getVmId() != 0){ - usageDesc += " for Vm: "+vmDiskInfo.getVmId()+" and Volume: "+ vmDiskInfo.getVolumeId(); + if ((vmDiskInfo.getVmId() != 0) && (vmDiskInfo.getVolumeId() != 0)){ + usageDesc += " for Vm: " + vmId + " and Volume: " + volumeId; } usageRecord = new UsageVO(vmDiskInfo.getZoneId(), account.getId(), account.getDomainId(), usageDesc, ioWrite + " io write", - UsageTypes.VM_DISK_BYTES_WRITE, new Double(ioWrite), vmId, "VirtualMachine", vmDiskInfo.getVolumeId(), startDate, endDate); - m_usageDao.persist(usageRecord); + UsageTypes.VM_DISK_BYTES_WRITE, new Double(ioWrite), vmId, null, null, null, vmDiskInfo.getVolumeId(), startDate, endDate, "VirtualMachine"); + usageRecords.add(usageRecord); // Create the usage record for bytes read usageDesc = "disk bytes read"; - if(vmDiskInfo.getVmId() != 0){ - vmId = vmDiskInfo.getVmId(); - usageDesc += " for Vm: "+vmDiskInfo.getVmId()+" and Volume: "+ vmDiskInfo.getVolumeId(); + if ((vmDiskInfo.getVmId() != 0) && (vmDiskInfo.getVolumeId() != 0)){ + usageDesc += " for Vm: " + vmId + " and Volume: " + volumeId; } usageRecord = new UsageVO(vmDiskInfo.getZoneId(), account.getId(), account.getDomainId(), usageDesc, bytesRead + " bytes read", - UsageTypes.VM_DISK_BYTES_READ, new Double(bytesRead), vmId, "VirtualMachine", vmDiskInfo.getVolumeId(), startDate, endDate); - m_usageDao.persist(usageRecord); + UsageTypes.VM_DISK_BYTES_READ, new Double(bytesRead), vmId, null, null, null, vmDiskInfo.getVolumeId(), startDate, endDate, "VirtualMachine"); + usageRecords.add(usageRecord); // Create the usage record for bytes write usageDesc = "disk bytes write"; - if(vmDiskInfo.getVmId() != 0){ - usageDesc += " for Vm: "+vmDiskInfo.getVmId()+" and Volume: "+ vmDiskInfo.getVolumeId(); + if ((vmDiskInfo.getVmId() != 0) && (vmDiskInfo.getVolumeId() != 0)){ + usageDesc += " for Vm: " + vmId + " and Volume: " + volumeId; } usageRecord = new UsageVO(vmDiskInfo.getZoneId(), account.getId(), account.getDomainId(), usageDesc, bytesWrite + " bytes write", - UsageTypes.VM_DISK_BYTES_WRITE, new Double(bytesWrite), vmId, "VirtualMachine", vmDiskInfo.getVolumeId(), startDate, endDate); - m_usageDao.persist(usageRecord); + UsageTypes.VM_DISK_BYTES_WRITE, new Double(bytesWrite), vmId, null, null, null, vmDiskInfo.getVolumeId(), startDate, endDate, "VirtualMachine"); + usageRecords.add(usageRecord); } else { // Don't charge anything if there were zero bytes processed @@ -154,6 +157,12 @@ public static final Logger s_logger = Logger.getLogger(VmDiskUsageParser.class.g } } + try { + m_usageDao.saveUsageRecords(usageRecords); + } catch (Exception ex) { + s_logger.error("Exception in usage manager", ex); + } + return true; }