From 2bc2a6232ce2d5d524314c0aa6cdb39f0fae7102 Mon Sep 17 00:00:00 2001 From: Ralph Soika Date: Sat, 10 Jun 2023 18:26:08 +0200 Subject: [PATCH] logging Issue #177 --- .../org/imixs/archive/export/ExportApi.java | 5 +- .../org/imixs/archive/export/ExportTest.java | 74 --------- .../{ => controller}/ExportController.java | 19 ++- .../export/{ => services}/ExportService.java | 143 +++++++++++++++--- .../{ => services}/ExportStatusHandler.java | 2 +- .../{ => export}/util/FTPConnector.java | 2 +- .../{ => export}/util/RestClientHelper.java | 2 +- .../org/imixs/archive/util/LogController.java | 102 ------------- .../src/main/webapp/css/imixs-admin.css | 10 +- .../src/main/webapp/index.xhtml | 2 +- 10 files changed, 136 insertions(+), 225 deletions(-) delete mode 100644 imixs-archive-exporter/src/main/java/org/imixs/archive/export/ExportTest.java rename imixs-archive-exporter/src/main/java/org/imixs/archive/export/{ => controller}/ExportController.java (87%) rename imixs-archive-exporter/src/main/java/org/imixs/archive/export/{ => services}/ExportService.java (72%) rename imixs-archive-exporter/src/main/java/org/imixs/archive/export/{ => services}/ExportStatusHandler.java (98%) rename imixs-archive-exporter/src/main/java/org/imixs/archive/{ => export}/util/FTPConnector.java (99%) rename imixs-archive-exporter/src/main/java/org/imixs/archive/{ => export}/util/RestClientHelper.java (99%) delete mode 100644 imixs-archive-exporter/src/main/java/org/imixs/archive/util/LogController.java diff --git a/imixs-archive-exporter/src/main/java/org/imixs/archive/export/ExportApi.java b/imixs-archive-exporter/src/main/java/org/imixs/archive/export/ExportApi.java index 72ddb98..45ad356 100644 --- a/imixs-archive-exporter/src/main/java/org/imixs/archive/export/ExportApi.java +++ b/imixs-archive-exporter/src/main/java/org/imixs/archive/export/ExportApi.java @@ -28,12 +28,11 @@ public class ExportApi extends Application { public static final String ENV_EXPORT_FTP_PORT = "EXPORT_FTP_PORT"; public static final String ENV_EXPORT_FTP_USER = "EXPORT_FTP_USER"; public static final String ENV_EXPORT_FTP_PASSWORD = "EXPORT_FTP_PASSWORD"; + public static final String ENV_EXPORT_FILE_PATH = "EXPORT_FILE_PATH"; - public static final String EVENTLOG_TOPIC_EXPORT = "snapshot.export"; + public static final String EVENTLOG_TOPIC_EXPORT = "file.export"; public static final String EXPORT_SYNC_DEADLOCK = "export.sync.deadlock"; - public static final String TOPIC_EXPORT = "EXPORT"; - public final static String SNAPSHOT_RESOURCE = "snapshot/"; /** diff --git a/imixs-archive-exporter/src/main/java/org/imixs/archive/export/ExportTest.java b/imixs-archive-exporter/src/main/java/org/imixs/archive/export/ExportTest.java deleted file mode 100644 index 144b989..0000000 --- a/imixs-archive-exporter/src/main/java/org/imixs/archive/export/ExportTest.java +++ /dev/null @@ -1,74 +0,0 @@ -package org.imixs.archive.export; - -import java.util.Map; -import java.util.SortedMap; - -import org.eclipse.microprofile.metrics.Counter; -import org.eclipse.microprofile.metrics.MetricID; -import org.eclipse.microprofile.metrics.MetricRegistry; -import org.eclipse.microprofile.metrics.annotation.Counted; -import org.eclipse.microprofile.metrics.annotation.RegistryType; - -import jakarta.enterprise.context.RequestScoped; -import jakarta.inject.Inject; -import jakarta.ws.rs.GET; -import jakarta.ws.rs.Path; -import jakarta.ws.rs.Produces; -import jakarta.ws.rs.core.MediaType; - -@RequestScoped -@Path("/test") -@Produces({ MediaType.TEXT_PLAIN }) -public class ExportTest { - - @Inject - @RegistryType(type = MetricRegistry.Type.APPLICATION) - MetricRegistry metricRegistry; - - @GET - @Path("/ping") - @Produces("text/plain") - @Counted(name = "exportPing", description = "Counting pings", displayName = "exportPing") - public String ping() { - - return "Pinga - " + System.currentTimeMillis(); - } - - /** - * Test to read the current coutner - * - * @return - */ - @GET - @Path("/count") - @Produces("text/plain") - public String count() { - System.out.println("Test P1"); - - SortedMap allCounters = metricRegistry.getCounters(); - - for (Map.Entry entry : allCounters.entrySet()) { - System.out.println(entry.getKey() + ":" + entry.getValue()); - - MetricID meti = entry.getKey(); - - Counter ding = entry.getValue(); - System.out.println(" coutner wert=" + ding.getCount() + " metric name " + meti.getName()); - - } - - // pingCount = metricRegistry.getCounter("exportPing"); - - System.out.println("Test Ping count="); - - // SortedMap counters = metricRegistry.getCounters(); - // Counter counter = - // counters.get("application_org_imixs_archive_export_ExportTest_exportPing_total"); - - // if (counter != null) { - // return " ping counter = " + counter.getCount(); - // } - - return "test counter found"; - } -} diff --git a/imixs-archive-exporter/src/main/java/org/imixs/archive/export/ExportController.java b/imixs-archive-exporter/src/main/java/org/imixs/archive/export/controller/ExportController.java similarity index 87% rename from imixs-archive-exporter/src/main/java/org/imixs/archive/export/ExportController.java rename to imixs-archive-exporter/src/main/java/org/imixs/archive/export/controller/ExportController.java index a4d27ca..022d721 100644 --- a/imixs-archive-exporter/src/main/java/org/imixs/archive/export/ExportController.java +++ b/imixs-archive-exporter/src/main/java/org/imixs/archive/export/controller/ExportController.java @@ -1,7 +1,8 @@ -package org.imixs.archive.export; +package org.imixs.archive.export.controller; import java.io.Serializable; import java.util.Date; +import java.util.List; import java.util.Map; import java.util.Optional; import java.util.SortedMap; @@ -12,7 +13,10 @@ import org.eclipse.microprofile.metrics.MetricID; import org.eclipse.microprofile.metrics.MetricRegistry; import org.eclipse.microprofile.metrics.annotation.RegistryType; -import org.imixs.archive.util.LogController; +import org.imixs.archive.export.ExportApi; +import org.imixs.archive.export.ExportException; +import org.imixs.archive.export.services.ExportService; +import org.imixs.archive.export.services.ExportStatusHandler; import jakarta.enterprise.context.RequestScoped; import jakarta.inject.Inject; @@ -70,10 +74,6 @@ public class ExportController implements Serializable { @Inject ExportService exportService; - - @Inject - LogController logController; - @Inject ExportStatusHandler exportStatusHandler; @@ -126,7 +126,7 @@ public void start() { try { exportService.startScheduler(true); } catch (ExportException e) { - logController.warning(ExportApi.TOPIC_EXPORT, e.getMessage()); + exportService.warning(ExportApi.EVENTLOG_TOPIC_EXPORT, e.getMessage()); } } @@ -137,7 +137,7 @@ public void stop() { try { exportService.stopScheduler(); } catch (ExportException e) { - logController.warning(ExportApi.TOPIC_EXPORT, e.getMessage()); + exportService.warning(ExportApi.EVENTLOG_TOPIC_EXPORT, e.getMessage()); } } @@ -162,4 +162,7 @@ public long getCounterByName(String name) { return 0; } + public List getLogEntries(String context) { + return exportService.getLogEntries();// logTopics.get(context); + } } \ No newline at end of file diff --git a/imixs-archive-exporter/src/main/java/org/imixs/archive/export/ExportService.java b/imixs-archive-exporter/src/main/java/org/imixs/archive/export/services/ExportService.java similarity index 72% rename from imixs-archive-exporter/src/main/java/org/imixs/archive/export/ExportService.java rename to imixs-archive-exporter/src/main/java/org/imixs/archive/export/services/ExportService.java index 56acc3f..49b8712 100644 --- a/imixs-archive-exporter/src/main/java/org/imixs/archive/export/ExportService.java +++ b/imixs-archive-exporter/src/main/java/org/imixs/archive/export/services/ExportService.java @@ -20,8 +20,11 @@ * Imixs Software Solutions GmbH - initial API and implementation * Ralph Soika *******************************************************************************/ -package org.imixs.archive.export; +package org.imixs.archive.export.services; +import java.text.SimpleDateFormat; +import java.util.ArrayList; +import java.util.Date; import java.util.List; import java.util.Optional; import java.util.logging.Logger; @@ -30,9 +33,10 @@ import org.eclipse.microprofile.metrics.MetricRegistry; import org.eclipse.microprofile.metrics.annotation.Counted; import org.eclipse.microprofile.metrics.annotation.RegistryType; -import org.imixs.archive.util.FTPConnector; -import org.imixs.archive.util.LogController; -import org.imixs.archive.util.RestClientHelper; +import org.imixs.archive.export.ExportApi; +import org.imixs.archive.export.ExportException; +import org.imixs.archive.export.util.FTPConnector; +import org.imixs.archive.export.util.RestClientHelper; import org.imixs.melman.DocumentClient; import org.imixs.melman.EventLogClient; import org.imixs.melman.RestAPIException; @@ -75,9 +79,6 @@ public class ExportService { private static Logger logger = Logger.getLogger(ExportService.class.getName()); - @Inject - LogController logController; - // timeout interval in ms @Inject @ConfigProperty(name = ExportApi.WORKFLOW_SYNC_INTERVAL, defaultValue = "10000") @@ -107,6 +108,10 @@ public class ExportService { @ConfigProperty(name = ExportApi.ENV_EXPORT_FTP_HOST) Optional ftpServer; + @Inject + @ConfigProperty(name = ExportApi.ENV_EXPORT_FILE_PATH) + Optional filePath; + // deadlock timeout interval in ms @Inject @ConfigProperty(name = ExportApi.EXPORT_SYNC_DEADLOCK, defaultValue = "60000") @@ -128,20 +133,47 @@ public class ExportService { @RegistryType(type = MetricRegistry.Type.APPLICATION) MetricRegistry metricRegistry; + private int maxSize = 30; + + private List logTopics; + public static final int LOG_INFO = 1; + public static final int LOG_WARNING = 2; + public static final int LOG_ERROR = 3; + @PostConstruct public void init() { + + info(ExportApi.EVENTLOG_TOPIC_EXPORT, "Setup..."); // init timer.... - if (workflowServiceEndpoint.isPresent()) { - // Registering a non-persistent Timer Service. + if (verifiyConfiguration()) { try { + // Registering a non-persistent Timer Service. startScheduler(true); } catch (ExportException e) { - logController.warning(ExportApi.TOPIC_EXPORT, "Failed to init scheduler: " + e.getMessage()); + warning(ExportApi.EVENTLOG_TOPIC_EXPORT, "Failed to init scheduler: " + e.getMessage()); } - } else { - logController.warning(ExportApi.TOPIC_EXPORT, + } + } + + /** + * Helper method to verify if the configuration is sufficient + * + * @return + */ + private boolean verifiyConfiguration() { + if (!workflowServiceEndpoint.isPresent()) { + severe(ExportApi.EVENTLOG_TOPIC_EXPORT, "Missing environment param 'WORKFLOW_SERVICE_ENDPOINT' - please verify configuration!"); + return false; + + } + if (!ftpServer.isPresent() && !filePath.isPresent()) { + severe(ExportApi.EVENTLOG_TOPIC_EXPORT, + "Missing environment param 'EXPORT_FTP_HOST or EXPORT_FILE_PATH' - please verify configuration!"); + return false; + } + return true; } /** @@ -151,10 +183,18 @@ public void init() { *

