问题描述
我们想将log4j2用作log bitting用Grails3.
从我到目前为止我能找到的东西.我们有许多使用各种记录仪的下属依赖关系,因此我们需要使用SLF4J API.然后,我们需要将每个将SLF4J API重新定向到记录绑定,而是将每个都重新定向到log4j2绑定.
,而不是让SLF4J API重新指导SLF4J API.由于Grails 3使用了记录绑定,因此我计划通过build.gradle中的每个依赖关系.这个可以吗?更新:是
我们还需要将Log4J2 API桥接到SLF4J API?我们需要什么依赖性?更新:请参见下文.
最后,我假设我们需要抛弃Grails 3 logback.groovy配置,然后将Log4J2配置之一放入SRC/MAIN/RESOUDIANT中.更新:是
我会在我们弄清楚的情况下发布更新,但是我敢打赌有人以前做过.
更新2016-03-18:
这很简单.我在我的Grails 3项目上做了一个./gradlew依赖关系,以查看哪些依赖项在记录绑定/实现中都拉动了(group:'ch.qos.logback',模块:'logback-classic')>
首先,这是通过" Grails create-app testit"命令生成的默认build.gradle:
buildscript { ext { grailsVersion = project.grailsVersion } repositories { mavenLocal() maven { url "https://repo.grails.org/grails/core" } } dependencies { classpath "org.grails:grails-gradle-plugin:$grailsVersion" classpath "com.bertramlabs.plugins:asset-pipeline-gradle:2.5.0" classpath "org.grails.plugins:hibernate4:5.0.2" } } version "0.1" group "testit" apply plugin:"eclipse" apply plugin:"idea" apply plugin:"war" apply plugin:"org.grails.grails-web" apply plugin:"org.grails.grails-gsp" apply plugin:"asset-pipeline" ext { grailsVersion = project.grailsVersion gradleWrapperVersion = project.gradleWrapperVersion } repositories { mavenLocal() maven { url "https://repo.grails.org/grails/core" } } dependencyManagement { imports { mavenBom "org.grails:grails-bom:$grailsVersion" } applyMavenExclusions false } dependencies { compile "org.springframework.boot:spring-boot-starter-logging" compile "org.springframework.boot:spring-boot-autoconfigure" compile "org.grails:grails-core" compile "org.springframework.boot:spring-boot-starter-actuator" compile "org.springframework.boot:spring-boot-starter-tomcat" compile "org.grails:grails-dependencies" compile "org.grails:grails-web-boot" compile "org.grails.plugins:cache" compile "org.grails.plugins:scaffolding" compile "org.grails.plugins:hibernate4" compile "org.hibernate:hibernate-ehcache" console "org.grails:grails-console" profile "org.grails.profiles:web:3.1.4" runtime "org.grails.plugins:asset-pipeline" runtime "com.h2database:h2" testCompile "org.grails:grails-plugin-testing" testCompile "org.grails.plugins:geb" testRuntime "org.seleniumhq.selenium:selenium-htmlunit-driver:2.47.1" testRuntime "net.sourceforge.htmlunit:htmlunit:2.18" } task wrapper(type: Wrapper) { gradleVersion = gradleWrapperVersion } assets { minifyJs = true minifyCss = true }
依赖性报告表明,它们是由两个依赖项提取的:
compile "org.springframework.boot:spring-boot-starter-logging"
和
compile "org.springframework.boot:spring-boot-starter-actuator"
所以,我只需要对build.gradle的依赖项部分进行几个更改:
dependencies { // commented out the original way using Logback //compile "org.springframework.boot:spring-boot-starter-logging" // added the new way using Log4j2, yes, spring makes it easy compile "org.springframework.boot:spring-boot-starter-log4j2" // changed spring-boot-autoconfigure so that it would not // pull in the logback binding/implementation compile ('org.springframework.boot:spring-boot-autoconfigure') { exclude group: 'ch.qos.logback', module: 'logback-classic' } // and finally, added the log4j2 binding/implementation compile "org.apache.logging.log4j:log4j-api:2.5" compile "org.apache.logging.log4j:log4j-core:2.5" // the rest is unchanged compile "org.grails:grails-core" compile "org.springframework.boot:spring-boot-starter-actuator" compile "org.springframework.boot:spring-boot-starter-tomcat" compile "org.grails:grails-dependencies" compile "org.grails:grails-web-boot" compile "org.grails.plugins:cache" compile "org.grails.plugins:scaffolding" compile "org.grails.plugins:hibernate4" compile "org.hibernate:hibernate-ehcache" console "org.grails:grails-console" profile "org.grails.profiles:web:3.1.4" runtime "org.grails.plugins:asset-pipeline" runtime "com.h2database:h2" testCompile "org.grails:grails-plugin-testing" testCompile "org.grails.plugins:geb" testRuntime "org.seleniumhq.selenium:selenium-htmlunit-driver:2.47.1" testRuntime "net.sourceforge.htmlunit:htmlunit:2.18" }
在src/main/资源中,我们添加了一个log4j2.xml.
在Groovy代码中,我们使用了:
import org.apache.logging.log4j.Logger import org.apache.logging.log4j.LogManager import org.apache.logging.log4j.ThreadContext private static final Logger log = LogManager.getLogger(getClass()) log.info('Hello World')
我们还将ThreadContext语句放在大量使用类的构造函数中.
就是这样.现在,我们正在执行快速,异步日志,该日志不会在配置更改时丢失任何日志消息.
推荐答案
忘记将某些内容作为答案.这是您可以投票的答案,但是我将有关解决方案的所有信息都放在上面的评论中.
问题描述
We would like to use Log4j2 as the log binding with grails 3.
From what I can figure out so far. We have many subordinate dependencies that use a variety of loggers, so we need to use the SLF4J API. Then, instead of letting grails / groovy / spring re-direct the SLF4J API to the Logback binding, we need to re-direct each to the Log4j2 binding.
Since grails 3 uses the Logback binding, I am planning to go through each dependency in the build.gradle, exclude the Logback binding, and include the Log4j2 binding. Will this work? Update: Yes
Do we also need to bridge the Log4j2 API to the SLF4j API? What dependency do we need for that? Update: See below.
Finally, I assume we need to ditch the grails 3 logback.groovy configuration and just put one of the log4j2 configs in src/main/resources. Update: Yes
I'll post updates as we figure this out, but I bet someone has done this before.
Update 2016-03-18:
This turned out to be very straight-forward. I did a './gradlew dependencies' on my grails 3 project to see which dependencies were pulling in the Logback binding/implementation (group: 'ch.qos.logback', module: 'logback-classic')
First, here's the default build.gradle generated via a 'grails create-app testit' command:
buildscript { ext { grailsVersion = project.grailsVersion } repositories { mavenLocal() maven { url "https://repo.grails.org/grails/core" } } dependencies { classpath "org.grails:grails-gradle-plugin:$grailsVersion" classpath "com.bertramlabs.plugins:asset-pipeline-gradle:2.5.0" classpath "org.grails.plugins:hibernate4:5.0.2" } } version "0.1" group "testit" apply plugin:"eclipse" apply plugin:"idea" apply plugin:"war" apply plugin:"org.grails.grails-web" apply plugin:"org.grails.grails-gsp" apply plugin:"asset-pipeline" ext { grailsVersion = project.grailsVersion gradleWrapperVersion = project.gradleWrapperVersion } repositories { mavenLocal() maven { url "https://repo.grails.org/grails/core" } } dependencyManagement { imports { mavenBom "org.grails:grails-bom:$grailsVersion" } applyMavenExclusions false } dependencies { compile "org.springframework.boot:spring-boot-starter-logging" compile "org.springframework.boot:spring-boot-autoconfigure" compile "org.grails:grails-core" compile "org.springframework.boot:spring-boot-starter-actuator" compile "org.springframework.boot:spring-boot-starter-tomcat" compile "org.grails:grails-dependencies" compile "org.grails:grails-web-boot" compile "org.grails.plugins:cache" compile "org.grails.plugins:scaffolding" compile "org.grails.plugins:hibernate4" compile "org.hibernate:hibernate-ehcache" console "org.grails:grails-console" profile "org.grails.profiles:web:3.1.4" runtime "org.grails.plugins:asset-pipeline" runtime "com.h2database:h2" testCompile "org.grails:grails-plugin-testing" testCompile "org.grails.plugins:geb" testRuntime "org.seleniumhq.selenium:selenium-htmlunit-driver:2.47.1" testRuntime "net.sourceforge.htmlunit:htmlunit:2.18" } task wrapper(type: Wrapper) { gradleVersion = gradleWrapperVersion } assets { minifyJs = true minifyCss = true }
The dependency report showed that they were being pulled in by two dependencies:
compile "org.springframework.boot:spring-boot-starter-logging"
and
compile "org.springframework.boot:spring-boot-starter-actuator"
So, I only had to make a couple changes to the dependencies section of the build.gradle:
dependencies { // commented out the original way using Logback //compile "org.springframework.boot:spring-boot-starter-logging" // added the new way using Log4j2, yes, spring makes it easy compile "org.springframework.boot:spring-boot-starter-log4j2" // changed spring-boot-autoconfigure so that it would not // pull in the logback binding/implementation compile ('org.springframework.boot:spring-boot-autoconfigure') { exclude group: 'ch.qos.logback', module: 'logback-classic' } // and finally, added the log4j2 binding/implementation compile "org.apache.logging.log4j:log4j-api:2.5" compile "org.apache.logging.log4j:log4j-core:2.5" // the rest is unchanged compile "org.grails:grails-core" compile "org.springframework.boot:spring-boot-starter-actuator" compile "org.springframework.boot:spring-boot-starter-tomcat" compile "org.grails:grails-dependencies" compile "org.grails:grails-web-boot" compile "org.grails.plugins:cache" compile "org.grails.plugins:scaffolding" compile "org.grails.plugins:hibernate4" compile "org.hibernate:hibernate-ehcache" console "org.grails:grails-console" profile "org.grails.profiles:web:3.1.4" runtime "org.grails.plugins:asset-pipeline" runtime "com.h2database:h2" testCompile "org.grails:grails-plugin-testing" testCompile "org.grails.plugins:geb" testRuntime "org.seleniumhq.selenium:selenium-htmlunit-driver:2.47.1" testRuntime "net.sourceforge.htmlunit:htmlunit:2.18" }
In the src/main/resources, we added a log4j2.xml.
In the groovy code, we used:
import org.apache.logging.log4j.Logger import org.apache.logging.log4j.LogManager import org.apache.logging.log4j.ThreadContext private static final Logger log = LogManager.getLogger(getClass()) log.info('Hello World')
We also put ThreadContext statements in the constructors of heavily used classes.
That was it. Now we're doing fast, async logging that doesn't lose any log messages upon config changes.
推荐答案
Forgot to post something as an answer. Here's an answer you can vote for, but I put all the information about the solution in the comments above.