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); }
