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/03 15:00:09 UTC
[3/4] syncope git commit: [SYNCOPE-882] Initial commit: support in
common,
core and cli with new log4j MemoryAppend which retains in memory the last N
statements
http://git-wip-us.apache.org/repos/asf/syncope/blob/c25e1da0/common/lib/src/main/java/org/apache/syncope/common/lib/log/package-info.java
----------------------------------------------------------------------
diff --git a/common/lib/src/main/java/org/apache/syncope/common/lib/log/package-info.java b/common/lib/src/main/java/org/apache/syncope/common/lib/log/package-info.java
new file mode 100644
index 0000000..1aa449d
--- /dev/null
+++ b/common/lib/src/main/java/org/apache/syncope/common/lib/log/package-info.java
@@ -0,0 +1,27 @@
+/*
+ * 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.
+ */
+@XmlSchema(
+ namespace = SyncopeConstants.NS,
+ xmlns = { @XmlNs(prefix = SyncopeConstants.NS_PREFIX,
+ namespaceURI = SyncopeConstants.NS) })
+package org.apache.syncope.common.lib.log;
+
+import javax.xml.bind.annotation.XmlNs;
+import javax.xml.bind.annotation.XmlSchema;
+import org.apache.syncope.common.lib.SyncopeConstants;
http://git-wip-us.apache.org/repos/asf/syncope/blob/c25e1da0/common/lib/src/main/java/org/apache/syncope/common/lib/to/EventCategoryTO.java
----------------------------------------------------------------------
diff --git a/common/lib/src/main/java/org/apache/syncope/common/lib/to/EventCategoryTO.java b/common/lib/src/main/java/org/apache/syncope/common/lib/to/EventCategoryTO.java
deleted file mode 100644
index 544e204..0000000
--- a/common/lib/src/main/java/org/apache/syncope/common/lib/to/EventCategoryTO.java
+++ /dev/null
@@ -1,92 +0,0 @@
-/*
- * 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.common.lib.to;
-
-import com.fasterxml.jackson.annotation.JsonProperty;
-import java.util.ArrayList;
-import java.util.List;
-import javax.xml.bind.annotation.XmlElement;
-import javax.xml.bind.annotation.XmlElementWrapper;
-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.AuditElements;
-
-@XmlRootElement(name = "eventCategory")
-@XmlType
-public class EventCategoryTO extends AbstractBaseBean {
-
- private static final long serialVersionUID = -4340060002701633401L;
-
- private AuditElements.EventCategoryType type;
-
- private String category;
-
- private String subcategory;
-
- private final List<String> events = new ArrayList<>();
-
- /**
- * Constructor for Type.REST event category.
- */
- public EventCategoryTO() {
- this(AuditElements.EventCategoryType.LOGIC);
- }
-
- /**
- * Constructor for the given Type event category.
- *
- * @param type event category type
- */
- public EventCategoryTO(final AuditElements.EventCategoryType type) {
- super();
- this.type = type;
- }
-
- public AuditElements.EventCategoryType getType() {
- return type;
- }
-
- public void setType(final AuditElements.EventCategoryType type) {
- this.type = type == null ? AuditElements.EventCategoryType.CUSTOM : type;
- }
-
- public String getCategory() {
- return category;
- }
-
- public void setCategory(final String category) {
- this.category = category;
- }
-
- public String getSubcategory() {
- return subcategory;
- }
-
- public void setSubcategory(final String subcategory) {
- this.subcategory = subcategory;
- }
-
- @XmlElementWrapper(name = "events")
- @XmlElement(name = "event")
- @JsonProperty("events")
- public List<String> getEvents() {
- return events;
- }
-}
http://git-wip-us.apache.org/repos/asf/syncope/blob/c25e1da0/common/lib/src/main/java/org/apache/syncope/common/lib/to/LoggerTO.java
----------------------------------------------------------------------
diff --git a/common/lib/src/main/java/org/apache/syncope/common/lib/to/LoggerTO.java b/common/lib/src/main/java/org/apache/syncope/common/lib/to/LoggerTO.java
deleted file mode 100644
index 0dfa8b5..0000000
--- a/common/lib/src/main/java/org/apache/syncope/common/lib/to/LoggerTO.java
+++ /dev/null
@@ -1,53 +0,0 @@
-/*
- * 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.common.lib.to;
-
-import javax.ws.rs.PathParam;
-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;
-
-@XmlRootElement(name = "logger")
-@XmlType
-public class LoggerTO extends AbstractBaseBean {
-
- private static final long serialVersionUID = -7794833835668648505L;
-
- private String key;
-
- private LoggerLevel level;
-
- public LoggerLevel getLevel() {
- return level;
- }
-
- public void setLevel(final LoggerLevel level) {
- this.level = level;
- }
-
- public String getKey() {
- return key;
- }
-
- @PathParam("key")
- public void setKey(final String key) {
- this.key = key;
- }
-}
http://git-wip-us.apache.org/repos/asf/syncope/blob/c25e1da0/common/lib/src/main/java/org/apache/syncope/common/lib/types/AuditLoggerName.java
----------------------------------------------------------------------
diff --git a/common/lib/src/main/java/org/apache/syncope/common/lib/types/AuditLoggerName.java b/common/lib/src/main/java/org/apache/syncope/common/lib/types/AuditLoggerName.java
index 25eaf9e..6988062 100644
--- a/common/lib/src/main/java/org/apache/syncope/common/lib/types/AuditLoggerName.java
+++ b/common/lib/src/main/java/org/apache/syncope/common/lib/types/AuditLoggerName.java
@@ -26,7 +26,7 @@ import org.apache.commons.lang3.StringUtils;
import org.apache.commons.lang3.tuple.ImmutablePair;
import org.apache.commons.lang3.tuple.Pair;
import org.apache.syncope.common.lib.AbstractBaseBean;
-import org.apache.syncope.common.lib.to.EventCategoryTO;
+import org.apache.syncope.common.lib.log.EventCategoryTO;
import org.apache.syncope.common.lib.types.AuditElements.EventCategoryType;
import org.apache.syncope.common.lib.types.AuditElements.Result;
http://git-wip-us.apache.org/repos/asf/syncope/blob/c25e1da0/common/rest-api/src/main/java/org/apache/syncope/common/rest/api/LoggerWrapper.java
----------------------------------------------------------------------
diff --git a/common/rest-api/src/main/java/org/apache/syncope/common/rest/api/LoggerWrapper.java b/common/rest-api/src/main/java/org/apache/syncope/common/rest/api/LoggerWrapper.java
index a8c6f04..99f3f9c 100644
--- a/common/rest-api/src/main/java/org/apache/syncope/common/rest/api/LoggerWrapper.java
+++ b/common/rest-api/src/main/java/org/apache/syncope/common/rest/api/LoggerWrapper.java
@@ -21,7 +21,7 @@ package org.apache.syncope.common.rest.api;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
-import org.apache.syncope.common.lib.to.LoggerTO;
+import org.apache.syncope.common.lib.log.LoggerTO;
import org.apache.syncope.common.lib.types.AuditLoggerName;
import org.apache.syncope.common.lib.types.LoggerLevel;
http://git-wip-us.apache.org/repos/asf/syncope/blob/c25e1da0/common/rest-api/src/main/java/org/apache/syncope/common/rest/api/service/LoggerService.java
----------------------------------------------------------------------
diff --git a/common/rest-api/src/main/java/org/apache/syncope/common/rest/api/service/LoggerService.java b/common/rest-api/src/main/java/org/apache/syncope/common/rest/api/service/LoggerService.java
index fcdab01..7250b7a 100644
--- a/common/rest-api/src/main/java/org/apache/syncope/common/rest/api/service/LoggerService.java
+++ b/common/rest-api/src/main/java/org/apache/syncope/common/rest/api/service/LoggerService.java
@@ -19,6 +19,7 @@
package org.apache.syncope.common.rest.api.service;
import java.util.List;
+import java.util.Queue;
import javax.validation.constraints.NotNull;
import javax.ws.rs.Consumes;
import javax.ws.rs.DELETE;
@@ -28,8 +29,10 @@ import javax.ws.rs.Path;
import javax.ws.rs.PathParam;
import javax.ws.rs.Produces;
import javax.ws.rs.core.MediaType;
-import org.apache.syncope.common.lib.to.EventCategoryTO;
-import org.apache.syncope.common.lib.to.LoggerTO;
+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.LoggerType;
/**
@@ -39,7 +42,28 @@ import org.apache.syncope.common.lib.types.LoggerType;
public interface LoggerService extends JAXRSService {
/**
- * Returns a list of all managed events in audit.
+ * Returns the list of memory appenders available in the current logging configuration.
+ *
+ * @return the list of memory appenders available in the current logging configuration
+ */
+ @GET
+ @Path("memoryAppenders")
+ @Produces({ MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML })
+ List<LogAppender> memoryAppenders();
+
+ /**
+ * Return the last log statements available in the provided memory appender.
+ *
+ * @param memoryAppender memory appender name
+ * @return the last log statements available in the provided memory appender
+ */
+ @GET
+ @Path("memoryAppenders/{memoryAppender}/lastLogStatements")
+ @Produces({ MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML })
+ Queue<LogStatementTO> getLastLogStatements(@NotNull @PathParam("memoryAppender") String memoryAppender);
+
+ /**
+ * Returns the list of all managed events in audit.
*
* @return list of all managed events in audit
*/
http://git-wip-us.apache.org/repos/asf/syncope/blob/c25e1da0/core/logic/src/main/java/org/apache/syncope/core/logic/LoggerLogic.java
----------------------------------------------------------------------
diff --git a/core/logic/src/main/java/org/apache/syncope/core/logic/LoggerLogic.java b/core/logic/src/main/java/org/apache/syncope/core/logic/LoggerLogic.java
index 070395e..0e3c887 100644
--- a/core/logic/src/main/java/org/apache/syncope/core/logic/LoggerLogic.java
+++ b/core/logic/src/main/java/org/apache/syncope/core/logic/LoggerLogic.java
@@ -23,6 +23,7 @@ import java.lang.reflect.Modifier;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
+import java.util.Queue;
import java.util.Set;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.collections4.IteratorUtils;
@@ -34,8 +35,10 @@ import org.apache.logging.log4j.core.LoggerContext;
import org.apache.logging.log4j.core.config.LoggerConfig;
import org.apache.syncope.common.lib.SyncopeClientException;
import org.apache.syncope.common.lib.SyncopeConstants;
-import org.apache.syncope.common.lib.to.EventCategoryTO;
-import org.apache.syncope.common.lib.to.LoggerTO;
+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.AuditElements.EventCategoryType;
import org.apache.syncope.common.lib.types.AuditLoggerName;
import org.apache.syncope.common.lib.types.ClientExceptionType;
@@ -48,6 +51,7 @@ import org.apache.syncope.common.lib.types.UnmatchingRule;
import org.apache.syncope.common.lib.types.AnyTypeKind;
import org.apache.syncope.common.lib.types.AuditElements;
import org.apache.syncope.common.lib.types.StandardEntitlement;
+import org.apache.syncope.core.logic.init.LoggerLoader;
import org.apache.syncope.core.persistence.api.dao.ExternalResourceDAO;
import org.apache.syncope.core.persistence.api.dao.LoggerDAO;
import org.apache.syncope.core.persistence.api.dao.NotFoundException;
@@ -76,6 +80,9 @@ import org.springframework.util.SystemPropertyUtils;
public class LoggerLogic extends AbstractTransactionalLogic<LoggerTO> {
@Autowired
+ private LoggerLoader loggerLoader;
+
+ @Autowired
private LoggerDAO loggerDAO;
@Autowired
@@ -101,6 +108,33 @@ public class LoggerLogic extends AbstractTransactionalLogic<LoggerTO> {
@PreAuthorize("hasRole('" + StandardEntitlement.LOG_LIST + "') and authentication.details.domain == "
+ "T(org.apache.syncope.common.lib.SyncopeConstants).MASTER_DOMAIN")
+ public List<LogAppender> memoryAppenders() {
+ return CollectionUtils.collect(
+ loggerLoader.getMemoryAppenders().keySet(),
+ new Transformer<String, LogAppender>() {
+
+ @Override
+ public LogAppender transform(final String input) {
+ LogAppender logAppender = new LogAppender();
+ logAppender.setName(input);
+ return logAppender;
+ }
+ }, new ArrayList<LogAppender>());
+ }
+
+ @PreAuthorize("hasRole('" + StandardEntitlement.LOG_READ + "') and authentication.details.domain == "
+ + "T(org.apache.syncope.common.lib.SyncopeConstants).MASTER_DOMAIN")
+ public Queue<LogStatementTO> getLastLogStatements(final String memoryAppender) {
+ MemoryAppender appender = loggerLoader.getMemoryAppenders().get(memoryAppender);
+ if (appender == null) {
+ throw new NotFoundException("Appender " + memoryAppender);
+ }
+
+ return appender.getStatements();
+ }
+
+ @PreAuthorize("hasRole('" + StandardEntitlement.LOG_LIST + "') and authentication.details.domain == "
+ + "T(org.apache.syncope.common.lib.SyncopeConstants).MASTER_DOMAIN")
@Transactional(readOnly = true)
public List<LoggerTO> listLogs() {
return list(LoggerType.LOG);
http://git-wip-us.apache.org/repos/asf/syncope/blob/c25e1da0/core/logic/src/main/java/org/apache/syncope/core/logic/MemoryAppender.java
----------------------------------------------------------------------
diff --git a/core/logic/src/main/java/org/apache/syncope/core/logic/MemoryAppender.java b/core/logic/src/main/java/org/apache/syncope/core/logic/MemoryAppender.java
new file mode 100644
index 0000000..8183979
--- /dev/null
+++ b/core/logic/src/main/java/org/apache/syncope/core/logic/MemoryAppender.java
@@ -0,0 +1,95 @@
+/*
+ * 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.core.logic;
+
+import java.util.Queue;
+import org.apache.commons.collections4.queue.CircularFifoQueue;
+import org.apache.logging.log4j.core.Appender;
+import org.apache.logging.log4j.core.Filter;
+import org.apache.logging.log4j.core.LogEvent;
+import org.apache.logging.log4j.core.appender.AbstractAppender;
+import org.apache.logging.log4j.core.config.plugins.Plugin;
+import org.apache.logging.log4j.core.config.plugins.PluginAttribute;
+import org.apache.logging.log4j.core.config.plugins.PluginElement;
+import org.apache.logging.log4j.core.config.plugins.PluginFactory;
+import org.apache.logging.log4j.message.Message;
+import org.apache.logging.log4j.message.ReusableMessage;
+import org.apache.syncope.common.lib.log.LogStatementTO;
+import org.apache.syncope.common.lib.types.LoggerLevel;
+import org.apache.syncope.core.provisioning.api.utils.ExceptionUtils2;
+
+@Plugin(name = "Memory", category = "Core", elementType = Appender.ELEMENT_TYPE, printObject = true)
+public class MemoryAppender extends AbstractAppender {
+
+ private final CircularFifoQueue<LogStatementTO> statements;
+
+ protected MemoryAppender(
+ final String name,
+ final int size,
+ final Filter filter,
+ final boolean ignoreExceptions) {
+
+ super(name, filter, null, ignoreExceptions);
+ this.statements = new CircularFifoQueue<>(size);
+ }
+
+ @Override
+ public void append(final LogEvent event) {
+ LogStatementTO statement = new LogStatementTO();
+
+ statement.setLevel(LoggerLevel.fromLevel(event.getLevel()));
+ statement.setLoggerName(event.getLoggerName());
+
+ Message msg = event.getMessage();
+ statement.setMessage((msg instanceof ReusableMessage
+ ? ((ReusableMessage) msg).memento()
+ : msg).getFormattedMessage());
+
+ statement.setTimeMillis(event.getTimeMillis());
+
+ if (event.getThrown() != null) {
+ statement.setStackTrace(ExceptionUtils2.getFullStackTrace(event.getThrown()));
+ }
+
+ statement.setThreadId(event.getThreadId());
+ statement.setThreadName(event.getThreadName());
+ statement.setThreadPriority(event.getThreadPriority());
+
+ this.statements.add(statement);
+ }
+
+ public Queue<LogStatementTO> getStatements() {
+ return statements;
+ }
+
+ @PluginFactory
+ public static MemoryAppender createAppender(
+ @PluginAttribute("name") final String name,
+ @PluginAttribute(value = "size", defaultInt = 10) final int size,
+ @PluginElement("Filter") final Filter filter,
+ @PluginAttribute(value = "ignoreExceptions", defaultBoolean = true) final boolean ignoreExceptions) {
+
+ return new MemoryAppender(
+ name,
+ size,
+ filter,
+ ignoreExceptions);
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/syncope/blob/c25e1da0/core/logic/src/main/java/org/apache/syncope/core/logic/init/LoggerLoader.java
----------------------------------------------------------------------
diff --git a/core/logic/src/main/java/org/apache/syncope/core/logic/init/LoggerLoader.java b/core/logic/src/main/java/org/apache/syncope/core/logic/init/LoggerLoader.java
index 9f96ccc..3280fe0 100644
--- a/core/logic/src/main/java/org/apache/syncope/core/logic/init/LoggerLoader.java
+++ b/core/logic/src/main/java/org/apache/syncope/core/logic/init/LoggerLoader.java
@@ -20,6 +20,7 @@ package org.apache.syncope.core.logic.init;
import java.sql.Connection;
import java.sql.SQLException;
+import java.util.HashMap;
import java.util.Map;
import javax.sql.DataSource;
import org.apache.logging.log4j.Level;
@@ -30,6 +31,7 @@ import org.apache.logging.log4j.core.appender.db.jdbc.ColumnConfig;
import org.apache.logging.log4j.core.appender.db.jdbc.ConnectionSource;
import org.apache.logging.log4j.core.appender.db.jdbc.JdbcAppender;
import org.apache.logging.log4j.core.config.LoggerConfig;
+import org.apache.syncope.core.logic.MemoryAppender;
import org.apache.syncope.core.provisioning.java.AuditManagerImpl;
import org.apache.syncope.core.spring.security.AuthContextUtils;
import org.apache.syncope.core.persistence.api.DomainsHolder;
@@ -47,6 +49,8 @@ public class LoggerLoader implements SyncopeLoader {
@Autowired
private LoggerAccessor loggerAccessor;
+ private final Map<String, MemoryAppender> memoryAppenders = new HashMap<>();
+
@Override
public Integer getPriority() {
return 300;
@@ -56,6 +60,12 @@ public class LoggerLoader implements SyncopeLoader {
public void load() {
final LoggerContext ctx = (LoggerContext) LogManager.getContext(false);
+ for (Map.Entry<String, Appender> entry : ctx.getConfiguration().getAppenders().entrySet()) {
+ if (entry.getValue() instanceof MemoryAppender) {
+ memoryAppenders.put(entry.getKey(), (MemoryAppender) entry.getValue());
+ }
+ }
+
// Audit table and DataSource for each configured domain
ColumnConfig[] columns = {
ColumnConfig.createColumnConfig(ctx.getConfiguration(), "EVENT_DATE", null, null, "true", null, null),
@@ -97,6 +107,10 @@ public class LoggerLoader implements SyncopeLoader {
ctx.updateLoggers();
}
+ public Map<String, MemoryAppender> getMemoryAppenders() {
+ return memoryAppenders;
+ }
+
private static class DataSourceConnectionSource implements ConnectionSource {
private final DataSource dataSource;
http://git-wip-us.apache.org/repos/asf/syncope/blob/c25e1da0/core/rest-cxf/src/main/java/org/apache/syncope/core/rest/cxf/service/LoggerServiceImpl.java
----------------------------------------------------------------------
diff --git a/core/rest-cxf/src/main/java/org/apache/syncope/core/rest/cxf/service/LoggerServiceImpl.java b/core/rest-cxf/src/main/java/org/apache/syncope/core/rest/cxf/service/LoggerServiceImpl.java
index b8a9fa7..bc406ed 100644
--- a/core/rest-cxf/src/main/java/org/apache/syncope/core/rest/cxf/service/LoggerServiceImpl.java
+++ b/core/rest-cxf/src/main/java/org/apache/syncope/core/rest/cxf/service/LoggerServiceImpl.java
@@ -20,9 +20,12 @@ package org.apache.syncope.core.rest.cxf.service;
import java.text.ParseException;
import java.util.List;
+import java.util.Queue;
import javax.ws.rs.BadRequestException;
-import org.apache.syncope.common.lib.to.EventCategoryTO;
-import org.apache.syncope.common.lib.to.LoggerTO;
+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.LoggerType;
import org.apache.syncope.common.rest.api.LoggerWrapper;
@@ -38,6 +41,16 @@ public class LoggerServiceImpl extends AbstractServiceImpl implements LoggerServ
private LoggerLogic logic;
@Override
+ public List<LogAppender> memoryAppenders() {
+ return logic.memoryAppenders();
+ }
+
+ @Override
+ public Queue<LogStatementTO> getLastLogStatements(final String memoryAppender) {
+ return logic.getLastLogStatements(memoryAppender);
+ }
+
+ @Override
public void delete(final LoggerType type, final String name) {
switch (type) {
case LOG:
http://git-wip-us.apache.org/repos/asf/syncope/blob/c25e1da0/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 02bb591..7416d92 100644
--- a/fit/core-reference/src/main/resources/log4j2.xml
+++ b/fit/core-reference/src/main/resources/log4j2.xml
@@ -32,6 +32,7 @@ under the License.
<SizeBasedTriggeringPolicy size="250 MB"/>
</Policies>
</RollingRandomAccessFile>
+ <Memory name="mainMemory" size="25"/>
<RollingRandomAccessFile name="persistence" fileName="${log.directory}/core-persistence.log"
filePattern="${log.directory}/core-persistence-%d{yyyy-MM-dd}.log.gz"
@@ -44,6 +45,7 @@ under the License.
<SizeBasedTriggeringPolicy size="250 MB"/>
</Policies>
</RollingRandomAccessFile>
+ <Memory name="persistenceMemory" size="25"/>
<RollingRandomAccessFile name="rest" fileName="${log.directory}/core-rest.log"
filePattern="${log.directory}/core-rest-%d{yyyy-MM-dd}.log.gz"
@@ -56,6 +58,7 @@ under the License.
<SizeBasedTriggeringPolicy size="250 MB"/>
</Policies>
</RollingRandomAccessFile>
+ <Memory name="restMemory" size="25"/>
<RollingRandomAccessFile name="connid" fileName="${log.directory}/core-connid.log"
filePattern="${log.directory}/core-connid-%d{yyyy-MM-dd}.log.gz"
@@ -68,6 +71,7 @@ under the License.
<SizeBasedTriggeringPolicy size="250 MB"/>
</Policies>
</RollingRandomAccessFile>
+ <Memory name="connidMemory" size="25"/>
</appenders>
@@ -75,61 +79,79 @@ under the License.
<asyncLogger name="org.apache.syncope.core.persistence" additivity="false" level="INFO">
<appender-ref ref="persistence"/>
+ <appender-ref ref="persistenceMemory"/>
</asyncLogger>
<asyncLogger name="org.springframework.orm" additivity="false" level="INFO">
<appender-ref ref="persistence"/>
+ <appender-ref ref="persistenceMemory"/>
</asyncLogger>
<asyncLogger name="org.apache.syncope.core.rest" additivity="false" level="INFO">
<appender-ref ref="rest"/>
+ <appender-ref ref="restMemory"/>
</asyncLogger>
<asyncLogger name="org.springframework.web" additivity="false" level="INFO">
<appender-ref ref="rest"/>
+ <appender-ref ref="restMemory"/>
</asyncLogger>
<asyncLogger name="org.apache.http" additivity="false" level="INFO">
<appender-ref ref="rest"/>
+ <appender-ref ref="restMemory"/>
</asyncLogger>
<asyncLogger name="org.apache.cxf" additivity="false" level="ERROR">
<appender-ref ref="rest"/>
+ <appender-ref ref="restMemory"/>
</asyncLogger>
<asyncLogger name="org.identityconnectors" additivity="false" level="DEBUG">
<appender-ref ref="connid"/>
+ <appender-ref ref="connidMemory"/>
</asyncLogger>
<asyncLogger name="net.tirasa.connid" additivity="false" level="DEBUG">
<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="connid"/>
+ <appender-ref ref="connidMemory"/>
</asyncLogger>
<asyncLogger name="org.apache.syncope" additivity="false" level="INFO">
<appender-ref ref="main"/>
+ <appender-ref ref="mainMemory"/>
</asyncLogger>
<asyncLogger name="org.apache.syncope.core.provisioning" additivity="false" level="INFO">
<appender-ref ref="main"/>
+ <appender-ref ref="mainMemory"/>
</asyncLogger>
<asyncLogger name="org.apache.syncope.core.logic" additivity="false" level="INFO">
<appender-ref ref="main"/>
+ <appender-ref ref="mainMemory"/>
</asyncLogger>
<asyncLogger name="org.springframework" additivity="false" level="INFO">
<appender-ref ref="main"/>
+ <appender-ref ref="mainMemory"/>
</asyncLogger>
<asyncLogger name="org.quartz" additivity="false" level="INFO">
<appender-ref ref="main"/>
+ <appender-ref ref="mainMemory"/>
</asyncLogger>
<asyncLogger name="org.activiti" additivity="false" level="ERROR">
<appender-ref ref="main"/>
+ <appender-ref ref="mainMemory"/>
</asyncLogger>
<asyncLogger name="org.apache.camel" additivity="false" level="ERROR">
<appender-ref ref="main"/>
+ <appender-ref ref="mainMemory"/>
</asyncLogger>
<asyncLogger name="io.swagger" additivity="false" level="ERROR">
<appender-ref ref="main"/>
+ <appender-ref ref="mainMemory"/>
</asyncLogger>
<root level="INFO">
<appender-ref ref="main"/>
+ <appender-ref ref="mainMemory"/>
</root>
</loggers>
http://git-wip-us.apache.org/repos/asf/syncope/blob/c25e1da0/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 080e8f2..366770d 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
@@ -38,6 +38,7 @@ import org.apache.syncope.client.cli.commands.connector.ConnectorCommand;
import org.apache.syncope.client.cli.commands.entitlement.EntitlementCommand;
import org.apache.syncope.client.cli.commands.group.GroupCommand;
import org.apache.syncope.client.cli.commands.install.InstallCommand;
+import org.apache.syncope.client.cli.commands.logger.LoggerCommand;
import org.apache.syncope.client.cli.commands.policy.PolicyCommand;
import org.apache.syncope.client.cli.commands.report.ReportCommand;
import org.apache.syncope.client.cli.commands.role.RoleCommand;
@@ -307,4 +308,24 @@ public class CLIITCase extends AbstractITCase {
}
}
}
+
+ @Test
+ public void lastStatements() {
+ Process process = null;
+ try {
+ PROCESS_BUILDER.command(getCommand(
+ new LoggerCommand().getClass().getAnnotation(Command.class).name(),
+ LoggerCommand.LoggerOptions.LAST_STATEMENTS.getOptionName(),
+ "connidMemory"));
+ process = PROCESS_BUILDER.start();
+ final String result = IOUtils.toString(process.getInputStream(), SyncopeConstants.DEFAULT_CHARSET);
+ assertTrue(result.contains("\"level\" : \"DEBUG\","));
+ } catch (IOException e) {
+ fail(e.getMessage());
+ } finally {
+ if (process != null) {
+ process.destroy();
+ }
+ }
+ }
}
http://git-wip-us.apache.org/repos/asf/syncope/blob/c25e1da0/fit/core-reference/src/test/java/org/apache/syncope/fit/console/LogsITCase.java
----------------------------------------------------------------------
diff --git a/fit/core-reference/src/test/java/org/apache/syncope/fit/console/LogsITCase.java b/fit/core-reference/src/test/java/org/apache/syncope/fit/console/LogsITCase.java
index d192d57..fb3b071 100644
--- a/fit/core-reference/src/test/java/org/apache/syncope/fit/console/LogsITCase.java
+++ b/fit/core-reference/src/test/java/org/apache/syncope/fit/console/LogsITCase.java
@@ -22,7 +22,7 @@ import static org.junit.Assert.assertNotNull;
import java.lang.reflect.InvocationTargetException;
import org.apache.syncope.client.console.pages.Logs;
-import org.apache.syncope.common.lib.to.LoggerTO;
+import org.apache.syncope.common.lib.log.LoggerTO;
import org.apache.wicket.Component;
import org.apache.wicket.ajax.markup.html.AjaxFallbackLink;
import org.apache.wicket.core.util.lang.PropertyResolver;
http://git-wip-us.apache.org/repos/asf/syncope/blob/c25e1da0/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 373f28a..07416c6 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
@@ -26,13 +26,16 @@ import static org.junit.Assert.fail;
import java.text.ParseException;
import java.util.List;
+import java.util.Queue;
import javax.ws.rs.core.Response;
import javax.xml.ws.WebServiceException;
import org.apache.commons.collections4.IterableUtils;
import org.apache.commons.collections4.Predicate;
import org.apache.syncope.common.lib.SyncopeClientException;
-import org.apache.syncope.common.lib.to.EventCategoryTO;
-import org.apache.syncope.common.lib.to.LoggerTO;
+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.AnyTypeKind;
import org.apache.syncope.common.lib.types.AuditElements;
import org.apache.syncope.common.lib.types.AuditElements.EventCategoryType;
@@ -51,6 +54,31 @@ import org.junit.Test;
public class LoggerITCase extends AbstractITCase {
@Test
+ public void listMemoryAppenders() {
+ List<LogAppender> memoryAppenders = loggerService.memoryAppenders();
+ assertNotNull(memoryAppenders);
+ assertFalse(memoryAppenders.isEmpty());
+ for (LogAppender appender : memoryAppenders) {
+ assertNotNull(appender);
+ assertNotNull(appender.getName());
+ }
+ }
+
+ @Test
+ public void lastStatements() {
+ Queue<LogStatementTO> statements = loggerService.getLastLogStatements("connidMemory");
+ assertNotNull(statements);
+ assertFalse(statements.isEmpty());
+
+ LogStatementTO statement = statements.element();
+ assertNotNull(statement);
+ assertNotNull(statement.getLoggerName());
+ assertNotNull(statement.getLevel());
+ assertNotNull(statement.getMessage());
+ assertNotNull(statement.getTimeMillis());
+ }
+
+ @Test
public void listLogs() {
List<LoggerTO> loggers = loggerService.list(LoggerType.LOG);
assertNotNull(loggers);
http://git-wip-us.apache.org/repos/asf/syncope/blob/c25e1da0/fit/core-reference/src/test/java/org/apache/syncope/fit/core/ReportITCase.java
----------------------------------------------------------------------
diff --git a/fit/core-reference/src/test/java/org/apache/syncope/fit/core/ReportITCase.java b/fit/core-reference/src/test/java/org/apache/syncope/fit/core/ReportITCase.java
index 9f9f8be..4dc4663 100644
--- a/fit/core-reference/src/test/java/org/apache/syncope/fit/core/ReportITCase.java
+++ b/fit/core-reference/src/test/java/org/apache/syncope/fit/core/ReportITCase.java
@@ -37,7 +37,7 @@ import org.apache.syncope.common.lib.SyncopeConstants;
import org.apache.syncope.common.lib.report.AuditReportletConf;
import org.apache.syncope.common.lib.report.UserReportletConf;
import org.apache.syncope.common.lib.to.BulkActionResult;
-import org.apache.syncope.common.lib.to.LoggerTO;
+import org.apache.syncope.common.lib.log.LoggerTO;
import org.apache.syncope.common.lib.to.ExecTO;
import org.apache.syncope.common.lib.to.ReportTO;
import org.apache.syncope.common.lib.types.AuditElements;