Comments (12)
Hello,
I also have this issue with both slf4j and log4j2, and when I apply the exclusions in the maven config.
My production logs are fine, but no configuration is applied to my test logs.
I'll try to make a sample Github project for you to understand.
And one more point, SLF4J say the following about librairies (maybe it can help) :
"Embedded components such as libraries or frameworks should not declare a dependency on any SLF4J binding but only depend on slf4j-api. When a library declares a compile-time dependency on a SLF4J binding, it imposes that binding on the end-user, thus negating SLF4J's purpose. When you come across an embedded component declaring a compile-time dependency on any SLF4J binding, please take the time to contact the authors of said component/library and kindly ask them to mend their ways."
http://www.slf4j.org/codes.html#multiple_bindings
from log-captor.
Hello again.
You can find a well known code of yours here : https://github.com/Edhilion/java-tutorials 😉
You will find two new "tutorials" :
- log-captor-with-slf4j-log4j-with-configuration
- slf4j-log4j-with-configuration-without-logcaptor
How to see the issue ?
You will see that each log4j2.xml contains a "with-config" or "with-config-without-logcaptor" in the appended pattern layout.
Launch each module test.
- The slf4j-log4j-with-configuration-without-logcaptor displays with-config-without-logcaptor in the log. 👍
- The log-captor-with-slf4j-log4j-with-configuration doesn't display with-config in the log. 👎
Happy bug hunting. 🙂
from log-captor.
Hi @Hakky54.
Thank you so much for all this long description.
I'll try to test it on my side and, if I can, I'll be proud to contribute to your project.
from log-captor.
Never mind. After some deep analyzis in SLF4J code, it seems this is really not possible.
And I think it won't be possible in their next version either...
When I say "it is not possible", I mean "I can write production code that will work, but I can't test it inside the very same project", so it is a no go for me.
Ah thats sad to hear, but I can understand it. I was still hoping this was somehow possible and it would be nice to add it to this library. Having a logcaptor for two different logging api's in this case 1 for SLF4J and 1 for Log4J2 would be more powerful and more customisable, but I choose to redirect all non SLF4J based logs to SLF4J and just use Logback to capture it and for the basic assertions this is sufficient. (for the most developers i think...)
So I guess I'll make my own version based on log4j2 instead of logback.
I still don't know if I'll put it on GitHub, because I am not a frequent Open Source contributor, and don't want people to rely on a work I will not really maintain. 😕
Sounds as a great idea, please let me know if you start on it. I would love to contribute!
I will close this issue as it is not-fixable (for now...). But I will reopen it when I find a solution, or feel free to reopen when you or someone else has a solution.
from log-captor.
Hey,
To help you out and to understand the root cause of the issue I need a bit more information. Did you added the dependency as a test scoped dependency? Could you share pom or other project configuration?
from log-captor.
Hi mate @mhammadkassem any news from your side, looking forward to see your project configuration
from log-captor.
Amazing @Edhilion thank you for the detailed description and the examples of the issues on the forked repo. I have now a clear understanding what the issue is you are facing, this is helpful. I will ping you when I have any updates from my side.
from log-captor.
Hi @Edhilion and @mhammadkassem
I have analysed the issue and came to a conclusion that sadly this option is not possible with LogCaptor. Let me first try to explain how I came to this conclusion...
The log configuration xml file contains a list of appenders, which can be configured to have a different kind of formatting or other configuration such as log level. While LogCaptor uses a custom appender, to be very specific the ListAppender of Logback which is an in-memory list for collecting log events. So when LogCaptor is being used (during the tests) it will use a different appender than configured in your log4j2.xml
and that is the reason why your logs look different than how you have configured in your log4j2.xml
.
So would it be possible to use the ListAppender of Logback, which LogCapture is using, and also use the log4j2.xml
file? Unfortunately not and the main reason is that LogCaptor relies on SLF4J api and it uses Logback under the covers to capture the logs which is a SLF4J implementation. SLF4J won't allow to have multiple implementations during runtime. The log4j-slf4j-impl
is able to process the log4j2.xml
file because it is an SLF4J implementation which developers can use to forward their log4j2 logs to slf4j without the need of changing their code base. But log4j-slf4j-impl
cannot be present when using LogCaptor because SLF4J won't allow multiple implementation as LogCaptor is already using Logback
What will happen to my production logs when using LogCaptor?
If LogCaptor is configured as a test scoped dependency it won't be available when you run your application on production. It won't be available on the classpath for example if you generate an executable jar. So in your case it will just use your default log dependency and also log configuration. So please add it as a test scoped dependency and not as a compile time dependency.
What is the alternative?
Well LogCaptor will capture the log4j2 logs and you can easily assert it. But I can understand that you also want to test your logs with the log4j2.xml
configuration file. You could convert it to a Logback configuration file, but that would not be a nice alternative... A good alternative would be I think not using LogCaptor and add a console listener within your unit tests to capture the console logs or a file listener/reader to read and extract the the content of a log file and to test it during the unit test. An alternative could be something like this mentioned at stackoverflow: Java, Junit - Capture the standard input / Output for use in a unit test
You also mentioned the following:
And one more point, SLF4J say the following about librairies (maybe it can help) :
"Embedded components such as libraries or frameworks should not declare a dependency on any SLF4J binding but only depend on slf4j-api. When a library declares a compile-time dependency on a SLF4J binding, it imposes that binding on the end-user, thus negating SLF4J's purpose. When you come across an embedded component declaring a compile-time dependency on any SLF4J binding, please take the time to contact the authors of said component/library and kindly ask them to mend their ways."
http://www.slf4j.org/codes.html#multiple_bindings
LogCaptor forwards all type of logs (Log4j, Log4j2, Java Util Logging etc) to SLF4J and afterwords it uses Logback as SLF4J implementation to capture those logs. So to have a functional LogCaptor I need to ship it with a SLF4J binding or else it won't be able to capture the logs and I think it is pretty essential as the sole purpose of the library is to capture logs... But I agree with your statement. I have another library, see here: GitHub - SSLContext Kickstart which only depends on slf4j-api
and does not include a compile-time dependency on a SLF4J binding. So I agree with the statement of the SLF4J team and I am following their advice for my other libraries. I appreciate that you went through their documentation and mentioned their advice to me! ❤️
I hope this makes sense. If you have any other questions or concerns please drop it here. And if you think it is possible to use LogCaptor while also applying the Log4j2 configuration during the test phase please share it 😊 or feel free to contribute to the project if you can add this capability to the library.
from log-captor.
Hi again,
If I want to make it work with both Logback and Log4j2, do you mind I propose two implementations of your LogCaptor, one for each framework, with a switch based on slf4jLogger instanceof Logger
?
from log-captor.
Never mind. After some deep analyzis in SLF4J code, it seems this is really not possible.
And I think it won't be possible in their next version either...
When I say "it is not possible", I mean "I can write production code that will work, but I can't test it inside the very same project", so it is a no go for me.
So I guess I'll make my own version based on log4j2 instead of logback.
I still don't know if I'll put it on GitHub, because I am not a frequent Open Source contributor, and don't want people to rely on a work I will not really maintain. 😕
from log-captor.
Hey @Edhilion and @mhammadkassem!
I have some update regarding this issue/limitation.
I have created a new library to support specifically this use-case and it works for all logging api and implementations. It just captures all the output generated on the console. Either by a logging api or just System.out. You can also easily capture the prefix or suffix or assert the logging format etc.
You can view it here: GitHub - ConsoleCaptor
I would love to hear your opinion.
from log-captor.
This issue has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs. Thank you for your contributions.
from log-captor.
Related Issues (20)
- Running the unit test directly from IDEA gives error HOT 7
- Not working with org.jacoco:jacoco-maven-plugin HOT 6
- There appears to be a classloading problem when using LogCaptor with `@QuarkusTest` test classes HOT 2
- LogEvent should implement toString() HOT 4
- Not compatible with log4j2 2.17.2 HOT 5
- Allow to retrieve logs for custom log levels HOT 2
- consoleCaptor.getStandardOutput() doesn't work HOT 6
- Does this project target Log4J API 1.7? HOT 9
- spring-boot-starter + log-captor: log4j-slf4j-impl cannot be present with log4j-to-slf4j HOT 5
- Upgrade to 2.8.0 HOT 18
- Suppressing Console Output HOT 3
- Are we supposed to close LogCaptor at the end of a test? HOT 3
- Issue with custom levels HOT 3
- Seeing DEBUG level logs after adding logcaptor dependency HOT 2
- disableConsoleOutput() is throwing NPE HOT 3
- Documentation Request for Use in Quarkus; Problem with SLF4J HOT 4
- ava.lang.NoClassDefFoundError: org/slf4j/spi/LoggingEventAware HOT 13
- IllegalArgumentException while using logcaptor HOT 1
- java.lang.ClassNotFoundException: ch.qos.logback.core.Appender HOT 3
- Not working with static variable HOT 2
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from log-captor.