Skip to content

Commit c3a1c78

Browse files
SadiJrSadiJr
andauthored
backup: Improve Veeam Plugin logs (apache#5455)
* Improve Veeam Plugin logs * Address reviews * Address reviews Co-authored-by: SadiJr <sadi@scclouds.com.br>
1 parent 06f602c commit c3a1c78

File tree

3 files changed

+89
-55
lines changed

3 files changed

+89
-55
lines changed

plugins/backup/veeam/src/main/java/org/apache/cloudstack/backup/VeeamBackupProvider.java

Lines changed: 25 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -24,17 +24,20 @@
2424
import java.util.HashMap;
2525
import java.util.List;
2626
import java.util.Map;
27+
import java.util.Objects;
2728
import java.util.stream.Collectors;
2829

2930
import javax.inject.Inject;
3031

3132
import org.apache.cloudstack.api.InternalIdentity;
33+
import org.apache.cloudstack.backup.Backup.Metric;
3234
import org.apache.cloudstack.backup.dao.BackupDao;
3335
import org.apache.cloudstack.backup.veeam.VeeamClient;
3436
import org.apache.cloudstack.backup.veeam.api.Job;
3537
import org.apache.cloudstack.framework.config.ConfigKey;
3638
import org.apache.cloudstack.framework.config.Configurable;
3739
import org.apache.commons.collections.CollectionUtils;
40+
import org.apache.commons.lang3.BooleanUtils;
3841
import org.apache.log4j.Logger;
3942

4043
import com.cloud.hypervisor.Hypervisor;
@@ -149,7 +152,7 @@ public boolean assignVMToBackupOffering(final VirtualMachine vm, final BackupOff
149152
for (final BackupOffering job : client.listJobs()) {
150153
if (job.getName().equals(clonedJobName)) {
151154
final Job clonedJob = client.listJob(job.getExternalId());
152-
if (clonedJob.getScheduleConfigured() && !clonedJob.getScheduleEnabled()) {
155+
if (BooleanUtils.isTrue(clonedJob.getScheduleConfigured()) && !clonedJob.getScheduleEnabled()) {
153156
client.toggleJobSchedule(clonedJob.getId());
154157
}
155158
LOG.debug("Veeam job (backup offering) for backup offering ID: " + backupOffering.getExternalId() + " found, now trying to assign the VM to the job.");
@@ -216,15 +219,24 @@ public Pair<Boolean, String> restoreBackedUpVolume(Backup backup, String volumeU
216219
@Override
217220
public Map<VirtualMachine, Backup.Metric> getBackupMetrics(final Long zoneId, final List<VirtualMachine> vms) {
218221
final Map<VirtualMachine, Backup.Metric> metrics = new HashMap<>();
219-
if (vms == null || vms.isEmpty()) {
222+
if (CollectionUtils.isEmpty(vms)) {
223+
LOG.warn("Unable to get VM Backup Metrics because the list of VMs is empty.");
220224
return metrics;
221225
}
226+
227+
List<String> vmUuids = vms.stream().filter(Objects::nonNull).map(VirtualMachine::getUuid).collect(Collectors.toList());
228+
LOG.debug(String.format("Get Backup Metrics for VMs: [%s].", String.join(", ", vmUuids)));
229+
222230
final Map<String, Backup.Metric> backendMetrics = getClient(zoneId).getBackupMetrics();
223231
for (final VirtualMachine vm : vms) {
224232
if (vm == null || !backendMetrics.containsKey(vm.getUuid())) {
225233
continue;
226234
}
227-
metrics.put(vm, backendMetrics.get(vm.getUuid()));
235+
236+
Metric metric = backendMetrics.get(vm.getUuid());
237+
LOG.debug(String.format("Metrics for VM [uuid: %s, name: %s] is [backup size: %s, data size: %s].", vm.getUuid(),
238+
vm.getInstanceName(), metric.getBackupSize(), metric.getDataSize()));
239+
metrics.put(vm, metric);
228240
}
229241
return metrics;
230242
}
@@ -237,7 +249,8 @@ private List<Backup.RestorePoint> listRestorePoints(VirtualMachine vm) {
237249
@Override
238250
public void syncBackups(VirtualMachine vm, Backup.Metric metric) {
239251
List<Backup.RestorePoint> restorePoints = listRestorePoints(vm);
240-
if (restorePoints == null || restorePoints.isEmpty()) {
252+
if (CollectionUtils.isEmpty(restorePoints)) {
253+
LOG.debug(String.format("Can't find any restore point to VM: [uuid: %s, name: %s].", vm.getUuid(), vm.getInstanceName()));
241254
return;
242255
}
243256
Transaction.execute(new TransactionCallbackNoReturn() {
@@ -252,6 +265,9 @@ public void doInTransactionWithoutResult(TransactionStatus status) {
252265
backupExists = true;
253266
removeList.remove(backup.getId());
254267
if (metric != null) {
268+
LOG.debug(String.format("Update backup with [uuid: %s, external id: %s] from [size: %s, protected size: %s] to [size: %s, protected size: %s].",
269+
backup.getUuid(), backup.getExternalId(), backup.getSize(), backup.getProtectedSize(), metric.getBackupSize(), metric.getDataSize()));
270+
255271
((BackupVO) backup).setSize(metric.getBackupSize());
256272
((BackupVO) backup).setProtectedSize(metric.getDataSize());
257273
backupDao.update(backup.getId(), ((BackupVO) backup));
@@ -276,9 +292,14 @@ public void doInTransactionWithoutResult(TransactionStatus status) {
276292
backup.setAccountId(vm.getAccountId());
277293
backup.setDomainId(vm.getDomainId());
278294
backup.setZoneId(vm.getDataCenterId());
295+
296+
LOG.debug(String.format("Creating a new entry in backups: [uuid: %s, vm_id: %s, external_id: %s, type: %s, date: %s, backup_offering_id: %s, account_id: %s, "
297+
+ "domain_id: %s, zone_id: %s].", backup.getUuid(), backup.getVmId(), backup.getExternalId(), backup.getType(), backup.getDate(),
298+
backup.getBackupOfferingId(), backup.getAccountId(), backup.getDomainId(), backup.getZoneId()));
279299
backupDao.persist(backup);
280300
}
281301
for (final Long backupIdToRemove : removeList) {
302+
LOG.warn(String.format("Removing backup with ID: [%s].", backupIdToRemove));
282303
backupDao.remove(backupIdToRemove);
283304
}
284305
}

plugins/backup/veeam/src/main/java/org/apache/cloudstack/backup/veeam/VeeamClient.java

Lines changed: 30 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -163,7 +163,7 @@ private void checkResponseOK(final HttpResponse response) {
163163
if (!(response.getStatusLine().getStatusCode() == HttpStatus.SC_OK ||
164164
response.getStatusLine().getStatusCode() == HttpStatus.SC_ACCEPTED) &&
165165
response.getStatusLine().getStatusCode() != HttpStatus.SC_NO_CONTENT) {
166-
LOG.debug("HTTP request failed, status code is " + response.getStatusLine().getStatusCode() + ", response is: " + response.toString());
166+
LOG.debug(String.format("HTTP request failed, status code is [%s], response is: [%s].", response.getStatusLine().getStatusCode(), response.toString()));
167167
throw new ServerApiException(ApiErrorCode.INTERNAL_ERROR, "Got invalid API status code returned by the Veeam server");
168168
}
169169
}
@@ -175,10 +175,13 @@ private void checkResponseTimeOut(final Exception e) {
175175
}
176176

177177
private HttpResponse get(final String path) throws IOException {
178-
final HttpGet request = new HttpGet(apiURI.toString() + path);
178+
String url = apiURI.toString() + path;
179+
final HttpGet request = new HttpGet(url);
179180
request.setHeader(SESSION_HEADER, veeamSessionId);
180181
final HttpResponse response = httpClient.execute(request);
181182
checkAuthFailure(response);
183+
184+
LOG.debug(String.format("Response received in GET request is: [%s] for URL: [%s].", response.toString(), url));
182185
return response;
183186
}
184187

@@ -193,7 +196,8 @@ private HttpResponse post(final String path, final Object obj) throws IOExceptio
193196
xml = xml.replace(" xmlns=\"\"", "");
194197
}
195198

196-
final HttpPost request = new HttpPost(apiURI.toString() + path);
199+
String url = apiURI.toString() + path;
200+
final HttpPost request = new HttpPost(url);
197201
request.setHeader(SESSION_HEADER, veeamSessionId);
198202
request.setHeader("Content-type", "application/xml");
199203
if (StringUtils.isNotBlank(xml)) {
@@ -202,14 +206,19 @@ private HttpResponse post(final String path, final Object obj) throws IOExceptio
202206

203207
final HttpResponse response = httpClient.execute(request);
204208
checkAuthFailure(response);
209+
210+
LOG.debug(String.format("Response received in POST request with body [%s] is: [%s] for URL [%s].", xml, response.toString(), url));
205211
return response;
206212
}
207213

208214
private HttpResponse delete(final String path) throws IOException {
209-
final HttpDelete request = new HttpDelete(apiURI.toString() + path);
215+
String url = apiURI.toString() + path;
216+
final HttpDelete request = new HttpDelete(url);
210217
request.setHeader(SESSION_HEADER, veeamSessionId);
211218
final HttpResponse response = httpClient.execute(request);
212219
checkAuthFailure(response);
220+
221+
LOG.debug(String.format("Response received in DELETE request is: [%s] for URL [%s].", response.toString(), url));
213222
return response;
214223
}
215224

@@ -524,11 +533,18 @@ protected String transformPowerShellCommandList(List<String> cmds) {
524533
*/
525534
protected Pair<Boolean, String> executePowerShellCommands(List<String> cmds) {
526535
try {
527-
Pair<Boolean, String> pairResult = SshHelper.sshExecute(veeamServerIp, veeamServerPort,
536+
String commands = transformPowerShellCommandList(cmds);
537+
Pair<Boolean, String> response = SshHelper.sshExecute(veeamServerIp, veeamServerPort,
528538
veeamServerUsername, null, veeamServerPassword,
529-
transformPowerShellCommandList(cmds),
530-
120000, 120000, 3600000);
531-
return pairResult;
539+
commands, 120000, 120000, 3600000);
540+
541+
if (response == null || !response.first()) {
542+
LOG.error(String.format("Veeam PowerShell commands [%s] failed due to: [%s].", commands, response != null ? response.second() : "no PowerShell output returned"));
543+
} else {
544+
LOG.debug(String.format("Veeam response for PowerShell commands [%s] is: [%s].", commands, response.second()));
545+
}
546+
547+
return response;
532548
} catch (Exception e) {
533549
throw new CloudRuntimeException("Error while executing PowerShell commands due to: " + e.getMessage());
534550
}
@@ -595,6 +611,7 @@ public Map<String, Backup.Metric> getBackupMetrics() {
595611
}
596612

597613
private Backup.RestorePoint getRestorePointFromBlock(String[] parts) {
614+
LOG.debug(String.format("Processing block of restore points: [%s].", StringUtils.join(parts, ", ")));
598615
String id = null;
599616
String created = null;
600617
String type = null;
@@ -616,18 +633,20 @@ private Backup.RestorePoint getRestorePointFromBlock(String[] parts) {
616633
public List<Backup.RestorePoint> listRestorePoints(String backupName, String vmInternalName) {
617634
final List<String> cmds = Arrays.asList(
618635
String.format("$backup = Get-VBRBackup -Name \"%s\"", backupName),
619-
String.format("if ($backup) { (Get-VBRRestorePoint -Backup:$backup -Name \"%s\" ^| Where-Object {$_.IsConsistent -eq $true}) }", vmInternalName)
636+
String.format("if ($backup) { $restore = (Get-VBRRestorePoint -Backup:$backup -Name \"%s\" ^| Where-Object {$_.IsConsistent -eq $true})", vmInternalName),
637+
"if ($restore) { $restore ^| Format-List } }"
620638
);
621639
Pair<Boolean, String> response = executePowerShellCommands(cmds);
622640
final List<Backup.RestorePoint> restorePoints = new ArrayList<>();
623641
if (response == null || !response.first()) {
624-
LOG.debug("Veeam restore point listing failed due to: " + (response != null ? response.second() : "no powershell output returned"));
625642
return restorePoints;
626643
}
644+
627645
for (final String block : response.second().split("\r\n\r\n")) {
628646
if (block.isEmpty()) {
629647
continue;
630648
}
649+
LOG.debug(String.format("Found restore points from [backupName: %s, vmInternalName: %s] which is: [%s].", backupName, vmInternalName, block));
631650
final String[] parts = block.split("\r\n");
632651
restorePoints.add(getRestorePointFromBlock(parts));
633652
}
@@ -651,4 +670,4 @@ public Pair<Boolean, String> restoreVMToDifferentLocation(String restorePointId,
651670
}
652671
return new Pair<>(result.first(), restoreLocation);
653672
}
654-
}
673+
}

0 commit comments

Comments
 (0)