* Each eventLogEntry is locked to guaranty exclusive processing. * + * + * The metric generated : + * + * executions count: count of method executions processing Time: + * application_org_imixs_archive_export_ExportService_executions_total event + * count: error count: + * application_org_imixs_archive_export_ExportService_errors_total + * + * * @throws RestAPIException **/ - - @Counted(name = "exportServiceInvocations", description = "Counting the invocations of export service", displayName = "exportServiceInvocations") + @Counted(name = "executions", description = "Counting the invocations of export service", displayName = "executions") @SuppressWarnings("unused") @Timeout public void onTimeout(jakarta.ejb.Timer _timer) { @@ -170,7 +210,7 @@ public void onTimeout(jakarta.ejb.Timer _timer) { DocumentClient documentClient = restClientHelper.getDocumentClient(); EventLogClient eventLogClient = restClientHelper.getEventLogClient(documentClient); if (documentClient == null || eventLogClient == null) { - logController.warning(ExportApi.TOPIC_EXPORT, + warning(ExportApi.EVENTLOG_TOPIC_EXPORT, "Unable to connect to workflow instance endpoint - please verify configuration!"); try { stopScheduler(); @@ -210,25 +250,27 @@ public void onTimeout(jakarta.ejb.Timer _timer) { // finally remove the event log entry... eventLogClient.deleteEventLogEntry(id); success++; + metricRegistry.counter("application_org_imixs_archive_export_ExportService_events").inc(); } catch (InvalidAccessException | EJBException | ExportException | RestAPIException e) { // we also catch EJBExceptions here because we do not want to cancel the // ManagedScheduledExecutorService - logController.warning(ExportApi.TOPIC_EXPORT, + warning(ExportApi.EVENTLOG_TOPIC_EXPORT, "SnapshotEvent " + id + " export failed: " + e.getMessage()); + metricRegistry.counter("application_org_imixs_archive_export_ExportService_errors").inc(); errors++; } } // print log if (total > 0) { - logController.info(ExportApi.TOPIC_EXPORT, success + " snapshots export up, " + errors + " errors..."); + info(ExportApi.EVENTLOG_TOPIC_EXPORT, success + " snapshots export up, " + errors + " errors..."); } exportStatusHandler.setStatus(ExportStatusHandler.STATUS_SCHEDULED); } catch (InvalidAccessException | EJBException | RestAPIException e) { - logController.severe(ExportApi.TOPIC_EXPORT, "processing EventLog failed: " + e.getMessage()); - metricRegistry.counter("org_imixs_archive_export_errors").inc(); + severe(ExportApi.EVENTLOG_TOPIC_EXPORT, "processing EventLog failed: " + e.getMessage()); + metricRegistry.counter("application_org_imixs_archive_export_ExportService_errors").inc(); } } @@ -279,9 +321,9 @@ public ItemCollection pullSnapshot(ItemCollection eventLogEntry, DocumentClient return snapshot; } } catch (RestAPIException e) { - logController.warning(ExportApi.TOPIC_EXPORT, "Snapshot " + ref + " pull failed: " + e.getMessage()); + warning(ExportApi.EVENTLOG_TOPIC_EXPORT, "Snapshot " + ref + " pull failed: " + e.getMessage()); // now we need to remove the batch event - logController.warning(ExportApi.TOPIC_EXPORT, "EventLogEntry " + id + " will be removed!"); + warning(ExportApi.EVENTLOG_TOPIC_EXPORT, "EventLogEntry " + id + " will be removed!"); try { eventLogClient.deleteEventLogEntry(id); } catch (RestAPIException e1) { @@ -314,9 +356,9 @@ public void startScheduler(boolean clearLog) throws ExportException { try { if (clearLog) { // clear log in case of a normal start - logController.reset(ExportApi.TOPIC_EXPORT); + // reset(ExportApi.EVENTLOG_TOPIC_EXPORT); } - logController.info(ExportApi.TOPIC_EXPORT, + info(ExportApi.EVENTLOG_TOPIC_EXPORT, "Starting export scheduler - initalDelay=" + initialDelay + "ms inverval=" + interval + "ms ...."); // start archive schedulers.... // Registering a non-persistent Timer Service. @@ -341,16 +383,67 @@ public boolean stopScheduler() throws ExportException { Timer timer = exportStatusHandler.getTimer(); if (timer != null) { try { - logController.info(ExportApi.TOPIC_EXPORT, "Stopping the export scheduler..."); + info(ExportApi.EVENTLOG_TOPIC_EXPORT, "Stopping the export scheduler..."); timer.cancel(); } catch (IllegalArgumentException | IllegalStateException | EJBException e) { throw new ExportException("TIMER_EXCEPTION", "Failed to stop scheduler ", e); } // update status message - logController.info(ExportApi.TOPIC_EXPORT, "Timer stopped. "); + info(ExportApi.EVENTLOG_TOPIC_EXPORT, "Timer stopped. "); } exportStatusHandler.setStatus(ExportStatusHandler.STATUS_STOPPED); return true; } + /** + * Logs a new message to the message log + * + * @param message + */ + private void add(String topic, int type, String message) { + String pattern = " HH:mm:ss.SSSZ"; + SimpleDateFormat simpleDateFormat = new SimpleDateFormat(pattern); + + // get the logger + + if (logTopics == null) { + logTopics = new ArrayList(); + } + + // check maxsize... + while (logTopics.size() > maxSize) { + logTopics.remove(0); + } + + String entry = simpleDateFormat.format(new Date()) + " "; + if (type == LOG_ERROR) { + entry = entry + "[ERROR] "; + logger.severe(message); + } else if (type == LOG_WARNING) { + entry = entry + "[WARNING] "; + logger.warning(message); + } else { + entry = entry + "[INFO] "; + logger.info(message); + + } + entry = entry + message; + logTopics.add(entry); + } + + public List getLogEntries() { + return logTopics; + } + + public void info(String context, String message) { + add(context, LOG_INFO, message); + } + + public void warning(String context, String message) { + add(context, LOG_WARNING, message); + } + + public void severe(String context, String message) { + add(context, LOG_ERROR, message); + } } diff --git a/imixs-archive-exporter/src/main/java/org/imixs/archive/export/ExportStatusHandler.java b/imixs-archive-exporter/src/main/java/org/imixs/archive/export/services/ExportStatusHandler.java similarity index 98% rename from imixs-archive-exporter/src/main/java/org/imixs/archive/export/ExportStatusHandler.java rename to imixs-archive-exporter/src/main/java/org/imixs/archive/export/services/ExportStatusHandler.java index c8b4d7e..9b0a2eb 100644 --- a/imixs-archive-exporter/src/main/java/org/imixs/archive/export/ExportStatusHandler.java +++ b/imixs-archive-exporter/src/main/java/org/imixs/archive/export/services/ExportStatusHandler.java @@ -20,7 +20,7 @@ * Imixs Software Solutions GmbH - initial API and implementation * Ralph Soika *******************************************************************************/ -package org.imixs.archive.export; +package org.imixs.archive.export.services; import java.util.Date; import java.util.logging.Logger; diff --git a/imixs-archive-exporter/src/main/java/org/imixs/archive/util/FTPConnector.java b/imixs-archive-exporter/src/main/java/org/imixs/archive/export/util/FTPConnector.java similarity index 99% rename from imixs-archive-exporter/src/main/java/org/imixs/archive/util/FTPConnector.java rename to imixs-archive-exporter/src/main/java/org/imixs/archive/export/util/FTPConnector.java index a60a404..58dcf80 100644 --- a/imixs-archive-exporter/src/main/java/org/imixs/archive/util/FTPConnector.java +++ b/imixs-archive-exporter/src/main/java/org/imixs/archive/export/util/FTPConnector.java @@ -20,7 +20,7 @@ * Imixs Software Solutions GmbH - initial API and implementation * Ralph Soika *******************************************************************************/ -package org.imixs.archive.util; +package org.imixs.archive.export.util; import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; diff --git a/imixs-archive-exporter/src/main/java/org/imixs/archive/util/RestClientHelper.java b/imixs-archive-exporter/src/main/java/org/imixs/archive/export/util/RestClientHelper.java similarity index 99% rename from imixs-archive-exporter/src/main/java/org/imixs/archive/util/RestClientHelper.java rename to imixs-archive-exporter/src/main/java/org/imixs/archive/export/util/RestClientHelper.java index be1351d..b49d816 100644 --- a/imixs-archive-exporter/src/main/java/org/imixs/archive/util/RestClientHelper.java +++ b/imixs-archive-exporter/src/main/java/org/imixs/archive/export/util/RestClientHelper.java @@ -1,4 +1,4 @@ -package org.imixs.archive.util; +package org.imixs.archive.export.util; import java.io.Serializable; import java.util.List; diff --git a/imixs-archive-exporter/src/main/java/org/imixs/archive/util/LogController.java b/imixs-archive-exporter/src/main/java/org/imixs/archive/util/LogController.java deleted file mode 100644 index 8493ae8..0000000 --- a/imixs-archive-exporter/src/main/java/org/imixs/archive/util/LogController.java +++ /dev/null @@ -1,102 +0,0 @@ -package org.imixs.archive.util; - -import java.io.Serializable; -import java.text.SimpleDateFormat; -import java.util.ArrayList; -import java.util.Date; -import java.util.HashMap; -import java.util.List; -import java.util.Map; -import java.util.logging.Logger; - -import jakarta.enterprise.context.ApplicationScoped; -import jakarta.inject.Named; - -/** - * The LogController stores a message log under a specific topic. In this way - * the logController can be use in different context. - * - * @author rsoika - * - */ -@Named -@ApplicationScoped -public class LogController implements Serializable { - - private static final long serialVersionUID = 1L; - - public static final int LOG_INFO = 1; - public static final int LOG_WARNING = 2; - public static final int LOG_ERROR = 3; - - private static Logger logger = Logger.getLogger(LogController.class.getName()); - String pattern = " HH:mm:ss.SSSZ"; - SimpleDateFormat simpleDateFormat = new SimpleDateFormat(pattern); - - private Map> logTopics; - - private int maxSize = 30; - - /** - * Init LogTopics - */ - public LogController() { - super(); - logTopics = new HashMap>(); - } - - public List reset(String context) { - logTopics.put(context, new ArrayList()); - return logTopics.get(context); - } - - public void info(String context, String message) { - add(context, LOG_INFO, message); - } - - public void warning(String context, String message) { - add(context, LOG_WARNING, message); - } - - public void severe(String context, String message) { - add(context, LOG_ERROR, message); - } - - /** - * Logs a new message to the message log - * - * @param message - */ - private void add(String topic, int type, String message) { - // get the logger - List logEntries = logTopics.get(topic); - if (logEntries == null) { - logEntries = reset(topic); - } - - // check maxsize... - while (logEntries.size() > maxSize) { - logEntries.remove(0); - } - - String entry = simpleDateFormat.format(new Date()) + " "; - if (type == LOG_ERROR) { - entry = entry + "[ERROR] "; - logger.severe(message); - } else if (type == LOG_WARNING) { - entry = entry + "[WARNING] "; - logger.warning(message); - } else { - entry = entry + "[INFO] "; - logger.info(message); - - } - entry = entry + message; - logEntries.add(entry); - } - - public List getLogEntries(String context) { - return logTopics.get(context); - } - -} \ No newline at end of file diff --git a/imixs-archive-exporter/src/main/webapp/css/imixs-admin.css b/imixs-archive-exporter/src/main/webapp/css/imixs-admin.css index 2870324..ef07dd7 100644 --- a/imixs-archive-exporter/src/main/webapp/css/imixs-admin.css +++ b/imixs-archive-exporter/src/main/webapp/css/imixs-admin.css @@ -125,7 +125,6 @@ .nav-sidebar .nav-item:hover a label { - xbackground-color: #1d2531 !important; color: #fff; font-weight: bold; } @@ -134,12 +133,6 @@ - - - - - - .main-container { padding: 16px 20px; } @@ -236,8 +229,7 @@ input[type="file"] { } #imixs-footer { - width: 100%; - padding: 10px 30px 10px 210px; + width: 100%; text-align: right; } #imixs-footer ul li { diff --git a/imixs-archive-exporter/src/main/webapp/index.xhtml b/imixs-archive-exporter/src/main/webapp/index.xhtml index 93d1917..74f047f 100644 --- a/imixs-archive-exporter/src/main/webapp/index.xhtml +++ b/imixs-archive-exporter/src/main/webapp/index.xhtml @@ -122,7 +122,7 @@ Log

-						
+