I want to provide a client-library for wrapping rest-request to a server and log errors, so that a client can use it in his app and also see the logs. (There is also a question if i should just log the errors or rethrow it. When i use an asynchronized call (multithreaded) this might be quite tricky..)
I read that slf4j might help, because the client, who is using the library, can choose which logging framework he prefers.
Somethings puzzles me about this slf4j-thing. If he gets my library and i just provide, let's say the slf4j-api, errors will be thrown, cause the SLF4J bindings aren't included. The solution might be that he has to include the binding on his own, and the question is if he is willing to read the README for this crucial information.
If i include one "standard"-slf4j binding (e.g. the simple one), the app can't "override" this, because there is just one binding allowed on the classpath. It won't be flexible anymoe
So i am thinking to just use log4j and forget every other logging-framework. I may think to complicated on this subject, maybe someone might help me out on this?
You have to remember, your library does not set the wrapping application's classpath. The wrapping application will set a classpath that includes your library, the slf4j API library and the implementing library.
The wrapping application will take care of what slf4j implementation to use and setup all of the logging parameters. You just need to worry about logging your libraries events with the slf4j API. This is common practice, don't worry about the wrapping application.
By packaging log4j within your library, you are defeating the purpose of a logging facade. Doing so will not allow the user to pick the slf4j implementation.
Related
I am currently developing/maintaining a java/maven library. Previously I was using a-lot of additional libraries, after removing the not required ones I only had one remaining: SLF4J api. I want to depend as less as possible to prevent a dependency hell to the end-users.
I thought having slf4j would be fine as a-lot of other projects also use it. I didn't include a binding, so the end-user doesn't need to exclude it explicitly when having another type of binding. So one day someone included a slf4j binding in his project when using my library. This person was not using slf4j at all but was using the java util logging and therefor he was forced to add a binding.
So a solution for this use case on my library side would be maybe drop slf4j api and using the java util logging, but what would be the downside of switching in this case? Will the end-user still be able to configure his own logging and the logging my library when using it together?
Or should I stay with slf4j api and include a default binding which is mark optional within maven. Or not mark optional and provide it as a transitive dependency to the end users.
To be honest, I am not very experienced to decide what would be a proper solution and I hope you guys could help to make it more clear for me.
I want this library I'm working on to have logging support, but Android and SE have their own ways of logging. In SE you can use System.out.println methods or the java.util.logging.Logger class. Android uses android.util.Log to log on logcat. At first I used reflection to check if android was usable, then reflectively call the log methods in Log.class; but that wasn't a good idea.
My solution is to have the developers using my library handle logs themselves. There will be a Handler interface they set and has an onLog method
public void onLog(int level, String tag, String msg);
The library will call the onLog method on the handlers in my custom Logger class. Is it a good idea to have developers handle the logs instead of the library itself? Seems to be the best solution so far and if I document it good then it should't be an issue.
I agree with you that logging should be delegated to clients, and your homegrown approach is indeed sensible.
IMO, the SLF4J facade would be ideal for your situation. Your library would include the slf4j-api jar and contain SLF4J logging statements. If clients wanted logging, they'd just drop in a logging backend (and an optional config file) into their application's classpath to capture/view your log statements.
The advantages to this approach are that it grants clients the most control with zero coding required to get logging; and that it allows the client to choose among many available backends.
I would use logback as the backend for J2SE apps and logback-android for Android.
You can try microlog
http://code.google.com/p/microlog4android/
It can help you use a consistent logging mechanism across android and java. If you use slf4j, it can be used as a wrapper both for microlog (in case of your android project) and log4j (for your java projects)
I am using SLF4J as logging facade and let users decide where and what to log. Now in case of a crash, I want to send a file to the server that contains debugging information--which basically means a log-file. And since we already have all that log-statements scattered in the code, why not use them?
So basically, I want to create a log file programmatically via SLF4J, transparent for the user who still can plug in his own logging backend and configuration.
My first idea was to implement the org.slf4j.impl.StaticLoggerBinder, deliver my own implementation of a logger that does its logging and then delegates to the user-configured logger. However, I see certain issues with this: If the user puts a normal logging backend, then multiple instances of org.slf4j.impl.StaticLoggerBinder are on the classpath. This will issue a warning AND I might not be able to make sure, that my implementation is the one to get called.
Are there better solutions to this? A whole different approach? Is the idea inherently bad? How to accomplish this?
The point of SLF4J is not to let application end-users choose their logging framework (why would they care?) but to let developers include a library without being tied into the library's choice of logging framework.
So if you want to upload debug information from a deployed application, it's fine to fix the logging implementation. The user can still edit the implementation's configuration file, if they want.
Since SLF4J is open-source, you can modify it to use another class than org.slf4j.impl.StaticLoggerBinder. Then your custom StaticLoggerBinder class could load the original, user-provided org.slf4j.impl.StaticLoggerBinder (if it exists).
Another idea is using a custom LoggerFactory (not org.slf4j.LoggerFactory) in your application which returns a Logger delegate. This delegate class delegate logging method calls to the original Logger implementation and also sends the logs to the server if it is necessary.
Anyway, both would look an awkward hack to me, creating two artifacts (one for end-users and another one for developers) smells better.
(Finally, I don't know what kind of library/application it is, but in my working environment it would not be acceptable if a library sends data to a third party server. Are you sure that you really need to to do this?)
I will try to use the Apache Commons Logging to logs in my system. I need some simple, just to keep up on the information and errors, nothing too complex.
I saw that there a lot of implementations there (SimpleLog, AvalonLog, etc.) Someone can explain me the most appropriate or the most complete/full of resources?
Actually I don't know which one to use.
Commons-logging is not a simple logging mechanism. It's a method of allow you to write a library that works regardless of the logging mechanism chosen by someone who incorporates your library.
If you want a simple logging mechanism, just use java.util.logging directly. If you want an even simpler API, use slf4j and then use their 'simple' backend.
You don't need commons-logging unless you have to fit into other people's environments.
I'm creating a small Java framework, which will log its events. I don't want the framework to be dependent on any particular logging implementation (jul, commons logging, log4j, slf4j, logback, etc). Instead, I want to allow my clients to choose anything they prefer.
The question is - how should I realize such decoupling? How my framework should log its events?
slf4j is designed to solve exactly this problem: it decouples the API from the logging implementation.
slf4j is not a logging implementation by itself. It depends on the existence of a back-end implementation. Logback just happens to natively implement the slf4j API but there are bindings for log4j, java.util.Logging and others.
At some level you must have an API for your clients to use. You might as well make it one of the existing APIs rather than writing your own.
I think that will be difficult to achieve as your code must call something in order to log information and error messages. I think you will have to choose one (I recommend slf4j) and stick to it - this seems to be what is generally done by everyone else.
I would include support for AspectJ and Commons Logging.