We are splitting our logging functionality as a separate logging library which will be used as a logging jar for all web application. Currently we are using ESAPI 2.1 to prevent log forging, we have also upgraded our logging framework to log4j 2 to support async logging.
From this post https://security.stackexchange.com/questions/170523/is-owasp-esapi-still-the-recommended-way-to-secure-jsp-pages , I came to know that ESAPI seems to be outdated and not used anymore, is there any better alternative to create a secure logging library?
Dead you say? Oh Really?
At any rate, if you just want our logging capabilities just git clone https://github.com/ESAPI/esapi-java-legacy and copy the code you like while respecting our FreeBSD license.
Also, if its log injection that you're worried about, also come to an agreement on a log format message that always encloses user input in symbols you control. Makes it easier to detect mischief.
Related
We are planning to use open-telemetry as the logging tool in a new Spring-boot based micro-service. We have explored two ways to use otel, first is using manual instrumentation provided by Java and other is using Spring-cloud-sleuth using #NewSpan annotation
However, I could not find a way to specify different logging levels like INFO/ERROR/DEBUG. We need to have an ability to control and restrict the excessive logging. However, additional debug logs can help in troubleshooting if required.
How can we set the logging levels with open-telemetry java or spring-sleuth?
Uodate: As commented by #Jan , I was getting confused between tracing and logging. However, I can not find any documentation about support for logging with opentelemetry-java. Is there any way to do it? Also, if we use different tools for tracing and logging, will it be considered a bad practice?
So generally how do we use combination of tracing and logging? Can we use different frameworks for both? For example, if we use open-telemetry for tracing and slf4j/log4j for logging, will it be considered a bad practice?
OpenTelemetry will never have a "logging" API meant to be used by ordinary users, it is supposed to capture logs produced by actual logging libraries (like log4j or logback).
OpenTelemetry support for logs is still in the alpha state (meaning that the logging SPI/SDK might still change in non-backward compatible ways), but we already have dedicated OpenTelemetry appenders for several of the most commonly used logging libraries, like log4j or logback. You should be able to use these and expect relatively little breaking changes.
I am reading about logging using java and came across this: enter link description here
It talks about an advantage of slf4j here that:
One can select his logging framework at deployment time ==> The desired logging framework can be plugged in at deployment time by inserting the appropriate jar file (binding) on your class path.
Can someone explain to me why and where we would need this?
You're writing a generic-pupose library, which generates logs using SLF4J.
Company A uses it, and has already configured all its IT infrastructure to use log4J. They're happy that your API can also use log4J to log.
Company B uses it as well, and has already configured all its IT infrastructure to use java util logging. They're happy that your API can also use java util logging to log.
Company C uses it as well, and has already configured all its IT infrastructure to use logback. They're happy that your API can also use logback to log.
I can think of the following scenario:
Websphere uses JCL logging, if also using JCL, then you can set/modify log levels and filters at runtime.
Appserver X is more geared towards Log4J, so might be better to use that...
With SLF4J you don't need to refactor the code for the underlying logging framework to use...
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 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.
Should new projects use logback instead of log4j as a logging framework ?
Or with other words :'Is logback better than log4j (leaving the SLF4J-'feature' of logback beside)?'
You should use SLF4J+Logback for logging.
It provides neat features like parametrized messages and (in contrast to commons-logging) a Mapped Diagnostic Context (MDC, javadoc, documentation).
Using SLF4J makes the logging backend exchangeable in a quite elegant way.
Additionally, SLF4J supports bridging of other logging frameworks to the actual SLF4J implementation you'll be using so logging events from third party software will show up in your unified logs - with the exception of java.util.logging that can't be bridged the same way that other logging frameworks are.
Bridging jul is explained in the javadocs of SLF4JBridgeHandler.
I've had a very good experience using the SLF4J+Logback combination in several projects and LOG4J development has pretty much stalled.
SLF4J has the following remaining downsides:
It does not support varargs to stay compatible with Java < 1.5
It does not support using both parametrized message and an exception at the same time.
It does not contain support for a Nested Diagnostic Context (NDC, javadoc) which LOG4J has.
The author (of both Logback and Log4j) has a list of reasons to change at http://logback.qos.ch/reasonsToSwitch.html.
Here are a few that stuck out at me;
Faster implementation
Based on our previous work on log4j,
logback internals have been
re-written to perform about ten times
faster on certain critical execution
paths. Not only are logback
components faster, they have a
smaller memory footprint as well.
Automatic reloading of configuration
files
Logback-classic can automatically
reload its configuration file upon
modification. The scanning process is
both fast and safe as it does not
involve the creation of a separate
thread for scanning. This technical
subtlety ensures that logback plays
well within application servers and
more generally within the JEE
environment.
Stack traces with packaging data
When logback prints an exception, the
stack trace will include packaging
data. Here is a sample stack trace
generated by the logback-demo
web-application.
14:28:48.835 [btpool0-7] INFO
c.q.l.demo.prime.PrimeAction - 99 is
not a valid value
java.lang.Exception: 99 is invalid
at
ch.qos.logback.demo.prime.PrimeAction.execute(PrimeAction.java:28)
[classes/:na] at
org.apache.struts.action.RequestProcessor.processActionPerform(RequestProcessor.java:431)
[struts-1.2.9.jar:1.2.9] at
org.apache.struts.action.RequestProcessor.process(RequestProcessor.java:236)
[struts-1.2.9.jar:1.2.9] at
org.apache.struts.action.ActionServlet.doPost(ActionServlet.java:432)
[struts-1.2.9.jar:1.2.9] at
javax.servlet.http.HttpServlet.service(HttpServlet.java:820)
[servlet-api-2.5-6.1.12.jar:6.1.12]
at
org.mortbay.jetty.servlet.ServletHolder.handle(ServletHolder.java:502)
[jetty-6.1.12.jar:6.1.12] at
ch.qos.logback.demo.UserServletFilter.doFilter(UserServletFilter.java:44)
[classes/:na] at
org.mortbay.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1115)
[jetty-6.1.12.jar:6.1.12] at
org.mortbay.jetty.servlet.ServletHandler.handle(ServletHandler.java:361)
[jetty-6.1.12.jar:6.1.12] at
org.mortbay.jetty.webapp.WebAppContext.handle(WebAppContext.java:417)
[jetty-6.1.12.jar:6.1.12] at
org.mortbay.jetty.handler.ContextHandlerCollection.handle(ContextHandlerCollection.java:230)
[jetty-6.1.12.jar:6.1.12]
From the above, you can recognize
that the application is using Struts
version 1.2.9 and was deployed under
jetty version 6.1.12. Thus, stack
traces will quickly inform the reader
about the classes invervening in the
exception but also the package and
package versions they belong to. When
your customers send you a stack
trace, as a developer you will no
longer need to ask them to send you
information about the versions of
packages they are using. The
information will be part of the stack
trace. See "%xThrowable" conversion
word for details.
This feature can be quite helpful to
the point that some users mistakenly
consider it a feature of their IDE.
Automatic removal of old log archives
By setting the maxHistory property of
TimeBasedRollingPolicy or
SizeAndTimeBasedFNATP, you can
control the maximum number of
archived files. If your rolling
policy calls for monthly rollover and
you wish to keep one year's worth of
logs, simply set the maxHistory
property to 12. Archived log files
older than 12 months will be
automatically removed.
There may be a bias there, but the same guy did write both frameworks and if he is saying use Logback over Log4j he's probably worth listening to.
I would use slf4j for logging in all cases. This allow you to choose which actual logging backend you want to use, at deploy time instead of code time.
This has proven to be very valuable to me. It allows me to use log4j in old JVM's, and logback in 1.5+ JVM's, and also java.util.logging if needed.
Logback more Java EE aware:
in general (from code to documentation) it’s keeping in mind containers – how multiple apps coexist, how class loaders implemented etc. Contexts for loggers, JNDI, JMX configuration included etc.
from developer prospective almost same, Logback adds
Parameterized logging (no need to use if(logger.isDebugEnabled()) to avoid string concatenation overhead )
Log4j – only giant plus is old JVM support, small (IMO)
NDC (Logback only MDC), some extensions. For example I wrote extension for configureAndWatch for Log4j, no such thing for Logback
the original log4j and logback were designed and implemented by the same guy.
several open source tools have used SLF4J. I don't see any significant deficiencies in this tool. So unless you have a lot extensions to log4j in your codebase, I would go ahead with logback.
I would think that your decision should come down to the same one it would if you were deciding between using log4j or Jakarta Commons Logging - are you developing a library which will be included in other applications? If so, then it doesn't seem fair to force users of your library to also use your logging library of choice.
If the answer is no, I would just go with what is simpler to add and what you are more comfortable with. Sounds like logback is just as extensible and reliable as log4j, so if you're comfortable using it, go ahead.
I'm not familiar with SLF4J, and I've only taken a brief look at logback, but two things come to mind.
First, why are you excluding a tool from examination? I think it's important to keep an open mind and examine all possibilities to choose the best one.
Second, I think that in some projects one tool is a better than another tool, and the opposite might be true in a different project. I don't think that one tool is always better than another tool. There is, after all, no silver bullet.
To answer your question - Yes and no. It depends on the project, and how familiar the team is with one tool. I wouldn't say "don't use log4j" if the entire team is very comfortable with it, it meets all the needs, and logback doesn't offer anything that we need to complete the task.