Giter VIP home page Giter VIP logo

Comments (12)

Edhilion avatar Edhilion commented on May 30, 2024 1

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.

Edhilion avatar Edhilion commented on May 30, 2024 1

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.

Edhilion avatar Edhilion commented on May 30, 2024 1

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.

Hakky54 avatar Hakky54 commented on May 30, 2024 1

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.

Hakky54 avatar Hakky54 commented on May 30, 2024

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.

Hakky54 avatar Hakky54 commented on May 30, 2024

Hi mate @mhammadkassem any news from your side, looking forward to see your project configuration

from log-captor.

Hakky54 avatar Hakky54 commented on May 30, 2024

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.

Hakky54 avatar Hakky54 commented on May 30, 2024

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.

Edhilion avatar Edhilion commented on May 30, 2024

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.

Edhilion avatar Edhilion commented on May 30, 2024

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.

Hakky54 avatar Hakky54 commented on May 30, 2024

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.

stale avatar stale commented on May 30, 2024

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)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo 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.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.