You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@cloudstack.apache.org by da...@apache.org on 2026/08/03 09:06:11 UTC
(cloudstack) 01/02: generic formatting facility for alert messages
This is an automated email from the ASF dual-hosted git repository.
DaanHoogland pushed a commit to branch ghi7297-messages
in repository https://gitbox.apache.org/repos/asf/cloudstack.git
commit 53de46134064af69c1479561c9667cfafe2c531f
Author: Daan Hoogland <da...@apache.org>
AuthorDate: Mon Aug 3 11:03:29 2026 +0200
generic formatting facility for alert messages
---
.../java/com/cloud/alert/AlertFormatUtils.java | 39 ++++++++++++++++++++++
.../com/cloud/agent/manager/AgentManagerImpl.java | 10 +++---
.../storage/image/BaseImageStoreDriverImpl.java | 6 ++--
.../datastore/provider/DefaultHostListener.java | 2 +-
.../com/cloud/ha/HighAvailabilityManagerImpl.java | 15 +++++++--
.../ha/provider/host/HAAbstractHostProvider.java | 8 ++---
6 files changed, 64 insertions(+), 16 deletions(-)
diff --git a/engine/components-api/src/main/java/com/cloud/alert/AlertFormatUtils.java b/engine/components-api/src/main/java/com/cloud/alert/AlertFormatUtils.java
new file mode 100644
index 00000000000..390e1a77097
--- /dev/null
+++ b/engine/components-api/src/main/java/com/cloud/alert/AlertFormatUtils.java
@@ -0,0 +1,39 @@
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements. See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership. The ASF licenses this file
+// to you under the Apache License, Version 2.0 (the
+// "License"); you may not use this file except in compliance
+// with the License. You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing,
+// software distributed under the License is distributed on an
+// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+// KIND, either express or implied. See the License for the
+// specific language governing permissions and limitations
+// under the License.
+package com.cloud.alert;
+
+import com.cloud.dc.DataCenter;
+import com.cloud.dc.Pod;
+import com.cloud.host.Host;
+
+/**
+ * Shared formatting for the host/zone/pod description that recurs, independently
+ * hand-rolled and inconsistently worded (and occasionally mislabelled), across the
+ * HA and agent-management alert call sites. See CLOUDSTACK-7297.
+ */
+public final class AlertFormatUtils {
+
+ private AlertFormatUtils() {
+ }
+
+ public static String describeHostLocation(Host host, DataCenter zone, Pod pod) {
+ return String.format("name: %s (id: %d, uuid: %s), availability zone: %s, pod: %s",
+ host.getName(), host.getId(), host.getUuid(),
+ zone != null ? zone.getName() : "unknown",
+ pod != null ? pod.getName() : "unknown");
+ }
+}
diff --git a/engine/orchestration/src/main/java/com/cloud/agent/manager/AgentManagerImpl.java b/engine/orchestration/src/main/java/com/cloud/agent/manager/AgentManagerImpl.java
index 1215829d92f..1ea6439f3f3 100644
--- a/engine/orchestration/src/main/java/com/cloud/agent/manager/AgentManagerImpl.java
+++ b/engine/orchestration/src/main/java/com/cloud/agent/manager/AgentManagerImpl.java
@@ -91,6 +91,7 @@ import com.cloud.agent.api.StartupStorageCommand;
import com.cloud.agent.api.UnsupportedAnswer;
import com.cloud.agent.transport.Request;
import com.cloud.agent.transport.Response;
+import com.cloud.alert.AlertFormatUtils;
import com.cloud.alert.AlertManager;
import com.cloud.cluster.ManagementServerHostVO;
import com.cloud.cluster.dao.ManagementServerHostDao;
@@ -1151,7 +1152,7 @@ public class AgentManagerImpl extends ManagerBase implements AgentManager, Handl
logger.debug(String.format("Skipping sending alert for %s as it already in %s state",
host, host.getStatus()));
} else if (!HOST_DOWN_ALERT_UNSUPPORTED_HOST_TYPES.contains(host.getType())) {
- _alertMgr.sendAlert(AlertManager.AlertType.ALERT_TYPE_HOST, host.getDataCenterId(), host.getPodId(), "Host down, " + host.getId(), message);
+ _alertMgr.sendAlert(AlertManager.AlertType.ALERT_TYPE_HOST, host.getDataCenterId(), host.getPodId(), "Host down, " + host, message);
}
event = Status.Event.HostDown;
} else if (determinedState == Status.Up) {
@@ -1173,7 +1174,7 @@ public class AgentManagerImpl extends ManagerBase implements AgentManager, Handl
} else if (currentStatus == Status.Up) {
final DataCenterVO dcVO = _dcDao.findById(host.getDataCenterId());
final HostPodVO podVO = _podDao.findById(host.getPodId());
- final String hostDesc = "name: " + host.getName() + " (id:" + host.getUuid() + "), availability zone: " + dcVO.getName() + ", pod: " + podVO.getName();
+ final String hostDesc = AlertFormatUtils.describeHostLocation(host, dcVO, podVO);
if (host.getType() != Host.Type.SecondaryStorage && host.getType() != Host.Type.ConsoleProxy) {
_alertMgr.sendAlert(AlertManager.AlertType.ALERT_TYPE_HOST, host.getDataCenterId(), host.getPodId(), "Host disconnected, " + hostDesc,
"If the agent for host [" + hostDesc + "] is not restarted within " + AlertWait + " seconds, host will go to Alert state");
@@ -1184,12 +1185,11 @@ public class AgentManagerImpl extends ManagerBase implements AgentManager, Handl
// if we end up here we are in alert state, send an alert
final DataCenterVO dcVO = _dcDao.findById(host.getDataCenterId());
final HostPodVO podVO = _podDao.findById(host.getPodId());
- final String podName = podVO != null ? podVO.getName() : "NO POD";
- final String hostDesc = String.format("%s, availability zone: %s, pod: %s", host, dcVO, podName);
+ final String hostDesc = AlertFormatUtils.describeHostLocation(host, dcVO, podVO);
_alertMgr.sendAlert(AlertManager.AlertType.ALERT_TYPE_HOST,
host.getDataCenterId(), host.getPodId(),
String.format("Host in ALERT state, %s", hostDesc),
- String.format("In availability zone %s, host is in alert state: %s", dcVO, host));
+ String.format("Host is in alert state: %s", hostDesc));
}
} else {
logger.debug("The next status of agent {} is not Alert, no need to investigate what happened", host);
diff --git a/engine/storage/src/main/java/org/apache/cloudstack/storage/image/BaseImageStoreDriverImpl.java b/engine/storage/src/main/java/org/apache/cloudstack/storage/image/BaseImageStoreDriverImpl.java
index 26b39e30776..c7cd30b4dde 100644
--- a/engine/storage/src/main/java/org/apache/cloudstack/storage/image/BaseImageStoreDriverImpl.java
+++ b/engine/storage/src/main/java/org/apache/cloudstack/storage/image/BaseImageStoreDriverImpl.java
@@ -248,7 +248,7 @@ public abstract class BaseImageStoreDriverImpl implements ImageStoreDriver {
result.setSuccess(false);
result.setResult(answer.getErrorString());
caller.complete(result);
- String msg = "Failed to register template: " + obj.getUuid() + " with error: " + answer.getErrorString();
+ String msg = "Failed to register template: " + obj + " with error: " + answer.getErrorString();
_alertMgr.sendAlert(AlertManager.AlertType.ALERT_TYPE_UPLOAD_FAILED, _vmTemplateZoneDao.listByTemplateId(obj.getId()).get(0).getZoneId(), null, msg, msg);
logger.error(msg);
} else if (answer.getDownloadStatus() == VMTemplateStorageResourceAssoc.Status.DOWNLOADED) {
@@ -306,7 +306,7 @@ public abstract class BaseImageStoreDriverImpl implements ImageStoreDriver {
result.setSuccess(false);
result.setResult(answer.getErrorString());
caller.complete(result);
- String msg = "Failed to upload volume: " + obj.getUuid() + " with error: " + answer.getErrorString();
+ String msg = "Failed to upload volume: " + obj + " with error: " + answer.getErrorString();
_alertMgr.sendAlert(AlertManager.AlertType.ALERT_TYPE_UPLOAD_FAILED,
(volStoreVO == null ? -1L : volStoreVO.getZoneId()), null, msg, msg);
logger.error(msg);
@@ -352,7 +352,7 @@ public abstract class BaseImageStoreDriverImpl implements ImageStoreDriver {
result.setSuccess(false);
result.setResult(answer.getErrorString());
caller.complete(result);
- String msg = "Failed to copy snapshot: " + obj.getUuid() + " with error: " + answer.getErrorString();
+ String msg = "Failed to copy snapshot: " + obj + " with error: " + answer.getErrorString();
Long zoneId = dataStoreManager.getStoreZoneId(store.getId(), store.getRole());
_alertMgr.sendAlert(AlertManager.AlertType.ALERT_TYPE_UPLOAD_FAILED,
zoneId, null, msg, msg);
diff --git a/engine/storage/volume/src/main/java/org/apache/cloudstack/storage/datastore/provider/DefaultHostListener.java b/engine/storage/volume/src/main/java/org/apache/cloudstack/storage/datastore/provider/DefaultHostListener.java
index 7644d4688f7..4047eca58d3 100644
--- a/engine/storage/volume/src/main/java/org/apache/cloudstack/storage/datastore/provider/DefaultHostListener.java
+++ b/engine/storage/volume/src/main/java/org/apache/cloudstack/storage/datastore/provider/DefaultHostListener.java
@@ -163,7 +163,7 @@ public class DefaultHostListener implements HypervisorHostListener {
}
if (!answer.getResult()) {
- String msg = String.format("Unable to attach storage pool %s to the host %d", pool, hostId);
+ String msg = String.format("Unable to attach storage pool %s to the host %s", pool, host);
alertMgr.sendAlert(AlertManager.AlertType.ALERT_TYPE_HOST, pool.getDataCenterId(), pool.getPodId(), msg, msg);
throw new CloudRuntimeException(String.format("Unable to establish connection from storage head to storage pool %s due to %s %s",
pool, answer.getDetails(), pool.getUuid()));
diff --git a/server/src/main/java/com/cloud/ha/HighAvailabilityManagerImpl.java b/server/src/main/java/com/cloud/ha/HighAvailabilityManagerImpl.java
index 755de00dec2..dadecdfe92f 100644
--- a/server/src/main/java/com/cloud/ha/HighAvailabilityManagerImpl.java
+++ b/server/src/main/java/com/cloud/ha/HighAvailabilityManagerImpl.java
@@ -52,6 +52,7 @@ import org.apache.logging.log4j.ThreadContext;
import org.apache.commons.collections.CollectionUtils;
import com.cloud.agent.AgentManager;
+import com.cloud.alert.AlertFormatUtils;
import com.cloud.alert.AlertManager;
import com.cloud.cluster.ClusterManagerListener;
import com.cloud.consoleproxy.ConsoleProxyManager;
@@ -374,7 +375,7 @@ public class HighAvailabilityManagerImpl extends ManagerBase implements Configur
}
// send an email alert that the host is down, include VMs
HostPodVO podVO = _podDao.findById(host.getPodId());
- String hostDesc = "name: " + host.getName() + " (id:" + host.getId() + "), availability zone: " + dcVO.getName() + ", pod: " + podVO.getName();
+ String hostDesc = AlertFormatUtils.describeHostLocation(host, dcVO, podVO);
_alertMgr.sendAlert(AlertManager.AlertType.ALERT_TYPE_HOST, host.getDataCenterId(), host.getPodId(), "Host is down, " + hostDesc,
"Host [" + hostDesc + "] is down." + ((sb != null) ? sb.toString() : ""));
@@ -513,9 +514,17 @@ public class HighAvailabilityManagerImpl extends ManagerBase implements Configur
}
if (!(ForceHA.value() || vm.isHaEnabled())) {
- String hostDesc = "id:" + vm.getHostId() + ", availability zone id:" + vm.getDataCenterId() + ", pod id:" + vm.getPodIdToDeployIn();
+ HostVO stoppedHost = hostId != null ? _hostDao.findById(hostId) : null;
+ String hostDesc;
+ if (stoppedHost != null) {
+ DataCenterVO stoppedHostDcVO = _dcDao.findById(stoppedHost.getDataCenterId());
+ HostPodVO stoppedHostPodVO = _podDao.findById(stoppedHost.getPodId());
+ hostDesc = AlertFormatUtils.describeHostLocation(stoppedHost, stoppedHostDcVO, stoppedHostPodVO);
+ } else {
+ hostDesc = "host id: " + hostId;
+ }
_alertMgr.sendAlert(alertType, vm.getDataCenterId(), vm.getPodIdToDeployIn(), "VM (name: " + vm.getHostName() + ", id: " + vm.getId() +
- ") stopped unexpectedly on host " + hostDesc, "Virtual Machine " + vm.getHostName() + " (id: " + vm.getId() + ") running on host [" + vm.getHostId() +
+ ") stopped unexpectedly on host " + hostDesc, "Virtual Machine " + vm.getHostName() + " (id: " + vm.getId() + ") running on host [" + hostDesc +
"] stopped unexpectedly.");
if (logger.isDebugEnabled()) {
diff --git a/server/src/main/java/org/apache/cloudstack/ha/provider/host/HAAbstractHostProvider.java b/server/src/main/java/org/apache/cloudstack/ha/provider/host/HAAbstractHostProvider.java
index 2d77e6f9d20..c8dbf17d9a8 100644
--- a/server/src/main/java/org/apache/cloudstack/ha/provider/host/HAAbstractHostProvider.java
+++ b/server/src/main/java/org/apache/cloudstack/ha/provider/host/HAAbstractHostProvider.java
@@ -95,11 +95,11 @@ public abstract class HAAbstractHostProvider extends AdapterBase implements HAPr
String subject = "HA operation performed for host";
String body = subject;
if (HAConfig.HAState.Fencing.equals(nextState)) {
- subject = String.format("HA Fencing of host id=%d, in dc id=%d performed", host.getId(), host.getDataCenterId());
- body = String.format("HA Fencing has been performed for host id=%d, uuid=%s in datacenter id=%d", host.getId(), host.getUuid(), host.getDataCenterId());
+ subject = String.format("HA Fencing of host %s performed", host);
+ body = String.format("HA Fencing has been performed for host %s", host);
} else if (HAConfig.HAState.Recovering.equals(nextState)) {
- subject = String.format("HA Recovery of host id=%d, in dc id=%d performed", host.getId(), host.getDataCenterId());
- body = String.format("HA Recovery has been performed for host id=%d, uuid=%s in datacenter id=%d", host.getId(), host.getUuid(), host.getDataCenterId());
+ subject = String.format("HA Recovery of host %s performed", host);
+ body = String.format("HA Recovery has been performed for host %s", host);
}
alertManager.sendAlert(AlertService.AlertType.ALERT_TYPE_HA_ACTION, host.getDataCenterId(), host.getPodId(), subject, body);
}