diff --git a/spring-data-log4j-appender/pom.xml b/spring-data-log4j-appender/pom.xml new file mode 100644 index 000000000..d73e5e185 --- /dev/null +++ b/spring-data-log4j-appender/pom.xml @@ -0,0 +1,163 @@ + + 4.0.0 + + org.springframework.data + spring-data-document-parent + 1.0.0.BUILD-SNAPSHOT + ../spring-data-document-parent/pom.xml + + spring-data-log4j-appender + jar + Spring Data MongoDB Log4J Appender + + + 2.3 + + + + + + + org.springframework + spring-beans + + + org.springframework + spring-tx + + + org.springframework + spring-expression + + + org.springframework + spring-test + test + + + + + org.springframework.data + spring-data-document-core + ${project.version} + + + org.springframework.data + spring-data-commons-core + ${data.commons.version} + + + + + org.mongodb + mongo-java-driver + ${mongo.version} + + + + + org.slf4j + slf4j-api + + + org.slf4j + jcl-over-slf4j + compile + + + org.slf4j + slf4j-log4j12 + runtime + + + log4j + log4j + + + javax.mail + mail + + + javax.jms + jms + + + com.sun.jdmk + jmxtools + + + com.sun.jmx + jmxri + + + compile + + + + + org.mockito + mockito-all + test + + + + org.hamcrest + hamcrest-all + 1.1 + test + + + + junit + junit + test + + + + joda-time + joda-time + 1.6 + test + + + + + + + com.springsource.bundlor + com.springsource.bundlor.maven + + + + com.mysema.maven + maven-apt-plugin + 1.0 + + + generate-test-sources + + test-process + + + target/generated-sources/test-annotations + org.springframework.data.document.mongodb.repository.MongoAnnotationProcessor + + + + + + + + + + querydsl + Mysema QueryDsl + http://source.mysema.com/maven2/releases + + false + + + + diff --git a/spring-data-log4j-appender/src/main/java/org/springframework/data/document/mongodb/log4j/MongoLog4jAppender.java b/spring-data-log4j-appender/src/main/java/org/springframework/data/document/mongodb/log4j/MongoLog4jAppender.java new file mode 100644 index 000000000..0620be138 --- /dev/null +++ b/spring-data-log4j-appender/src/main/java/org/springframework/data/document/mongodb/log4j/MongoLog4jAppender.java @@ -0,0 +1,162 @@ +/* + * Copyright (c) 2011 by the original author(s). + * + * Licensed 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.springframework.data.document.mongodb.log4j; + +import java.net.UnknownHostException; +import java.util.Arrays; +import java.util.Calendar; +import java.util.Map; + +import com.mongodb.BasicDBList; +import com.mongodb.BasicDBObject; +import com.mongodb.DB; +import com.mongodb.Mongo; +import com.mongodb.WriteConcern; +import org.apache.log4j.AppenderSkeleton; +import org.apache.log4j.Level; +import org.apache.log4j.spi.LoggingEvent; + +/** + * @author Jon Brisbin + */ +public class MongoLog4jAppender extends AppenderSkeleton { + + public static final String LEVEL = "level"; + public static final String NAME = "name"; + public static final String TIMESTAMP = "timestamp"; + public static final String PROPERTIES = "properties"; + public static final String TRACEBACK = "traceback"; + public static final String MESSAGE = "message"; + + protected String host = "localhost"; + protected int port = 27017; + protected String database = "logs"; + protected String collection = null; + protected Mongo mongo; + protected DB db; + + public MongoLog4jAppender() { + } + + public MongoLog4jAppender(boolean isActive) { + super(isActive); + } + + public String getHost() { + return host; + } + + public void setHost(String host) { + this.host = host; + } + + public int getPort() { + return port; + } + + public void setPort(int port) { + this.port = port; + } + + public String getDatabase() { + return database; + } + + public void setDatabase(String database) { + this.database = database; + } + + public String getCollection() { + return collection; + } + + public void setCollection(String collection) { + this.collection = collection; + } + + protected void connectToMongo() throws UnknownHostException { + this.mongo = new Mongo(host, port); + this.db = mongo.getDB(database); + } + + @SuppressWarnings({"unchecked"}) + @Override + protected void append(final LoggingEvent event) { + if (null == db) { + try { + connectToMongo(); + } catch (UnknownHostException e) { + throw new RuntimeException(e.getMessage(), e); + } + } + + BasicDBObject dbo = new BasicDBObject(); + dbo.put(NAME, event.getLogger().getName()); + dbo.put(LEVEL, event.getLevel().toString()); + dbo.put(TIMESTAMP, String.format("%s", event.getTimeStamp())); + + // Copy properties into document + Map props = event.getProperties(); + if (null != props && props.size() > 0) { + BasicDBObject propsDbo = new BasicDBObject(); + for (Map.Entry entry : props.entrySet()) { + propsDbo.put(entry.getKey().toString(), entry.getValue().toString()); + } + dbo.put(PROPERTIES, propsDbo); + } + + // Copy traceback info (if there is any) into the document + String[] traceback = event.getThrowableStrRep(); + if (null != traceback && traceback.length > 0) { + BasicDBList tbDbo = new BasicDBList(); + tbDbo.addAll(Arrays.asList(traceback)); + dbo.put(TRACEBACK, tbDbo); + } + + // Put the rendered message into the document + dbo.put(MESSAGE, event.getRenderedMessage()); + + // Insert the document + if (null == collection) { + // Use the category name + collection = event.getLogger().getName(); + } else { + Calendar now = Calendar.getInstance(); + collection = String.format(collection, + now.get(Calendar.YEAR), + now.get(Calendar.MONTH), + now.get(Calendar.DAY_OF_MONTH), + now.get(Calendar.HOUR_OF_DAY), + event.getLevel().toString(), + event.getLogger().getName()); + } + + WriteConcern wc = WriteConcern.NORMAL; + if (event.getLevel().isGreaterOrEqual(Level.WARN)) { + wc = WriteConcern.SAFE; + } + db.getCollection(collection).insert(dbo, wc); + } + + public void close() { + mongo.close(); + } + + public boolean requiresLayout() { + return true; + } +} diff --git a/spring-data-log4j-appender/src/test/java/org/springframework/data/document/mongodb/log4j/AppenderTest.java b/spring-data-log4j-appender/src/test/java/org/springframework/data/document/mongodb/log4j/AppenderTest.java new file mode 100644 index 000000000..de0793e5c --- /dev/null +++ b/spring-data-log4j-appender/src/test/java/org/springframework/data/document/mongodb/log4j/AppenderTest.java @@ -0,0 +1,71 @@ +/* + * Copyright (c) 2011 by the original author(s). + * + * Licensed 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.springframework.data.document.mongodb.log4j; + +import static org.hamcrest.Matchers.*; +import static org.junit.Assert.*; + +import java.net.UnknownHostException; + +import com.mongodb.DB; +import com.mongodb.DBCursor; +import com.mongodb.Mongo; +import org.apache.log4j.Logger; +import org.apache.log4j.MDC; +import org.junit.Before; +import org.junit.Test; + +/** + * @author Jon Brisbin + */ +public class AppenderTest { + + private static final String NAME = AppenderTest.class.getName(); + private Logger log = Logger.getLogger(NAME); + private Mongo mongo; + private DB db; + + @Before + public void setup() { + try { + mongo = new Mongo("localhost", 27017); + db = mongo.getDB("logs"); + db.getCollection(NAME).drop(); + } catch (UnknownHostException e) { + throw new RuntimeException(e.getMessage(), e); + } + } + + @Test + public void testLogging() { + log.debug("DEBUG message"); + log.info("INFO message"); + log.warn("WARN message"); + log.error("ERROR message"); + + DBCursor msgs = db.getCollection(NAME).find(); + assertThat(msgs.count(), is(4)); + + } + + @Test + public void testProperties() { + MDC.put("property", "one"); + log.debug("DEBUG message"); + } + +} diff --git a/spring-data-log4j-appender/src/test/resources/log4j.properties b/spring-data-log4j-appender/src/test/resources/log4j.properties new file mode 100644 index 000000000..b21f9aece --- /dev/null +++ b/spring-data-log4j-appender/src/test/resources/log4j.properties @@ -0,0 +1,17 @@ +log4j.rootCategory=INFO, stdout + +log4j.appender.stdout=org.springframework.data.document.mongodb.log4j.MongoLog4jAppender +log4j.appender.stdout.layout=org.apache.log4j.PatternLayout +log4j.appender.stdout.layout.ConversionPattern=%d %p [%c] - <%m>%n +log4j.appender.stdout.host = localhost +log4j.appender.stdout.port = 27017 +log4j.appender.stdout.database = logs + +log4j.category.org.apache.activemq=ERROR +log4j.category.org.springframework.batch=DEBUG +log4j.category.org.springframework.data.document.mongodb=DEBUG +log4j.category.org.springframework.transaction=INFO + +log4j.category.org.hibernate.SQL=DEBUG +# for debugging datasource initialization +# log4j.category.test.jdbc=DEBUG diff --git a/spring-data-mongodb/src/main/java/org/springframework/data/document/mongodb/mapping/MappingConfigurationHelper.java b/spring-data-mongodb/src/main/java/org/springframework/data/document/mongodb/mapping/MappingConfigurationHelper.java index c347d2b63..c6eb716d3 100644 --- a/spring-data-mongodb/src/main/java/org/springframework/data/document/mongodb/mapping/MappingConfigurationHelper.java +++ b/spring-data-mongodb/src/main/java/org/springframework/data/document/mongodb/mapping/MappingConfigurationHelper.java @@ -23,7 +23,6 @@ import java.util.Map; import java.util.Set; import java.util.concurrent.ConcurrentHashMap; -import com.google.code.morphia.mapping.MappingException; import com.mongodb.BasicDBObject; import com.mongodb.DBCollection; import com.mongodb.DBObject; @@ -45,6 +44,7 @@ import org.springframework.data.document.mongodb.index.IndexDirection; import org.springframework.data.document.mongodb.index.Indexed; import org.springframework.data.mapping.PropertyHandler; import org.springframework.data.mapping.event.MappingContextEvent; +import org.springframework.data.mapping.model.MappingException; import org.springframework.data.mapping.model.PersistentEntity; import org.springframework.data.mapping.model.PersistentProperty;