You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@logging.apache.org by mi...@apache.org on 2017/10/19 19:47:40 UTC
[1/2] logging-log4j2 git commit: LOG4J2-2076 Rename packages
Repository: logging-log4j2
Updated Branches:
refs/heads/LOG4J2-2076 98a66a145 -> 44db87d0e
http://git-wip-us.apache.org/repos/asf/logging-log4j2/blob/44db87d0/log4j-couchdb/src/main/java/org/apache/logging/log4j/nosql/appender/couchdb/CouchDbProvider.java
----------------------------------------------------------------------
diff --git a/log4j-couchdb/src/main/java/org/apache/logging/log4j/nosql/appender/couchdb/CouchDbProvider.java b/log4j-couchdb/src/main/java/org/apache/logging/log4j/nosql/appender/couchdb/CouchDbProvider.java
deleted file mode 100644
index cdae592..0000000
--- a/log4j-couchdb/src/main/java/org/apache/logging/log4j/nosql/appender/couchdb/CouchDbProvider.java
+++ /dev/null
@@ -1,161 +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.couchdb;
-
-import java.lang.reflect.Method;
-
-import org.apache.logging.log4j.Logger;
-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.PluginFactory;
-import org.apache.logging.log4j.core.config.plugins.convert.TypeConverters;
-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.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 org.lightcouch.CouchDbClient;
-import org.lightcouch.CouchDbProperties;
-
-/**
- * The Apache CouchDB implementation of {@link NoSqlProvider}.
- */
-@Plugin(name = "CouchDB", category = "Core", printObject = true)
-public final class CouchDbProvider implements NoSqlProvider<CouchDbConnection> {
- private static final int HTTP = 80;
- private static final int HTTPS = 443;
- private static final Logger LOGGER = StatusLogger.getLogger();
-
- private final CouchDbClient client;
- private final String description;
-
- private CouchDbProvider(final CouchDbClient client, final String description) {
- this.client = client;
- this.description = "couchDb{ " + description + " }";
- }
-
- @Override
- public CouchDbConnection getConnection() {
- return new CouchDbConnection(this.client);
- }
-
- @Override
- public String toString() {
- return this.description;
- }
-
- /**
- * Factory method for creating an Apache CouchDB provider within the plugin manager.
- *
- * @param databaseName The name of the database to which log event documents will be written.
- * @param protocol Either "http" or "https," defaults to "http" and mutually exclusive with
- * {@code factoryClassName&factoryMethodName!=null}.
- * @param server The host name of the CouchDB server, defaults to localhost and mutually exclusive with
- * {@code factoryClassName&factoryMethodName!=null}.
- * @param port The port that CouchDB is listening on, defaults to 80 if {@code protocol} is "http" and 443 if
- * {@code protocol} is "https," and mutually exclusive with
- * {@code factoryClassName&factoryMethodName!=null}.
- * @param username The username to authenticate against the MongoDB server with, mutually exclusive with
- * {@code factoryClassName&factoryMethodName!=null}.
- * @param password The password to authenticate against the MongoDB server with, mutually exclusive with
- * {@code factoryClassName&factoryMethodName!=null}.
- * @param factoryClassName A fully qualified class name containing a static factory method capable of returning a
- * {@link CouchDbClient} or {@link CouchDbProperties}.
- * @param factoryMethodName The name of the public static factory method belonging to the aforementioned factory
- * class.
- * @return a new Apache CouchDB provider.
- */
- @PluginFactory
- public static CouchDbProvider createNoSqlProvider(
- @PluginAttribute("databaseName") final String databaseName,
- @PluginAttribute("protocol") String protocol,
- @PluginAttribute(value = "server", defaultString = "localhost") @ValidHost final String server,
- @PluginAttribute(value = "port", defaultString = "0") @ValidPort final String port,
- @PluginAttribute("username") final String username,
- @PluginAttribute(value = "password", sensitive = true) final String password,
- @PluginAttribute("factoryClassName") final String factoryClassName,
- @PluginAttribute("factoryMethodName") final String factoryMethodName) {
- CouchDbClient client;
- 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 CouchDbClient) {
- client = (CouchDbClient) object;
- description = "uri=" + client.getDBUri();
- } else if (object instanceof CouchDbProperties) {
- final CouchDbProperties properties = (CouchDbProperties) object;
- client = new CouchDbClient(properties);
- description = "uri=" + client.getDBUri() + ", username=" + properties.getUsername()
- + ", passwordHash=" + NameUtil.md5(password + CouchDbProvider.class.getName())
- + ", maxConnections=" + properties.getMaxConnections() + ", connectionTimeout="
- + properties.getConnectionTimeout() + ", socketTimeout=" + properties.getSocketTimeout();
- } 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;
- }
- } 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)) {
- if (protocol != null && protocol.length() > 0) {
- protocol = protocol.toLowerCase();
- if (!protocol.equals("http") && !protocol.equals("https")) {
- LOGGER.error("Only protocols [http] and [https] are supported, [{}] specified.", protocol);
- return null;
- }
- } else {
- protocol = "http";
- LOGGER.warn("No protocol specified, using default port [http].");
- }
-
- final int portInt = TypeConverters.convert(port, int.class, protocol.equals("https") ? HTTPS : HTTP);
-
- if (Strings.isEmpty(username) || Strings.isEmpty(password)) {
- LOGGER.error("You must provide a username and password for the CouchDB provider.");
- return null;
- }
-
- client = new CouchDbClient(databaseName, false, protocol, server, portInt, username, password);
- description = "uri=" + client.getDBUri() + ", username=" + username + ", passwordHash="
- + NameUtil.md5(password + CouchDbProvider.class.getName());
- } else {
- LOGGER.error("No factory method was provided so the database name is required.");
- return null;
- }
-
- return new CouchDbProvider(client, description);
- }
-}
http://git-wip-us.apache.org/repos/asf/logging-log4j2/blob/44db87d0/log4j-couchdb/src/main/java/org/apache/logging/log4j/nosql/appender/couchdb/package-info.java
----------------------------------------------------------------------
diff --git a/log4j-couchdb/src/main/java/org/apache/logging/log4j/nosql/appender/couchdb/package-info.java b/log4j-couchdb/src/main/java/org/apache/logging/log4j/nosql/appender/couchdb/package-info.java
deleted file mode 100644
index b783f87..0000000
--- a/log4j-couchdb/src/main/java/org/apache/logging/log4j/nosql/appender/couchdb/package-info.java
+++ /dev/null
@@ -1,20 +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.
- */
-/**
- * The classes in this package contain the Apache CouchDB provider for the NoSQL Appender.
- */
-package org.apache.logging.log4j.nosql.appender.couchdb;
http://git-wip-us.apache.org/repos/asf/logging-log4j2/blob/44db87d0/log4j-mongodb/src/main/java/org/apache/logging/log4j/mongodb/MongoDbConnection.java
----------------------------------------------------------------------
diff --git a/log4j-mongodb/src/main/java/org/apache/logging/log4j/mongodb/MongoDbConnection.java b/log4j-mongodb/src/main/java/org/apache/logging/log4j/mongodb/MongoDbConnection.java
new file mode 100644
index 0000000..4ad0671
--- /dev/null
+++ b/log4j-mongodb/src/main/java/org/apache/logging/log4j/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.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/44db87d0/log4j-mongodb/src/main/java/org/apache/logging/log4j/mongodb/MongoDbObject.java
----------------------------------------------------------------------
diff --git a/log4j-mongodb/src/main/java/org/apache/logging/log4j/mongodb/MongoDbObject.java b/log4j-mongodb/src/main/java/org/apache/logging/log4j/mongodb/MongoDbObject.java
new file mode 100644
index 0000000..541d941
--- /dev/null
+++ b/log4j-mongodb/src/main/java/org/apache/logging/log4j/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.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/44db87d0/log4j-mongodb/src/main/java/org/apache/logging/log4j/mongodb/MongoDbProvider.java
----------------------------------------------------------------------
diff --git a/log4j-mongodb/src/main/java/org/apache/logging/log4j/mongodb/MongoDbProvider.java b/log4j-mongodb/src/main/java/org/apache/logging/log4j/mongodb/MongoDbProvider.java
new file mode 100644
index 0000000..f7077b3
--- /dev/null
+++ b/log4j-mongodb/src/main/java/org/apache/logging/log4j/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.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/44db87d0/log4j-mongodb/src/main/java/org/apache/logging/log4j/mongodb/package-info.java
----------------------------------------------------------------------
diff --git a/log4j-mongodb/src/main/java/org/apache/logging/log4j/mongodb/package-info.java b/log4j-mongodb/src/main/java/org/apache/logging/log4j/mongodb/package-info.java
new file mode 100644
index 0000000..f944511
--- /dev/null
+++ b/log4j-mongodb/src/main/java/org/apache/logging/log4j/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.mongodb;
http://git-wip-us.apache.org/repos/asf/logging-log4j2/blob/44db87d0/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
deleted file mode 100644
index 66e205d..0000000
--- a/log4j-mongodb/src/main/java/org/apache/logging/log4j/nosql/appender/mongodb/MongoDbConnection.java
+++ /dev/null
@@ -1,96 +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.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/44db87d0/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
deleted file mode 100644
index 8eb6e46..0000000
--- a/log4j-mongodb/src/main/java/org/apache/logging/log4j/nosql/appender/mongodb/MongoDbObject.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.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/44db87d0/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
deleted file mode 100644
index 5167c3e..0000000
--- a/log4j-mongodb/src/main/java/org/apache/logging/log4j/nosql/appender/mongodb/MongoDbProvider.java
+++ /dev/null
@@ -1,351 +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.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/44db87d0/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
deleted file mode 100644
index 54a2878..0000000
--- a/log4j-mongodb/src/main/java/org/apache/logging/log4j/nosql/appender/mongodb/package-info.java
+++ /dev/null
@@ -1,20 +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.
- */
-/**
- * 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/44db87d0/log4j-mongodb/src/test/java/org/apache/logging/log4j/mongodb/MongoDbAuthTest.java
----------------------------------------------------------------------
diff --git a/log4j-mongodb/src/test/java/org/apache/logging/log4j/mongodb/MongoDbAuthTest.java b/log4j-mongodb/src/test/java/org/apache/logging/log4j/mongodb/MongoDbAuthTest.java
new file mode 100644
index 0000000..142a470
--- /dev/null
+++ b/log4j-mongodb/src/test/java/org/apache/logging/log4j/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.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/44db87d0/log4j-mongodb/src/test/java/org/apache/logging/log4j/mongodb/MongoDbCappedTest.java
----------------------------------------------------------------------
diff --git a/log4j-mongodb/src/test/java/org/apache/logging/log4j/mongodb/MongoDbCappedTest.java b/log4j-mongodb/src/test/java/org/apache/logging/log4j/mongodb/MongoDbCappedTest.java
new file mode 100644
index 0000000..d5aa5a9
--- /dev/null
+++ b/log4j-mongodb/src/test/java/org/apache/logging/log4j/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.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/44db87d0/log4j-mongodb/src/test/java/org/apache/logging/log4j/mongodb/MongoDbTest.java
----------------------------------------------------------------------
diff --git a/log4j-mongodb/src/test/java/org/apache/logging/log4j/mongodb/MongoDbTest.java b/log4j-mongodb/src/test/java/org/apache/logging/log4j/mongodb/MongoDbTest.java
new file mode 100644
index 0000000..eab3c1c
--- /dev/null
+++ b/log4j-mongodb/src/test/java/org/apache/logging/log4j/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.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/44db87d0/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
deleted file mode 100644
index 3641a75..0000000
--- a/log4j-mongodb/src/test/java/org/apache/logging/log4j/nosql/appender/mongodb/MongoDbAuthTest.java
+++ /dev/null
@@ -1,40 +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.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/44db87d0/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
deleted file mode 100644
index a001b4b..0000000
--- a/log4j-mongodb/src/test/java/org/apache/logging/log4j/nosql/appender/mongodb/MongoDbCappedTest.java
+++ /dev/null
@@ -1,40 +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.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/44db87d0/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
deleted file mode 100644
index 59ef951..0000000
--- a/log4j-mongodb/src/test/java/org/apache/logging/log4j/nosql/appender/mongodb/MongoDbTest.java
+++ /dev/null
@@ -1,40 +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.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/44db87d0/src/site/xdoc/manual/appenders.xml
----------------------------------------------------------------------
diff --git a/src/site/xdoc/manual/appenders.xml b/src/site/xdoc/manual/appenders.xml
index ae86b54..bdfeddd 100644
--- a/src/site/xdoc/manual/appenders.xml
+++ b/src/site/xdoc/manual/appenders.xml
@@ -380,7 +380,7 @@
</Cassandra>
</Appenders>
<Loggers>
- <Logger name="org.apache.logging.log4j.nosql.appender.cassandra" level="DEBUG">
+ <Logger name="org.apache.logging.log4j.cassandra" level="DEBUG">
<AppenderRef ref="Cassandra"/>
</Logger>
<Root level="ERROR"/>
[2/2] logging-log4j2 git commit: LOG4J2-2076 Rename packages
Posted by mi...@apache.org.
LOG4J2-2076 Rename packages
Project: http://git-wip-us.apache.org/repos/asf/logging-log4j2/repo
Commit: http://git-wip-us.apache.org/repos/asf/logging-log4j2/commit/44db87d0
Tree: http://git-wip-us.apache.org/repos/asf/logging-log4j2/tree/44db87d0
Diff: http://git-wip-us.apache.org/repos/asf/logging-log4j2/diff/44db87d0
Branch: refs/heads/LOG4J2-2076
Commit: 44db87d0e921bac3b207f575889618ced5288e5f
Parents: 98a66a1
Author: Mikael Ståldal <mi...@staldal.nu>
Authored: Thu Oct 19 21:47:31 2017 +0200
Committer: Mikael Ståldal <mi...@staldal.nu>
Committed: Thu Oct 19 21:47:31 2017 +0200
----------------------------------------------------------------------
.../log4j/cassandra/CassandraAppender.java | 185 ++++++++++
.../log4j/cassandra/CassandraManager.java | 218 ++++++++++++
.../cassandra/ClockTimestampGenerator.java | 34 ++
.../logging/log4j/cassandra/package-info.java | 23 ++
.../appender/cassandra/CassandraAppender.java | 185 ----------
.../appender/cassandra/CassandraManager.java | 218 ------------
.../cassandra/ClockTimestampGenerator.java | 34 --
.../nosql/appender/cassandra/package-info.java | 23 --
.../log4j/cassandra/CassandraAppenderIT.java | 96 +++++
.../logging/log4j/cassandra/CassandraRule.java | 141 ++++++++
.../appender/cassandra/CassandraAppenderIT.java | 96 -----
.../nosql/appender/cassandra/CassandraRule.java | 141 --------
.../test/resources/CassandraAppenderTest.xml | 2 +-
.../log4j/couchdb/CouchDbConnection.java | 69 ++++
.../logging/log4j/couchdb/CouchDbProvider.java | 161 +++++++++
.../logging/log4j/couchdb/package-info.java | 20 ++
.../appender/couchdb/CouchDbConnection.java | 69 ----
.../nosql/appender/couchdb/CouchDbProvider.java | 161 ---------
.../nosql/appender/couchdb/package-info.java | 20 --
.../log4j/mongodb/MongoDbConnection.java | 96 +++++
.../logging/log4j/mongodb/MongoDbObject.java | 66 ++++
.../logging/log4j/mongodb/MongoDbProvider.java | 351 +++++++++++++++++++
.../logging/log4j/mongodb/package-info.java | 20 ++
.../appender/mongodb/MongoDbConnection.java | 96 -----
.../nosql/appender/mongodb/MongoDbObject.java | 66 ----
.../nosql/appender/mongodb/MongoDbProvider.java | 351 -------------------
.../nosql/appender/mongodb/package-info.java | 20 --
.../logging/log4j/mongodb/MongoDbAuthTest.java | 40 +++
.../log4j/mongodb/MongoDbCappedTest.java | 40 +++
.../logging/log4j/mongodb/MongoDbTest.java | 40 +++
.../nosql/appender/mongodb/MongoDbAuthTest.java | 40 ---
.../appender/mongodb/MongoDbCappedTest.java | 40 ---
.../nosql/appender/mongodb/MongoDbTest.java | 40 ---
src/site/xdoc/manual/appenders.xml | 2 +-
34 files changed, 1602 insertions(+), 1602 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/logging-log4j2/blob/44db87d0/log4j-cassandra/src/main/java/org/apache/logging/log4j/cassandra/CassandraAppender.java
----------------------------------------------------------------------
diff --git a/log4j-cassandra/src/main/java/org/apache/logging/log4j/cassandra/CassandraAppender.java b/log4j-cassandra/src/main/java/org/apache/logging/log4j/cassandra/CassandraAppender.java
new file mode 100644
index 0000000..7a9ade9
--- /dev/null
+++ b/log4j-cassandra/src/main/java/org/apache/logging/log4j/cassandra/CassandraAppender.java
@@ -0,0 +1,185 @@
+/*
+ * 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.cassandra;
+
+import com.datastax.driver.core.BatchStatement;
+import org.apache.logging.log4j.core.Core;
+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.appender.db.ColumnMapping;
+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.PluginElement;
+import org.apache.logging.log4j.core.config.plugins.validation.constraints.Required;
+import org.apache.logging.log4j.core.net.SocketAddress;
+import org.apache.logging.log4j.core.util.Clock;
+
+/**
+ * Appender plugin that uses a Cassandra database.
+ *
+ * @see SocketAddress
+ * @see ColumnMapping
+ */
+@Plugin(name = "Cassandra", category = Core.CATEGORY_NAME, elementType = CassandraAppender.ELEMENT_TYPE, printObject = true)
+public class CassandraAppender extends AbstractDatabaseAppender<CassandraManager> {
+
+ private CassandraAppender(final String name, final Filter filter, final boolean ignoreExceptions,
+ final CassandraManager manager) {
+ super(name, filter, ignoreExceptions, manager);
+ }
+
+ @PluginBuilderFactory
+ public static <B extends Builder<B>> B newBuilder() {
+ return new Builder<B>().asBuilder();
+ }
+
+ public static class Builder<B extends Builder<B>> extends AbstractAppender.Builder<B>
+ implements org.apache.logging.log4j.core.util.Builder<CassandraAppender> {
+
+ /**
+ * List of Cassandra node contact points. Addresses without a port (or port set to 0) will use the default
+ * Cassandra port (9042).
+ */
+ @PluginElement("ContactPoints")
+ @Required(message = "No Cassandra servers provided")
+ private SocketAddress[] contactPoints = new SocketAddress[]{SocketAddress.getLoopback()};
+
+ /**
+ * List of column mappings to convert a LogEvent into a database row.
+ */
+ @PluginElement("Columns")
+ @Required(message = "No Cassandra columns provided")
+ private ColumnMapping[] columns;
+
+ @PluginBuilderAttribute
+ private boolean useTls;
+
+ @PluginBuilderAttribute
+ @Required(message = "No cluster name provided")
+ private String clusterName;
+
+ @PluginBuilderAttribute
+ @Required(message = "No keyspace provided")
+ private String keyspace;
+
+ @PluginBuilderAttribute
+ @Required(message = "No table name provided")
+ private String table;
+
+ @PluginBuilderAttribute
+ private String username;
+
+ @PluginBuilderAttribute(sensitive = true)
+ private String password;
+
+ /**
+ * Override the default TimestampGenerator with one based on the configured {@link Clock}.
+ */
+ @PluginBuilderAttribute
+ private boolean useClockForTimestampGenerator;
+
+ /**
+ * Number of LogEvents to buffer before writing. Can be used with or without batch statements.
+ */
+ @PluginBuilderAttribute
+ private int bufferSize;
+
+ /**
+ * Whether or not to use batch statements when inserting records.
+ */
+ @PluginBuilderAttribute
+ private boolean batched;
+
+ /**
+ * If batch statements are enabled, use this type of batch statement.
+ */
+ @PluginBuilderAttribute
+ private BatchStatement.Type batchType = BatchStatement.Type.LOGGED;
+
+ public B setContactPoints(final SocketAddress... contactPoints) {
+ this.contactPoints = contactPoints;
+ return asBuilder();
+ }
+
+ public B setColumns(final ColumnMapping... columns) {
+ this.columns = columns;
+ return asBuilder();
+ }
+
+ public B setUseTls(final boolean useTls) {
+ this.useTls = useTls;
+ return asBuilder();
+ }
+
+ public B setClusterName(final String clusterName) {
+ this.clusterName = clusterName;
+ return asBuilder();
+ }
+
+ public B setKeyspace(final String keyspace) {
+ this.keyspace = keyspace;
+ return asBuilder();
+ }
+
+ public B setTable(final String table) {
+ this.table = table;
+ 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 setUseClockForTimestampGenerator(final boolean useClockForTimestampGenerator) {
+ this.useClockForTimestampGenerator = useClockForTimestampGenerator;
+ return asBuilder();
+ }
+
+ public B setBufferSize(final int bufferSize) {
+ this.bufferSize = bufferSize;
+ return asBuilder();
+ }
+
+ public B setBatched(final boolean batched) {
+ this.batched = batched;
+ return asBuilder();
+ }
+
+ public B setBatchType(final BatchStatement.Type batchType) {
+ this.batchType = batchType;
+ return asBuilder();
+ }
+
+ @Override
+ public CassandraAppender build() {
+ final CassandraManager manager = CassandraManager.getManager(getName(), contactPoints, columns, useTls,
+ clusterName, keyspace, table, username, password, useClockForTimestampGenerator, bufferSize, batched,
+ batchType);
+ return new CassandraAppender(getName(), getFilter(), isIgnoreExceptions(), manager);
+ }
+
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/logging-log4j2/blob/44db87d0/log4j-cassandra/src/main/java/org/apache/logging/log4j/cassandra/CassandraManager.java
----------------------------------------------------------------------
diff --git a/log4j-cassandra/src/main/java/org/apache/logging/log4j/cassandra/CassandraManager.java b/log4j-cassandra/src/main/java/org/apache/logging/log4j/cassandra/CassandraManager.java
new file mode 100644
index 0000000..5ca82d3
--- /dev/null
+++ b/log4j-cassandra/src/main/java/org/apache/logging/log4j/cassandra/CassandraManager.java
@@ -0,0 +1,218 @@
+/*
+ * 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.cassandra;
+
+import java.net.InetSocketAddress;
+import java.util.ArrayList;
+import java.util.Date;
+import java.util.List;
+
+import com.datastax.driver.core.BatchStatement;
+import com.datastax.driver.core.BoundStatement;
+import com.datastax.driver.core.Cluster;
+import com.datastax.driver.core.PreparedStatement;
+import com.datastax.driver.core.Session;
+import org.apache.logging.log4j.core.LogEvent;
+import org.apache.logging.log4j.core.appender.ManagerFactory;
+import org.apache.logging.log4j.core.appender.db.AbstractDatabaseManager;
+import org.apache.logging.log4j.core.appender.db.ColumnMapping;
+import org.apache.logging.log4j.core.config.plugins.convert.DateTypeConverter;
+import org.apache.logging.log4j.core.config.plugins.convert.TypeConverters;
+import org.apache.logging.log4j.core.net.SocketAddress;
+import org.apache.logging.log4j.spi.ThreadContextMap;
+import org.apache.logging.log4j.spi.ThreadContextStack;
+import org.apache.logging.log4j.util.ReadOnlyStringMap;
+import org.apache.logging.log4j.util.Strings;
+
+/**
+ * Manager for a Cassandra appender instance.
+ */
+public class CassandraManager extends AbstractDatabaseManager {
+
+ private static final int DEFAULT_PORT = 9042;
+
+ private final Cluster cluster;
+ private final String keyspace;
+ private final String insertQueryTemplate;
+ private final List<ColumnMapping> columnMappings;
+ private final BatchStatement batchStatement;
+ // re-usable argument binding array
+ private final Object[] values;
+
+ private Session session;
+ private PreparedStatement preparedStatement;
+
+ private CassandraManager(final String name, final int bufferSize, final Cluster cluster,
+ final String keyspace, final String insertQueryTemplate,
+ final List<ColumnMapping> columnMappings, final BatchStatement batchStatement) {
+ super(name, bufferSize);
+ this.cluster = cluster;
+ this.keyspace = keyspace;
+ this.insertQueryTemplate = insertQueryTemplate;
+ this.columnMappings = columnMappings;
+ this.batchStatement = batchStatement;
+ this.values = new Object[columnMappings.size()];
+ }
+
+ @Override
+ protected void startupInternal() throws Exception {
+ session = cluster.connect(keyspace);
+ preparedStatement = session.prepare(insertQueryTemplate);
+ }
+
+ @Override
+ protected boolean shutdownInternal() throws Exception {
+ session.close();
+ cluster.close();
+ return true;
+ }
+
+ @Override
+ protected void connectAndStart() {
+ // a Session automatically manages connections for us
+ }
+
+ @Override
+ protected void writeInternal(final LogEvent event) {
+ for (int i = 0; i < columnMappings.size(); i++) {
+ final ColumnMapping columnMapping = columnMappings.get(i);
+ if (ThreadContextMap.class.isAssignableFrom(columnMapping.getType())
+ || ReadOnlyStringMap.class.isAssignableFrom(columnMapping.getType())) {
+ values[i] = event.getContextData().toMap();
+ } else if (ThreadContextStack.class.isAssignableFrom(columnMapping.getType())) {
+ values[i] = event.getContextStack().asList();
+ } else if (Date.class.isAssignableFrom(columnMapping.getType())) {
+ values[i] = DateTypeConverter.fromMillis(event.getTimeMillis(), columnMapping.getType().asSubclass(Date.class));
+ } else {
+ values[i] = TypeConverters.convert(columnMapping.getLayout().toSerializable(event),
+ columnMapping.getType(), null);
+ }
+ }
+ final BoundStatement boundStatement = preparedStatement.bind(values);
+ if (batchStatement == null) {
+ session.execute(boundStatement);
+ } else {
+ batchStatement.add(boundStatement);
+ }
+ }
+
+ @Override
+ protected boolean commitAndClose() {
+ if (batchStatement != null) {
+ session.execute(batchStatement);
+ }
+ return true;
+ }
+
+ public static CassandraManager getManager(final String name, final SocketAddress[] contactPoints,
+ final ColumnMapping[] columns, final boolean useTls,
+ final String clusterName, final String keyspace, final String table,
+ final String username, final String password,
+ final boolean useClockForTimestampGenerator, final int bufferSize,
+ final boolean batched, final BatchStatement.Type batchType) {
+ return getManager(name,
+ new FactoryData(contactPoints, columns, useTls, clusterName, keyspace, table, username, password,
+ useClockForTimestampGenerator, bufferSize, batched, batchType), CassandraManagerFactory.INSTANCE);
+ }
+
+ private static class CassandraManagerFactory implements ManagerFactory<CassandraManager, FactoryData> {
+
+ private static final CassandraManagerFactory INSTANCE = new CassandraManagerFactory();
+
+ @Override
+ public CassandraManager createManager(final String name, final FactoryData data) {
+ final Cluster.Builder builder = Cluster.builder()
+ .addContactPointsWithPorts(data.contactPoints)
+ .withClusterName(data.clusterName);
+ if (data.useTls) {
+ builder.withSSL();
+ }
+ if (Strings.isNotBlank(data.username)) {
+ builder.withCredentials(data.username, data.password);
+ }
+ if (data.useClockForTimestampGenerator) {
+ builder.withTimestampGenerator(new ClockTimestampGenerator());
+ }
+ final Cluster cluster = builder.build();
+
+ final StringBuilder sb = new StringBuilder("INSERT INTO ").append(data.table).append(" (");
+ for (final ColumnMapping column : data.columns) {
+ sb.append(column.getName()).append(',');
+ }
+ sb.setCharAt(sb.length() - 1, ')');
+ sb.append(" VALUES (");
+ final List<ColumnMapping> columnMappings = new ArrayList<>(data.columns.length);
+ for (final ColumnMapping column : data.columns) {
+ if (Strings.isNotEmpty(column.getLiteralValue())) {
+ sb.append(column.getLiteralValue());
+ } else {
+ sb.append('?');
+ columnMappings.add(column);
+ }
+ sb.append(',');
+ }
+ sb.setCharAt(sb.length() - 1, ')');
+ final String insertQueryTemplate = sb.toString();
+ LOGGER.debug("Using CQL for appender {}: {}", name, insertQueryTemplate);
+ return new CassandraManager(name, data.getBufferSize(), cluster, data.keyspace, insertQueryTemplate,
+ columnMappings, data.batched ? new BatchStatement(data.batchType) : null);
+ }
+ }
+
+ private static class FactoryData extends AbstractFactoryData {
+ private final InetSocketAddress[] contactPoints;
+ private final ColumnMapping[] columns;
+ private final boolean useTls;
+ private final String clusterName;
+ private final String keyspace;
+ private final String table;
+ private final String username;
+ private final String password;
+ private final boolean useClockForTimestampGenerator;
+ private final boolean batched;
+ private final BatchStatement.Type batchType;
+
+ private FactoryData(final SocketAddress[] contactPoints, final ColumnMapping[] columns, final boolean useTls,
+ final String clusterName, final String keyspace, final String table, final String username,
+ final String password, final boolean useClockForTimestampGenerator, final int bufferSize,
+ final boolean batched, final BatchStatement.Type batchType) {
+ super(bufferSize);
+ this.contactPoints = convertAndAddDefaultPorts(contactPoints);
+ this.columns = columns;
+ this.useTls = useTls;
+ this.clusterName = clusterName;
+ this.keyspace = keyspace;
+ this.table = table;
+ this.username = username;
+ this.password = password;
+ this.useClockForTimestampGenerator = useClockForTimestampGenerator;
+ this.batched = batched;
+ this.batchType = batchType;
+ }
+
+ private static InetSocketAddress[] convertAndAddDefaultPorts(final SocketAddress... socketAddresses) {
+ final InetSocketAddress[] inetSocketAddresses = new InetSocketAddress[socketAddresses.length];
+ for (int i = 0; i < inetSocketAddresses.length; i++) {
+ final SocketAddress socketAddress = socketAddresses[i];
+ inetSocketAddresses[i] = socketAddress.getPort() == 0
+ ? new InetSocketAddress(socketAddress.getAddress(), DEFAULT_PORT)
+ : socketAddress.getSocketAddress();
+ }
+ return inetSocketAddresses;
+ }
+ }
+}
http://git-wip-us.apache.org/repos/asf/logging-log4j2/blob/44db87d0/log4j-cassandra/src/main/java/org/apache/logging/log4j/cassandra/ClockTimestampGenerator.java
----------------------------------------------------------------------
diff --git a/log4j-cassandra/src/main/java/org/apache/logging/log4j/cassandra/ClockTimestampGenerator.java b/log4j-cassandra/src/main/java/org/apache/logging/log4j/cassandra/ClockTimestampGenerator.java
new file mode 100644
index 0000000..1c7328b
--- /dev/null
+++ b/log4j-cassandra/src/main/java/org/apache/logging/log4j/cassandra/ClockTimestampGenerator.java
@@ -0,0 +1,34 @@
+/*
+ * 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.cassandra;
+
+import com.datastax.driver.core.TimestampGenerator;
+import org.apache.logging.log4j.core.util.Clock;
+import org.apache.logging.log4j.core.util.ClockFactory;
+
+/**
+ * A {@link TimestampGenerator} implementation using the configured {@link Clock}.
+ */
+public class ClockTimestampGenerator implements TimestampGenerator {
+
+ private final Clock clock = ClockFactory.getClock();
+
+ @Override
+ public long next() {
+ return clock.currentTimeMillis();
+ }
+}
http://git-wip-us.apache.org/repos/asf/logging-log4j2/blob/44db87d0/log4j-cassandra/src/main/java/org/apache/logging/log4j/cassandra/package-info.java
----------------------------------------------------------------------
diff --git a/log4j-cassandra/src/main/java/org/apache/logging/log4j/cassandra/package-info.java b/log4j-cassandra/src/main/java/org/apache/logging/log4j/cassandra/package-info.java
new file mode 100644
index 0000000..0336dd0
--- /dev/null
+++ b/log4j-cassandra/src/main/java/org/apache/logging/log4j/cassandra/package-info.java
@@ -0,0 +1,23 @@
+/*
+ * 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.
+ */
+/**
+ * Log4j appender plugin and supporting classes for Apache Cassandra.
+ *
+ * @see <a href="https://logging.apache.org/log4j/2.x/manual/appenders.html#CassandraAppender">Cassandra Appender manual</a>
+ * @since 2.8
+ */
+package org.apache.logging.log4j.cassandra;
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/logging-log4j2/blob/44db87d0/log4j-cassandra/src/main/java/org/apache/logging/log4j/nosql/appender/cassandra/CassandraAppender.java
----------------------------------------------------------------------
diff --git a/log4j-cassandra/src/main/java/org/apache/logging/log4j/nosql/appender/cassandra/CassandraAppender.java b/log4j-cassandra/src/main/java/org/apache/logging/log4j/nosql/appender/cassandra/CassandraAppender.java
deleted file mode 100644
index fb344c2..0000000
--- a/log4j-cassandra/src/main/java/org/apache/logging/log4j/nosql/appender/cassandra/CassandraAppender.java
+++ /dev/null
@@ -1,185 +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.cassandra;
-
-import com.datastax.driver.core.BatchStatement;
-import org.apache.logging.log4j.core.Core;
-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.appender.db.ColumnMapping;
-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.PluginElement;
-import org.apache.logging.log4j.core.config.plugins.validation.constraints.Required;
-import org.apache.logging.log4j.core.net.SocketAddress;
-import org.apache.logging.log4j.core.util.Clock;
-
-/**
- * Appender plugin that uses a Cassandra database.
- *
- * @see SocketAddress
- * @see ColumnMapping
- */
-@Plugin(name = "Cassandra", category = Core.CATEGORY_NAME, elementType = CassandraAppender.ELEMENT_TYPE, printObject = true)
-public class CassandraAppender extends AbstractDatabaseAppender<CassandraManager> {
-
- private CassandraAppender(final String name, final Filter filter, final boolean ignoreExceptions,
- final CassandraManager manager) {
- super(name, filter, ignoreExceptions, manager);
- }
-
- @PluginBuilderFactory
- public static <B extends Builder<B>> B newBuilder() {
- return new Builder<B>().asBuilder();
- }
-
- public static class Builder<B extends Builder<B>> extends AbstractAppender.Builder<B>
- implements org.apache.logging.log4j.core.util.Builder<CassandraAppender> {
-
- /**
- * List of Cassandra node contact points. Addresses without a port (or port set to 0) will use the default
- * Cassandra port (9042).
- */
- @PluginElement("ContactPoints")
- @Required(message = "No Cassandra servers provided")
- private SocketAddress[] contactPoints = new SocketAddress[]{SocketAddress.getLoopback()};
-
- /**
- * List of column mappings to convert a LogEvent into a database row.
- */
- @PluginElement("Columns")
- @Required(message = "No Cassandra columns provided")
- private ColumnMapping[] columns;
-
- @PluginBuilderAttribute
- private boolean useTls;
-
- @PluginBuilderAttribute
- @Required(message = "No cluster name provided")
- private String clusterName;
-
- @PluginBuilderAttribute
- @Required(message = "No keyspace provided")
- private String keyspace;
-
- @PluginBuilderAttribute
- @Required(message = "No table name provided")
- private String table;
-
- @PluginBuilderAttribute
- private String username;
-
- @PluginBuilderAttribute(sensitive = true)
- private String password;
-
- /**
- * Override the default TimestampGenerator with one based on the configured {@link Clock}.
- */
- @PluginBuilderAttribute
- private boolean useClockForTimestampGenerator;
-
- /**
- * Number of LogEvents to buffer before writing. Can be used with or without batch statements.
- */
- @PluginBuilderAttribute
- private int bufferSize;
-
- /**
- * Whether or not to use batch statements when inserting records.
- */
- @PluginBuilderAttribute
- private boolean batched;
-
- /**
- * If batch statements are enabled, use this type of batch statement.
- */
- @PluginBuilderAttribute
- private BatchStatement.Type batchType = BatchStatement.Type.LOGGED;
-
- public B setContactPoints(final SocketAddress... contactPoints) {
- this.contactPoints = contactPoints;
- return asBuilder();
- }
-
- public B setColumns(final ColumnMapping... columns) {
- this.columns = columns;
- return asBuilder();
- }
-
- public B setUseTls(final boolean useTls) {
- this.useTls = useTls;
- return asBuilder();
- }
-
- public B setClusterName(final String clusterName) {
- this.clusterName = clusterName;
- return asBuilder();
- }
-
- public B setKeyspace(final String keyspace) {
- this.keyspace = keyspace;
- return asBuilder();
- }
-
- public B setTable(final String table) {
- this.table = table;
- 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 setUseClockForTimestampGenerator(final boolean useClockForTimestampGenerator) {
- this.useClockForTimestampGenerator = useClockForTimestampGenerator;
- return asBuilder();
- }
-
- public B setBufferSize(final int bufferSize) {
- this.bufferSize = bufferSize;
- return asBuilder();
- }
-
- public B setBatched(final boolean batched) {
- this.batched = batched;
- return asBuilder();
- }
-
- public B setBatchType(final BatchStatement.Type batchType) {
- this.batchType = batchType;
- return asBuilder();
- }
-
- @Override
- public CassandraAppender build() {
- final CassandraManager manager = CassandraManager.getManager(getName(), contactPoints, columns, useTls,
- clusterName, keyspace, table, username, password, useClockForTimestampGenerator, bufferSize, batched,
- batchType);
- return new CassandraAppender(getName(), getFilter(), isIgnoreExceptions(), manager);
- }
-
- }
-
-}
http://git-wip-us.apache.org/repos/asf/logging-log4j2/blob/44db87d0/log4j-cassandra/src/main/java/org/apache/logging/log4j/nosql/appender/cassandra/CassandraManager.java
----------------------------------------------------------------------
diff --git a/log4j-cassandra/src/main/java/org/apache/logging/log4j/nosql/appender/cassandra/CassandraManager.java b/log4j-cassandra/src/main/java/org/apache/logging/log4j/nosql/appender/cassandra/CassandraManager.java
deleted file mode 100644
index cfbc528..0000000
--- a/log4j-cassandra/src/main/java/org/apache/logging/log4j/nosql/appender/cassandra/CassandraManager.java
+++ /dev/null
@@ -1,218 +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.cassandra;
-
-import java.net.InetSocketAddress;
-import java.util.ArrayList;
-import java.util.Date;
-import java.util.List;
-
-import com.datastax.driver.core.BatchStatement;
-import com.datastax.driver.core.BoundStatement;
-import com.datastax.driver.core.Cluster;
-import com.datastax.driver.core.PreparedStatement;
-import com.datastax.driver.core.Session;
-import org.apache.logging.log4j.core.LogEvent;
-import org.apache.logging.log4j.core.appender.ManagerFactory;
-import org.apache.logging.log4j.core.appender.db.AbstractDatabaseManager;
-import org.apache.logging.log4j.core.appender.db.ColumnMapping;
-import org.apache.logging.log4j.core.config.plugins.convert.DateTypeConverter;
-import org.apache.logging.log4j.core.config.plugins.convert.TypeConverters;
-import org.apache.logging.log4j.core.net.SocketAddress;
-import org.apache.logging.log4j.spi.ThreadContextMap;
-import org.apache.logging.log4j.spi.ThreadContextStack;
-import org.apache.logging.log4j.util.ReadOnlyStringMap;
-import org.apache.logging.log4j.util.Strings;
-
-/**
- * Manager for a Cassandra appender instance.
- */
-public class CassandraManager extends AbstractDatabaseManager {
-
- private static final int DEFAULT_PORT = 9042;
-
- private final Cluster cluster;
- private final String keyspace;
- private final String insertQueryTemplate;
- private final List<ColumnMapping> columnMappings;
- private final BatchStatement batchStatement;
- // re-usable argument binding array
- private final Object[] values;
-
- private Session session;
- private PreparedStatement preparedStatement;
-
- private CassandraManager(final String name, final int bufferSize, final Cluster cluster,
- final String keyspace, final String insertQueryTemplate,
- final List<ColumnMapping> columnMappings, final BatchStatement batchStatement) {
- super(name, bufferSize);
- this.cluster = cluster;
- this.keyspace = keyspace;
- this.insertQueryTemplate = insertQueryTemplate;
- this.columnMappings = columnMappings;
- this.batchStatement = batchStatement;
- this.values = new Object[columnMappings.size()];
- }
-
- @Override
- protected void startupInternal() throws Exception {
- session = cluster.connect(keyspace);
- preparedStatement = session.prepare(insertQueryTemplate);
- }
-
- @Override
- protected boolean shutdownInternal() throws Exception {
- session.close();
- cluster.close();
- return true;
- }
-
- @Override
- protected void connectAndStart() {
- // a Session automatically manages connections for us
- }
-
- @Override
- protected void writeInternal(final LogEvent event) {
- for (int i = 0; i < columnMappings.size(); i++) {
- final ColumnMapping columnMapping = columnMappings.get(i);
- if (ThreadContextMap.class.isAssignableFrom(columnMapping.getType())
- || ReadOnlyStringMap.class.isAssignableFrom(columnMapping.getType())) {
- values[i] = event.getContextData().toMap();
- } else if (ThreadContextStack.class.isAssignableFrom(columnMapping.getType())) {
- values[i] = event.getContextStack().asList();
- } else if (Date.class.isAssignableFrom(columnMapping.getType())) {
- values[i] = DateTypeConverter.fromMillis(event.getTimeMillis(), columnMapping.getType().asSubclass(Date.class));
- } else {
- values[i] = TypeConverters.convert(columnMapping.getLayout().toSerializable(event),
- columnMapping.getType(), null);
- }
- }
- final BoundStatement boundStatement = preparedStatement.bind(values);
- if (batchStatement == null) {
- session.execute(boundStatement);
- } else {
- batchStatement.add(boundStatement);
- }
- }
-
- @Override
- protected boolean commitAndClose() {
- if (batchStatement != null) {
- session.execute(batchStatement);
- }
- return true;
- }
-
- public static CassandraManager getManager(final String name, final SocketAddress[] contactPoints,
- final ColumnMapping[] columns, final boolean useTls,
- final String clusterName, final String keyspace, final String table,
- final String username, final String password,
- final boolean useClockForTimestampGenerator, final int bufferSize,
- final boolean batched, final BatchStatement.Type batchType) {
- return getManager(name,
- new FactoryData(contactPoints, columns, useTls, clusterName, keyspace, table, username, password,
- useClockForTimestampGenerator, bufferSize, batched, batchType), CassandraManagerFactory.INSTANCE);
- }
-
- private static class CassandraManagerFactory implements ManagerFactory<CassandraManager, FactoryData> {
-
- private static final CassandraManagerFactory INSTANCE = new CassandraManagerFactory();
-
- @Override
- public CassandraManager createManager(final String name, final FactoryData data) {
- final Cluster.Builder builder = Cluster.builder()
- .addContactPointsWithPorts(data.contactPoints)
- .withClusterName(data.clusterName);
- if (data.useTls) {
- builder.withSSL();
- }
- if (Strings.isNotBlank(data.username)) {
- builder.withCredentials(data.username, data.password);
- }
- if (data.useClockForTimestampGenerator) {
- builder.withTimestampGenerator(new ClockTimestampGenerator());
- }
- final Cluster cluster = builder.build();
-
- final StringBuilder sb = new StringBuilder("INSERT INTO ").append(data.table).append(" (");
- for (final ColumnMapping column : data.columns) {
- sb.append(column.getName()).append(',');
- }
- sb.setCharAt(sb.length() - 1, ')');
- sb.append(" VALUES (");
- final List<ColumnMapping> columnMappings = new ArrayList<>(data.columns.length);
- for (final ColumnMapping column : data.columns) {
- if (Strings.isNotEmpty(column.getLiteralValue())) {
- sb.append(column.getLiteralValue());
- } else {
- sb.append('?');
- columnMappings.add(column);
- }
- sb.append(',');
- }
- sb.setCharAt(sb.length() - 1, ')');
- final String insertQueryTemplate = sb.toString();
- LOGGER.debug("Using CQL for appender {}: {}", name, insertQueryTemplate);
- return new CassandraManager(name, data.getBufferSize(), cluster, data.keyspace, insertQueryTemplate,
- columnMappings, data.batched ? new BatchStatement(data.batchType) : null);
- }
- }
-
- private static class FactoryData extends AbstractFactoryData {
- private final InetSocketAddress[] contactPoints;
- private final ColumnMapping[] columns;
- private final boolean useTls;
- private final String clusterName;
- private final String keyspace;
- private final String table;
- private final String username;
- private final String password;
- private final boolean useClockForTimestampGenerator;
- private final boolean batched;
- private final BatchStatement.Type batchType;
-
- private FactoryData(final SocketAddress[] contactPoints, final ColumnMapping[] columns, final boolean useTls,
- final String clusterName, final String keyspace, final String table, final String username,
- final String password, final boolean useClockForTimestampGenerator, final int bufferSize,
- final boolean batched, final BatchStatement.Type batchType) {
- super(bufferSize);
- this.contactPoints = convertAndAddDefaultPorts(contactPoints);
- this.columns = columns;
- this.useTls = useTls;
- this.clusterName = clusterName;
- this.keyspace = keyspace;
- this.table = table;
- this.username = username;
- this.password = password;
- this.useClockForTimestampGenerator = useClockForTimestampGenerator;
- this.batched = batched;
- this.batchType = batchType;
- }
-
- private static InetSocketAddress[] convertAndAddDefaultPorts(final SocketAddress... socketAddresses) {
- final InetSocketAddress[] inetSocketAddresses = new InetSocketAddress[socketAddresses.length];
- for (int i = 0; i < inetSocketAddresses.length; i++) {
- final SocketAddress socketAddress = socketAddresses[i];
- inetSocketAddresses[i] = socketAddress.getPort() == 0
- ? new InetSocketAddress(socketAddress.getAddress(), DEFAULT_PORT)
- : socketAddress.getSocketAddress();
- }
- return inetSocketAddresses;
- }
- }
-}
http://git-wip-us.apache.org/repos/asf/logging-log4j2/blob/44db87d0/log4j-cassandra/src/main/java/org/apache/logging/log4j/nosql/appender/cassandra/ClockTimestampGenerator.java
----------------------------------------------------------------------
diff --git a/log4j-cassandra/src/main/java/org/apache/logging/log4j/nosql/appender/cassandra/ClockTimestampGenerator.java b/log4j-cassandra/src/main/java/org/apache/logging/log4j/nosql/appender/cassandra/ClockTimestampGenerator.java
deleted file mode 100644
index 06758dd..0000000
--- a/log4j-cassandra/src/main/java/org/apache/logging/log4j/nosql/appender/cassandra/ClockTimestampGenerator.java
+++ /dev/null
@@ -1,34 +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.cassandra;
-
-import com.datastax.driver.core.TimestampGenerator;
-import org.apache.logging.log4j.core.util.Clock;
-import org.apache.logging.log4j.core.util.ClockFactory;
-
-/**
- * A {@link TimestampGenerator} implementation using the configured {@link Clock}.
- */
-public class ClockTimestampGenerator implements TimestampGenerator {
-
- private final Clock clock = ClockFactory.getClock();
-
- @Override
- public long next() {
- return clock.currentTimeMillis();
- }
-}
http://git-wip-us.apache.org/repos/asf/logging-log4j2/blob/44db87d0/log4j-cassandra/src/main/java/org/apache/logging/log4j/nosql/appender/cassandra/package-info.java
----------------------------------------------------------------------
diff --git a/log4j-cassandra/src/main/java/org/apache/logging/log4j/nosql/appender/cassandra/package-info.java b/log4j-cassandra/src/main/java/org/apache/logging/log4j/nosql/appender/cassandra/package-info.java
deleted file mode 100644
index 79107c9..0000000
--- a/log4j-cassandra/src/main/java/org/apache/logging/log4j/nosql/appender/cassandra/package-info.java
+++ /dev/null
@@ -1,23 +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.
- */
-/**
- * Log4j appender plugin and supporting classes for Apache Cassandra.
- *
- * @see <a href="https://logging.apache.org/log4j/2.x/manual/appenders.html#CassandraAppender">Cassandra Appender manual</a>
- * @since 2.8
- */
-package org.apache.logging.log4j.nosql.appender.cassandra;
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/logging-log4j2/blob/44db87d0/log4j-cassandra/src/test/java/org/apache/logging/log4j/cassandra/CassandraAppenderIT.java
----------------------------------------------------------------------
diff --git a/log4j-cassandra/src/test/java/org/apache/logging/log4j/cassandra/CassandraAppenderIT.java b/log4j-cassandra/src/test/java/org/apache/logging/log4j/cassandra/CassandraAppenderIT.java
new file mode 100644
index 0000000..9cd0794
--- /dev/null
+++ b/log4j-cassandra/src/test/java/org/apache/logging/log4j/cassandra/CassandraAppenderIT.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.cassandra;
+
+import java.util.Date;
+import java.util.List;
+import java.util.Map;
+import java.util.UUID;
+import java.util.concurrent.TimeUnit;
+
+import com.datastax.driver.core.Row;
+import com.datastax.driver.core.Session;
+import org.apache.logging.log4j.Logger;
+import org.apache.logging.log4j.MarkerManager;
+import org.apache.logging.log4j.ThreadContext;
+import org.apache.logging.log4j.categories.Appenders;
+import org.apache.logging.log4j.junit.LoggerContextRule;
+import org.junit.ClassRule;
+import org.junit.Test;
+import org.junit.experimental.categories.Category;
+import org.junit.rules.RuleChain;
+
+import static org.junit.Assert.*;
+
+/**
+ * Integration test for CassandraAppender.
+ */
+@Category(Appenders.Cassandra.class)
+public class CassandraAppenderIT {
+
+ private static final String DDL = "CREATE TABLE logs (" +
+ "id timeuuid PRIMARY KEY," +
+ "timeid timeuuid," +
+ "message text," +
+ "level text," +
+ "marker text," +
+ "logger text," +
+ "timestamp timestamp," +
+ "mdc map<text,text>," +
+ "ndc list<text>" +
+ ")";
+
+ private static final LoggerContextRule CTX = new LoggerContextRule("CassandraAppenderTest.xml");
+ private static final CassandraRule CASSANDRA = new CassandraRule("test", DDL);
+
+ @ClassRule
+ public static RuleChain rules = RuleChain.outerRule(CASSANDRA).around(CTX);
+
+ @Test
+ public void appendManyEvents() throws Exception {
+ final Logger logger = CTX.getLogger();
+ ThreadContext.put("test", "mdc");
+ ThreadContext.push("ndc");
+ for (int i = 0; i < 20; i++) {
+ logger.info(MarkerManager.getMarker("MARKER"), "Test log message");
+ }
+ ThreadContext.clearAll();
+
+ TimeUnit.SECONDS.sleep(3);
+
+ int i = 0;
+ try (final Session session = CASSANDRA.connect()) {
+ for (final Row row : session.execute("SELECT * FROM logs")) {
+ assertNotNull(row.get("id", UUID.class));
+ assertNotNull(row.get("timeid", UUID.class));
+ assertNotNull(row.get("timestamp", Date.class));
+ assertEquals("Test log message", row.getString("message"));
+ assertEquals("MARKER", row.getString("marker"));
+ assertEquals("INFO", row.getString("level"));
+ assertEquals(getClass().getName(), row.getString("logger"));
+ final Map<String, String> mdc = row.getMap("mdc", String.class, String.class);
+ assertEquals(1, mdc.size());
+ assertEquals("mdc", mdc.get("test"));
+ final List<String> ndc = row.getList("ndc", String.class);
+ assertEquals(1, ndc.size());
+ assertEquals("ndc", ndc.get(0));
+ ++i;
+ }
+ }
+ assertEquals(20, i);
+ }
+}
http://git-wip-us.apache.org/repos/asf/logging-log4j2/blob/44db87d0/log4j-cassandra/src/test/java/org/apache/logging/log4j/cassandra/CassandraRule.java
----------------------------------------------------------------------
diff --git a/log4j-cassandra/src/test/java/org/apache/logging/log4j/cassandra/CassandraRule.java b/log4j-cassandra/src/test/java/org/apache/logging/log4j/cassandra/CassandraRule.java
new file mode 100644
index 0000000..2939d07
--- /dev/null
+++ b/log4j-cassandra/src/test/java/org/apache/logging/log4j/cassandra/CassandraRule.java
@@ -0,0 +1,141 @@
+/*
+ * 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.cassandra;
+
+import java.io.IOException;
+import java.net.InetAddress;
+import java.nio.file.Files;
+import java.nio.file.Path;
+import java.security.Permission;
+import java.util.concurrent.CountDownLatch;
+import java.util.concurrent.ThreadFactory;
+
+import com.datastax.driver.core.Cluster;
+import com.datastax.driver.core.Session;
+import org.apache.cassandra.service.CassandraDaemon;
+import org.apache.logging.log4j.LoggingException;
+import org.apache.logging.log4j.core.util.Cancellable;
+import org.apache.logging.log4j.core.util.Closer;
+import org.apache.logging.log4j.core.util.Log4jThreadFactory;
+import org.apache.logging.log4j.util.PropertiesUtil;
+import org.junit.rules.ExternalResource;
+
+/**
+ * JUnit rule to set up and tear down a Cassandra database instance.
+ */
+public class CassandraRule extends ExternalResource {
+
+ private static final ThreadFactory THREAD_FACTORY = Log4jThreadFactory.createThreadFactory("Cassandra");
+
+ private final CountDownLatch latch = new CountDownLatch(1);
+ private final Cancellable embeddedCassandra = new EmbeddedCassandra(latch);
+ private final String keyspace;
+ private final String tableDdl;
+ private Cluster cluster;
+
+ public CassandraRule(final String keyspace, final String tableDdl) {
+ this.keyspace = keyspace;
+ this.tableDdl = tableDdl;
+ }
+
+ public Cluster getCluster() {
+ return cluster;
+ }
+
+ public Session connect() {
+ return cluster.connect(keyspace);
+ }
+
+ @Override
+ protected void before() throws Throwable {
+ final Path root = Files.createTempDirectory("cassandra");
+ Files.createDirectories(root.resolve("data"));
+ final Path config = root.resolve("cassandra.yml");
+ Files.copy(getClass().getResourceAsStream("/cassandra.yaml"), config);
+ System.setProperty("cassandra.config", "file:" + config.toString());
+ System.setProperty("cassandra.storagedir", root.toString());
+ System.setProperty("cassandra-foreground", "true"); // prevents Cassandra from closing stdout/stderr
+ THREAD_FACTORY.newThread(embeddedCassandra).start();
+ latch.await();
+ cluster = Cluster.builder().addContactPoints(InetAddress.getLoopbackAddress()).build();
+ try (final Session session = cluster.connect()) {
+ session.execute("CREATE KEYSPACE " + keyspace + " WITH REPLICATION = " +
+ "{ 'class': 'SimpleStrategy', 'replication_factor': 2 };");
+ }
+ try (final Session session = connect()) {
+ session.execute(tableDdl);
+ }
+ }
+
+ @Override
+ protected void after() {
+ Closer.closeSilently(cluster);
+ embeddedCassandra.cancel();
+ }
+
+ private static class EmbeddedCassandra implements Cancellable {
+
+ private final CassandraDaemon daemon = new CassandraDaemon();
+ private final CountDownLatch latch;
+
+ private EmbeddedCassandra(final CountDownLatch latch) {
+ this.latch = latch;
+ }
+
+ @Override
+ public void cancel() {
+ // LOG4J2-1850 Cassandra on Windows calls System.exit in the daemon stop method
+ if (PropertiesUtil.getProperties().isOsWindows()) {
+ cancelOnWindows();
+ } else {
+ daemon.stop();
+ }
+ }
+
+ private void cancelOnWindows() {
+ final SecurityManager currentSecurityManager = System.getSecurityManager();
+ try {
+ final SecurityManager securityManager = new SecurityManager() {
+ @Override
+ public void checkPermission(final Permission permission) {
+ final String permissionName = permission.getName();
+ if (permissionName != null && permissionName.startsWith("exitVM")) {
+ throw new SecurityException("test");
+ }
+ }
+ };
+ System.setSecurityManager(securityManager);
+ daemon.stop();
+ } catch (final SecurityException ex) {
+ // ignore
+ } finally {
+ System.setSecurityManager(currentSecurityManager);
+ }
+ }
+
+ @Override
+ public void run() {
+ try {
+ daemon.init(null);
+ } catch (final IOException e) {
+ throw new LoggingException("Cannot initialize embedded Cassandra instance", e);
+ }
+ daemon.start();
+ latch.countDown();
+ }
+ }
+}
http://git-wip-us.apache.org/repos/asf/logging-log4j2/blob/44db87d0/log4j-cassandra/src/test/java/org/apache/logging/log4j/nosql/appender/cassandra/CassandraAppenderIT.java
----------------------------------------------------------------------
diff --git a/log4j-cassandra/src/test/java/org/apache/logging/log4j/nosql/appender/cassandra/CassandraAppenderIT.java b/log4j-cassandra/src/test/java/org/apache/logging/log4j/nosql/appender/cassandra/CassandraAppenderIT.java
deleted file mode 100644
index caf72d5..0000000
--- a/log4j-cassandra/src/test/java/org/apache/logging/log4j/nosql/appender/cassandra/CassandraAppenderIT.java
+++ /dev/null
@@ -1,96 +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.cassandra;
-
-import java.util.Date;
-import java.util.List;
-import java.util.Map;
-import java.util.UUID;
-import java.util.concurrent.TimeUnit;
-
-import com.datastax.driver.core.Row;
-import com.datastax.driver.core.Session;
-import org.apache.logging.log4j.Logger;
-import org.apache.logging.log4j.MarkerManager;
-import org.apache.logging.log4j.ThreadContext;
-import org.apache.logging.log4j.categories.Appenders;
-import org.apache.logging.log4j.junit.LoggerContextRule;
-import org.junit.ClassRule;
-import org.junit.Test;
-import org.junit.experimental.categories.Category;
-import org.junit.rules.RuleChain;
-
-import static org.junit.Assert.*;
-
-/**
- * Integration test for CassandraAppender.
- */
-@Category(Appenders.Cassandra.class)
-public class CassandraAppenderIT {
-
- private static final String DDL = "CREATE TABLE logs (" +
- "id timeuuid PRIMARY KEY," +
- "timeid timeuuid," +
- "message text," +
- "level text," +
- "marker text," +
- "logger text," +
- "timestamp timestamp," +
- "mdc map<text,text>," +
- "ndc list<text>" +
- ")";
-
- private static final LoggerContextRule CTX = new LoggerContextRule("CassandraAppenderTest.xml");
- private static final CassandraRule CASSANDRA = new CassandraRule("test", DDL);
-
- @ClassRule
- public static RuleChain rules = RuleChain.outerRule(CASSANDRA).around(CTX);
-
- @Test
- public void appendManyEvents() throws Exception {
- final Logger logger = CTX.getLogger();
- ThreadContext.put("test", "mdc");
- ThreadContext.push("ndc");
- for (int i = 0; i < 20; i++) {
- logger.info(MarkerManager.getMarker("MARKER"), "Test log message");
- }
- ThreadContext.clearAll();
-
- TimeUnit.SECONDS.sleep(3);
-
- int i = 0;
- try (final Session session = CASSANDRA.connect()) {
- for (final Row row : session.execute("SELECT * FROM logs")) {
- assertNotNull(row.get("id", UUID.class));
- assertNotNull(row.get("timeid", UUID.class));
- assertNotNull(row.get("timestamp", Date.class));
- assertEquals("Test log message", row.getString("message"));
- assertEquals("MARKER", row.getString("marker"));
- assertEquals("INFO", row.getString("level"));
- assertEquals(getClass().getName(), row.getString("logger"));
- final Map<String, String> mdc = row.getMap("mdc", String.class, String.class);
- assertEquals(1, mdc.size());
- assertEquals("mdc", mdc.get("test"));
- final List<String> ndc = row.getList("ndc", String.class);
- assertEquals(1, ndc.size());
- assertEquals("ndc", ndc.get(0));
- ++i;
- }
- }
- assertEquals(20, i);
- }
-}
http://git-wip-us.apache.org/repos/asf/logging-log4j2/blob/44db87d0/log4j-cassandra/src/test/java/org/apache/logging/log4j/nosql/appender/cassandra/CassandraRule.java
----------------------------------------------------------------------
diff --git a/log4j-cassandra/src/test/java/org/apache/logging/log4j/nosql/appender/cassandra/CassandraRule.java b/log4j-cassandra/src/test/java/org/apache/logging/log4j/nosql/appender/cassandra/CassandraRule.java
deleted file mode 100644
index 36e2672..0000000
--- a/log4j-cassandra/src/test/java/org/apache/logging/log4j/nosql/appender/cassandra/CassandraRule.java
+++ /dev/null
@@ -1,141 +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.cassandra;
-
-import java.io.IOException;
-import java.net.InetAddress;
-import java.nio.file.Files;
-import java.nio.file.Path;
-import java.security.Permission;
-import java.util.concurrent.CountDownLatch;
-import java.util.concurrent.ThreadFactory;
-
-import com.datastax.driver.core.Cluster;
-import com.datastax.driver.core.Session;
-import org.apache.cassandra.service.CassandraDaemon;
-import org.apache.logging.log4j.LoggingException;
-import org.apache.logging.log4j.core.util.Cancellable;
-import org.apache.logging.log4j.core.util.Closer;
-import org.apache.logging.log4j.core.util.Log4jThreadFactory;
-import org.apache.logging.log4j.util.PropertiesUtil;
-import org.junit.rules.ExternalResource;
-
-/**
- * JUnit rule to set up and tear down a Cassandra database instance.
- */
-public class CassandraRule extends ExternalResource {
-
- private static final ThreadFactory THREAD_FACTORY = Log4jThreadFactory.createThreadFactory("Cassandra");
-
- private final CountDownLatch latch = new CountDownLatch(1);
- private final Cancellable embeddedCassandra = new EmbeddedCassandra(latch);
- private final String keyspace;
- private final String tableDdl;
- private Cluster cluster;
-
- public CassandraRule(final String keyspace, final String tableDdl) {
- this.keyspace = keyspace;
- this.tableDdl = tableDdl;
- }
-
- public Cluster getCluster() {
- return cluster;
- }
-
- public Session connect() {
- return cluster.connect(keyspace);
- }
-
- @Override
- protected void before() throws Throwable {
- final Path root = Files.createTempDirectory("cassandra");
- Files.createDirectories(root.resolve("data"));
- final Path config = root.resolve("cassandra.yml");
- Files.copy(getClass().getResourceAsStream("/cassandra.yaml"), config);
- System.setProperty("cassandra.config", "file:" + config.toString());
- System.setProperty("cassandra.storagedir", root.toString());
- System.setProperty("cassandra-foreground", "true"); // prevents Cassandra from closing stdout/stderr
- THREAD_FACTORY.newThread(embeddedCassandra).start();
- latch.await();
- cluster = Cluster.builder().addContactPoints(InetAddress.getLoopbackAddress()).build();
- try (final Session session = cluster.connect()) {
- session.execute("CREATE KEYSPACE " + keyspace + " WITH REPLICATION = " +
- "{ 'class': 'SimpleStrategy', 'replication_factor': 2 };");
- }
- try (final Session session = connect()) {
- session.execute(tableDdl);
- }
- }
-
- @Override
- protected void after() {
- Closer.closeSilently(cluster);
- embeddedCassandra.cancel();
- }
-
- private static class EmbeddedCassandra implements Cancellable {
-
- private final CassandraDaemon daemon = new CassandraDaemon();
- private final CountDownLatch latch;
-
- private EmbeddedCassandra(final CountDownLatch latch) {
- this.latch = latch;
- }
-
- @Override
- public void cancel() {
- // LOG4J2-1850 Cassandra on Windows calls System.exit in the daemon stop method
- if (PropertiesUtil.getProperties().isOsWindows()) {
- cancelOnWindows();
- } else {
- daemon.stop();
- }
- }
-
- private void cancelOnWindows() {
- final SecurityManager currentSecurityManager = System.getSecurityManager();
- try {
- final SecurityManager securityManager = new SecurityManager() {
- @Override
- public void checkPermission(final Permission permission) {
- final String permissionName = permission.getName();
- if (permissionName != null && permissionName.startsWith("exitVM")) {
- throw new SecurityException("test");
- }
- }
- };
- System.setSecurityManager(securityManager);
- daemon.stop();
- } catch (final SecurityException ex) {
- // ignore
- } finally {
- System.setSecurityManager(currentSecurityManager);
- }
- }
-
- @Override
- public void run() {
- try {
- daemon.init(null);
- } catch (final IOException e) {
- throw new LoggingException("Cannot initialize embedded Cassandra instance", e);
- }
- daemon.start();
- latch.countDown();
- }
- }
-}
http://git-wip-us.apache.org/repos/asf/logging-log4j2/blob/44db87d0/log4j-cassandra/src/test/resources/CassandraAppenderTest.xml
----------------------------------------------------------------------
diff --git a/log4j-cassandra/src/test/resources/CassandraAppenderTest.xml b/log4j-cassandra/src/test/resources/CassandraAppenderTest.xml
index b3956d1..e1f37e9 100644
--- a/log4j-cassandra/src/test/resources/CassandraAppenderTest.xml
+++ b/log4j-cassandra/src/test/resources/CassandraAppenderTest.xml
@@ -32,7 +32,7 @@
</Cassandra>
</Appenders>
<Loggers>
- <Logger name="org.apache.logging.log4j.nosql.appender.cassandra" level="DEBUG">
+ <Logger name="org.apache.logging.log4j.cassandra" level="DEBUG">
<AppenderRef ref="Cassandra"/>
</Logger>
<Root level="ERROR"/>
http://git-wip-us.apache.org/repos/asf/logging-log4j2/blob/44db87d0/log4j-couchdb/src/main/java/org/apache/logging/log4j/couchdb/CouchDbConnection.java
----------------------------------------------------------------------
diff --git a/log4j-couchdb/src/main/java/org/apache/logging/log4j/couchdb/CouchDbConnection.java b/log4j-couchdb/src/main/java/org/apache/logging/log4j/couchdb/CouchDbConnection.java
new file mode 100644
index 0000000..822f4a2
--- /dev/null
+++ b/log4j-couchdb/src/main/java/org/apache/logging/log4j/couchdb/CouchDbConnection.java
@@ -0,0 +1,69 @@
+/*
+ * 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.couchdb;
+
+import java.util.Map;
+
+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.DefaultNoSqlObject;
+import org.apache.logging.log4j.core.appender.nosql.NoSqlConnection;
+import org.apache.logging.log4j.core.appender.nosql.NoSqlObject;
+import org.apache.logging.log4j.util.Strings;
+import org.lightcouch.CouchDbClient;
+import org.lightcouch.Response;
+
+/**
+ * The Apache CouchDB implementation of {@link NoSqlConnection}.
+ */
+public final class CouchDbConnection extends AbstractNoSqlConnection<Map<String, Object>, DefaultNoSqlObject> {
+ private final CouchDbClient client;
+
+ public CouchDbConnection(final CouchDbClient client) {
+ this.client = client;
+ }
+
+ @Override
+ public DefaultNoSqlObject createObject() {
+ return new DefaultNoSqlObject();
+ }
+
+ @Override
+ public DefaultNoSqlObject[] createList(final int length) {
+ return new DefaultNoSqlObject[length];
+ }
+
+ @Override
+ public void insertObject(final NoSqlObject<Map<String, Object>> object) {
+ try {
+ final Response response = this.client.save(object.unwrap());
+ if (Strings.isNotEmpty(response.getError())) {
+ throw new AppenderLoggingException(
+ "Failed to write log event to CouchDB due to error: " + response.getError() + '.');
+ }
+ } catch (final Exception e) {
+ throw new AppenderLoggingException("Failed to write log event to CouchDB due to error: " + e.getMessage(),
+ e);
+ }
+ }
+
+ @Override
+ protected void closeImpl() {
+ this.client.shutdown();
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/logging-log4j2/blob/44db87d0/log4j-couchdb/src/main/java/org/apache/logging/log4j/couchdb/CouchDbProvider.java
----------------------------------------------------------------------
diff --git a/log4j-couchdb/src/main/java/org/apache/logging/log4j/couchdb/CouchDbProvider.java b/log4j-couchdb/src/main/java/org/apache/logging/log4j/couchdb/CouchDbProvider.java
new file mode 100644
index 0000000..2b233a8
--- /dev/null
+++ b/log4j-couchdb/src/main/java/org/apache/logging/log4j/couchdb/CouchDbProvider.java
@@ -0,0 +1,161 @@
+/*
+ * 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.couchdb;
+
+import java.lang.reflect.Method;
+
+import org.apache.logging.log4j.Logger;
+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.PluginFactory;
+import org.apache.logging.log4j.core.config.plugins.convert.TypeConverters;
+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.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 org.lightcouch.CouchDbClient;
+import org.lightcouch.CouchDbProperties;
+
+/**
+ * The Apache CouchDB implementation of {@link NoSqlProvider}.
+ */
+@Plugin(name = "CouchDB", category = "Core", printObject = true)
+public final class CouchDbProvider implements NoSqlProvider<CouchDbConnection> {
+ private static final int HTTP = 80;
+ private static final int HTTPS = 443;
+ private static final Logger LOGGER = StatusLogger.getLogger();
+
+ private final CouchDbClient client;
+ private final String description;
+
+ private CouchDbProvider(final CouchDbClient client, final String description) {
+ this.client = client;
+ this.description = "couchDb{ " + description + " }";
+ }
+
+ @Override
+ public CouchDbConnection getConnection() {
+ return new CouchDbConnection(this.client);
+ }
+
+ @Override
+ public String toString() {
+ return this.description;
+ }
+
+ /**
+ * Factory method for creating an Apache CouchDB provider within the plugin manager.
+ *
+ * @param databaseName The name of the database to which log event documents will be written.
+ * @param protocol Either "http" or "https," defaults to "http" and mutually exclusive with
+ * {@code factoryClassName&factoryMethodName!=null}.
+ * @param server The host name of the CouchDB server, defaults to localhost and mutually exclusive with
+ * {@code factoryClassName&factoryMethodName!=null}.
+ * @param port The port that CouchDB is listening on, defaults to 80 if {@code protocol} is "http" and 443 if
+ * {@code protocol} is "https," and mutually exclusive with
+ * {@code factoryClassName&factoryMethodName!=null}.
+ * @param username The username to authenticate against the MongoDB server with, mutually exclusive with
+ * {@code factoryClassName&factoryMethodName!=null}.
+ * @param password The password to authenticate against the MongoDB server with, mutually exclusive with
+ * {@code factoryClassName&factoryMethodName!=null}.
+ * @param factoryClassName A fully qualified class name containing a static factory method capable of returning a
+ * {@link CouchDbClient} or {@link CouchDbProperties}.
+ * @param factoryMethodName The name of the public static factory method belonging to the aforementioned factory
+ * class.
+ * @return a new Apache CouchDB provider.
+ */
+ @PluginFactory
+ public static CouchDbProvider createNoSqlProvider(
+ @PluginAttribute("databaseName") final String databaseName,
+ @PluginAttribute("protocol") String protocol,
+ @PluginAttribute(value = "server", defaultString = "localhost") @ValidHost final String server,
+ @PluginAttribute(value = "port", defaultString = "0") @ValidPort final String port,
+ @PluginAttribute("username") final String username,
+ @PluginAttribute(value = "password", sensitive = true) final String password,
+ @PluginAttribute("factoryClassName") final String factoryClassName,
+ @PluginAttribute("factoryMethodName") final String factoryMethodName) {
+ CouchDbClient client;
+ 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 CouchDbClient) {
+ client = (CouchDbClient) object;
+ description = "uri=" + client.getDBUri();
+ } else if (object instanceof CouchDbProperties) {
+ final CouchDbProperties properties = (CouchDbProperties) object;
+ client = new CouchDbClient(properties);
+ description = "uri=" + client.getDBUri() + ", username=" + properties.getUsername()
+ + ", passwordHash=" + NameUtil.md5(password + CouchDbProvider.class.getName())
+ + ", maxConnections=" + properties.getMaxConnections() + ", connectionTimeout="
+ + properties.getConnectionTimeout() + ", socketTimeout=" + properties.getSocketTimeout();
+ } 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;
+ }
+ } 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)) {
+ if (protocol != null && protocol.length() > 0) {
+ protocol = protocol.toLowerCase();
+ if (!protocol.equals("http") && !protocol.equals("https")) {
+ LOGGER.error("Only protocols [http] and [https] are supported, [{}] specified.", protocol);
+ return null;
+ }
+ } else {
+ protocol = "http";
+ LOGGER.warn("No protocol specified, using default port [http].");
+ }
+
+ final int portInt = TypeConverters.convert(port, int.class, protocol.equals("https") ? HTTPS : HTTP);
+
+ if (Strings.isEmpty(username) || Strings.isEmpty(password)) {
+ LOGGER.error("You must provide a username and password for the CouchDB provider.");
+ return null;
+ }
+
+ client = new CouchDbClient(databaseName, false, protocol, server, portInt, username, password);
+ description = "uri=" + client.getDBUri() + ", username=" + username + ", passwordHash="
+ + NameUtil.md5(password + CouchDbProvider.class.getName());
+ } else {
+ LOGGER.error("No factory method was provided so the database name is required.");
+ return null;
+ }
+
+ return new CouchDbProvider(client, description);
+ }
+}
http://git-wip-us.apache.org/repos/asf/logging-log4j2/blob/44db87d0/log4j-couchdb/src/main/java/org/apache/logging/log4j/couchdb/package-info.java
----------------------------------------------------------------------
diff --git a/log4j-couchdb/src/main/java/org/apache/logging/log4j/couchdb/package-info.java b/log4j-couchdb/src/main/java/org/apache/logging/log4j/couchdb/package-info.java
new file mode 100644
index 0000000..9fc2513
--- /dev/null
+++ b/log4j-couchdb/src/main/java/org/apache/logging/log4j/couchdb/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 Apache CouchDB provider for the NoSQL Appender.
+ */
+package org.apache.logging.log4j.couchdb;
http://git-wip-us.apache.org/repos/asf/logging-log4j2/blob/44db87d0/log4j-couchdb/src/main/java/org/apache/logging/log4j/nosql/appender/couchdb/CouchDbConnection.java
----------------------------------------------------------------------
diff --git a/log4j-couchdb/src/main/java/org/apache/logging/log4j/nosql/appender/couchdb/CouchDbConnection.java b/log4j-couchdb/src/main/java/org/apache/logging/log4j/nosql/appender/couchdb/CouchDbConnection.java
deleted file mode 100644
index 2c3248d..0000000
--- a/log4j-couchdb/src/main/java/org/apache/logging/log4j/nosql/appender/couchdb/CouchDbConnection.java
+++ /dev/null
@@ -1,69 +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.couchdb;
-
-import java.util.Map;
-
-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.DefaultNoSqlObject;
-import org.apache.logging.log4j.core.appender.nosql.NoSqlConnection;
-import org.apache.logging.log4j.core.appender.nosql.NoSqlObject;
-import org.apache.logging.log4j.util.Strings;
-import org.lightcouch.CouchDbClient;
-import org.lightcouch.Response;
-
-/**
- * The Apache CouchDB implementation of {@link NoSqlConnection}.
- */
-public final class CouchDbConnection extends AbstractNoSqlConnection<Map<String, Object>, DefaultNoSqlObject> {
- private final CouchDbClient client;
-
- public CouchDbConnection(final CouchDbClient client) {
- this.client = client;
- }
-
- @Override
- public DefaultNoSqlObject createObject() {
- return new DefaultNoSqlObject();
- }
-
- @Override
- public DefaultNoSqlObject[] createList(final int length) {
- return new DefaultNoSqlObject[length];
- }
-
- @Override
- public void insertObject(final NoSqlObject<Map<String, Object>> object) {
- try {
- final Response response = this.client.save(object.unwrap());
- if (Strings.isNotEmpty(response.getError())) {
- throw new AppenderLoggingException(
- "Failed to write log event to CouchDB due to error: " + response.getError() + '.');
- }
- } catch (final Exception e) {
- throw new AppenderLoggingException("Failed to write log event to CouchDB due to error: " + e.getMessage(),
- e);
- }
- }
-
- @Override
- protected void closeImpl() {
- this.client.shutdown();
- }
-
-}