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 <[email protected]>
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);
     }

Reply via email to