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

Fix log4j #5313

Merged
merged 4 commits into from
Sep 16, 2019
Merged
Show file tree
Hide file tree
Changes from 3 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
30 changes: 13 additions & 17 deletions build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -12,9 +12,7 @@ buildscript {
repositories {
mavenLocal()
jcenter()
maven {
url 'https://oss.sonatype.org/content/groups/public'
}
maven { url 'https://oss.sonatype.org/content/groups/public' }
}
}

Expand Down Expand Up @@ -95,9 +93,8 @@ sourceSets {
repositories {
mavenLocal()
jcenter()
maven {
url 'https://oss.sonatype.org/content/groups/public'
}
maven { url 'https://oss.sonatype.org/content/groups/public' }
maven { url 'https://repository.apache.org/snapshots' }
}

configurations {
Expand Down Expand Up @@ -174,12 +171,12 @@ dependencies {
compile 'org.jsoup:jsoup:1.12.1'
compile 'com.mashape.unirest:unirest-java:1.4.9'

// >1.8.0-beta is required for java 9 compatibility
compile 'org.slf4j:slf4j-api:2.0.0-alpha0'
compile 'org.apache.logging.log4j:log4j-slf4j18-impl:2.12.1'
compile 'org.apache.logging.log4j:log4j-jcl:2.12.1'
compile 'org.apache.logging.log4j:log4j-api:2.12.1'
compile 'org.apache.logging.log4j:log4j-core:2.12.1'
compile 'org.apache.logging.log4j:log4j-jcl:3.0.0-SNAPSHOT'
compile group: 'org.apache.logging.log4j', name: 'log4j-slf4j18-impl', version: '3.0.0-SNAPSHOT'
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

please change this back to the more compact format or we will all get hell of merge conflicts

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I thought that this is the "new" format, as many other dependencies are specified in this form. Personally, I have no strong opinion here but would prefer the extended form if only for the reason that you can simply copy & paste from maven.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's the same, just more verbose.
We should however be consistent.
I always use https://sagioto.github.io/maven2gradle/ to get the compact variant

implementation group: 'org.apache.logging.log4j', name: 'log4j-api', version: '3.0.0-SNAPSHOT'
compile group: 'org.apache.logging.log4j', name: 'log4j-core', version: '3.0.0-SNAPSHOT'
annotationProcessor group: 'org.apache.logging.log4j', name: 'log4j-core', version: '3.0.0-SNAPSHOT'

compile 'de.undercouch:citeproc-java:1.0.1'

Expand All @@ -203,16 +200,18 @@ dependencies {
*/

compile group: 'com.microsoft.azure', name: 'applicationinsights-core', version: '2.4.1'
compile group: 'com.microsoft.azure', name: 'applicationinsights-logging-log4j2', version: '2.4.1'
compile (group: 'com.microsoft.azure', name: 'applicationinsights-logging-log4j2', version: '2.4.1') {
exclude module: "log4j-core"
}

testCompile 'junit:junit:4.12'
testImplementation 'org.junit.jupiter:junit-jupiter:5.5.2'
testRuntimeOnly 'org.junit.vintage:junit-vintage-engine:5.5.2'
testCompile 'org.junit.platform:junit-platform-launcher:1.5.2'

testCompile 'net.bytebuddy:byte-buddy-parent:1.10.1'
testRuntime 'org.apache.logging.log4j:log4j-core:2.12.0'
testRuntime 'org.apache.logging.log4j:log4j-jul:2.12.1'
testRuntime group: 'org.apache.logging.log4j', name: 'log4j-core', version: '3.0.0-SNAPSHOT'
testRuntime group: 'org.apache.logging.log4j', name: 'log4j-jul', version: '3.0.0-SNAPSHOT'
testCompile 'org.mockito:mockito-core:3.0.0'
//testCompile 'com.github.tomakehurst:wiremock:2.24.1'
testCompile ('org.reflections:reflections:0.9.11') {
Expand Down Expand Up @@ -372,9 +371,6 @@ task generateModsSource(type: XjcTask) {
tasks.withType(JavaCompile) {
// use UTF-8
options.encoding = 'UTF-8'

// ignore annotation processor from log4j2
options.compilerArgs += '-proc:none'
}

compileJava {
Expand Down
3 changes: 3 additions & 0 deletions src/main/java/module-info.java
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,10 @@
requires org.slf4j;
requires org.apache.logging.log4j;
requires org.apache.logging.log4j.core;
requires org.apache.logging.log4j.plugins;
requires applicationinsights.logging.log4j2;
provides org.apache.logging.log4j.plugins.processor.PluginService
with org.jabref.gui.logging.plugins.Log4jPlugins;

// Preferences and XML
requires java.prefs;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,30 +3,27 @@
import org.jabref.Globals;
import org.jabref.logic.logging.LogMessages;

import com.microsoft.applicationinsights.log4j.v2.internal.ApplicationInsightsLogEvent;
import com.microsoft.applicationinsights.telemetry.ExceptionTelemetry;
import com.microsoft.applicationinsights.telemetry.Telemetry;
import com.microsoft.applicationinsights.telemetry.TraceTelemetry;
import org.apache.logging.log4j.core.Filter;
import org.apache.logging.log4j.core.LogEvent;
import org.apache.logging.log4j.core.appender.AbstractAppender;
import org.apache.logging.log4j.core.config.plugins.Plugin;
import org.apache.logging.log4j.core.config.plugins.PluginAttribute;
import org.apache.logging.log4j.core.config.plugins.PluginElement;
import org.apache.logging.log4j.core.config.plugins.PluginFactory;
import org.apache.logging.log4j.core.config.Property;
import org.apache.logging.log4j.plugins.Plugin;
import org.apache.logging.log4j.plugins.PluginBuilderFactory;

@Plugin(name = "OurApplicationInsightsAppender", category = "Core", elementType = "appender", printObject = true)
@SuppressWarnings("unused") // class is indirectly constructed by log4j
public class ApplicationInsightsAppender extends AbstractAppender {

private ApplicationInsightsAppender(String name, Filter filter) {
super(name, filter, null);
private ApplicationInsightsAppender(String name, Filter filter, boolean ignoreExceptions, Property[] properties) {
super(name, filter, null, ignoreExceptions, properties);
}

@PluginFactory
public static ApplicationInsightsAppender createAppender(@PluginAttribute("name") String name,
@PluginElement("Filters") Filter filter) {
return new ApplicationInsightsAppender(name, filter);
@PluginBuilderFactory
public static <B extends Builder<B>> B newBuilder() {
return new Builder<B>().asBuilder();
}

/**
Expand All @@ -51,4 +48,14 @@ public void append(LogEvent rawEvent) {

Globals.getTelemetryClient().ifPresent(client -> client.track(telemetry));
}

public static class Builder<B extends Builder<B>> extends AbstractAppender.Builder<B>
implements org.apache.logging.log4j.plugins.util.Builder<ApplicationInsightsAppender> {

@Override
public ApplicationInsightsAppender build() {
return new ApplicationInsightsAppender(this.getName(), this.getFilter(), this.isIgnoreExceptions(), this.getPropertyArray());
}
}

}
130 changes: 130 additions & 0 deletions src/main/java/org/jabref/gui/logging/ApplicationInsightsLogEvent.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,130 @@
package org.jabref.gui.logging;

/*
* ApplicationInsights-Java
* Copyright (c) Microsoft Corporation
* All rights reserved.
*
* MIT License
* Permission is hereby granted, free of charge, to any person obtaining a copy of this
* software and associated documentation files (the ""Software""), to deal in the Software
* without restriction, including without limitation the rights to use, copy, modify, merge,
* publish, distribute, sublicense, and/or sell copies of the Software, and to permit
* persons to whom the Software is furnished to do so, subject to the following conditions:
* The above copyright notice and this permission notice shall be included in all copies or
* substantial portions of the Software.
* THE SOFTWARE IS PROVIDED *AS IS*, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
* INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
* PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE
* FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
* OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
* DEALINGS IN THE SOFTWARE.
*/

import java.util.HashMap;
import java.util.Map;

import com.microsoft.applicationinsights.internal.common.ApplicationInsightsEvent;
import com.microsoft.applicationinsights.internal.logger.InternalLogger;
import com.microsoft.applicationinsights.telemetry.SeverityLevel;
import org.apache.logging.log4j.core.LogEvent;
import org.apache.logging.log4j.spi.StandardLevel;

// TODO: Remove this copy as soon as the one included in AI is compatible with log4j 3
public final class ApplicationInsightsLogEvent extends ApplicationInsightsEvent {

private LogEvent logEvent;

public ApplicationInsightsLogEvent(LogEvent logEvent) {
this.logEvent = logEvent;
}

@Override
public String getMessage() {
String message = this.logEvent.getMessage() != null ?
this.logEvent.getMessage().getFormattedMessage() :
"Log4j Trace";

return message;
}

@Override
public boolean isException() {
return this.logEvent.getThrown() != null;
}

@Override
public Exception getException() {
Exception exception = null;

if (isException()) {
Throwable throwable = this.logEvent.getThrown();
exception = throwable instanceof Exception ? (Exception) throwable : new Exception(throwable);
}

return exception;
}

@Override
public Map<String, String> getCustomParameters() {

Map<String, String> metaData = new HashMap<String, String>();

metaData.put("SourceType", "Log4j");

addLogEventProperty("LoggerName", logEvent.getLoggerName(), metaData);
addLogEventProperty("LoggingLevel", logEvent.getLevel() != null ? logEvent.getLevel().name() : null, metaData);
addLogEventProperty("ThreadName", logEvent.getThreadName(), metaData);
addLogEventProperty("TimeStamp", getFormattedDate(logEvent.getTimeMillis()), metaData);

if (isException()) {
addLogEventProperty("Logger Message", getMessage(), metaData);
}

if (logEvent.isIncludeLocation()) {
StackTraceElement stackTraceElement = logEvent.getSource();

addLogEventProperty("ClassName", stackTraceElement.getClassName(), metaData);
addLogEventProperty("FileName", stackTraceElement.getFileName(), metaData);
addLogEventProperty("MethodName", stackTraceElement.getMethodName(), metaData);
addLogEventProperty("LineNumber", String.valueOf(stackTraceElement.getLineNumber()), metaData);
}

for (Map.Entry<String, String> entry : logEvent.getContextData().toMap().entrySet()) {
addLogEventProperty(entry.getKey(), entry.getValue(), metaData);
}

// TODO: Username, domain and identity should be included as in .NET version.
// TODO: Should check, seems that it is not included in Log4j2.

return metaData;
}

@Override
public SeverityLevel getNormalizedSeverityLevel() {
int log4jLevelAsInt = logEvent.getLevel().intLevel();

switch (StandardLevel.getStandardLevel(log4jLevelAsInt)) {
case FATAL:
return SeverityLevel.Critical;

case ERROR:
return SeverityLevel.Error;

case WARN:
return SeverityLevel.Warning;

case INFO:
return SeverityLevel.Information;

case TRACE:
case DEBUG:
case ALL:
return SeverityLevel.Verbose;

default:
InternalLogger.INSTANCE.error("Unknown Log4j v2 option, %d, using TRACE level as default", log4jLevelAsInt);
return SeverityLevel.Verbose;
}
}
}
41 changes: 17 additions & 24 deletions src/main/java/org/jabref/gui/logging/GuiAppender.java
Original file line number Diff line number Diff line change
@@ -1,43 +1,27 @@
package org.jabref.gui.logging;

import java.io.Serializable;

import org.jabref.gui.util.DefaultTaskExecutor;
import org.jabref.logic.logging.LogMessages;

import org.apache.logging.log4j.core.Filter;
import org.apache.logging.log4j.core.Layout;
import org.apache.logging.log4j.core.LogEvent;
import org.apache.logging.log4j.core.appender.AbstractAppender;
import org.apache.logging.log4j.core.config.plugins.Plugin;
import org.apache.logging.log4j.core.config.plugins.PluginAttribute;
import org.apache.logging.log4j.core.config.plugins.PluginElement;
import org.apache.logging.log4j.core.config.plugins.PluginFactory;
import org.apache.logging.log4j.core.config.Property;
import org.apache.logging.log4j.core.impl.MutableLogEvent;
import org.apache.logging.log4j.core.layout.PatternLayout;
import org.apache.logging.log4j.plugins.Plugin;
import org.apache.logging.log4j.plugins.PluginBuilderFactory;

@Plugin(name = "GuiAppender", category = "Core", elementType = "appender", printObject = true)
@SuppressWarnings("unused") // class is indirectly constructed by log4j
public class GuiAppender extends AbstractAppender {

private GuiAppender(String name, Filter filter, Layout<? extends Serializable> layout) {
super(name, filter, layout);
private GuiAppender(String name, Filter filter, boolean ignoreExceptions, Property[] properties) {
super(name, filter, null, ignoreExceptions, properties);
}

@PluginFactory
public static GuiAppender createAppender(@PluginAttribute("name") String name,
@PluginElement("Layout") Layout<?> layout,
@PluginElement("Filters") Filter filter) {

if (name == null) {
LOGGER.error("No name provided for GuiAppender");
return null;
}

if (layout == null) {
layout = PatternLayout.createDefaultLayout();
}
return new GuiAppender(name, filter, layout);
@PluginBuilderFactory
public static <B extends GuiAppender.Builder<B>> B newBuilder() {
return new GuiAppender.Builder<B>().asBuilder();
}

/**
Expand All @@ -50,4 +34,13 @@ public void append(LogEvent event) {
copy.initFrom(event);
DefaultTaskExecutor.runInJavaFXThread(() -> LogMessages.getInstance().add(copy));
}

public static class Builder<B extends GuiAppender.Builder<B>> extends AbstractAppender.Builder<B>
implements org.apache.logging.log4j.plugins.util.Builder<GuiAppender> {

@Override
public GuiAppender build() {
return new GuiAppender(this.getName(), this.getFilter(), this.isIgnoreExceptions(), this.getPropertyArray());
}
}
}
6 changes: 2 additions & 4 deletions src/main/resources/log4j2.xml
Original file line number Diff line number Diff line change
@@ -1,12 +1,10 @@
<?xml version="1.0" encoding="UTF-8"?>
<Configuration status="INFO" packages="org.jabref">
<Configuration status="INFO">
<Appenders>
<Console name="CONSOLE" target="SYSTEM_OUT">
<PatternLayout pattern="%d{HH:mm:ss.SSS} [%t] %-5level %logger{36} - %msg%n" />
</Console>
<GuiAppender name="GuiLogger">
<PatternLayout pattern="%d{HH:mm:ss.SSS} [%t] %-5level %logger{36} - %msg%n" />
</GuiAppender>
<GuiAppender name="GuiLogger"/>
<OurApplicationInsightsAppender name="applicationInsightsAppender"/>
</Appenders>
<Loggers>
Expand Down