You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@syncope.apache.org by il...@apache.org on 2017/01/05 16:17:45 UTC
[2/2] syncope git commit: [SYNCOPE-882] Log viewer for the admin
console
[SYNCOPE-882] Log viewer for the admin console
Project: http://git-wip-us.apache.org/repos/asf/syncope/repo
Commit: http://git-wip-us.apache.org/repos/asf/syncope/commit/f4c717e7
Tree: http://git-wip-us.apache.org/repos/asf/syncope/tree/f4c717e7
Diff: http://git-wip-us.apache.org/repos/asf/syncope/diff/f4c717e7
Branch: refs/heads/master
Commit: f4c717e7d61e20cd205741dea1aad2c920362822
Parents: 3684437
Author: Francesco Chicchiricc� <il...@apache.org>
Authored: Wed Jan 4 09:07:24 2017 +0100
Committer: Francesco Chicchiricc� <il...@apache.org>
Committed: Thu Jan 5 17:17:29 2017 +0100
----------------------------------------------------------------------
.../syncope/client/console/pages/BasePage.java | 2 +-
.../syncope/client/console/pages/LogViewer.java | 243 +++++++++++++++++++
.../console/panels/AbstractLogsPanel.java | 10 +-
.../client/console/panels/CoreLogPanel.java | 6 +
.../client/console/panels/ExecMessageModal.java | 12 +-
.../console/panels/LogStatementPanel.java | 93 +++++++
.../client/console/rest/LoggerRestClient.java | 30 +++
.../client/console/widgets/JobActionPanel.java | 9 +-
.../client/console/widgets/JobWidget.java | 11 +-
.../syncope/client/console/pages/LogViewer.html | 34 +++
.../client/console/panels/CoreLogPanel.html | 5 +
.../client/console/panels/LabelPanel.html | 11 +-
.../console/panels/LogStatementPanel.html | 33 +++
.../syncope/common/lib/log/LogStatementTO.java | 8 +-
.../src/main/resources/log4j2.xml | 52 ++--
.../org/apache/syncope/fit/cli/CLIITCase.java | 2 +-
.../apache/syncope/fit/core/LoggerITCase.java | 2 +-
.../pom.xml | 22 ++
pom.xml | 6 +
.../workingwithapachesyncope/cli/logger.adoc | 10 +-
20 files changed, 545 insertions(+), 56 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/syncope/blob/f4c717e7/client/console/src/main/java/org/apache/syncope/client/console/pages/BasePage.java
----------------------------------------------------------------------
diff --git a/client/console/src/main/java/org/apache/syncope/client/console/pages/BasePage.java b/client/console/src/main/java/org/apache/syncope/client/console/pages/BasePage.java
index 2335b23..255145f 100644
--- a/client/console/src/main/java/org/apache/syncope/client/console/pages/BasePage.java
+++ b/client/console/src/main/java/org/apache/syncope/client/console/pages/BasePage.java
@@ -259,7 +259,7 @@ public class BasePage extends WebPage implements IAjaxIndicatorAware {
}
});
body.add(new Label("domain", SyncopeConsoleSession.get().getDomain()));
- body.add(new BookmarkablePageLink<>("logout", Logout.class));
+ body.add(new BookmarkablePageLink<Page>("logout", Logout.class));
// set 'active' menu item for everything but extensions
// 1. check if current class is set to top-level menu
http://git-wip-us.apache.org/repos/asf/syncope/blob/f4c717e7/client/console/src/main/java/org/apache/syncope/client/console/pages/LogViewer.java
----------------------------------------------------------------------
diff --git a/client/console/src/main/java/org/apache/syncope/client/console/pages/LogViewer.java b/client/console/src/main/java/org/apache/syncope/client/console/pages/LogViewer.java
new file mode 100644
index 0000000..c96ee1c
--- /dev/null
+++ b/client/console/src/main/java/org/apache/syncope/client/console/pages/LogViewer.java
@@ -0,0 +1,243 @@
+/*
+ * 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 org.apache.syncope.client.console.pages;
+
+import static org.apache.wicket.Component.ENABLE;
+
+import java.io.Serializable;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.concurrent.TimeUnit;
+import org.apache.commons.collections4.list.SetUniqueList;
+import org.apache.syncope.client.console.SyncopeConsoleSession;
+import org.apache.syncope.client.console.commons.Constants;
+import org.apache.syncope.client.console.panels.LogStatementPanel;
+import org.apache.syncope.client.console.rest.LoggerRestClient;
+import org.apache.syncope.client.console.wicket.markup.html.form.AjaxDropDownChoicePanel;
+import org.apache.syncope.common.lib.log.LogStatementTO;
+import org.apache.syncope.common.lib.types.StandardEntitlement;
+import org.apache.wicket.Application;
+import org.apache.wicket.ThreadContext;
+import org.apache.wicket.ajax.AjaxRequestTarget;
+import org.apache.wicket.ajax.form.AjaxFormComponentUpdatingBehavior;
+import org.apache.wicket.authroles.authorization.strategies.role.metadata.MetaDataRoleAuthorizationStrategy;
+import org.apache.wicket.event.IEvent;
+import org.apache.wicket.markup.html.WebMarkupContainer;
+import org.apache.wicket.markup.html.WebPage;
+import org.apache.wicket.markup.html.list.ListItem;
+import org.apache.wicket.markup.html.list.ListView;
+import org.apache.wicket.model.IModel;
+import org.apache.wicket.model.Model;
+import org.apache.wicket.model.util.ListModel;
+import org.apache.wicket.protocol.ws.WebSocketSettings;
+import org.apache.wicket.protocol.ws.api.WebSocketBehavior;
+import org.apache.wicket.protocol.ws.api.WebSocketPushBroadcaster;
+import org.apache.wicket.protocol.ws.api.event.WebSocketPushPayload;
+import org.apache.wicket.protocol.ws.api.message.ConnectedMessage;
+import org.apache.wicket.protocol.ws.api.message.IWebSocketPushMessage;
+import org.apache.wicket.protocol.ws.api.registry.IKey;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+public class LogViewer extends WebPage {
+
+ private static final Logger LOG = LoggerFactory.getLogger(LogViewer.class);
+
+ private static final int MAX_STATEMENTS_PER_APPENDER = 50;
+
+ private static final long serialVersionUID = -7578329899052708105L;
+
+ private final LoggerRestClient restClient = new LoggerRestClient();
+
+ private final IModel<Long> lastTimeInMillis = Model.of(0L);
+
+ private final WebMarkupContainer stContainer;
+
+ private final IModel<List<LogStatementTO>> statementViewModel;
+
+ private final ListView<LogStatementTO> statementView;
+
+ public LogViewer() {
+ final WebMarkupContainer viewer = new WebMarkupContainer("viewer");
+ viewer.setOutputMarkupId(true);
+ add(viewer);
+
+ final AjaxDropDownChoicePanel<String> appenders = new AjaxDropDownChoicePanel<>(
+ "appenders", "Appender", new Model<String>(), false);
+ MetaDataRoleAuthorizationStrategy.authorize(appenders, ENABLE, StandardEntitlement.LOG_READ);
+ appenders.setChoices(restClient.listMemoryAppenders());
+ viewer.add(appenders);
+
+ stContainer = new WebMarkupContainer("stContainer");
+ stContainer.setOutputMarkupId(true);
+ viewer.add(stContainer);
+
+ statementViewModel = new ListModel<>(new ArrayList<LogStatementTO>());
+ statementView = new ListView<LogStatementTO>("statements", statementViewModel) {
+
+ private static final long serialVersionUID = -9180479401817023838L;
+
+ @Override
+ protected void populateItem(final ListItem<LogStatementTO> item) {
+ LogStatementPanel panel = new LogStatementPanel("statement", item.getModelObject());
+ panel.setOutputMarkupId(true);
+ item.add(panel);
+ }
+ };
+ statementView.setOutputMarkupId(true);
+ stContainer.add(statementView);
+
+ appenders.getField().add(new AjaxFormComponentUpdatingBehavior(Constants.ON_CHANGE) {
+
+ private static final long serialVersionUID = -1107858522700306810L;
+
+ @Override
+ protected void onUpdate(final AjaxRequestTarget target) {
+ List<LogStatementTO> lastStatements = appenders.getModelObject() == null
+ ? new ArrayList<LogStatementTO>()
+ : restClient.getLastLogStatements(appenders.getModelObject(), 0);
+ statementViewModel.setObject(lastStatements);
+ target.add(stContainer);
+
+ lastTimeInMillis.setObject(0L);
+ }
+ });
+
+ add(new WebSocketBehavior() {
+
+ private static final long serialVersionUID = 3507933905864454312L;
+
+ @Override
+ protected void onConnect(final ConnectedMessage message) {
+ super.onConnect(message);
+
+ SyncopeConsoleSession.get().scheduleAtFixedRate(
+ new LogStatementUpdater(message, restClient, appenders, lastTimeInMillis),
+ 0, 10, TimeUnit.SECONDS);
+ }
+
+ });
+ }
+
+ @Override
+ public void onEvent(final IEvent<?> event) {
+ if (event.getPayload() instanceof WebSocketPushPayload) {
+ WebSocketPushPayload wsEvent = (WebSocketPushPayload) event.getPayload();
+ if (wsEvent.getMessage() instanceof LogViewerMessage) {
+ List<LogStatementTO> recentLogStatements =
+ ((LogViewerMessage) wsEvent.getMessage()).getRecentLogStatements();
+
+ if (!recentLogStatements.isEmpty()) {
+ // save scroll position
+ wsEvent.getHandler().prependJavaScript(
+ String.format("window.scrollTop = $('#%s').scrollTop();", stContainer.getMarkupId()));
+
+ int currentSize = statementView.getModelObject().size();
+ int recentSize = recentLogStatements.size();
+
+ List<LogStatementTO> newModelObject = SetUniqueList.<LogStatementTO>setUniqueList(
+ new ArrayList<LogStatementTO>(MAX_STATEMENTS_PER_APPENDER));
+ if (currentSize <= MAX_STATEMENTS_PER_APPENDER - recentSize) {
+ newModelObject.addAll(statementView.getModelObject());
+ } else {
+ newModelObject.addAll(statementView.getModelObject().subList(recentSize, currentSize));
+ }
+ newModelObject.addAll(recentLogStatements);
+
+ statementViewModel.setObject(newModelObject);
+ wsEvent.getHandler().add(LogViewer.this.stContainer);
+
+ // restore scroll position - might not work perfectly if items were removed from the top
+ wsEvent.getHandler().appendJavaScript(
+ String.format("$('#%s').scrollTop(window.scrollTop);", stContainer.getMarkupId()));
+ }
+ }
+ }
+ }
+
+ private static final class LogStatementUpdater implements Runnable {
+
+ private final Application application;
+
+ private final SyncopeConsoleSession session;
+
+ private final IKey key;
+
+ private final LoggerRestClient restClient;
+
+ private final AjaxDropDownChoicePanel<String> appenders;
+
+ private final IModel<Long> lastTimeInMillis;
+
+ LogStatementUpdater(
+ final ConnectedMessage message,
+ final LoggerRestClient restClient,
+ final AjaxDropDownChoicePanel<String> appenders,
+ final IModel<Long> lastTimeInMillis) {
+
+ this.application = message.getApplication();
+ this.session = SyncopeConsoleSession.get();
+ this.key = message.getKey();
+ this.restClient = restClient;
+ this.appenders = appenders;
+ this.lastTimeInMillis = lastTimeInMillis;
+ }
+
+ @Override
+ public void run() {
+ try {
+ ThreadContext.setApplication(application);
+ ThreadContext.setSession(session);
+
+ List<LogStatementTO> recentLogStatements = appenders.getModelObject() == null
+ ? new ArrayList<LogStatementTO>()
+ : restClient.getLastLogStatements(appenders.getModelObject(), lastTimeInMillis.getObject());
+ if (!recentLogStatements.isEmpty()) {
+ lastTimeInMillis.setObject(recentLogStatements.get(recentLogStatements.size() - 1).getTimeMillis());
+ }
+
+ WebSocketSettings settings = WebSocketSettings.Holder.get(application);
+ WebSocketPushBroadcaster broadcaster = new WebSocketPushBroadcaster(settings.getConnectionRegistry());
+ broadcaster.broadcast(
+ new ConnectedMessage(application, session.getId(), key),
+ new LogViewerMessage(recentLogStatements));
+ } catch (Throwable t) {
+ LOG.error("Unexpected error while checking for recent log statements", t);
+ } finally {
+ ThreadContext.detach();
+ }
+ }
+ }
+
+ private static class LogViewerMessage implements IWebSocketPushMessage, Serializable {
+
+ private static final long serialVersionUID = 7241149017008105769L;
+
+ private final List<LogStatementTO> recentLogStatements;
+
+ LogViewerMessage(final List<LogStatementTO> recentLogStatements) {
+ this.recentLogStatements = recentLogStatements;
+ }
+
+ public List<LogStatementTO> getRecentLogStatements() {
+ return recentLogStatements;
+ }
+
+ }
+}
http://git-wip-us.apache.org/repos/asf/syncope/blob/f4c717e7/client/console/src/main/java/org/apache/syncope/client/console/panels/AbstractLogsPanel.java
----------------------------------------------------------------------
diff --git a/client/console/src/main/java/org/apache/syncope/client/console/panels/AbstractLogsPanel.java b/client/console/src/main/java/org/apache/syncope/client/console/panels/AbstractLogsPanel.java
index dac4ab5..fef5be5 100644
--- a/client/console/src/main/java/org/apache/syncope/client/console/panels/AbstractLogsPanel.java
+++ b/client/console/src/main/java/org/apache/syncope/client/console/panels/AbstractLogsPanel.java
@@ -48,6 +48,8 @@ public abstract class AbstractLogsPanel<T extends AbstractBaseBean> extends Pane
private static final long serialVersionUID = -6313532280206208227L;
+ protected WebMarkupContainer loggerContainer;
+
public AbstractLogsPanel(
final String id,
final PageReference pageRef,
@@ -55,9 +57,9 @@ public abstract class AbstractLogsPanel<T extends AbstractBaseBean> extends Pane
super(id);
- WebMarkupContainer container = new WebMarkupContainer("loggerContainer");
- container.setOutputMarkupId(true);
- add(container);
+ loggerContainer = new WebMarkupContainer("loggerContainer");
+ loggerContainer.setOutputMarkupId(true);
+ add(loggerContainer);
ListViewPanel.Builder<LoggerTO> builder = new ListViewPanel.Builder<LoggerTO>(LoggerTO.class, pageRef) {
@@ -104,7 +106,7 @@ public abstract class AbstractLogsPanel<T extends AbstractBaseBean> extends Pane
withChecks(ListViewPanel.CheckAvailability.NONE).
setReuseItem(false);
- container.add(builder.build("logger"));
+ loggerContainer.add(builder.build("logger"));
}
protected abstract void update(final LoggerTO loggerTO);
http://git-wip-us.apache.org/repos/asf/syncope/blob/f4c717e7/client/console/src/main/java/org/apache/syncope/client/console/panels/CoreLogPanel.java
----------------------------------------------------------------------
diff --git a/client/console/src/main/java/org/apache/syncope/client/console/panels/CoreLogPanel.java b/client/console/src/main/java/org/apache/syncope/client/console/panels/CoreLogPanel.java
index aeb672e..1fc45a8 100644
--- a/client/console/src/main/java/org/apache/syncope/client/console/panels/CoreLogPanel.java
+++ b/client/console/src/main/java/org/apache/syncope/client/console/panels/CoreLogPanel.java
@@ -19,10 +19,13 @@
package org.apache.syncope.client.console.panels;
import org.apache.syncope.client.console.SyncopeConsoleSession;
+import org.apache.syncope.client.console.pages.LogViewer;
import org.apache.syncope.common.lib.log.LoggerTO;
import org.apache.syncope.common.lib.types.LoggerType;
import org.apache.syncope.common.rest.api.service.LoggerService;
import org.apache.wicket.PageReference;
+import org.apache.wicket.markup.html.link.BookmarkablePageLink;
+import org.apache.wicket.markup.html.link.PopupSettings;
public class CoreLogPanel extends AbstractLogsPanel<LoggerTO> {
@@ -31,6 +34,9 @@ public class CoreLogPanel extends AbstractLogsPanel<LoggerTO> {
public CoreLogPanel(final String id, final PageReference pageReference) {
super(id, pageReference, SyncopeConsoleSession.get().getService(LoggerService.class).list(LoggerType.LOG));
+ BookmarkablePageLink<Void> viewer = new BookmarkablePageLink<>("viewer", LogViewer.class);
+ viewer.setPopupSettings(new PopupSettings().setHeight(600).setWidth(800));
+ loggerContainer.add(viewer);
}
@Override
http://git-wip-us.apache.org/repos/asf/syncope/blob/f4c717e7/client/console/src/main/java/org/apache/syncope/client/console/panels/ExecMessageModal.java
----------------------------------------------------------------------
diff --git a/client/console/src/main/java/org/apache/syncope/client/console/panels/ExecMessageModal.java b/client/console/src/main/java/org/apache/syncope/client/console/panels/ExecMessageModal.java
index 23f411b..91e0b98 100644
--- a/client/console/src/main/java/org/apache/syncope/client/console/panels/ExecMessageModal.java
+++ b/client/console/src/main/java/org/apache/syncope/client/console/panels/ExecMessageModal.java
@@ -19,16 +19,20 @@
package org.apache.syncope.client.console.panels;
import org.apache.syncope.client.console.wicket.markup.html.bootstrap.dialog.BaseModal;
-import org.apache.wicket.PageReference;
import org.apache.wicket.markup.html.basic.Label;
import org.apache.wicket.markup.html.panel.Panel;
public class ExecMessageModal extends Panel implements ModalPanel {
- private static final long serialVersionUID = 1L;
+ private static final long serialVersionUID = -8751533037282034918L;
- public ExecMessageModal(final PageReference pageRef, final String executionMessage) {
- super(BaseModal.CONTENT_ID);
+ public ExecMessageModal(final String executionMessage) {
+ this(BaseModal.CONTENT_ID, executionMessage);
+ }
+
+ public ExecMessageModal(final String id, final String executionMessage) {
+ super(id);
add(new Label("executionMessage", executionMessage).setOutputMarkupId(true));
}
+
}
http://git-wip-us.apache.org/repos/asf/syncope/blob/f4c717e7/client/console/src/main/java/org/apache/syncope/client/console/panels/LogStatementPanel.java
----------------------------------------------------------------------
diff --git a/client/console/src/main/java/org/apache/syncope/client/console/panels/LogStatementPanel.java b/client/console/src/main/java/org/apache/syncope/client/console/panels/LogStatementPanel.java
new file mode 100644
index 0000000..abae16b
--- /dev/null
+++ b/client/console/src/main/java/org/apache/syncope/client/console/panels/LogStatementPanel.java
@@ -0,0 +1,93 @@
+/*
+ * 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 org.apache.syncope.client.console.panels;
+
+import com.googlecode.wicket.jquery.core.Options;
+import com.googlecode.wicket.jquery.ui.JQueryUIBehavior;
+import de.agilecoders.wicket.core.markup.html.bootstrap.dialog.Alert;
+import de.agilecoders.wicket.core.util.Attributes;
+import org.apache.commons.lang3.StringUtils;
+import org.apache.commons.lang3.time.FastDateFormat;
+import org.apache.syncope.common.lib.log.LogStatementTO;
+import org.apache.wicket.markup.ComponentTag;
+import org.apache.wicket.markup.html.WebMarkupContainer;
+import org.apache.wicket.markup.html.basic.Label;
+import org.apache.wicket.markup.html.panel.Panel;
+import org.apache.wicket.model.Model;
+
+public class LogStatementPanel extends Panel {
+
+ private static final long serialVersionUID = 1610867968070669922L;
+
+ private static final FastDateFormat FORMAT = FastDateFormat.getInstance("yyyy-MM-dd'T'HH:mm:ss.SSS");
+
+ private final String labelCssClass;
+
+ public LogStatementPanel(final String id, final LogStatementTO statement) {
+ super(id);
+
+ Alert.Type type;
+ switch (statement.getLevel()) {
+ case DEBUG:
+ type = Alert.Type.Success;
+ break;
+
+ case INFO:
+ type = Alert.Type.Info;
+ break;
+
+ case ERROR:
+ type = Alert.Type.Danger;
+ break;
+
+ case WARN:
+ type = Alert.Type.Warning;
+ break;
+
+ default:
+ type = Alert.Type.Info;
+ }
+ labelCssClass = "label-" + type.name().toLowerCase();
+
+ add(new Label("logger", Model.of(statement.getLoggerName())));
+ add(new Label("instant", Model.of(FORMAT.format(statement.getTimeMillis()))));
+ add(new Label("message", Model.of(statement.getMessage())));
+
+ WebMarkupContainer collapse = new WebMarkupContainer("collapse");
+ collapse.setOutputMarkupId(true);
+ collapse.setOutputMarkupPlaceholderTag(true);
+ collapse.setVisible(StringUtils.isNotBlank(statement.getStackTrace()));
+ collapse.add(new JQueryUIBehavior(
+ "#" + collapse.getMarkupId(), "accordion", new Options("active", false).set("collapsible", true)));
+ add(collapse);
+
+ Label stacktrace = new Label("stacktrace", Model.of(statement.getStackTrace()));
+ stacktrace.setOutputMarkupId(true);
+ collapse.add(stacktrace);
+ }
+
+ @Override
+ protected void onComponentTag(final ComponentTag tag) {
+ super.onComponentTag(tag);
+
+ checkComponentTag(tag, "div");
+ Attributes.addClass(tag, labelCssClass);
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/syncope/blob/f4c717e7/client/console/src/main/java/org/apache/syncope/client/console/rest/LoggerRestClient.java
----------------------------------------------------------------------
diff --git a/client/console/src/main/java/org/apache/syncope/client/console/rest/LoggerRestClient.java b/client/console/src/main/java/org/apache/syncope/client/console/rest/LoggerRestClient.java
index 4922940..bc31608 100644
--- a/client/console/src/main/java/org/apache/syncope/client/console/rest/LoggerRestClient.java
+++ b/client/console/src/main/java/org/apache/syncope/client/console/rest/LoggerRestClient.java
@@ -18,13 +18,21 @@
*/
package org.apache.syncope.client.console.rest;
+import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
+import org.apache.commons.collections4.CollectionUtils;
+import org.apache.commons.collections4.IterableUtils;
+import org.apache.commons.collections4.Predicate;
+import org.apache.commons.collections4.Transformer;
+import org.apache.commons.collections4.TransformerUtils;
import org.apache.syncope.common.lib.log.EventCategoryTO;
+import org.apache.syncope.common.lib.log.LogAppender;
+import org.apache.syncope.common.lib.log.LogStatementTO;
import org.apache.syncope.common.lib.log.LoggerTO;
import org.apache.syncope.common.lib.types.AuditLoggerName;
import org.apache.syncope.common.lib.types.LoggerLevel;
@@ -36,6 +44,28 @@ public class LoggerRestClient extends BaseRestClient {
private static final long serialVersionUID = 4579786978763032240L;
+ public List<String> listMemoryAppenders() {
+ return CollectionUtils.collect(getService(LoggerService.class).memoryAppenders(),
+ new Transformer<LogAppender, String>() {
+
+ @Override
+ public String transform(final LogAppender input) {
+ return input.getName();
+ }
+ }, new ArrayList<String>());
+ }
+
+ public List<LogStatementTO> getLastLogStatements(final String appender, final long lastStatementTime) {
+ return CollectionUtils.collect(IterableUtils.filteredIterable(
+ getService(LoggerService.class).getLastLogStatements(appender), new Predicate<LogStatementTO>() {
+
+ @Override
+ public boolean evaluate(final LogStatementTO object) {
+ return object.getTimeMillis() > lastStatementTime;
+ }
+ }), TransformerUtils.<LogStatementTO>nopTransformer(), new ArrayList<LogStatementTO>());
+ }
+
public List<LoggerTO> listLogs() {
return getService(LoggerService.class).list(LoggerType.LOG);
}
http://git-wip-us.apache.org/repos/asf/syncope/blob/f4c717e7/client/console/src/main/java/org/apache/syncope/client/console/widgets/JobActionPanel.java
----------------------------------------------------------------------
diff --git a/client/console/src/main/java/org/apache/syncope/client/console/widgets/JobActionPanel.java b/client/console/src/main/java/org/apache/syncope/client/console/widgets/JobActionPanel.java
index ab245c7..30797ae 100644
--- a/client/console/src/main/java/org/apache/syncope/client/console/widgets/JobActionPanel.java
+++ b/client/console/src/main/java/org/apache/syncope/client/console/widgets/JobActionPanel.java
@@ -57,8 +57,13 @@ public class JobActionPanel extends WizardMgtPanel<Serializable> {
private final BaseModal<Serializable> jobModal;
- public JobActionPanel(final String id, final JobTO jobTO, final JobWidget widget,
- final BaseModal<Serializable> jobModal, final PageReference pageRef) {
+ public JobActionPanel(
+ final String id,
+ final JobTO jobTO,
+ final JobWidget widget,
+ final BaseModal<Serializable> jobModal,
+ final PageReference pageRef) {
+
super(id, true);
this.jobModal = jobModal;
setOutputMarkupId(true);
http://git-wip-us.apache.org/repos/asf/syncope/blob/f4c717e7/client/console/src/main/java/org/apache/syncope/client/console/widgets/JobWidget.java
----------------------------------------------------------------------
diff --git a/client/console/src/main/java/org/apache/syncope/client/console/widgets/JobWidget.java b/client/console/src/main/java/org/apache/syncope/client/console/widgets/JobWidget.java
index e02f729..bc9db0d 100644
--- a/client/console/src/main/java/org/apache/syncope/client/console/widgets/JobWidget.java
+++ b/client/console/src/main/java/org/apache/syncope/client/console/widgets/JobWidget.java
@@ -280,6 +280,10 @@ public class JobWidget extends BaseWidget {
columns.add(new PropertyColumn<JobTO, String>(new ResourceModel("refDesc"), "refDesc", "refDesc"));
+ columns.add(new BooleanPropertyColumn<JobTO>(new ResourceModel("scheduled"), "scheduled", "scheduled"));
+
+ columns.add(new DatePropertyColumn<JobTO>(new ResourceModel("start"), "start", "start"));
+
columns.add(new AbstractColumn<JobTO, String>(new Model<>(""), "running") {
private static final long serialVersionUID = -4008579357070833846L;
@@ -309,10 +313,6 @@ public class JobWidget extends BaseWidget {
});
- columns.add(new BooleanPropertyColumn<JobTO>(new ResourceModel("scheduled"), "scheduled", "scheduled"));
-
- columns.add(new DatePropertyColumn<JobTO>(new ResourceModel("start"), "start", "start"));
-
return columns;
}
@@ -412,8 +412,7 @@ public class JobWidget extends BaseWidget {
StringResourceModel stringResourceModel =
new StringResourceModel("execution.view", JobWidget.this, model);
detailModal.header(stringResourceModel);
- detailModal.
- setContent(new ExecMessageModal(pageRef, model.getObject().getMessage()));
+ detailModal.setContent(new ExecMessageModal(model.getObject().getMessage()));
detailModal.show(true);
target.add(detailModal);
}
http://git-wip-us.apache.org/repos/asf/syncope/blob/f4c717e7/client/console/src/main/resources/org/apache/syncope/client/console/pages/LogViewer.html
----------------------------------------------------------------------
diff --git a/client/console/src/main/resources/org/apache/syncope/client/console/pages/LogViewer.html b/client/console/src/main/resources/org/apache/syncope/client/console/pages/LogViewer.html
new file mode 100644
index 0000000..c68b2e4
--- /dev/null
+++ b/client/console/src/main/resources/org/apache/syncope/client/console/pages/LogViewer.html
@@ -0,0 +1,34 @@
+<!DOCTYPE html>
+<!--
+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.
+-->
+<html xmlns="http://www.w3.org/1999/xhtml" xmlns:wicket="http://wicket.apache.org">
+ <head>
+ <title>Apache Syncope - Log Viewer</title>
+ </head>
+ <body>
+ <div wicket:id="viewer" style="padding: 5px;">
+ <div wicket:id="appenders" style="margin-bottom: 10px;"></div>
+ <div wicket:id="stContainer" style="overflow-y: auto; overflow-x: auto; max-width: 100vw; max-height: 85vh;">
+ <div wicket:id="statements">
+ <div wicket:id="statement"/>
+ </div>
+ </div>
+ </div>
+ </body>
+</html>
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/syncope/blob/f4c717e7/client/console/src/main/resources/org/apache/syncope/client/console/panels/CoreLogPanel.html
----------------------------------------------------------------------
diff --git a/client/console/src/main/resources/org/apache/syncope/client/console/panels/CoreLogPanel.html b/client/console/src/main/resources/org/apache/syncope/client/console/panels/CoreLogPanel.html
index a4cd024..ccf729f 100644
--- a/client/console/src/main/resources/org/apache/syncope/client/console/panels/CoreLogPanel.html
+++ b/client/console/src/main/resources/org/apache/syncope/client/console/panels/CoreLogPanel.html
@@ -20,6 +20,11 @@ under the License.
<wicket:panel>
<span wicket:id="loggerContainer">
<div class="logs">
+ <div class="pull-right">
+ <button class="btn btn-primary" wicket:id="viewer">
+ <span class="glyphicon glyphicon-list-alt"></span> Log Viewer
+ </button>
+ </div>
<span wicket:id="logger">[logger]</span>
</div>
</span>
http://git-wip-us.apache.org/repos/asf/syncope/blob/f4c717e7/client/console/src/main/resources/org/apache/syncope/client/console/panels/LabelPanel.html
----------------------------------------------------------------------
diff --git a/client/console/src/main/resources/org/apache/syncope/client/console/panels/LabelPanel.html b/client/console/src/main/resources/org/apache/syncope/client/console/panels/LabelPanel.html
index 745e35a..c2ec0a9 100644
--- a/client/console/src/main/resources/org/apache/syncope/client/console/panels/LabelPanel.html
+++ b/client/console/src/main/resources/org/apache/syncope/client/console/panels/LabelPanel.html
@@ -17,12 +17,7 @@ specific language governing permissions and limitations
under the License.
-->
<html xmlns="http://www.w3.org/1999/xhtml" xmlns:wicket="http://wicket.apache.org">
- <head>
- <title>Label panel</title>
- </head>
- <body>
- <wicket:panel>
- <label wicket:id="label" />
- </wicket:panel>
- </body>
+ <wicket:panel>
+ <label wicket:id="label"/>
+ </wicket:panel>
</html>
http://git-wip-us.apache.org/repos/asf/syncope/blob/f4c717e7/client/console/src/main/resources/org/apache/syncope/client/console/panels/LogStatementPanel.html
----------------------------------------------------------------------
diff --git a/client/console/src/main/resources/org/apache/syncope/client/console/panels/LogStatementPanel.html b/client/console/src/main/resources/org/apache/syncope/client/console/panels/LogStatementPanel.html
new file mode 100644
index 0000000..95d49b0
--- /dev/null
+++ b/client/console/src/main/resources/org/apache/syncope/client/console/panels/LogStatementPanel.html
@@ -0,0 +1,33 @@
+<!--
+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.
+-->
+<html xmlns="http://www.w3.org/1999/xhtml" xmlns:wicket="http://wicket.apache.org">
+ <wicket:panel>
+ <div style="padding: 5px; font-family: monospace;">
+ [<span wicket:id="instant"></span>]
+ <span wicket:id="logger"></span><br/>
+ <span wicket:id="message"></span>
+ <div wicket:id="collapse">
+ <span>+ <u>Error Details</u></span>
+ <div>
+ <pre wicket:id="stacktrace" style="white-space: pre-wrap;max-width: 95vw;"></pre>
+ </div>
+ </div>
+ </div>
+ </wicket:panel>
+</html>
http://git-wip-us.apache.org/repos/asf/syncope/blob/f4c717e7/common/lib/src/main/java/org/apache/syncope/common/lib/log/LogStatementTO.java
----------------------------------------------------------------------
diff --git a/common/lib/src/main/java/org/apache/syncope/common/lib/log/LogStatementTO.java b/common/lib/src/main/java/org/apache/syncope/common/lib/log/LogStatementTO.java
index 11e22c9..7d28e15 100644
--- a/common/lib/src/main/java/org/apache/syncope/common/lib/log/LogStatementTO.java
+++ b/common/lib/src/main/java/org/apache/syncope/common/lib/log/LogStatementTO.java
@@ -18,10 +18,14 @@
*/
package org.apache.syncope.common.lib.log;
-import java.io.Serializable;
+import javax.xml.bind.annotation.XmlRootElement;
+import javax.xml.bind.annotation.XmlType;
+import org.apache.syncope.common.lib.AbstractBaseBean;
import org.apache.syncope.common.lib.types.LoggerLevel;
-public class LogStatementTO implements Serializable {
+@XmlRootElement(name = "logStatement")
+@XmlType
+public class LogStatementTO extends AbstractBaseBean {
private static final long serialVersionUID = -2931205859104653385L;
http://git-wip-us.apache.org/repos/asf/syncope/blob/f4c717e7/fit/core-reference/src/main/resources/log4j2.xml
----------------------------------------------------------------------
diff --git a/fit/core-reference/src/main/resources/log4j2.xml b/fit/core-reference/src/main/resources/log4j2.xml
index 7416d92..d8a0c6c 100644
--- a/fit/core-reference/src/main/resources/log4j2.xml
+++ b/fit/core-reference/src/main/resources/log4j2.xml
@@ -21,7 +21,7 @@ under the License.
<appenders>
- <RollingRandomAccessFile name="main" fileName="${log.directory}/core.log"
+ <RollingRandomAccessFile name="mainFile" fileName="${log.directory}/core.log"
filePattern="${log.directory}/core-%d{yyyy-MM-dd}.log.gz"
immediateFlush="false" append="true">
<PatternLayout>
@@ -32,9 +32,9 @@ under the License.
<SizeBasedTriggeringPolicy size="250 MB"/>
</Policies>
</RollingRandomAccessFile>
- <Memory name="mainMemory" size="25"/>
+ <Memory name="main" size="25"/>
- <RollingRandomAccessFile name="persistence" fileName="${log.directory}/core-persistence.log"
+ <RollingRandomAccessFile name="persistenceFile" fileName="${log.directory}/core-persistence.log"
filePattern="${log.directory}/core-persistence-%d{yyyy-MM-dd}.log.gz"
immediateFlush="false" append="true">
<PatternLayout>
@@ -45,9 +45,9 @@ under the License.
<SizeBasedTriggeringPolicy size="250 MB"/>
</Policies>
</RollingRandomAccessFile>
- <Memory name="persistenceMemory" size="25"/>
+ <Memory name="persistence" size="25"/>
- <RollingRandomAccessFile name="rest" fileName="${log.directory}/core-rest.log"
+ <RollingRandomAccessFile name="restFile" fileName="${log.directory}/core-rest.log"
filePattern="${log.directory}/core-rest-%d{yyyy-MM-dd}.log.gz"
immediateFlush="false" append="true">
<PatternLayout>
@@ -58,9 +58,9 @@ under the License.
<SizeBasedTriggeringPolicy size="250 MB"/>
</Policies>
</RollingRandomAccessFile>
- <Memory name="restMemory" size="25"/>
+ <Memory name="rest" size="25"/>
- <RollingRandomAccessFile name="connid" fileName="${log.directory}/core-connid.log"
+ <RollingRandomAccessFile name="connidFile" fileName="${log.directory}/core-connid.log"
filePattern="${log.directory}/core-connid-%d{yyyy-MM-dd}.log.gz"
immediateFlush="false" append="true">
<PatternLayout>
@@ -71,87 +71,87 @@ under the License.
<SizeBasedTriggeringPolicy size="250 MB"/>
</Policies>
</RollingRandomAccessFile>
- <Memory name="connidMemory" size="25"/>
+ <Memory name="connid" size="25"/>
</appenders>
<loggers>
<asyncLogger name="org.apache.syncope.core.persistence" additivity="false" level="INFO">
+ <appender-ref ref="persistenceFile"/>
<appender-ref ref="persistence"/>
- <appender-ref ref="persistenceMemory"/>
</asyncLogger>
<asyncLogger name="org.springframework.orm" additivity="false" level="INFO">
+ <appender-ref ref="persistenceFile"/>
<appender-ref ref="persistence"/>
- <appender-ref ref="persistenceMemory"/>
</asyncLogger>
<asyncLogger name="org.apache.syncope.core.rest" additivity="false" level="INFO">
+ <appender-ref ref="restFile"/>
<appender-ref ref="rest"/>
- <appender-ref ref="restMemory"/>
</asyncLogger>
<asyncLogger name="org.springframework.web" additivity="false" level="INFO">
+ <appender-ref ref="restFile"/>
<appender-ref ref="rest"/>
- <appender-ref ref="restMemory"/>
</asyncLogger>
<asyncLogger name="org.apache.http" additivity="false" level="INFO">
+ <appender-ref ref="restFile"/>
<appender-ref ref="rest"/>
- <appender-ref ref="restMemory"/>
</asyncLogger>
<asyncLogger name="org.apache.cxf" additivity="false" level="ERROR">
+ <appender-ref ref="restFile"/>
<appender-ref ref="rest"/>
- <appender-ref ref="restMemory"/>
</asyncLogger>
<asyncLogger name="org.identityconnectors" additivity="false" level="DEBUG">
+ <appender-ref ref="connidFile"/>
<appender-ref ref="connid"/>
- <appender-ref ref="connidMemory"/>
</asyncLogger>
<asyncLogger name="net.tirasa.connid" additivity="false" level="DEBUG">
+ <appender-ref ref="connidFile"/>
<appender-ref ref="connid"/>
- <appender-ref ref="connidMemory"/>
</asyncLogger>
<asyncLogger name="org.apache.syncope.core.provisioning.api.ConnIdBundleManager" additivity="false" level="INFO">
+ <appender-ref ref="connidFile"/>
<appender-ref ref="connid"/>
- <appender-ref ref="connidMemory"/>
</asyncLogger>
<asyncLogger name="org.apache.syncope" additivity="false" level="INFO">
+ <appender-ref ref="mainFile"/>
<appender-ref ref="main"/>
- <appender-ref ref="mainMemory"/>
</asyncLogger>
<asyncLogger name="org.apache.syncope.core.provisioning" additivity="false" level="INFO">
+ <appender-ref ref="mainFile"/>
<appender-ref ref="main"/>
- <appender-ref ref="mainMemory"/>
</asyncLogger>
<asyncLogger name="org.apache.syncope.core.logic" additivity="false" level="INFO">
+ <appender-ref ref="mainFile"/>
<appender-ref ref="main"/>
- <appender-ref ref="mainMemory"/>
</asyncLogger>
<asyncLogger name="org.springframework" additivity="false" level="INFO">
+ <appender-ref ref="mainFile"/>
<appender-ref ref="main"/>
- <appender-ref ref="mainMemory"/>
</asyncLogger>
<asyncLogger name="org.quartz" additivity="false" level="INFO">
+ <appender-ref ref="mainFile"/>
<appender-ref ref="main"/>
- <appender-ref ref="mainMemory"/>
</asyncLogger>
<asyncLogger name="org.activiti" additivity="false" level="ERROR">
+ <appender-ref ref="mainFile"/>
<appender-ref ref="main"/>
- <appender-ref ref="mainMemory"/>
</asyncLogger>
<asyncLogger name="org.apache.camel" additivity="false" level="ERROR">
+ <appender-ref ref="mainFile"/>
<appender-ref ref="main"/>
- <appender-ref ref="mainMemory"/>
</asyncLogger>
<asyncLogger name="io.swagger" additivity="false" level="ERROR">
+ <appender-ref ref="mainFile"/>
<appender-ref ref="main"/>
- <appender-ref ref="mainMemory"/>
</asyncLogger>
<root level="INFO">
+ <appender-ref ref="mainFile"/>
<appender-ref ref="main"/>
- <appender-ref ref="mainMemory"/>
</root>
</loggers>
http://git-wip-us.apache.org/repos/asf/syncope/blob/f4c717e7/fit/core-reference/src/test/java/org/apache/syncope/fit/cli/CLIITCase.java
----------------------------------------------------------------------
diff --git a/fit/core-reference/src/test/java/org/apache/syncope/fit/cli/CLIITCase.java b/fit/core-reference/src/test/java/org/apache/syncope/fit/cli/CLIITCase.java
index 366770d..d139820 100644
--- a/fit/core-reference/src/test/java/org/apache/syncope/fit/cli/CLIITCase.java
+++ b/fit/core-reference/src/test/java/org/apache/syncope/fit/cli/CLIITCase.java
@@ -316,7 +316,7 @@ public class CLIITCase extends AbstractITCase {
PROCESS_BUILDER.command(getCommand(
new LoggerCommand().getClass().getAnnotation(Command.class).name(),
LoggerCommand.LoggerOptions.LAST_STATEMENTS.getOptionName(),
- "connidMemory"));
+ "connid"));
process = PROCESS_BUILDER.start();
final String result = IOUtils.toString(process.getInputStream(), SyncopeConstants.DEFAULT_CHARSET);
assertTrue(result.contains("\"level\" : \"DEBUG\","));
http://git-wip-us.apache.org/repos/asf/syncope/blob/f4c717e7/fit/core-reference/src/test/java/org/apache/syncope/fit/core/LoggerITCase.java
----------------------------------------------------------------------
diff --git a/fit/core-reference/src/test/java/org/apache/syncope/fit/core/LoggerITCase.java b/fit/core-reference/src/test/java/org/apache/syncope/fit/core/LoggerITCase.java
index 07416c6..d534764 100644
--- a/fit/core-reference/src/test/java/org/apache/syncope/fit/core/LoggerITCase.java
+++ b/fit/core-reference/src/test/java/org/apache/syncope/fit/core/LoggerITCase.java
@@ -66,7 +66,7 @@ public class LoggerITCase extends AbstractITCase {
@Test
public void lastStatements() {
- Queue<LogStatementTO> statements = loggerService.getLastLogStatements("connidMemory");
+ Queue<LogStatementTO> statements = loggerService.getLastLogStatements("connid");
assertNotNull(statements);
assertFalse(statements.isEmpty());
http://git-wip-us.apache.org/repos/asf/syncope/blob/f4c717e7/ide/eclipse/bundles/org.apache.syncope.ide.eclipse.plugin/pom.xml
----------------------------------------------------------------------
diff --git a/ide/eclipse/bundles/org.apache.syncope.ide.eclipse.plugin/pom.xml b/ide/eclipse/bundles/org.apache.syncope.ide.eclipse.plugin/pom.xml
index 3999eb5..8a35ff0 100644
--- a/ide/eclipse/bundles/org.apache.syncope.ide.eclipse.plugin/pom.xml
+++ b/ide/eclipse/bundles/org.apache.syncope.ide.eclipse.plugin/pom.xml
@@ -53,9 +53,31 @@ under the License.
<build>
<outputDirectory>./bin</outputDirectory>
+
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-clean-plugin</artifactId>
+ <configuration>
+ <filesets>
+ <fileset>
+ <directory>bin</directory>
+ <includes>
+ <include>**/*</include>
+ </includes>
+ </fileset>
+ <fileset>
+ <directory>lib</directory>
+ <includes>
+ <include>**/*</include>
+ </includes>
+ </fileset>
+ </filesets>
+ </configuration>
+ </plugin>
+
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-dependency-plugin</artifactId>
<executions>
<execution>
http://git-wip-us.apache.org/repos/asf/syncope/blob/f4c717e7/pom.xml
----------------------------------------------------------------------
diff --git a/pom.xml b/pom.xml
index 28b1da2..eb38151 100644
--- a/pom.xml
+++ b/pom.xml
@@ -1406,6 +1406,12 @@ under the License.
<plugin>
<groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-clean-plugin</artifactId>
+ <version>3.0.0</version>
+ </plugin>
+
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-resources-plugin</artifactId>
<version>3.0.2</version>
<configuration>
http://git-wip-us.apache.org/repos/asf/syncope/blob/f4c717e7/src/main/asciidoc/reference-guide/workingwithapachesyncope/cli/logger.adoc
----------------------------------------------------------------------
diff --git a/src/main/asciidoc/reference-guide/workingwithapachesyncope/cli/logger.adoc b/src/main/asciidoc/reference-guide/workingwithapachesyncope/cli/logger.adoc
index 6ebc5a3..236cde9 100644
--- a/src/main/asciidoc/reference-guide/workingwithapachesyncope/cli/logger.adoc
+++ b/src/main/asciidoc/reference-guide/workingwithapachesyncope/cli/logger.adoc
@@ -26,7 +26,10 @@ This command is meant for tweaking runtime logger configuration.
Usage: logger [options]
Options:
--help
- --details
+ --details
+ --list-memory-appenders
+ --last-statements
+ Syntax: --last-statements {APPENDER-NAME}
--list
--read
Syntax: --read {LOG-NAME} {LOG-NAME} [...]
@@ -47,6 +50,11 @@ Usage: logger [options]
This option shows a table with some details about logger configuration.
--list::
Running the command with this option you will see the table of the loggers configuration.
+--list-memory-appenders
+Running the command with this option you will see the table of the memory appenders, whose last statements can be
+inspected
+--last-statements
+The option to get the last statements available for the passed memory appender
--read::
The option to read all the information of specified loggers.
--update::