Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add Tomcat JULI implementation #102

Merged
merged 1 commit into from
Feb 22, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
75 changes: 75 additions & 0 deletions log4j-tomcat-juli/pom.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
<?xml version="1.0" encoding="UTF-8"?>
<!--
~ Copyright © 2024 Piotr P. Karwasz
~
~ Licensed under the Apache License, Version 2.0 (the "License");
~ you may not use this file except in compliance with the License.
~ You may obtain a copy of the License at
~
~ http://www.apache.org/licenses/LICENSE-2.0
~
~ Unless required by applicable law or agreed to in writing, software
~ distributed under the License is distributed on an "AS IS" BASIS,
~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
~ See the License for the specific language governing permissions and
~ limitations under the License.
-->
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>eu.copernik</groupId>
<artifactId>log4j-plugins-parent</artifactId>
<version>3.0.0-SNAPSHOT</version>
</parent>

<groupId>org.apache.logging.log4j</groupId>
<artifactId>log4j-tomcat-juli</artifactId>
<name>Tomcat JULI to Log4j API bridge</name>
<description>Tomcat JULI implementation that forwards to the Log4j API.</description>

<properties>
<bnd.baseline.fail.on.missing>false</bnd.baseline.fail.on.missing>
</properties>

<dependencies>
<dependency>
<groupId>biz.aQute.bnd</groupId>
<artifactId>biz.aQute.bnd.annotation</artifactId>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.apache.logging.log4j</groupId>
<artifactId>log4j-api</artifactId>
</dependency>
<dependency>
<groupId>org.apache.tomcat</groupId>
<artifactId>tomcat-juli</artifactId>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.assertj</groupId>
<artifactId>assertj-core</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.junit.jupiter</groupId>
<artifactId>junit-jupiter-api</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.apache.logging.log4j</groupId>
<artifactId>log4j-api-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.apache.logging.log4j</groupId>
<artifactId>log4j-core-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.mockito</groupId>
<artifactId>mockito-core</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
</project>
Original file line number Diff line number Diff line change
@@ -0,0 +1,143 @@
/*
* Copyright © 2024 Piotr P. Karwasz
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package eu.copernik.log4j.tomcat.juli;

import aQute.bnd.annotation.Resolution;
import aQute.bnd.annotation.spi.ServiceProvider;
import org.apache.juli.logging.Log;
import org.apache.juli.logging.LogFactory;
import org.apache.logging.log4j.Level;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Marker;
import org.apache.logging.log4j.MarkerManager;
import org.apache.logging.log4j.spi.ExtendedLogger;
import org.apache.logging.log4j.spi.LoggerContextFactory;

/**
* An implementation of {@link Log} that forwards everything to the appropriate Log4j API logger.
*/
@ServiceProvider(value = Log.class, resolution = Resolution.OPTIONAL)
public class Log4jLog implements Log {

private static final String FQCN = Log4jLog.class.getName();
private static final String LOG_FACTORY_FQCN = LogFactory.class.getName();
private static final Marker TOMCAT_MARKER = MarkerManager.getMarker("TOMCAT");

private ExtendedLogger logger;

// Only used by ServiceLoader
public Log4jLog() {
this(LogManager.ROOT_LOGGER_NAME);
}

public Log4jLog(final String name) {
this(LogManager.getFactory(), name);
}

Log4jLog(final LoggerContextFactory factory, final String name) {
this.logger = factory.getContext(LOG_FACTORY_FQCN, null, null, false).getLogger(name);
}

@Override
public boolean isDebugEnabled() {
return logger.isDebugEnabled(TOMCAT_MARKER);
}

@Override
public boolean isErrorEnabled() {
return logger.isDebugEnabled(TOMCAT_MARKER);
}

@Override
public boolean isFatalEnabled() {
return logger.isFatalEnabled(TOMCAT_MARKER);
}

@Override
public boolean isInfoEnabled() {
return logger.isInfoEnabled(TOMCAT_MARKER);
}

@Override
public boolean isTraceEnabled() {
return logger.isTraceEnabled(TOMCAT_MARKER);
}

@Override
public boolean isWarnEnabled() {
return logger.isWarnEnabled(TOMCAT_MARKER);
}

@Override
public void trace(final Object message) {
logger.logIfEnabled(FQCN, Level.TRACE, TOMCAT_MARKER, message, null);
}

@Override
public void trace(final Object message, final Throwable t) {
logger.logIfEnabled(FQCN, Level.TRACE, TOMCAT_MARKER, message, t);
}

@Override
public void debug(final Object message) {
logger.logIfEnabled(FQCN, Level.DEBUG, TOMCAT_MARKER, message, null);
}

@Override
public void debug(final Object message, final Throwable t) {
logger.logIfEnabled(FQCN, Level.DEBUG, TOMCAT_MARKER, message, t);
}

@Override
public void info(final Object message) {
logger.logIfEnabled(FQCN, Level.INFO, TOMCAT_MARKER, message, null);
}

@Override
public void info(final Object message, final Throwable t) {
logger.logIfEnabled(FQCN, Level.INFO, TOMCAT_MARKER, message, t);
}

@Override
public void warn(final Object message) {
logger.logIfEnabled(FQCN, Level.WARN, TOMCAT_MARKER, message, null);
}

@Override
public void warn(final Object message, final Throwable t) {
logger.logIfEnabled(FQCN, Level.WARN, TOMCAT_MARKER, message, t);
}

@Override
public void error(final Object message) {
logger.logIfEnabled(FQCN, Level.ERROR, TOMCAT_MARKER, message, null);
}

@Override
public void error(final Object message, final Throwable t) {
logger.logIfEnabled(FQCN, Level.ERROR, TOMCAT_MARKER, message, t);
}

@Override
public void fatal(final Object message) {
logger.logIfEnabled(FQCN, Level.FATAL, TOMCAT_MARKER, message, null);
}

@Override
public void fatal(final Object message, final Throwable t) {
logger.logIfEnabled(FQCN, Level.FATAL, TOMCAT_MARKER, message, t);
}
}
81 changes: 81 additions & 0 deletions log4j-tomcat-juli/src/test/java/Log4jLogTest.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
/*
* Copyright © 2024 Piotr P. Karwasz
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import static org.assertj.core.api.Assertions.assertThat;

import java.util.List;
import org.apache.juli.logging.Log;
import org.apache.juli.logging.LogFactory;
import org.apache.logging.log4j.Level;
import org.apache.logging.log4j.core.LogEvent;
import org.apache.logging.log4j.core.LoggerContext;
import org.apache.logging.log4j.core.config.Configuration;
import org.apache.logging.log4j.core.test.appender.ListAppender;
import org.junit.jupiter.api.Test;

class Log4jLogTest {

private static final String MESSAGE = "MESSAGE";
private static final Throwable T = new RuntimeException();

@Test
void location() {
final Log log = LogFactory.getLog("location");
int i = 0;
int currentLine = 37;
log.trace(MESSAGE + i++);
log.trace(MESSAGE + i++, T);
log.debug(MESSAGE + i++);
log.debug(MESSAGE + i++, T);
log.info(MESSAGE + i++);
log.info(MESSAGE + i++, T);
log.warn(MESSAGE + i++);
log.warn(MESSAGE + i++, T);
log.error(MESSAGE + i++);
log.error(MESSAGE + i++, T);
log.fatal(MESSAGE + i++);
log.fatal(MESSAGE + i, T);
// Verification
final LoggerContext context = LoggerContext.getContext(false);
final Configuration config = context.getConfiguration();
final ListAppender list = config.getAppender("list");
final List<LogEvent> events = list.getEvents();
i = 0;
assertThat(events).hasSize(12);
assertLocation(events.get(i), Level.TRACE, MESSAGE + i++, null, ++currentLine);
assertLocation(events.get(i), Level.TRACE, MESSAGE + i++, T, ++currentLine);
assertLocation(events.get(i), Level.DEBUG, MESSAGE + i++, null, ++currentLine);
assertLocation(events.get(i), Level.DEBUG, MESSAGE + i++, T, ++currentLine);
assertLocation(events.get(i), Level.INFO, MESSAGE + i++, null, ++currentLine);
assertLocation(events.get(i), Level.INFO, MESSAGE + i++, T, ++currentLine);
assertLocation(events.get(i), Level.WARN, MESSAGE + i++, null, ++currentLine);
assertLocation(events.get(i), Level.WARN, MESSAGE + i++, T, ++currentLine);
assertLocation(events.get(i), Level.ERROR, MESSAGE + i++, null, ++currentLine);
assertLocation(events.get(i), Level.ERROR, MESSAGE + i++, T, ++currentLine);
assertLocation(events.get(i), Level.FATAL, MESSAGE + i++, null, ++currentLine);
assertLocation(events.get(i), Level.FATAL, MESSAGE + i, T, ++currentLine);
}

private void assertLocation(
final LogEvent event, final Level level, final String message, final Throwable t, final int lineNumber) {
assertThat(event.getLevel()).isEqualTo(level);
assertThat(event.getMessage().getFormattedMessage()).isEqualTo(message);
assertThat(event.getThrown()).isEqualTo(t);
final StackTraceElement location = event.getSource();
assertThat(location.getClassName()).isEqualTo(Log4jLogTest.class.getName());
assertThat(location.getMethodName()).isEqualTo("location");
assertThat(location.getLineNumber()).isEqualTo(lineNumber);
}
}
26 changes: 26 additions & 0 deletions log4j-tomcat-juli/src/test/resources/log4j2-test.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
<?xml version="1.0" encoding="UTF-8"?>
<!--
~ Copyright © 2024 Piotr P. Karwasz
~
~ Licensed under the Apache License, Version 2.0 (the "License");
~ you may not use this file except in compliance with the License.
~ You may obtain a copy of the License at
~
~ http://www.apache.org/licenses/LICENSE-2.0
~
~ Unless required by applicable law or agreed to in writing, software
~ distributed under the License is distributed on an "AS IS" BASIS,
~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
~ See the License for the specific language governing permissions and
~ limitations under the License.
-->
<Configuration status="OFF">
<Appenders>
<List name="list"/>
</Appenders>
<Loggers>
<Root level="TRACE">
<AppenderRef ref="list"/>
</Root>
</Loggers>
</Configuration>
1 change: 1 addition & 0 deletions pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,7 @@
<modules>
<module>log4j-tomcat</module>
<module>log4j-tomcat-env</module>
<module>log4j-tomcat-juli</module>
</modules>

<scm>
Expand Down
10 changes: 10 additions & 0 deletions src/changelog/.3.x.x/101_add_tomcat_juli.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
<?xml version="1.0" encoding="UTF-8"?>
<entry xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns="http://logging.apache.org/log4j/changelog"
xsi:schemaLocation="http://logging.apache.org/log4j/changelog https://logging.apache.org/log4j/changelog-0.1.3.xsd"
type="changed">
<issue id="101" link="https://github.com/copernik-eu/log4j-plugins/issues/101"/>
<description format="asciidoc">
Add Tomcat JULI implementation in artifact `log4j-tomcat-juli`.
</description>
</entry>