http://git-wip-us.apache.org/repos/asf/logging-log4j2/blob/ebec215e/log4j-couchdb/src/site/markdown/index.md.vm ---------------------------------------------------------------------- diff --git a/log4j-couchdb/src/site/markdown/index.md.vm b/log4j-couchdb/src/site/markdown/index.md.vm new file mode 100644 index 0000000..a6b9639 --- /dev/null +++ b/log4j-couchdb/src/site/markdown/index.md.vm @@ -0,0 +1,48 @@ +<!-- vim: set syn=markdown : --> +<!-- + 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. +--> +#set($h1='#') +#set($h2='##') +## TODO: use properties for dynamic dependency versions + +$h1 CouchDB Appender + +[Apache CouchDB](https://couchdb.apache.org/) is supported through the +[LightCouch](http://www.lightcouch.org/) driver. + +``` + <dependencyManagement> + <dependencies> + <dependency> + <groupId>org.lightcouch</groupId> + <artifactId>lightcouch</artifactId> + <version>0.0.6</version> + </dependency> + </dependencies> + </dependencyManagement> + <dependencies> + <dependency> + <groupId>org.lightcouch</groupId> + <artifactId>lightcouch</artifactId> + </dependency> + </dependencies> +``` + +$h2 Requirements + +The CouchDB Appender is dependent on the Log4j 2 API and implementation. +For more information, see [Runtime Dependencies](../runtime-dependencies.html).
http://git-wip-us.apache.org/repos/asf/logging-log4j2/blob/ebec215e/log4j-couchdb/src/site/site.xml ---------------------------------------------------------------------- diff --git a/log4j-couchdb/src/site/site.xml b/log4j-couchdb/src/site/site.xml new file mode 100644 index 0000000..affd43f --- /dev/null +++ b/log4j-couchdb/src/site/site.xml @@ -0,0 +1,52 @@ +<!-- + 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. + +--> +<project name="Log4j CouchDB Appender" + xmlns="http://maven.apache.org/DECORATION/1.4.0" + xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:schemaLocation="http://maven.apache.org/DECORATION/1.4.0 http://maven.apache.org/xsd/decoration-1.4.0.xsd"> + <body> + <links> + <item name="Apache" href="http://www.apache.org/" /> + <item name="Logging Services" href="http://logging.apache.org/"/> + <item name="Log4j" href="../index.html"/> + </links> + + <!-- Component-specific reports --> + <menu ref="reports"/> + + <!-- Overall Project Info --> + <menu name="Log4j Project Information" img="icon-info-sign"> + <item name="Dependencies" href="../dependencies.html" /> + <item name="Dependency Convergence" href="../dependency-convergence.html" /> + <item name="Dependency Management" href="../dependency-management.html" /> + <item name="Project Team" href="../team-list.html" /> + <item name="Mailing Lists" href="../mail-lists.html" /> + <item name="Issue Tracking" href="../issue-tracking.html" /> + <item name="Project License" href="../license.html" /> + <item name="Source Repository" href="../source-repository.html" /> + <item name="Project Summary" href="../project-summary.html" /> + </menu> + + <menu name="Log4j Project Reports" img="icon-cog"> + <item name="Changes Report" href="../changes-report.html" /> + <item name="JIRA Report" href="../jira-report.html" /> + <item name="Surefire Report" href="../surefire-report.html" /> + <item name="RAT Report" href="../rat-report.html" /> + </menu> + </body> +</project> http://git-wip-us.apache.org/repos/asf/logging-log4j2/blob/ebec215e/log4j-distribution/pom.xml ---------------------------------------------------------------------- diff --git a/log4j-distribution/pom.xml b/log4j-distribution/pom.xml index 651717a..fa46876 100644 --- a/log4j-distribution/pom.xml +++ b/log4j-distribution/pom.xml @@ -240,18 +240,52 @@ </dependency> <dependency> <groupId>org.apache.logging.log4j</groupId> - <artifactId>log4j-nosql</artifactId> + <artifactId>log4j-couchdb</artifactId> <version>${project.version}</version> </dependency> <dependency> <groupId>org.apache.logging.log4j</groupId> - <artifactId>log4j-nosql</artifactId> + <artifactId>log4j-couchdb</artifactId> <version>${project.version}</version> <classifier>sources</classifier> </dependency> <dependency> <groupId>org.apache.logging.log4j</groupId> - <artifactId>log4j-nosql</artifactId> + <artifactId>log4j-couchdb</artifactId> + <version>${project.version}</version> + <classifier>javadoc</classifier> + </dependency> + <dependency> + <groupId>org.apache.logging.log4j</groupId> + <artifactId>log4j-mongodb</artifactId> + <version>${project.version}</version> + </dependency> + <dependency> + <groupId>org.apache.logging.log4j</groupId> + <artifactId>log4j-mongodb</artifactId> + <version>${project.version}</version> + <classifier>sources</classifier> + </dependency> + <dependency> + <groupId>org.apache.logging.log4j</groupId> + <artifactId>log4j-mongodb</artifactId> + <version>${project.version}</version> + <classifier>javadoc</classifier> + </dependency> + <dependency> + <groupId>org.apache.logging.log4j</groupId> + <artifactId>log4j-cassandra</artifactId> + <version>${project.version}</version> + </dependency> + <dependency> + <groupId>org.apache.logging.log4j</groupId> + <artifactId>log4j-cassandra</artifactId> + <version>${project.version}</version> + <classifier>sources</classifier> + </dependency> + <dependency> + <groupId>org.apache.logging.log4j</groupId> + <artifactId>log4j-cassandra</artifactId> <version>${project.version}</version> <classifier>javadoc</classifier> </dependency> http://git-wip-us.apache.org/repos/asf/logging-log4j2/blob/ebec215e/log4j-mongodb/pom.xml ---------------------------------------------------------------------- diff --git a/log4j-mongodb/pom.xml b/log4j-mongodb/pom.xml new file mode 100644 index 0000000..29c511c --- /dev/null +++ b/log4j-mongodb/pom.xml @@ -0,0 +1,183 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + ~ 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. + --> + +<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> + <parent> + <groupId>org.apache.logging.log4j</groupId> + <artifactId>log4j</artifactId> + <version>2.10.0-SNAPSHOT</version> + </parent> + <modelVersion>4.0.0</modelVersion> + + <artifactId>log4j-mongodb</artifactId> + <name>Apache Log4j MongoDB</name> + <description> + MongoDB appender for Log4j. + </description> + <properties> + <log4jParentDir>${basedir}/..</log4jParentDir> + <docLabel>MongoDB Documentation</docLabel> + <projectDir>/log4j-mongodb</projectDir> + <module.name>org.apache.logging.log4j.mongodb</module.name> + </properties> + + <dependencies> + <dependency> + <groupId>org.apache.logging.log4j</groupId> + <artifactId>log4j-core</artifactId> + </dependency> + <dependency> + <groupId>org.mongodb</groupId> + <artifactId>mongo-java-driver</artifactId> + </dependency> + <!-- Test Dependencies --> + <dependency> + <groupId>junit</groupId> + <artifactId>junit</artifactId> + </dependency> + <dependency> + <groupId>org.mockito</groupId> + <artifactId>mockito-core</artifactId> + <scope>test</scope> + </dependency> + <dependency> + <groupId>org.apache.logging.log4j</groupId> + <artifactId>log4j-api</artifactId> + <type>test-jar</type> + </dependency> + <dependency> + <groupId>org.apache.logging.log4j</groupId> + <artifactId>log4j-core</artifactId> + <type>test-jar</type> + </dependency> + <dependency> + <groupId>org.apache.logging.log4j</groupId> + <artifactId>log4j-slf4j-impl</artifactId> + <scope>test</scope> + </dependency> + </dependencies> + + <build> + <plugins> + <plugin> + <groupId>org.apache.felix</groupId> + <artifactId>maven-bundle-plugin</artifactId> + <configuration> + <instructions> + <Fragment-Host>org.apache.logging.log4j.core</Fragment-Host> + <Export-Package>*</Export-Package> + </instructions> + </configuration> + </plugin> + </plugins> + </build> + <reporting> + <plugins> + <plugin> + <groupId>org.apache.maven.plugins</groupId> + <artifactId>maven-changes-plugin</artifactId> + <version>${changes.plugin.version}</version> + <reportSets> + <reportSet> + <reports> + <report>changes-report</report> + </reports> + </reportSet> + </reportSets> + <configuration> + <issueLinkTemplate>%URL%/show_bug.cgi?id=%ISSUE%</issueLinkTemplate> + <useJql>true</useJql> + </configuration> + </plugin> + <plugin> + <groupId>org.apache.maven.plugins</groupId> + <artifactId>maven-checkstyle-plugin</artifactId> + <version>${checkstyle.plugin.version}</version> + <configuration> + <!--<propertiesLocation>${vfs.parent.dir}/checkstyle.properties</propertiesLocation> --> + <configLocation>${log4jParentDir}/checkstyle.xml</configLocation> + <suppressionsLocation>${log4jParentDir}/checkstyle-suppressions.xml</suppressionsLocation> + <enableRulesSummary>false</enableRulesSummary> + <propertyExpansion>basedir=${basedir}</propertyExpansion> + <propertyExpansion>licensedir=${log4jParentDir}/checkstyle-header.txt</propertyExpansion> + </configuration> + </plugin> + <plugin> + <groupId>org.apache.maven.plugins</groupId> + <artifactId>maven-javadoc-plugin</artifactId> + <version>${javadoc.plugin.version}</version> + <configuration> + <bottom><![CDATA[<p align="center">Copyright © {inceptionYear}-{currentYear} {organizationName}. All Rights Reserved.<br /> + Apache Logging, Apache Log4j, Log4j, Apache, the Apache feather logo, the Apache Logging project logo, + and the Apache Log4j logo are trademarks of The Apache Software Foundation.</p>]]></bottom> + <!-- module link generation is completely broken in the javadoc plugin for a multi-module non-aggregating + project --> + <detectOfflineLinks>false</detectOfflineLinks> + <linksource>true</linksource> + </configuration> + <reportSets> + <reportSet> + <id>non-aggregate</id> + <reports> + <report>javadoc</report> + </reports> + </reportSet> + </reportSets> + </plugin> + <plugin> + <groupId>org.codehaus.mojo</groupId> + <artifactId>findbugs-maven-plugin</artifactId> + <version>${findbugs.plugin.version}</version> + <configuration> + <fork>true</fork> + <jvmArgs>-Duser.language=en</jvmArgs> + <threshold>Normal</threshold> + <effort>Default</effort> + <excludeFilterFile>${log4jParentDir}/findbugs-exclude-filter.xml</excludeFilterFile> + </configuration> + </plugin> + <plugin> + <groupId>org.apache.maven.plugins</groupId> + <artifactId>maven-jxr-plugin</artifactId> + <version>${jxr.plugin.version}</version> + <reportSets> + <reportSet> + <id>non-aggregate</id> + <reports> + <report>jxr</report> + </reports> + </reportSet> + <reportSet> + <id>aggregate</id> + <reports> + <report>aggregate</report> + </reports> + </reportSet> + </reportSets> + </plugin> + <plugin> + <groupId>org.apache.maven.plugins</groupId> + <artifactId>maven-pmd-plugin</artifactId> + <version>${pmd.plugin.version}</version> + <configuration> + <targetJdk>${maven.compiler.target}</targetJdk> + </configuration> + </plugin> + </plugins> + </reporting> +</project> http://git-wip-us.apache.org/repos/asf/logging-log4j2/blob/ebec215e/log4j-mongodb/src/main/java/org/apache/logging/log4j/nosql/appender/mongodb/MongoDbConnection.java ---------------------------------------------------------------------- diff --git a/log4j-mongodb/src/main/java/org/apache/logging/log4j/nosql/appender/mongodb/MongoDbConnection.java b/log4j-mongodb/src/main/java/org/apache/logging/log4j/nosql/appender/mongodb/MongoDbConnection.java new file mode 100644 index 0000000..66e205d --- /dev/null +++ b/log4j-mongodb/src/main/java/org/apache/logging/log4j/nosql/appender/mongodb/MongoDbConnection.java @@ -0,0 +1,96 @@ +/* + * 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.logging.log4j.nosql.appender.mongodb; + +import org.apache.logging.log4j.Level; +import org.apache.logging.log4j.Logger; +import org.apache.logging.log4j.core.appender.AppenderLoggingException; +import org.apache.logging.log4j.core.appender.nosql.AbstractNoSqlConnection; +import org.apache.logging.log4j.core.appender.nosql.NoSqlConnection; +import org.apache.logging.log4j.core.appender.nosql.NoSqlObject; +import org.apache.logging.log4j.status.StatusLogger; +import org.bson.BSON; +import org.bson.Transformer; + +import com.mongodb.BasicDBObject; +import com.mongodb.DB; +import com.mongodb.DBCollection; +import com.mongodb.MongoException; +import com.mongodb.WriteConcern; + +/** + * The MongoDB implementation of {@link NoSqlConnection}. + */ +public final class MongoDbConnection extends AbstractNoSqlConnection<BasicDBObject, MongoDbObject> { + + private static final Logger LOGGER = StatusLogger.getLogger(); + + static { + BSON.addEncodingHook(Level.class, new Transformer() { + @Override + public Object transform(final Object o) { + if (o instanceof Level) { + return ((Level) o).name(); + } + return o; + } + }); + } + + private final DBCollection collection; + private final WriteConcern writeConcern; + + public MongoDbConnection(final DB database, final WriteConcern writeConcern, final String collectionName, + final Boolean isCapped, final Integer collectionSize) { + if (database.collectionExists(collectionName)) { + collection = database.getCollection(collectionName); + } else { + final BasicDBObject options = new BasicDBObject(); + options.put("capped", isCapped); + options.put("size", collectionSize); + this.collection = database.createCollection(collectionName, options); + } + this.writeConcern = writeConcern; + } + + @Override + public MongoDbObject createObject() { + return new MongoDbObject(); + } + + @Override + public MongoDbObject[] createList(final int length) { + return new MongoDbObject[length]; + } + + @Override + public void insertObject(final NoSqlObject<BasicDBObject> object) { + try { + this.collection.insert(object.unwrap(), this.writeConcern); + } catch (final MongoException e) { + throw new AppenderLoggingException("Failed to write log event to MongoDB due to error: " + e.getMessage(), + e); + } + } + + @Override + public void closeImpl() { + // LOG4J2-1196 + this.collection.getDB().getMongo().close(); + } + +} http://git-wip-us.apache.org/repos/asf/logging-log4j2/blob/ebec215e/log4j-mongodb/src/main/java/org/apache/logging/log4j/nosql/appender/mongodb/MongoDbObject.java ---------------------------------------------------------------------- diff --git a/log4j-mongodb/src/main/java/org/apache/logging/log4j/nosql/appender/mongodb/MongoDbObject.java b/log4j-mongodb/src/main/java/org/apache/logging/log4j/nosql/appender/mongodb/MongoDbObject.java new file mode 100644 index 0000000..8eb6e46 --- /dev/null +++ b/log4j-mongodb/src/main/java/org/apache/logging/log4j/nosql/appender/mongodb/MongoDbObject.java @@ -0,0 +1,66 @@ +/* + * 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.logging.log4j.nosql.appender.mongodb; + +import java.util.Collections; + +import org.apache.logging.log4j.core.appender.nosql.NoSqlObject; + +import com.mongodb.BasicDBList; +import com.mongodb.BasicDBObject; + +/** + * The MongoDB implementation of {@link NoSqlObject}. + */ +public final class MongoDbObject implements NoSqlObject<BasicDBObject> { + private final BasicDBObject mongoObject; + + public MongoDbObject() { + this.mongoObject = new BasicDBObject(); + } + + @Override + public void set(final String field, final Object value) { + this.mongoObject.append(field, value); + } + + @Override + public void set(final String field, final NoSqlObject<BasicDBObject> value) { + this.mongoObject.append(field, value.unwrap()); + } + + @Override + public void set(final String field, final Object[] values) { + final BasicDBList list = new BasicDBList(); + Collections.addAll(list, values); + this.mongoObject.append(field, list); + } + + @Override + public void set(final String field, final NoSqlObject<BasicDBObject>[] values) { + final BasicDBList list = new BasicDBList(); + for (final NoSqlObject<BasicDBObject> value : values) { + list.add(value.unwrap()); + } + this.mongoObject.append(field, list); + } + + @Override + public BasicDBObject unwrap() { + return this.mongoObject; + } +} http://git-wip-us.apache.org/repos/asf/logging-log4j2/blob/ebec215e/log4j-mongodb/src/main/java/org/apache/logging/log4j/nosql/appender/mongodb/MongoDbProvider.java ---------------------------------------------------------------------- diff --git a/log4j-mongodb/src/main/java/org/apache/logging/log4j/nosql/appender/mongodb/MongoDbProvider.java b/log4j-mongodb/src/main/java/org/apache/logging/log4j/nosql/appender/mongodb/MongoDbProvider.java new file mode 100644 index 0000000..5167c3e --- /dev/null +++ b/log4j-mongodb/src/main/java/org/apache/logging/log4j/nosql/appender/mongodb/MongoDbProvider.java @@ -0,0 +1,351 @@ +/* + * 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.logging.log4j.nosql.appender.mongodb; + +import java.lang.reflect.Field; +import java.lang.reflect.Method; +import java.util.ArrayList; +import java.util.List; + +import org.apache.logging.log4j.Logger; +import org.apache.logging.log4j.core.Core; +import org.apache.logging.log4j.core.config.plugins.Plugin; +import org.apache.logging.log4j.core.config.plugins.PluginBuilderAttribute; +import org.apache.logging.log4j.core.config.plugins.PluginBuilderFactory; +import org.apache.logging.log4j.core.config.plugins.PluginFactory; +import org.apache.logging.log4j.core.config.plugins.convert.TypeConverters; +import org.apache.logging.log4j.core.config.plugins.validation.constraints.Required; +import org.apache.logging.log4j.core.config.plugins.validation.constraints.ValidHost; +import org.apache.logging.log4j.core.config.plugins.validation.constraints.ValidPort; +import org.apache.logging.log4j.core.filter.AbstractFilterable; +import org.apache.logging.log4j.core.util.NameUtil; +import org.apache.logging.log4j.core.appender.nosql.NoSqlProvider; +import org.apache.logging.log4j.status.StatusLogger; +import org.apache.logging.log4j.util.LoaderUtil; +import org.apache.logging.log4j.util.Strings; + +import com.mongodb.DB; +import com.mongodb.MongoClient; +import com.mongodb.MongoCredential; +import com.mongodb.ServerAddress; +import com.mongodb.WriteConcern; + +/** + * The MongoDB implementation of {@link NoSqlProvider}. + */ +@Plugin(name = "MongoDb", category = Core.CATEGORY_NAME, printObject = true) +public final class MongoDbProvider implements NoSqlProvider<MongoDbConnection> { + + private static final WriteConcern DEFAULT_WRITE_CONCERN = WriteConcern.ACKNOWLEDGED; + private static final Logger LOGGER = StatusLogger.getLogger(); + private static final int DEFAULT_PORT = 27017; + private static final int DEFAULT_COLLECTION_SIZE = 536870912; + + private final String collectionName; + private final DB database; + private final String description; + private final WriteConcern writeConcern; + private final boolean isCapped; + private final Integer collectionSize; + + private MongoDbProvider(final DB database, final WriteConcern writeConcern, final String collectionName, + final boolean isCapped, final Integer collectionSize, final String description) { + this.database = database; + this.writeConcern = writeConcern; + this.collectionName = collectionName; + this.isCapped = isCapped; + this.collectionSize = collectionSize; + this.description = "mongoDb{ " + description + " }"; + } + + @Override + public MongoDbConnection getConnection() { + return new MongoDbConnection(this.database, this.writeConcern, this.collectionName, this.isCapped, this.collectionSize); + } + + @Override + public String toString() { + return this.description; + } + + /** + * Factory method for creating a MongoDB provider within the plugin manager. + * + * @param collectionName The name of the MongoDB collection to which log events should be written. + * @param writeConcernConstant The {@link WriteConcern} constant to control writing details, defaults to + * {@link WriteConcern#ACKNOWLEDGED}. + * @param writeConcernConstantClassName The name of a class containing the aforementioned static WriteConcern + * constant. Defaults to {@link WriteConcern}. + * @param databaseName The name of the MongoDB database containing the collection to which log events should be + * written. Mutually exclusive with {@code factoryClassName&factoryMethodName!=null}. + * @param server The host name of the MongoDB server, defaults to localhost and mutually exclusive with + * {@code factoryClassName&factoryMethodName!=null}. + * @param port The port the MongoDB server is listening on, defaults to the default MongoDB port and mutually + * exclusive with {@code factoryClassName&factoryMethodName!=null}. + * @param userName The username to authenticate against the MongoDB server with. + * @param password The password to authenticate against the MongoDB server with. + * @param factoryClassName A fully qualified class name containing a static factory method capable of returning a + * {@link DB} or a {@link MongoClient}. + * @param factoryMethodName The name of the public static factory method belonging to the aforementioned factory + * class. + * @return a new MongoDB provider. + * @deprecated in 2.8; use {@link #newBuilder()} instead. + */ + @PluginFactory + public static MongoDbProvider createNoSqlProvider( + final String collectionName, + final String writeConcernConstant, + final String writeConcernConstantClassName, + final String databaseName, + final String server, + final String port, + final String userName, + final String password, + final String factoryClassName, + final String factoryMethodName) { + LOGGER.info("createNoSqlProvider"); + return newBuilder().setCollectionName(collectionName).setWriteConcernConstant(writeConcernConstantClassName) + .setWriteConcernConstant(writeConcernConstant).setDatabaseName(databaseName).setServer(server) + .setPort(port).setUserName(userName).setPassword(password).setFactoryClassName(factoryClassName) + .setFactoryMethodName(factoryMethodName).build(); + } + + @PluginBuilderFactory + public static <B extends Builder<B>> B newBuilder() { + return new Builder<B>().asBuilder(); + } + + public static class Builder<B extends Builder<B>> extends AbstractFilterable.Builder<B> + implements org.apache.logging.log4j.core.util.Builder<MongoDbProvider> { + + @PluginBuilderAttribute + @ValidHost + private String server = "localhost"; + + @PluginBuilderAttribute + @ValidPort + private String port = "" + DEFAULT_PORT; + + @PluginBuilderAttribute + @Required(message = "No database name provided") + private String databaseName; + + @PluginBuilderAttribute + @Required(message = "No collection name provided") + private String collectionName; + + @PluginBuilderAttribute + private String userName; + + @PluginBuilderAttribute(sensitive = true) + private String password; + + @PluginBuilderAttribute("capped") + private boolean isCapped = false; + + @PluginBuilderAttribute + private int collectionSize = DEFAULT_COLLECTION_SIZE; + + @PluginBuilderAttribute + private String factoryClassName; + + @PluginBuilderAttribute + private String factoryMethodName; + + @PluginBuilderAttribute + private String writeConcernConstantClassName; + + @PluginBuilderAttribute + private String writeConcernConstant; + + public B setServer(final String server) { + this.server = server; + return asBuilder(); + } + + public B setPort(final String port) { + this.port = port; + return asBuilder(); + } + + public B setDatabaseName(final String databaseName) { + this.databaseName = databaseName; + return asBuilder(); + } + + public B setCollectionName(final String collectionName) { + this.collectionName = collectionName; + return asBuilder(); + } + + public B setUserName(final String userName) { + this.userName = userName; + return asBuilder(); + } + + public B setPassword(final String password) { + this.password = password; + return asBuilder(); + } + + public B setCapped(final boolean isCapped) { + this.isCapped = isCapped; + return asBuilder(); + } + + public B setCollectionSize(final int collectionSize) { + this.collectionSize = collectionSize; + return asBuilder(); + } + + public B setFactoryClassName(final String factoryClassName) { + this.factoryClassName = factoryClassName; + return asBuilder(); + } + + public B setFactoryMethodName(final String factoryMethodName) { + this.factoryMethodName = factoryMethodName; + return asBuilder(); + } + + public B setWriteConcernConstantClassName(final String writeConcernConstantClassName) { + this.writeConcernConstantClassName = writeConcernConstantClassName; + return asBuilder(); + } + + public B setWriteConcernConstant(final String writeConcernConstant) { + this.writeConcernConstant = writeConcernConstant; + return asBuilder(); + } + + @Override + public MongoDbProvider build() { + DB database; + String description; + if (Strings.isNotEmpty(factoryClassName) && Strings.isNotEmpty(factoryMethodName)) { + try { + final Class<?> factoryClass = LoaderUtil.loadClass(factoryClassName); + final Method method = factoryClass.getMethod(factoryMethodName); + final Object object = method.invoke(null); + + if (object instanceof DB) { + database = (DB) object; + } else if (object instanceof MongoClient) { + if (Strings.isNotEmpty(databaseName)) { + database = ((MongoClient) object).getDB(databaseName); + } else { + LOGGER.error("The factory method [{}.{}()] returned a MongoClient so the database name is " + + "required.", factoryClassName, factoryMethodName); + return null; + } + } else if (object == null) { + LOGGER.error("The factory method [{}.{}()] returned null.", factoryClassName, factoryMethodName); + return null; + } else { + LOGGER.error("The factory method [{}.{}()] returned an unsupported type [{}].", factoryClassName, + factoryMethodName, object.getClass().getName()); + return null; + } + + description = "database=" + database.getName(); + final List<ServerAddress> addresses = database.getMongo().getAllAddress(); + if (addresses.size() == 1) { + description += ", server=" + addresses.get(0).getHost() + ", port=" + addresses.get(0).getPort(); + } else { + description += ", servers=["; + for (final ServerAddress address : addresses) { + description += " { " + address.getHost() + ", " + address.getPort() + " } "; + } + description += "]"; + } + } catch (final ClassNotFoundException e) { + LOGGER.error("The factory class [{}] could not be loaded.", factoryClassName, e); + return null; + } catch (final NoSuchMethodException e) { + LOGGER.error("The factory class [{}] does not have a no-arg method named [{}].", factoryClassName, + factoryMethodName, e); + return null; + } catch (final Exception e) { + LOGGER.error("The factory method [{}.{}()] could not be invoked.", factoryClassName, factoryMethodName, + e); + return null; + } + } else if (Strings.isNotEmpty(databaseName)) { + final List<MongoCredential> credentials = new ArrayList<>(); + description = "database=" + databaseName; + if (Strings.isNotEmpty(userName) && Strings.isNotEmpty(password)) { + description += ", username=" + userName + ", passwordHash=" + + NameUtil.md5(password + MongoDbProvider.class.getName()); + credentials.add(MongoCredential.createCredential(userName, databaseName, password.toCharArray())); + } + try { + final int portInt = TypeConverters.convert(port, int.class, DEFAULT_PORT); + description += ", server=" + server + ", port=" + portInt; + database = new MongoClient(new ServerAddress(server, portInt), credentials).getDB(databaseName); + } catch (final Exception e) { + LOGGER.error( + "Failed to obtain a database instance from the MongoClient at server [{}] and " + "port [{}].", + server, port); + return null; + } + } else { + LOGGER.error("No factory method was provided so the database name is required."); + return null; + } + + try { + database.getCollectionNames(); // Check if the database actually requires authentication + } catch (final Exception e) { + LOGGER.error( + "The database is not up, or you are not authenticated, try supplying a username and password to the MongoDB provider.", + e); + return null; + } + + final WriteConcern writeConcern = toWriteConcern(writeConcernConstant, writeConcernConstantClassName); + + return new MongoDbProvider(database, writeConcern, collectionName, isCapped, collectionSize, description); + } + + private static WriteConcern toWriteConcern(final String writeConcernConstant, + final String writeConcernConstantClassName) { + WriteConcern writeConcern; + if (Strings.isNotEmpty(writeConcernConstant)) { + if (Strings.isNotEmpty(writeConcernConstantClassName)) { + try { + final Class<?> writeConcernConstantClass = LoaderUtil.loadClass(writeConcernConstantClassName); + final Field field = writeConcernConstantClass.getField(writeConcernConstant); + writeConcern = (WriteConcern) field.get(null); + } catch (final Exception e) { + LOGGER.error("Write concern constant [{}.{}] not found, using default.", + writeConcernConstantClassName, writeConcernConstant); + writeConcern = DEFAULT_WRITE_CONCERN; + } + } else { + writeConcern = WriteConcern.valueOf(writeConcernConstant); + if (writeConcern == null) { + LOGGER.warn("Write concern constant [{}] not found, using default.", writeConcernConstant); + writeConcern = DEFAULT_WRITE_CONCERN; + } + } + } else { + writeConcern = DEFAULT_WRITE_CONCERN; + } + return writeConcern; + } + } +} http://git-wip-us.apache.org/repos/asf/logging-log4j2/blob/ebec215e/log4j-mongodb/src/main/java/org/apache/logging/log4j/nosql/appender/mongodb/package-info.java ---------------------------------------------------------------------- diff --git a/log4j-mongodb/src/main/java/org/apache/logging/log4j/nosql/appender/mongodb/package-info.java b/log4j-mongodb/src/main/java/org/apache/logging/log4j/nosql/appender/mongodb/package-info.java new file mode 100644 index 0000000..54a2878 --- /dev/null +++ b/log4j-mongodb/src/main/java/org/apache/logging/log4j/nosql/appender/mongodb/package-info.java @@ -0,0 +1,20 @@ +/* + * 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. + */ +/** + * The classes in this package contain the MongoDB provider for the NoSQL Appender. + */ +package org.apache.logging.log4j.nosql.appender.mongodb; http://git-wip-us.apache.org/repos/asf/logging-log4j2/blob/ebec215e/log4j-mongodb/src/site/markdown/index.md.vm ---------------------------------------------------------------------- diff --git a/log4j-mongodb/src/site/markdown/index.md.vm b/log4j-mongodb/src/site/markdown/index.md.vm new file mode 100644 index 0000000..1bdd5a5 --- /dev/null +++ b/log4j-mongodb/src/site/markdown/index.md.vm @@ -0,0 +1,48 @@ +<!-- vim: set syn=markdown : --> +<!-- + 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. +--> +#set($h1='#') +#set($h2='##') +## TODO: use properties for dynamic dependency versions + +$h1 MongoDB appender + +[MongoDB](http://www.mongodb.org/) is supported through the +[Java MongoDB Driver](http://docs.mongodb.org/ecosystem/drivers/java/). + +``` + <dependencyManagement> + <dependencies> + <dependency> + <groupId>org.mongodb</groupId> + <artifactId>mongo-java-driver</artifactId> + <version>2.12.3</version> + </dependency> + </dependencies> + </dependencyManagement> + <dependencies> + <dependency> + <groupId>org.mongodb</groupId> + <artifactId>mongo-java-driver</artifactId> + </dependency> + </dependencies> +``` + +$h2 Requirements + +The MongoDB Appender is dependent on the Log4j 2 API and implementation. +For more information, see [Runtime Dependencies](../runtime-dependencies.html). http://git-wip-us.apache.org/repos/asf/logging-log4j2/blob/ebec215e/log4j-mongodb/src/site/site.xml ---------------------------------------------------------------------- diff --git a/log4j-mongodb/src/site/site.xml b/log4j-mongodb/src/site/site.xml new file mode 100644 index 0000000..54ea9be --- /dev/null +++ b/log4j-mongodb/src/site/site.xml @@ -0,0 +1,52 @@ +<!-- + 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. + +--> +<project name="Log4j MongoDB Appender" + xmlns="http://maven.apache.org/DECORATION/1.4.0" + xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:schemaLocation="http://maven.apache.org/DECORATION/1.4.0 http://maven.apache.org/xsd/decoration-1.4.0.xsd"> + <body> + <links> + <item name="Apache" href="http://www.apache.org/" /> + <item name="Logging Services" href="http://logging.apache.org/"/> + <item name="Log4j" href="../index.html"/> + </links> + + <!-- Component-specific reports --> + <menu ref="reports"/> + + <!-- Overall Project Info --> + <menu name="Log4j Project Information" img="icon-info-sign"> + <item name="Dependencies" href="../dependencies.html" /> + <item name="Dependency Convergence" href="../dependency-convergence.html" /> + <item name="Dependency Management" href="../dependency-management.html" /> + <item name="Project Team" href="../team-list.html" /> + <item name="Mailing Lists" href="../mail-lists.html" /> + <item name="Issue Tracking" href="../issue-tracking.html" /> + <item name="Project License" href="../license.html" /> + <item name="Source Repository" href="../source-repository.html" /> + <item name="Project Summary" href="../project-summary.html" /> + </menu> + + <menu name="Log4j Project Reports" img="icon-cog"> + <item name="Changes Report" href="../changes-report.html" /> + <item name="JIRA Report" href="../jira-report.html" /> + <item name="Surefire Report" href="../surefire-report.html" /> + <item name="RAT Report" href="../rat-report.html" /> + </menu> + </body> +</project> http://git-wip-us.apache.org/repos/asf/logging-log4j2/blob/ebec215e/log4j-mongodb/src/test/java/org/apache/logging/log4j/nosql/appender/mongodb/MongoDbAuthTest.java ---------------------------------------------------------------------- diff --git a/log4j-mongodb/src/test/java/org/apache/logging/log4j/nosql/appender/mongodb/MongoDbAuthTest.java b/log4j-mongodb/src/test/java/org/apache/logging/log4j/nosql/appender/mongodb/MongoDbAuthTest.java new file mode 100644 index 0000000..3641a75 --- /dev/null +++ b/log4j-mongodb/src/test/java/org/apache/logging/log4j/nosql/appender/mongodb/MongoDbAuthTest.java @@ -0,0 +1,40 @@ +/* + * 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.logging.log4j.nosql.appender.mongodb; + +import org.apache.logging.log4j.LogManager; +import org.apache.logging.log4j.Logger; +import org.apache.logging.log4j.categories.Appenders; +import org.apache.logging.log4j.junit.LoggerContextRule; +import org.junit.ClassRule; +import org.junit.Ignore; +import org.junit.Test; +import org.junit.experimental.categories.Category; + +@Ignore("Requires a running MongoDB server") +@Category(Appenders.MongoDb.class) +public class MongoDbAuthTest { + + @ClassRule + public static LoggerContextRule context = new LoggerContextRule("log4j2-mongodb-auth.xml"); + + @Test + public void test() { + final Logger logger = LogManager.getLogger(); + logger.info("Hello log"); + } +} http://git-wip-us.apache.org/repos/asf/logging-log4j2/blob/ebec215e/log4j-mongodb/src/test/java/org/apache/logging/log4j/nosql/appender/mongodb/MongoDbCappedTest.java ---------------------------------------------------------------------- diff --git a/log4j-mongodb/src/test/java/org/apache/logging/log4j/nosql/appender/mongodb/MongoDbCappedTest.java b/log4j-mongodb/src/test/java/org/apache/logging/log4j/nosql/appender/mongodb/MongoDbCappedTest.java new file mode 100644 index 0000000..a001b4b --- /dev/null +++ b/log4j-mongodb/src/test/java/org/apache/logging/log4j/nosql/appender/mongodb/MongoDbCappedTest.java @@ -0,0 +1,40 @@ +/* + * 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.logging.log4j.nosql.appender.mongodb; + +import org.apache.logging.log4j.LogManager; +import org.apache.logging.log4j.Logger; +import org.apache.logging.log4j.categories.Appenders; +import org.apache.logging.log4j.junit.LoggerContextRule; +import org.junit.ClassRule; +import org.junit.Ignore; +import org.junit.Test; +import org.junit.experimental.categories.Category; + +@Ignore("Requires a running MongoDB server") +@Category(Appenders.MongoDb.class) +public class MongoDbCappedTest { + + @ClassRule + public static LoggerContextRule context = new LoggerContextRule("log4j2-mongodb-capped.xml"); + + @Test + public void test() { + final Logger logger = LogManager.getLogger(); + logger.info("Hello log"); + } +} http://git-wip-us.apache.org/repos/asf/logging-log4j2/blob/ebec215e/log4j-mongodb/src/test/java/org/apache/logging/log4j/nosql/appender/mongodb/MongoDbTest.java ---------------------------------------------------------------------- diff --git a/log4j-mongodb/src/test/java/org/apache/logging/log4j/nosql/appender/mongodb/MongoDbTest.java b/log4j-mongodb/src/test/java/org/apache/logging/log4j/nosql/appender/mongodb/MongoDbTest.java new file mode 100644 index 0000000..59ef951 --- /dev/null +++ b/log4j-mongodb/src/test/java/org/apache/logging/log4j/nosql/appender/mongodb/MongoDbTest.java @@ -0,0 +1,40 @@ +/* + * 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.logging.log4j.nosql.appender.mongodb; + +import org.apache.logging.log4j.LogManager; +import org.apache.logging.log4j.Logger; +import org.apache.logging.log4j.categories.Appenders; +import org.apache.logging.log4j.junit.LoggerContextRule; +import org.junit.ClassRule; +import org.junit.Ignore; +import org.junit.Test; +import org.junit.experimental.categories.Category; + +@Ignore("Requires a running MongoDB server") +@Category(Appenders.MongoDb.class) +public class MongoDbTest { + + @ClassRule + public static LoggerContextRule context = new LoggerContextRule("log4j2-mongodb.xml"); + + @Test + public void test() { + final Logger logger = LogManager.getLogger(); + logger.info("Hello log"); + } +} http://git-wip-us.apache.org/repos/asf/logging-log4j2/blob/ebec215e/log4j-mongodb/src/test/resources/log4j2-mongodb-auth.xml ---------------------------------------------------------------------- diff --git a/log4j-mongodb/src/test/resources/log4j2-mongodb-auth.xml b/log4j-mongodb/src/test/resources/log4j2-mongodb-auth.xml new file mode 100644 index 0000000..2eec2b6 --- /dev/null +++ b/log4j-mongodb/src/test/resources/log4j2-mongodb-auth.xml @@ -0,0 +1,30 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + 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. + +--> +<Configuration status="error"> + <Appenders> + <NoSql name="MongoDbAppender"> + <MongoDb databaseName="test" collectionName="applog" server="localhost" userName="log4jUser" password="12345678"/> + </NoSql> + </Appenders> + <Loggers> + <Root level="ALL"> + <AppenderRef ref="MongoDbAppender" /> + </Root> + </Loggers> +</Configuration> http://git-wip-us.apache.org/repos/asf/logging-log4j2/blob/ebec215e/log4j-mongodb/src/test/resources/log4j2-mongodb-capped.xml ---------------------------------------------------------------------- diff --git a/log4j-mongodb/src/test/resources/log4j2-mongodb-capped.xml b/log4j-mongodb/src/test/resources/log4j2-mongodb-capped.xml new file mode 100644 index 0000000..24d964b --- /dev/null +++ b/log4j-mongodb/src/test/resources/log4j2-mongodb-capped.xml @@ -0,0 +1,30 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + 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. + +--> +<Configuration status="error"> + <Appenders> + <NoSql name="MongoDbAppender"> + <MongoDb databaseName="test" collectionName="applog" server="localhost" capped="true" collectionSize="1073741824" /> + </NoSql> + </Appenders> + <Loggers> + <Root level="ALL"> + <AppenderRef ref="MongoDbAppender" /> + </Root> + </Loggers> +</Configuration> http://git-wip-us.apache.org/repos/asf/logging-log4j2/blob/ebec215e/log4j-mongodb/src/test/resources/log4j2-mongodb.xml ---------------------------------------------------------------------- diff --git a/log4j-mongodb/src/test/resources/log4j2-mongodb.xml b/log4j-mongodb/src/test/resources/log4j2-mongodb.xml new file mode 100644 index 0000000..c759054 --- /dev/null +++ b/log4j-mongodb/src/test/resources/log4j2-mongodb.xml @@ -0,0 +1,30 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + 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. + +--> +<Configuration status="error"> + <Appenders> + <NoSql name="MongoDbAppender"> + <MongoDb databaseName="test" collectionName="applog" server="localhost" /> + </NoSql> + </Appenders> + <Loggers> + <Root level="ALL"> + <AppenderRef ref="MongoDbAppender" /> + </Root> + </Loggers> +</Configuration> http://git-wip-us.apache.org/repos/asf/logging-log4j2/blob/ebec215e/log4j-nosql/pom.xml ---------------------------------------------------------------------- diff --git a/log4j-nosql/pom.xml b/log4j-nosql/pom.xml deleted file mode 100644 index 8572765..0000000 --- a/log4j-nosql/pom.xml +++ /dev/null @@ -1,194 +0,0 @@ -<?xml version="1.0" encoding="UTF-8"?> -<!-- - ~ 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. - --> - -<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> - <parent> - <groupId>org.apache.logging.log4j</groupId> - <artifactId>log4j</artifactId> - <version>2.10.0-SNAPSHOT</version> - </parent> - <modelVersion>4.0.0</modelVersion> - - <artifactId>log4j-nosql</artifactId> - <name>Apache Log4j NoSQL</name> - <description> - NoSQL appenders for Log4j. These include appenders to databases such as MongoDB and Apache CouchDB. - </description> - <properties> - <log4jParentDir>${basedir}/..</log4jParentDir> - <docLabel>NoSQL Documentation</docLabel> - <projectDir>/log4j-nosql</projectDir> - <module.name>org.apache.logging.log4j.nosql</module.name> - </properties> - - <dependencies> - <dependency> - <groupId>org.apache.logging.log4j</groupId> - <artifactId>log4j-core</artifactId> - </dependency> - <dependency> - <groupId>org.mongodb</groupId> - <artifactId>mongo-java-driver</artifactId> - <optional>true</optional> - </dependency> - <dependency> - <groupId>org.lightcouch</groupId> - <artifactId>lightcouch</artifactId> - <optional>true</optional> - </dependency> - <dependency> - <groupId>com.datastax.cassandra</groupId> - <artifactId>cassandra-driver-core</artifactId> - <optional>true</optional> - </dependency> - <!-- Test Dependencies --> - <dependency> - <groupId>junit</groupId> - <artifactId>junit</artifactId> - </dependency> - <dependency> - <groupId>org.mockito</groupId> - <artifactId>mockito-core</artifactId> - <scope>test</scope> - </dependency> - <dependency> - <groupId>org.apache.logging.log4j</groupId> - <artifactId>log4j-api</artifactId> - <type>test-jar</type> - </dependency> - <dependency> - <groupId>org.apache.logging.log4j</groupId> - <artifactId>log4j-core</artifactId> - <type>test-jar</type> - </dependency> - <dependency> - <groupId>org.apache.logging.log4j</groupId> - <artifactId>log4j-slf4j-impl</artifactId> - <scope>test</scope> - </dependency> - </dependencies> - - <build> - <plugins> - <plugin> - <groupId>org.apache.felix</groupId> - <artifactId>maven-bundle-plugin</artifactId> - <configuration> - <instructions> - <Fragment-Host>org.apache.logging.log4j.core</Fragment-Host> - <Export-Package>*</Export-Package> - </instructions> - </configuration> - </plugin> - </plugins> - </build> - <reporting> - <plugins> - <plugin> - <groupId>org.apache.maven.plugins</groupId> - <artifactId>maven-changes-plugin</artifactId> - <version>${changes.plugin.version}</version> - <reportSets> - <reportSet> - <reports> - <report>changes-report</report> - </reports> - </reportSet> - </reportSets> - <configuration> - <issueLinkTemplate>%URL%/show_bug.cgi?id=%ISSUE%</issueLinkTemplate> - <useJql>true</useJql> - </configuration> - </plugin> - <plugin> - <groupId>org.apache.maven.plugins</groupId> - <artifactId>maven-checkstyle-plugin</artifactId> - <version>${checkstyle.plugin.version}</version> - <configuration> - <!--<propertiesLocation>${vfs.parent.dir}/checkstyle.properties</propertiesLocation> --> - <configLocation>${log4jParentDir}/checkstyle.xml</configLocation> - <suppressionsLocation>${log4jParentDir}/checkstyle-suppressions.xml</suppressionsLocation> - <enableRulesSummary>false</enableRulesSummary> - <propertyExpansion>basedir=${basedir}</propertyExpansion> - <propertyExpansion>licensedir=${log4jParentDir}/checkstyle-header.txt</propertyExpansion> - </configuration> - </plugin> - <plugin> - <groupId>org.apache.maven.plugins</groupId> - <artifactId>maven-javadoc-plugin</artifactId> - <version>${javadoc.plugin.version}</version> - <configuration> - <bottom><![CDATA[<p align="center">Copyright © {inceptionYear}-{currentYear} {organizationName}. All Rights Reserved.<br /> - Apache Logging, Apache Log4j, Log4j, Apache, the Apache feather logo, the Apache Logging project logo, - and the Apache Log4j logo are trademarks of The Apache Software Foundation.</p>]]></bottom> - <!-- module link generation is completely broken in the javadoc plugin for a multi-module non-aggregating - project --> - <detectOfflineLinks>false</detectOfflineLinks> - <linksource>true</linksource> - </configuration> - <reportSets> - <reportSet> - <id>non-aggregate</id> - <reports> - <report>javadoc</report> - </reports> - </reportSet> - </reportSets> - </plugin> - <plugin> - <groupId>org.codehaus.mojo</groupId> - <artifactId>findbugs-maven-plugin</artifactId> - <version>${findbugs.plugin.version}</version> - <configuration> - <fork>true</fork> - <jvmArgs>-Duser.language=en</jvmArgs> - <threshold>Normal</threshold> - <effort>Default</effort> - <excludeFilterFile>${log4jParentDir}/findbugs-exclude-filter.xml</excludeFilterFile> - </configuration> - </plugin> - <plugin> - <groupId>org.apache.maven.plugins</groupId> - <artifactId>maven-jxr-plugin</artifactId> - <version>${jxr.plugin.version}</version> - <reportSets> - <reportSet> - <id>non-aggregate</id> - <reports> - <report>jxr</report> - </reports> - </reportSet> - <reportSet> - <id>aggregate</id> - <reports> - <report>aggregate</report> - </reports> - </reportSet> - </reportSets> - </plugin> - <plugin> - <groupId>org.apache.maven.plugins</groupId> - <artifactId>maven-pmd-plugin</artifactId> - <version>${pmd.plugin.version}</version> - <configuration> - <targetJdk>${maven.compiler.target}</targetJdk> - </configuration> - </plugin> - </plugins> - </reporting> -</project> http://git-wip-us.apache.org/repos/asf/logging-log4j2/blob/ebec215e/log4j-nosql/src/main/java/org/apache/logging/log4j/nosql/appender/AbstractNoSqlConnection.java ---------------------------------------------------------------------- diff --git a/log4j-nosql/src/main/java/org/apache/logging/log4j/nosql/appender/AbstractNoSqlConnection.java b/log4j-nosql/src/main/java/org/apache/logging/log4j/nosql/appender/AbstractNoSqlConnection.java deleted file mode 100644 index ac52eba..0000000 --- a/log4j-nosql/src/main/java/org/apache/logging/log4j/nosql/appender/AbstractNoSqlConnection.java +++ /dev/null @@ -1,48 +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.logging.log4j.nosql.appender; - -import java.util.concurrent.atomic.AtomicBoolean; - -/** - * Facilitates implementations of {@link NoSqlConnection}. - * - * @param <W> - * See {@link NoSqlConnection}. - * @param <T>See - * {@link NoSqlConnection}. - */ -public abstract class AbstractNoSqlConnection<W, T extends NoSqlObject<W>> implements NoSqlConnection<W, T> { - - private final AtomicBoolean closed = new AtomicBoolean(false); - - @Override - public void close() { - if (this.closed.compareAndSet(false, true)) { - closeImpl(); - } - } - - protected abstract void closeImpl(); - - @Override - public boolean isClosed() { - return this.closed.get(); - } - -} http://git-wip-us.apache.org/repos/asf/logging-log4j2/blob/ebec215e/log4j-nosql/src/main/java/org/apache/logging/log4j/nosql/appender/DefaultNoSqlObject.java ---------------------------------------------------------------------- diff --git a/log4j-nosql/src/main/java/org/apache/logging/log4j/nosql/appender/DefaultNoSqlObject.java b/log4j-nosql/src/main/java/org/apache/logging/log4j/nosql/appender/DefaultNoSqlObject.java deleted file mode 100644 index 4437e55..0000000 --- a/log4j-nosql/src/main/java/org/apache/logging/log4j/nosql/appender/DefaultNoSqlObject.java +++ /dev/null @@ -1,66 +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.logging.log4j.nosql.appender; - -import java.util.ArrayList; -import java.util.Arrays; -import java.util.HashMap; -import java.util.List; -import java.util.Map; - -/** - * Default implementation of {@link org.apache.logging.log4j.nosql.appender.NoSqlObject}. Most NoSQL Java APIs tend - * to re-use the Map interface for storage and retrieval of the underlying JSON documents. Therefore, this - * implementation is provided for convenience. - */ -public class DefaultNoSqlObject implements NoSqlObject<Map<String, Object>> { - - private final Map<String, Object> map; - - public DefaultNoSqlObject() { - this.map = new HashMap<>(); - } - - @Override - public void set(final String field, final Object value) { - this.map.put(field, value); - } - - @Override - public void set(final String field, final NoSqlObject<Map<String, Object>> value) { - this.map.put(field, value.unwrap()); - } - - @Override - public void set(final String field, final Object[] values) { - this.map.put(field, Arrays.asList(values)); - } - - @Override - public void set(final String field, final NoSqlObject<Map<String, Object>>[] values) { - final List<Map<String, Object>> list = new ArrayList<>(values.length); - for (final NoSqlObject<Map<String, Object>> value : values) { - list.add(value.unwrap()); - } - this.map.put(field, list); - } - - @Override - public Map<String, Object> unwrap() { - return this.map; - } -} http://git-wip-us.apache.org/repos/asf/logging-log4j2/blob/ebec215e/log4j-nosql/src/main/java/org/apache/logging/log4j/nosql/appender/NoSqlAppender.java ---------------------------------------------------------------------- diff --git a/log4j-nosql/src/main/java/org/apache/logging/log4j/nosql/appender/NoSqlAppender.java b/log4j-nosql/src/main/java/org/apache/logging/log4j/nosql/appender/NoSqlAppender.java deleted file mode 100644 index 55ecc61..0000000 --- a/log4j-nosql/src/main/java/org/apache/logging/log4j/nosql/appender/NoSqlAppender.java +++ /dev/null @@ -1,106 +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.logging.log4j.nosql.appender; - -import org.apache.logging.log4j.core.Appender; -import org.apache.logging.log4j.core.Filter; -import org.apache.logging.log4j.core.appender.AbstractAppender; -import org.apache.logging.log4j.core.appender.db.AbstractDatabaseAppender; -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.core.util.Booleans; - -/** - * This Appender writes logging events to a NoSQL database using a configured NoSQL provider. It requires - * implementations of {@link NoSqlObject}, {@link NoSqlConnection}, and {@link NoSqlProvider} to "know" how to write - * events to the chosen NoSQL database. - * - * <p> - * Two provider implementations are provided: - * </p> - * <ul> - * <li> - * MongoDB (org.mongodb:mongo-java-driver:3.0.4 or newer must be on the classpath)</li> - * <li> - * Apache CouchDB (org.lightcouch:lightcouch:0.0.6 or newer must be on the classpath).</li> - * </ul> - * <p> - * For examples on how to write your own NoSQL provider, see the simple source code for the MongoDB and CouchDB - * providers. - * </p> - * - * @see NoSqlObject - * @see NoSqlConnection - * @see NoSqlProvider - */ -@Plugin(name = "NoSql", category = "Core", elementType = Appender.ELEMENT_TYPE, printObject = true) -public final class NoSqlAppender extends AbstractDatabaseAppender<NoSqlDatabaseManager<?>> { - private final String description; - - private NoSqlAppender(final String name, final Filter filter, final boolean ignoreExceptions, - final NoSqlDatabaseManager<?> manager) { - super(name, filter, ignoreExceptions, manager); - this.description = this.getName() + "{ manager=" + this.getManager() + " }"; - } - - @Override - public String toString() { - return this.description; - } - - /** - * Factory method for creating a NoSQL appender within the plugin manager. - * - * @param name The name of the appender. - * @param ignore If {@code "true"} (default) exceptions encountered when appending events are logged; otherwise - * they are propagated to the caller. - * @param filter The filter, if any, to use. - * @param bufferSize If an integer greater than 0, this causes the appender to buffer log events and flush whenever - * the buffer reaches this size. - * @param provider The NoSQL provider that provides connections to the chosen NoSQL database. - * @return a new NoSQL appender. - */ - @PluginFactory - public static NoSqlAppender createAppender( - @PluginAttribute("name") final String name, - @PluginAttribute("ignoreExceptions") final String ignore, - @PluginElement("Filter") final Filter filter, - @PluginAttribute("bufferSize") final String bufferSize, - @PluginElement("NoSqlProvider") final NoSqlProvider<?> provider) { - if (provider == null) { - LOGGER.error("NoSQL provider not specified for appender [{}].", name); - return null; - } - - final int bufferSizeInt = AbstractAppender.parseInt(bufferSize, 0); - final boolean ignoreExceptions = Booleans.parseBoolean(ignore, true); - - final String managerName = "noSqlManager{ description=" + name + ", bufferSize=" + bufferSizeInt - + ", provider=" + provider + " }"; - - final NoSqlDatabaseManager<?> manager = NoSqlDatabaseManager.getNoSqlDatabaseManager( - managerName, bufferSizeInt, provider - ); - if (manager == null) { - return null; - } - - return new NoSqlAppender(name, filter, ignoreExceptions, manager); - } -} http://git-wip-us.apache.org/repos/asf/logging-log4j2/blob/ebec215e/log4j-nosql/src/main/java/org/apache/logging/log4j/nosql/appender/NoSqlConnection.java ---------------------------------------------------------------------- diff --git a/log4j-nosql/src/main/java/org/apache/logging/log4j/nosql/appender/NoSqlConnection.java b/log4j-nosql/src/main/java/org/apache/logging/log4j/nosql/appender/NoSqlConnection.java deleted file mode 100644 index 8df6eed..0000000 --- a/log4j-nosql/src/main/java/org/apache/logging/log4j/nosql/appender/NoSqlConnection.java +++ /dev/null @@ -1,76 +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.logging.log4j.nosql.appender; - -import java.io.Closeable; - -/** - * Represents a connection to the NoSQL database. Serves as a factory for new (empty) objects and an endpoint for - * inserted objects. - * - * @param <T> Specifies which implementation of {@link NoSqlObject} this connection provides. - * @param <W> Specifies which type of database object is wrapped by the {@link NoSqlObject} implementation provided. - */ -public interface NoSqlConnection<W, T extends NoSqlObject<W>> extends Closeable { - /** - * Instantiates and returns a {@link NoSqlObject} instance whose properties can be configured before ultimate - * insertion via {@link #insertObject(NoSqlObject)}. - * - * @return a new object. - * @see NoSqlObject - */ - T createObject(); - - /** - * Creates an array of the specified length typed to match the {@link NoSqlObject} implementation appropriate for - * this provider. - * - * @param length the length of the array to create. - * @return a new array. - * @see NoSqlObject - */ - T[] createList(int length); - - /** - * Inserts the given object into the underlying NoSQL database. - * - * @param object The object to insert. - */ - void insertObject(NoSqlObject<W> object); - - /** - * Closes the underlying connection. This method call should be idempotent. Only the first call should have any - * effect; all further calls should be ignored. It's possible the underlying connection is stateless (such as an - * HTTP web service), in which case this method would be a no-op. This method should also commit any open - * transactions, if applicable and if not already committed. - * <p> - * If this connection is part of a connection pool, executing this method should commit the transaction and return - * the connection to the pool, but it should not actually close the underlying connection. - * </p> - */ - @Override - void close(); - - /** - * Indicates whether the underlying connection is closed. If the underlying connection is stateless (such as an - * HTTP web service), this method would likely always return true. Essentially, this method should only return - * {@code true} if a call to {@link #insertObject(NoSqlObject)} <b>will</b> fail due to the state of this object. - * - * @return {@code true} if this object is considered closed. - */ - boolean isClosed(); -} http://git-wip-us.apache.org/repos/asf/logging-log4j2/blob/ebec215e/log4j-nosql/src/main/java/org/apache/logging/log4j/nosql/appender/NoSqlDatabaseManager.java ---------------------------------------------------------------------- diff --git a/log4j-nosql/src/main/java/org/apache/logging/log4j/nosql/appender/NoSqlDatabaseManager.java b/log4j-nosql/src/main/java/org/apache/logging/log4j/nosql/appender/NoSqlDatabaseManager.java deleted file mode 100644 index e1526fc..0000000 --- a/log4j-nosql/src/main/java/org/apache/logging/log4j/nosql/appender/NoSqlDatabaseManager.java +++ /dev/null @@ -1,224 +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.logging.log4j.nosql.appender; - -import org.apache.logging.log4j.Marker; -import org.apache.logging.log4j.ThreadContext; -import org.apache.logging.log4j.core.LogEvent; -import org.apache.logging.log4j.core.appender.AppenderLoggingException; -import org.apache.logging.log4j.core.appender.ManagerFactory; -import org.apache.logging.log4j.core.appender.db.AbstractDatabaseManager; -import org.apache.logging.log4j.core.util.Closer; -import org.apache.logging.log4j.util.BiConsumer; -import org.apache.logging.log4j.util.ReadOnlyStringMap; - -/** - * An {@link AbstractDatabaseManager} implementation for all NoSQL databases. - * - * @param <W> A type parameter for reassuring the compiler that all operations are using the same {@link NoSqlObject}. - */ -public final class NoSqlDatabaseManager<W> extends AbstractDatabaseManager { - private static final NoSQLDatabaseManagerFactory FACTORY = new NoSQLDatabaseManagerFactory(); - - private final NoSqlProvider<NoSqlConnection<W, ? extends NoSqlObject<W>>> provider; - - private NoSqlConnection<W, ? extends NoSqlObject<W>> connection; - - private NoSqlDatabaseManager(final String name, final int bufferSize, - final NoSqlProvider<NoSqlConnection<W, ? extends NoSqlObject<W>>> provider) { - super(name, bufferSize); - this.provider = provider; - } - - @Override - protected void startupInternal() { - // nothing to see here - } - - @Override - protected boolean shutdownInternal() { - // NoSQL doesn't use transactions, so all we need to do here is simply close the client - return Closer.closeSilently(this.connection); - } - - @Override - protected void connectAndStart() { - try { - this.connection = this.provider.getConnection(); - } catch (final Exception e) { - throw new AppenderLoggingException("Failed to get connection from NoSQL connection provider.", e); - } - } - - @Override - protected void writeInternal(final LogEvent event) { - if (!this.isRunning() || this.connection == null || this.connection.isClosed()) { - throw new AppenderLoggingException( - "Cannot write logging event; NoSQL manager not connected to the database."); - } - - final NoSqlObject<W> entity = this.connection.createObject(); - entity.set("level", event.getLevel()); - entity.set("loggerName", event.getLoggerName()); - entity.set("message", event.getMessage() == null ? null : event.getMessage().getFormattedMessage()); - - final StackTraceElement source = event.getSource(); - if (source == null) { - entity.set("source", (Object) null); - } else { - entity.set("source", this.convertStackTraceElement(source)); - } - - final Marker marker = event.getMarker(); - if (marker == null) { - entity.set("marker", (Object) null); - } else { - entity.set("marker", buildMarkerEntity(marker)); - } - - entity.set("threadId", event.getThreadId()); - entity.set("threadName", event.getThreadName()); - entity.set("threadPriority", event.getThreadPriority()); - entity.set("millis", event.getTimeMillis()); - entity.set("date", new java.util.Date(event.getTimeMillis())); - - @SuppressWarnings("ThrowableResultOfMethodCallIgnored") - Throwable thrown = event.getThrown(); - if (thrown == null) { - entity.set("thrown", (Object) null); - } else { - final NoSqlObject<W> originalExceptionEntity = this.connection.createObject(); - NoSqlObject<W> exceptionEntity = originalExceptionEntity; - exceptionEntity.set("type", thrown.getClass().getName()); - exceptionEntity.set("message", thrown.getMessage()); - exceptionEntity.set("stackTrace", this.convertStackTrace(thrown.getStackTrace())); - while (thrown.getCause() != null) { - thrown = thrown.getCause(); - final NoSqlObject<W> causingExceptionEntity = this.connection.createObject(); - causingExceptionEntity.set("type", thrown.getClass().getName()); - causingExceptionEntity.set("message", thrown.getMessage()); - causingExceptionEntity.set("stackTrace", this.convertStackTrace(thrown.getStackTrace())); - exceptionEntity.set("cause", causingExceptionEntity); - exceptionEntity = causingExceptionEntity; - } - - entity.set("thrown", originalExceptionEntity); - } - - final ReadOnlyStringMap contextMap = event.getContextData(); - if (contextMap == null) { - entity.set("contextMap", (Object) null); - } else { - final NoSqlObject<W> contextMapEntity = this.connection.createObject(); - contextMap.forEach(new BiConsumer<String, String>() { - @Override - public void accept(final String key, final String val) { - contextMapEntity.set(key, val); - } - }); - entity.set("contextMap", contextMapEntity); - } - - final ThreadContext.ContextStack contextStack = event.getContextStack(); - if (contextStack == null) { - entity.set("contextStack", (Object) null); - } else { - entity.set("contextStack", contextStack.asList().toArray()); - } - - this.connection.insertObject(entity); - } - - private NoSqlObject<W> buildMarkerEntity(final Marker marker) { - final NoSqlObject<W> entity = this.connection.createObject(); - entity.set("name", marker.getName()); - - final Marker[] parents = marker.getParents(); - if (parents != null) { - @SuppressWarnings("unchecked") - final NoSqlObject<W>[] parentEntities = new NoSqlObject[parents.length]; - for (int i = 0; i < parents.length; i++) { - parentEntities[i] = buildMarkerEntity(parents[i]); - } - entity.set("parents", parentEntities); - } - return entity; - } - - @Override - protected boolean commitAndClose() { - // all NoSQL drivers auto-commit (since NoSQL doesn't generally use the concept of transactions). - // also, all our NoSQL drivers use internal connection pooling and provide clients, not connections. - // thus, we should not be closing the client until shutdown as NoSQL is very different from SQL. - // see LOG4J2-591 and LOG4J2-676 - return true; - } - - private NoSqlObject<W>[] convertStackTrace(final StackTraceElement[] stackTrace) { - final NoSqlObject<W>[] stackTraceEntities = this.connection.createList(stackTrace.length); - for (int i = 0; i < stackTrace.length; i++) { - stackTraceEntities[i] = this.convertStackTraceElement(stackTrace[i]); - } - return stackTraceEntities; - } - - private NoSqlObject<W> convertStackTraceElement(final StackTraceElement element) { - final NoSqlObject<W> elementEntity = this.connection.createObject(); - elementEntity.set("className", element.getClassName()); - elementEntity.set("methodName", element.getMethodName()); - elementEntity.set("fileName", element.getFileName()); - elementEntity.set("lineNumber", element.getLineNumber()); - return elementEntity; - } - - /** - * Creates a NoSQL manager for use within the {@link NoSqlAppender}, or returns a suitable one if it already exists. - * - * @param name The name of the manager, which should include connection details and hashed passwords where possible. - * @param bufferSize The size of the log event buffer. - * @param provider A provider instance which will be used to obtain connections to the chosen NoSQL database. - * @return a new or existing NoSQL manager as applicable. - */ - public static NoSqlDatabaseManager<?> getNoSqlDatabaseManager(final String name, final int bufferSize, - final NoSqlProvider<?> provider) { - return AbstractDatabaseManager.getManager(name, new FactoryData(bufferSize, provider), FACTORY); - } - - /** - * Encapsulates data that {@link NoSQLDatabaseManagerFactory} uses to create managers. - */ - private static final class FactoryData extends AbstractDatabaseManager.AbstractFactoryData { - private final NoSqlProvider<?> provider; - - protected FactoryData(final int bufferSize, final NoSqlProvider<?> provider) { - super(bufferSize); - this.provider = provider; - } - } - - /** - * Creates managers. - */ - private static final class NoSQLDatabaseManagerFactory implements - ManagerFactory<NoSqlDatabaseManager<?>, FactoryData> { - @Override - @SuppressWarnings("unchecked") - public NoSqlDatabaseManager<?> createManager(final String name, final FactoryData data) { - return new NoSqlDatabaseManager(name, data.getBufferSize(), data.provider); - } - } -}