Reputation: 1922
I’m getting killed here trying to redirect log4j to a Cassandra database. I’ve spent an enormous amount of time trying everything I could think of, so I won’t be able to cover everything I’ve tried, but I’ll try to describe what I’m trying to do and what I’m running into as concisely as I can.
Our codebase currently uses log4j 1.2.17, so my first try is to get com.datastax.logging.appender.CassandraAppender working.
The relevant Maven dependency is this:
<dependency>
<groupId>com.datastax.logging</groupId>
<artifactId>cassandra-log4j-appender</artifactId>
<version>3.1.0</version>
</dependency>
The relevant appender entry in log4j.xml is this:
<appender name="cassandra" class="com.datastax.logging.appender.CassandraAppender"/>
The appender defaults to “localhost”, or “127.0.0.1”, I don’t remember which, and I’ve tried both explicitly. It also defaults to port 9042, which is what my Cassandra is configured for. In fact, here’s the console output from Cassandra:
Binding thrift service to localhost/127.0.0.1:9160
All I can get out of this is an exception:
log4j:ERROR Error
com.datastax.driver.core.exceptions.NoHostAvailableException: All host(s) tried for query failed (tried: localhost/127.0.0.1:9042 (null))
at com.datastax.driver.core.ControlConnection.reconnectInternal(ControlConnection.java:196)
at com.datastax.driver.core.ControlConnection.connect(ControlConnection.java:80)
at com.datastax.driver.core.Cluster$Manager.init(Cluster.java:1145)
at com.datastax.driver.core.Cluster.init(Cluster.java:149)
at com.datastax.driver.core.Cluster.connect(Cluster.java:225)
at com.datastax.logging.appender.CassandraAppender.initClient(CassandraAppender.java:141)
at com.datastax.logging.appender.CassandraAppender.append(CassandraAppender.java:97)
at org.apache.log4j.AppenderSkeleton.doAppend(AppenderSkeleton.java:251)
at org.apache.log4j.helpers.AppenderAttachableImpl.appendLoopOnAppenders(AppenderAttachableImpl.java:66)
at org.apache.log4j.Category.callAppenders(Category.java:206)
<snip>
log4j:ERROR Error setting up cassandra logging schema: com.datastax.driver.core.exceptions.NoHostAvailableException: All host(s) tried for query failed (tried: localhost/127.0.0.1:9042 (null))
After banging my head against the wall, I thought I would try to get the Apache Cassandra appender working. Unfortunately, it’s only for log4j2, and updating our codebase is non-trivial. That said, I’m having even less luck with it.
I created a small test project to try to get something working. In log4j2, Cassandra is supposed to be a built-in appender type, according to https://logging.apache.org/log4j/2.x/manual/appenders.html#CassandraAppender. However, it absolutely can’t find it when I specify it in my log4j2.xml file. Here’s my file:
<?xml version="1.0" encoding="UTF-8"?>
<Configuration status="INFO">
<Appenders>
<Console name="Console" target="SYSTEM_OUT">
<PatternLayout pattern="%d{HH:mm:ss.SSS} [%t] %-5level %logger{36} - %msg%n" />
</Console>
<File name="MyFile" fileName="all.log" immediateFlush="false" append="false">
<PatternLayout pattern="%d{yyy-MM-dd HH:mm:ss.SSS} [%t] %-5level %logger{36} - %msg%n"/>
</File>
<Cassandra name="Cassandra" clusterName="Test Cluster" keyspace="gii" table="gii_event_log" bufferSize="10" batched="true">
<SocketAddress host="localhost" port="9042"/>
<ColumnMapping name="id" pattern="%uuid{TIME}" type="java.util.UUID"/>
<ColumnMapping name="identifier" pattern="%marker"/>
<ColumnMapping name="message" pattern="%message"/>
<ColumnMapping name="priority" pattern="%level"/>
<ColumnMapping name="scope" pattern="%level"/>
<ColumnMapping name="time_stamp" literal="now()"/>
<ColumnMapping name="type" pattern="%level"/>
</Cassandra>
</Appenders>
<Loggers>
<Root level="debug">
<AppenderRef ref="Console"/>
<AppenderRef ref="MyFile"/>
<AppenderRef ref="Cassandra"/>
</Root>
</Loggers>
</Configuration>
Here’s what happens:
Exception in thread "main" java.lang.NoClassDefFoundError: org/apache/logging/log4j/LogManager
at com.ge.enconn.TestClass.<init>(TestClass.java:10)
at com.ge.enconn.App.main(App.java:11)
Caused by: java.lang.ClassNotFoundException: org.apache.logging.log4j.LogManager
at java.net.URLClassLoader.findClass(Unknown Source)
at java.lang.ClassLoader.loadClass(Unknown Source)
at sun.misc.Launcher$AppClassLoader.loadClass(Unknown Source)
at java.lang.ClassLoader.loadClass(Unknown Source)
... 2 more
Here are the relevant dependencies from my pom file:
<dependency>
<groupId>org.apache.logging.log4j</groupId>
<artifactId>log4j-api</artifactId>
<version>${log4j.version}</version>
</dependency>
<dependency>
<groupId>org.apache.logging.log4j</groupId>
<artifactId>log4j-core</artifactId>
<version>${log4j.version}</version>
</dependency>
<dependency>
<groupId>org.apache.logging.log4j</groupId>
<artifactId>log4j-nosql</artifactId>
<version>${log4j.version}</version>
</dependency>
<dependency>
<groupId>com.datastax.cassandra</groupId>
<artifactId>cassandra-driver-core</artifactId>
<version>3.1.0</version>
</dependency>
The pom for log4j-nosql is here: https://github.com/apache/logging-log4j2/blob/master/log4j-nosql/pom.xml. This should get it into my classpath, right?
Upvotes: 5
Views: 2314
Reputation: 1
As soon as I added the following dependency the error was resolved.
ERROR: , Exception in thread "main" java.lang.NoClassDefFoundError: org/apache/logging/log4j/LogManager
Dependency:
<dependency>
<groupId>org.apache.logging.log4j</groupId>
<artifactId>log4j-cassandra</artifactId>
<version>2.11.1</version>
</dependency>
Upvotes: 0
Reputation: 12840
First Use this inside dependencies tag of the pom file :
<!-- Apache Cassandra -->
<dependency>
<groupId>com.datastax.cassandra</groupId>
<artifactId>cassandra-driver-core</artifactId>
<version>3.1.4</version>
</dependency>
<!-- Log4j2 -->
<dependency>
<groupId>org.apache.logging.log4j</groupId>
<artifactId>log4j-api</artifactId>
<version>2.8.1</version>
</dependency>
<dependency>
<groupId>org.apache.logging.log4j</groupId>
<artifactId>log4j-core</artifactId>
<version>2.8.1</version>
</dependency>
<dependency>
<groupId>org.apache.logging.log4j</groupId>
<artifactId>log4j-1.2-api</artifactId>
<version>2.8.1</version>
</dependency>
<dependency>
<groupId>org.apache.logging.log4j</groupId>
<artifactId>log4j-jcl</artifactId>
<version>2.8.1</version>
</dependency>
<dependency>
<groupId>org.apache.logging.log4j</groupId>
<artifactId>log4j-slf4j-impl</artifactId>
<version>2.8.1</version>
</dependency>
<dependency>
<groupId>org.apache.logging.log4j</groupId>
<artifactId>log4j-nosql</artifactId>
<version>2.8.1</version>
</dependency>
Second Create table in Cassandra :
CREATE TABLE gii_event_log (
id timeuuid PRIMARY KEY,
identifier text,
message text,
priority text,
scope text,
time_stamp timeuuid,
type text
);
Third Update your log4j2 file check host value if you get No Host available ERROR. And add username and password inside Cassandra tag if you get Authentication ERROR.
Sample Java Code :
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
/**
*
* @author Ashraful Islam
*/
public class CassandraLog {
private final static Logger LOGGER = LogManager.getLogger();
public void printDemo() {
for (int i = 0; i < 10; i++) {
System.out.println(i);
LOGGER.info("Testing {}", i);
LOGGER.error("Testing {}", i);
LOGGER.debug("Testing {}", i);
}
}
/**
* @param args the command line arguments
*/
public static void main(String[] args) {
new CassandraLog().printDemo();
}
}
Output :
id | identifier | message | priority | scope | time_stamp | type
--------------------------------------+------------+-----------+----------+-------+--------------------------------------+-------
b85caa03-0ecb-11e7-af5e-b083fe92c73a | | Testing 1 | ERROR | ERROR | b85222b2-0ecb-11e7-a374-55d83eefb705 | ERROR
b85eccec-0ecb-11e7-af5e-b083fe92c73a | | Testing 4 | DEBUG | DEBUG | b85222bb-0ecb-11e7-a374-55d83eefb705 | DEBUG
b8602c83-0ecb-11e7-af5e-b083fe92c73a | | Testing 6 | ERROR | ERROR | b85222c2-0ecb-11e7-a374-55d83eefb705 | ERROR
b862285b-0ecb-11e7-af5e-b083fe92c73a | | Testing 9 | DEBUG | DEBUG | b85222ca-0ecb-11e7-a374-55d83eefb705 | DEBUG
Upvotes: 4