PageRenderTime 55ms CodeModel.GetById 25ms RepoModel.GetById 0ms app.codeStats 0ms

/ojc-core/bpelse/bpelcore/src/com/sun/jbi/engine/bpel/core/bpel/trace/BPELTraceManager.java

https://bitbucket.org/openesb/openesb-components
Java | 548 lines | 386 code | 51 blank | 111 comment | 70 complexity | 7e844849476732cfef77406562c0997c MD5 | raw file
Possible License(s): AGPL-3.0
  1. /*
  2. * BEGIN_HEADER - DO NOT EDIT
  3. *
  4. * The contents of this file are subject to the terms
  5. * of the Common Development and Distribution License
  6. * (the "License"). You may not use this file except
  7. * in compliance with the License.
  8. *
  9. * You can obtain a copy of the license at
  10. * https://open-jbi-components.dev.java.net/public/CDDLv1.0.html.
  11. * See the License for the specific language governing
  12. * permissions and limitations under the License.
  13. *
  14. * When distributing Covered Code, include this CDDL
  15. * HEADER in each file and include the License file at
  16. * https://open-jbi-components.dev.java.net/public/CDDLv1.0.html.
  17. * If applicable add the following below this CDDL HEADER,
  18. * with the fields enclosed by brackets "[]" replaced with
  19. * your own identifying information: Portions Copyright
  20. * [year] [name of copyright owner]
  21. */
  22. /*
  23. * @(#)BPELTracer.java
  24. *
  25. * Copyright 2004-2007 Sun Microsystems, Inc. All Rights Reserved.
  26. *
  27. * END_HEADER - DO NOT EDIT
  28. */
  29. package com.sun.jbi.engine.bpel.core.bpel.trace;
  30. import java.io.PrintWriter;
  31. import java.io.StringWriter;
  32. import java.text.DateFormat;
  33. import java.text.SimpleDateFormat;
  34. import java.util.Date;
  35. import java.util.Iterator;
  36. import java.util.logging.Level;
  37. import java.util.logging.Logger;
  38. import org.apache.commons.jxpath.Pointer;
  39. import org.w3c.dom.Node;
  40. import com.sun.bpel.model.From;
  41. import com.sun.bpel.model.extensions.Alert;
  42. import com.sun.bpel.model.extensions.Log;
  43. import com.sun.bpel.model.extensions.Trace;
  44. import com.sun.bpel.model.meta.RActivity;
  45. import com.sun.jbi.alerter.Alerter;
  46. import com.sun.jbi.alerter.AlerterImpl;
  47. import com.sun.jbi.alerter.EventFactory;
  48. import com.sun.jbi.alerter.NotificationEvent;
  49. import com.sun.jbi.common.util.NDC;
  50. import com.sun.jbi.engine.bpel.core.bpel.engine.BPELProcessInstance;
  51. import com.sun.jbi.engine.bpel.core.bpel.management.BPELSEManagement;
  52. import com.sun.jbi.engine.bpel.core.bpel.model.runtime.Context;
  53. import com.sun.jbi.engine.bpel.core.bpel.model.runtime.WSMessage;
  54. import com.sun.jbi.engine.bpel.core.bpel.util.DOMHelper;
  55. import com.sun.jbi.engine.bpel.core.bpel.util.FromEvaluatorFactory;
  56. import com.sun.jbi.engine.bpel.core.bpel.util.I18n;
  57. import com.sun.jbi.engine.bpel.core.bpel.util.FromEvaluatorFactory.FromEvaluator;
  58. import java.io.IOException;
  59. import java.util.ArrayList;
  60. import java.util.List;
  61. import java.util.logging.FileHandler;
  62. /**
  63. *
  64. *
  65. *
  66. * @author Sun Microsystems
  67. */
  68. public class BPELTraceManager {
  69. /**
  70. * The category under which BPEL processes will log
  71. */
  72. public static final String BPEL_TRACE_CATEGORY = BPELTraceManager.class.getName();//"sun-bpel-engine.Application";
  73. /* Current logger can return a logger only with a class. Until new logging api's are available, use
  74. * BPELTraceManager as the log category for BPEL process logging.
  75. */
  76. private static final Logger BPEL_LOGGER = Logger.getLogger(BPELTraceManager.class.getName());
  77. /* Logger for the BPELTraceManager class */
  78. private static final Logger LOGGER = Logger.getLogger(BPELTraceManager.class.getName());
  79. /* The name of the component */
  80. private static final String COMPONENT_NAME = "sun-bpel-engine";
  81. /* The type of the component. Service Engine in this case */
  82. private static final String COMPONENT_TYPE = "ServiceEngine";
  83. /* The server type */
  84. private static final String SERVER_TYPE = "glassfish";
  85. /* */
  86. private static final String LINE_SEPARATOR = System.getProperty("line.separator", "\n");
  87. /* Instance of BPELTraceManager */
  88. private static BPELTraceManager bpelTraceManager;
  89. private static DateFormat simpleDateFormat = new SimpleDateFormat("yyyy/MM/dd HH:mm:ss SSS");
  90. private static NotificationEvent EVENT = new EventFactory().getNotificationEvent();
  91. /*
  92. * Private constructor
  93. */
  94. private BPELTraceManager() {
  95. }
  96. static {
  97. bpelTraceManager = new BPELTraceManager();
  98. }
  99. /**
  100. *
  101. * @return
  102. */
  103. public static BPELTraceManager getInstance() {
  104. return bpelTraceManager;
  105. }
  106. /**
  107. * Could be called for Virtual activities like CompensateUnit for which the
  108. * RActivity is null, hence care is taken to avoid trace calls.
  109. *
  110. * @param trace
  111. * @param context
  112. */
  113. public void doTraceOnStart(RActivity activity, Context context,
  114. BPELProcessInstance process) {
  115. if (activity != null) {
  116. Trace trace = activity.getTrace();
  117. if (trace != null) {
  118. if (trace.hasOnStartLogs()) {
  119. logMessages(trace.getOnStartLogs().iterator(), context,
  120. activity.getName(), process);
  121. }
  122. if (trace.hasOnStartAlerts()) {
  123. sendAlerts(trace.getOnStartAlerts().iterator(), context);
  124. }
  125. }
  126. }
  127. }
  128. /**
  129. * Could be called for Virtual activities like CompensateUnit for which the
  130. * RActivity is null, hence care is taken to avoid trace calls.
  131. *
  132. * @param trace
  133. * @param context
  134. */
  135. public void doTraceOnComplete(RActivity activity, Context context,
  136. BPELProcessInstance process) {
  137. if (activity != null) {
  138. Trace trace = activity.getTrace();
  139. if (trace != null) {
  140. if (trace.hasOnCompleteLogs()) {
  141. logMessages(trace.getOnCompleteLogs().iterator(), context,
  142. activity.getName(), process);
  143. }
  144. if (trace.hasOnCompleteAlerts()) {
  145. sendAlerts(trace.getOnCompleteAlerts().iterator(), context);
  146. }
  147. }
  148. }
  149. }
  150. /*
  151. *
  152. */
  153. private void logMessages(Iterator<Log> logIter, Context context, String actName, BPELProcessInstance process) {
  154. if (!process.getBPELProcessManager().isLoggingEnabled()) {
  155. return;
  156. }
  157. String assemblyName = process.getBPELProcessManager().getServiceAssemblyName();
  158. Logger serviceAssemblyLogger = getServiceAssemblyLogger(assemblyName);
  159. NDC ndc = null;
  160. try {
  161. List<String> contextNDC = new ArrayList(20);
  162. contextNDC.add("Service Assembly Name");
  163. contextNDC.add(assemblyName);
  164. contextNDC.add("BPEL Process Name");
  165. contextNDC.add(process.getBPELProcessManager().getBPELProcess().getName());
  166. contextNDC.add("Process Instance Id");
  167. contextNDC.add(process.getId());
  168. contextNDC.add("Activity Name");
  169. contextNDC.add(actName);
  170. contextNDC.addAll(process.getBPELProcessManager().getExtraNDC());
  171. Object [] arrContextNDC = contextNDC.toArray();
  172. ndc = NDC.enter(arrContextNDC);
  173. while (logIter.hasNext()) {
  174. Log log = logIter.next();
  175. try {
  176. String level = log.getLevel();
  177. From from = log.getFrom();
  178. if (level.equals(Log.SEVERE)) {
  179. serviceAssemblyLogger.log(Level.SEVERE, evaluateFrom(arrContextNDC, from, context), arrContextNDC);
  180. } else if (level.equals(Log.WARNING)) {
  181. if (serviceAssemblyLogger.isLoggable(Level.WARNING)) {
  182. serviceAssemblyLogger.log(Level.WARNING, evaluateFrom(arrContextNDC, from, context), arrContextNDC);
  183. }
  184. } else if (level.equals(Log.CONFIG)) {
  185. if (serviceAssemblyLogger.isLoggable(Level.CONFIG)) {
  186. serviceAssemblyLogger.log(Level.CONFIG, evaluateFrom(arrContextNDC, from, context), arrContextNDC);
  187. }
  188. } else if (level.equals(Log.INFO)) {
  189. if (serviceAssemblyLogger.isLoggable(Level.INFO)) {
  190. serviceAssemblyLogger.log(Level.INFO, evaluateFrom(arrContextNDC, from, context), arrContextNDC);
  191. }
  192. } else if (level.equals(Log.FINE)) {
  193. if (serviceAssemblyLogger.isLoggable(Level.FINE)) {
  194. serviceAssemblyLogger.log(Level.FINE, evaluateFrom(arrContextNDC, from, context), arrContextNDC);
  195. }
  196. } else if (level.equals(Log.FINER)) {
  197. if (serviceAssemblyLogger.isLoggable(Level.FINER)) {
  198. serviceAssemblyLogger.log(Level.FINER, evaluateFrom(arrContextNDC, from, context), arrContextNDC);
  199. }
  200. } else if (level.equals(Log.FINEST)) {
  201. if (serviceAssemblyLogger.isLoggable(Level.FINEST)) {
  202. serviceAssemblyLogger.log(Level.FINEST, evaluateFrom(arrContextNDC, from, context), arrContextNDC);
  203. }
  204. } else {
  205. LOGGER.warning(I18n.loc("BPCOR-6086: Invalid log level '{0}' specified at location {1}.",
  206. level, log.getLocator().getLineNumber()));
  207. }
  208. } catch (Exception e) {
  209. // log exception and continue.
  210. LOGGER.warning(I18n.loc("BPCOR-6087: Encountered an exception while logging at location {0}. "
  211. + "Exception: {1}.", log.getLocator().getLineNumber(), e));
  212. }
  213. }
  214. } finally {
  215. // exit ndc
  216. if (ndc != null) {
  217. ndc.exit();
  218. }
  219. }
  220. }
  221. private Logger getServiceAssemblyLogger(String serviceAssemblyName) {
  222. String loggerName
  223. = new StringBuilder(BPELTraceManager.class.getName())
  224. .append('.')
  225. .append(serviceAssemblyName)
  226. .toString();
  227. return Logger.getLogger(loggerName);
  228. /*
  229. try {
  230. logger.addHandler(new FileHandler("Users/david/openesb-standalone-packaging-3.0.2/logs/" + serviceAssemblyName + ".log", true));
  231. } catch (IOException ex) {
  232. Logger.getLogger(BPELTraceManager.class.getName()).log(Level.SEVERE, null, ex);
  233. } catch (SecurityException ex) {
  234. Logger.getLogger(BPELTraceManager.class.getName()).log(Level.SEVERE, null, ex);
  235. }
  236. return logger;
  237. */
  238. }
  239. private static String buildString(Object[] ctx) {
  240. StringBuilder buff = new StringBuilder();
  241. int len = ctx.length;
  242. if (len == 1) {
  243. buff.append("[{0}]");
  244. } else if ((len % 2) == 0) { // even count, key-value pairs
  245. buff.append('[');
  246. boolean comma = false;
  247. // ndc prints out key values in backwards order, so shall we
  248. for (int i = (len - 1); i >= 0; i -= 2) {
  249. if (comma) {
  250. buff.append(',');
  251. }
  252. buff.append('{').append((i - 1)).append("}={").append(i).append('}');
  253. comma = true;
  254. }
  255. buff.append(']');
  256. }
  257. return buff.toString();
  258. }
  259. /*
  260. *
  261. */
  262. private void sendAlerts(Iterator<Alert> alertIter, Context context) {
  263. while (alertIter.hasNext()) {
  264. Alert alert = alertIter.next();
  265. try {
  266. String level = alert.getLevel();
  267. From from = alert.getFrom();
  268. Alerter alerter = new AlerterImpl();
  269. String deploymentName = context.getProcessInstance().getBPELProcessManager().getServiceUnitName();
  270. // Developer Note: Alerter also has a severity level 'FATAL'. This is not applicable to
  271. // alerts from within BPEL.
  272. if (level.equals(Alert.CRITICAL)) {
  273. alerter.custom(NotificationEvent.EVENT_TYPE_ALERT, NotificationEvent.SEVERITY_TYPE_CRITICAL,
  274. evaluateFrom(null, from, context), COMPONENT_NAME, deploymentName, SERVER_TYPE,
  275. COMPONENT_TYPE, NotificationEvent.OPERATIONAL_STATE_RUNNING, null);
  276. } else if (level.equals(Alert.MAJOR)) {
  277. alerter.custom(NotificationEvent.EVENT_TYPE_ALERT, NotificationEvent.SEVERITY_TYPE_MAJOR,
  278. evaluateFrom(null, from, context), COMPONENT_NAME, deploymentName, SERVER_TYPE,
  279. COMPONENT_TYPE, NotificationEvent.OPERATIONAL_STATE_RUNNING, null);
  280. } else if (level.equals(Alert.MINOR)) {
  281. alerter.custom(NotificationEvent.EVENT_TYPE_ALERT, NotificationEvent.SEVERITY_TYPE_MINOR,
  282. evaluateFrom(null, from, context), COMPONENT_NAME, deploymentName, SERVER_TYPE,
  283. COMPONENT_TYPE, NotificationEvent.OPERATIONAL_STATE_RUNNING, null);
  284. } else if (level.equals(Alert.WARNING)) {
  285. alerter.custom(NotificationEvent.EVENT_TYPE_ALERT, NotificationEvent.SEVERITY_TYPE_WARNING,
  286. evaluateFrom(null, from, context), COMPONENT_NAME, deploymentName, SERVER_TYPE,
  287. COMPONENT_TYPE, NotificationEvent.OPERATIONAL_STATE_RUNNING, null);
  288. } else if (level.equals(Alert.INFO)) {
  289. alerter.custom(NotificationEvent.EVENT_TYPE_ALERT, NotificationEvent.SEVERITY_TYPE_INFO,
  290. evaluateFrom(null, from, context), COMPONENT_NAME, deploymentName, SERVER_TYPE,
  291. COMPONENT_TYPE, NotificationEvent.OPERATIONAL_STATE_RUNNING, null);
  292. } else {
  293. LOGGER.warning(I18n.loc("BPCOR-6088: Invalid alert level '{0}' specified at location {1}.",
  294. level, alert.getLocator().getLineNumber()));
  295. }
  296. } catch (Exception e) {
  297. // log exception and continue.
  298. LOGGER.warning(I18n.loc("BPCOR-6089: Encountered an exception while sending an alert at "
  299. + "location {0}. Exception: {1}.", alert.getLocator().getLineNumber(), e));
  300. }
  301. }
  302. }
  303. /*
  304. * Evaluates <code>from</code> and returns a <code>String</code>.
  305. */
  306. private String evaluateFrom(Object [] contextNDC, From from, Context context) throws Exception {
  307. StringBuilder traceMessage = null;
  308. if (contextNDC != null) {
  309. traceMessage = new StringBuilder(buildString(contextNDC));
  310. } else {
  311. traceMessage = new StringBuilder();
  312. }
  313. FromEvaluator fromEval = FromEvaluatorFactory.getFromEvaluator(from);
  314. Object fromVal = fromEval.evaluateFrom(from, context, null);
  315. if (fromVal instanceof Iterator) {
  316. // StringBuffer stringBuffer = new StringBuffer();
  317. Iterator<?> sourcePtrIterator = (Iterator<?>) fromVal;
  318. while (sourcePtrIterator.hasNext()) {
  319. Pointer currentSourcePtr = (Pointer) sourcePtrIterator.next();
  320. /*
  321. * The source can be an DOMAttributePointer, Object (string,
  322. * etc), or a Node represent an element with simple context.
  323. * sourcePtr.getValue().toString()) will work for all three
  324. * cases.
  325. */
  326. traceMessage.append(currentSourcePtr.getValue().toString());
  327. if (sourcePtrIterator.hasNext()) {
  328. traceMessage.append(LINE_SEPARATOR);
  329. }
  330. }
  331. // traceMessage = stringBuffer.toString();
  332. } else if (fromVal instanceof WSMessage) {
  333. // JBIMessageImpl implements WSMessage and has overridden the toString() method to
  334. // give relevant output. Hence using that method.
  335. traceMessage.append(fromVal.toString());
  336. } else if (fromVal instanceof Node) {
  337. traceMessage.append(DOMHelper.createXmlString((Node) fromVal));
  338. } else {
  339. // Most probably it is a String, Number or Boolean. Do a simple toString on it.
  340. traceMessage.append(fromVal.toString());
  341. }
  342. return traceMessage.toString();
  343. }
  344. public void alertEngineStatusChange(String engineId, int operationState) {
  345. try {
  346. Alerter alerter = new AlerterImpl();
  347. String message = I18n.loc("BPCOR-5005: Engine {0} status changed to {1} at {2}",
  348. engineId, EVENT.getOpStateString(operationState),
  349. simpleDateFormat.format(new Date(System.currentTimeMillis())));
  350. alerter.info(message, COMPONENT_NAME, null, null, NotificationEvent.COMPONENT_TYPE_BPEL,
  351. operationState, NotificationEvent.EVENT_TYPE_ALERT, null);
  352. } catch (Exception e) {
  353. // log exception and continue.
  354. try {
  355. LOGGER.warning(I18n.loc("BPCOR-6139: Failed to send an alert for engine status change : "
  356. + "Engine {0}, status {1}", engineId, operationState));
  357. } catch (Exception ex) {
  358. }
  359. }
  360. }
  361. public void alertUnableToCreateInstance(String engineId, String bpName,
  362. Throwable th) {
  363. try {
  364. Alerter alerter = new AlerterImpl();
  365. String cause = null;
  366. if (th != null) {
  367. StringWriter strWrt = new StringWriter();
  368. PrintWriter pr = new PrintWriter(strWrt);
  369. th.printStackTrace(pr);
  370. strWrt.flush();
  371. cause = strWrt.getBuffer().toString();
  372. }
  373. String message = I18n.loc("BPCOR-7010: Engine {0} unable to create process instance for"
  374. + " : {1} at {3}. Cause : {2}", engineId, bpName, cause,
  375. simpleDateFormat.format(new Date(System.currentTimeMillis())));
  376. alerter.critical(message, COMPONENT_NAME,
  377. null, null, NotificationEvent.COMPONENT_TYPE_BPEL,
  378. NotificationEvent.OPERATIONAL_STATE_RUNNING,
  379. NotificationEvent.EVENT_TYPE_ALERT, null);
  380. } catch (Exception e) {
  381. // log exception and continue.
  382. try {
  383. LOGGER.warning(I18n.loc("BPCOR-6140: Failed to send an alert for unable to create instance: "
  384. + "Engine {0}, bp {1}", engineId, bpName));
  385. } catch (Exception ex) {
  386. }
  387. }
  388. }
  389. public void alertBPInstanceChangeByAPI(String engineId, String bpName,
  390. String instanceId, String varName,
  391. BPELSEManagement.ActionType actionType) {
  392. try {
  393. Alerter alerter = new AlerterImpl();
  394. String msg = null;
  395. if (varName != null) {
  396. msg = I18n.loc("BPCOR-5006: Business process instance variable changed by API at {4}. Engine : {0}, "
  397. + "process: {1}, instance: {2}, variable: {3}", engineId, bpName, instanceId, varName,
  398. simpleDateFormat.format(new Date(System.currentTimeMillis())));
  399. } else {
  400. msg = I18n.loc("BPCOR-5007: Business process instance {3} by API at {4} . Engine : {0}, "
  401. + "process: {1}, instance: {2}", engineId, bpName, instanceId, actionType.toString(),
  402. simpleDateFormat.format(new Date(System.currentTimeMillis())));
  403. }
  404. alerter.info(msg, COMPONENT_NAME, null, null,
  405. NotificationEvent.COMPONENT_TYPE_BPEL,
  406. NotificationEvent.OPERATIONAL_STATE_RUNNING,
  407. NotificationEvent.EVENT_TYPE_ALERT, null);
  408. } catch (Exception e) {
  409. // log exception and continue.
  410. try {
  411. LOGGER.warning(I18n.loc("BPCOR-6141: Failed to send an alert for instance state change by API : "
  412. + "Engine {0}, process: {1}, instance: {2}, type {3}", engineId, bpName, instanceId,
  413. actionType.toString()));
  414. } catch (Exception ex) {
  415. }
  416. }
  417. }
  418. public void alertBPInstanceTerminatedOnUnHandledFault(String engineId,
  419. String bpName, String instanceId, String cause) {
  420. try {
  421. Alerter alerter = new AlerterImpl();
  422. String message = I18n.loc("BPCOR-6142: Business process instance terminated on unhandled fault at {4}. "
  423. + "Engine : {0}, process: {1}, instance: {2}. Cause : {3}", engineId, bpName, instanceId, cause,
  424. simpleDateFormat.format(new Date(System.currentTimeMillis())));
  425. alerter.major(message, COMPONENT_NAME,
  426. null, null, NotificationEvent.COMPONENT_TYPE_BPEL,
  427. NotificationEvent.OPERATIONAL_STATE_RUNNING,
  428. NotificationEvent.EVENT_TYPE_ALERT, null);
  429. } catch (Exception e) {
  430. // log exception and continue.
  431. try {
  432. LOGGER.warning(I18n.loc("BPCOR-6143: Failed to send an alert for instance terminated on unhandled "
  433. + "fault : Engine : {0}, process: {1}, instance: {2}, Cause : {3}", engineId, bpName,
  434. instanceId, cause));
  435. } catch (Exception ex) {
  436. }
  437. }
  438. }
  439. public void alertUnableToConnectToDB(String engineId, String cause) {
  440. try {
  441. Alerter alerter = new AlerterImpl();
  442. String message = I18n.loc("BPCOR-6144: Unable to connect to database at {2}. Engine : {0}, Cause : {1}",
  443. engineId, cause, simpleDateFormat.format(new Date(System.currentTimeMillis())));
  444. LOGGER.warning(message);
  445. alerter.major(message, COMPONENT_NAME,
  446. null, null, NotificationEvent.COMPONENT_TYPE_BPEL,
  447. NotificationEvent.OPERATIONAL_STATE_RUNNING,
  448. NotificationEvent.EVENT_TYPE_ALERT, null);
  449. } catch (Exception e) {
  450. // log exception and continue.
  451. try {
  452. LOGGER.warning(I18n.loc("BPCOR-6145: Failed to send an alert for unable to connect to DB. "
  453. + "Engine : {0}, Cause : {1}", engineId, cause));
  454. } catch (Exception ex) {
  455. }
  456. }
  457. }
  458. public void alertDBConnectionRestored(String engineId) {
  459. try {
  460. Alerter alerter = new AlerterImpl();
  461. String message = I18n.loc("BPCOR-6146: DB connection restored at {1}. Engine : {0}", engineId,
  462. simpleDateFormat.format(new Date(System.currentTimeMillis())));
  463. LOGGER.info(message);
  464. alerter.major(message, COMPONENT_NAME,
  465. null, null, NotificationEvent.COMPONENT_TYPE_BPEL,
  466. NotificationEvent.OPERATIONAL_STATE_RUNNING,
  467. NotificationEvent.EVENT_TYPE_ALERT, null);
  468. } catch (Exception e) {
  469. // log exception and continue.
  470. try {
  471. LOGGER.warning(I18n.loc("BPCOR-6147: Failed to send an alert for DB Connection restored : Engine {0}",
  472. engineId));
  473. } catch (Exception ex) {
  474. }
  475. }
  476. }
  477. public void alertSUStatusChange(String engineId, String suName,
  478. int operationState) {
  479. try {
  480. Alerter alerter = new AlerterImpl();
  481. String message = I18n.loc("BPCOR-5008: SU {1} on Engine {0} changed status to {2} at {3}", engineId,
  482. suName, EVENT.getOpStateString(operationState),
  483. simpleDateFormat.format(new Date(System.currentTimeMillis())));
  484. alerter.info(message, COMPONENT_NAME,
  485. suName, null, NotificationEvent.COMPONENT_TYPE_BPEL,
  486. operationState, NotificationEvent.EVENT_TYPE_ALERT, null);
  487. } catch (Exception e) {
  488. // log exception and continue.
  489. try {
  490. LOGGER.warning(I18n.loc("BPCOR-6148: Failed to send an alert for SU status chang : Engine {0}, "
  491. + "SU {1}, status {1}", engineId, suName, operationState));
  492. } catch (Exception ex) {
  493. }
  494. }
  495. }
  496. }