I am writing an application in which I am uploading a file using HTTP protocol to a server. Everything is working fine and I am able to upload the file, I have used Apache HTTP client jar set to accomplish this. In the application I have used log4j logging framework which has been set to DEBUG level, by default Apache HTTP Client has also picked up the same logging framework with same logging level and it is producing tons of logs. Can anyone guide me how I can i disable logging of apache Http client?
I am configuring log4j with the help of an XML file name log4j.xml.
Assuming you are using httpclient 4, doesn't adding something like this to your log4j.xml work:
<logger name="org.apache.http">
<level value="warn"/>
</logger>
I you don't have a log4j.xml create one and it to your classpath.
If you're using httpclient 3 then you'll have to use something like:
<logger name="org.apache.commons.httpclient">
<level value="warn"/>
</logger>
In these examples I've set the level to warn, you might chose to use none, but a minimum of error would be sensible.
The given answers are good examples of people answering questions they don't even understand. They just repeat what they have heard or read in poor documentations like the one from Apache HTTP client. Something like:
<logger name="org.apache.commons.httpclient">
<level value="warn"/>
</logger>
is what should be done if the documentation of Apache HTTP client was right. In such case, the poster of this question would have resolved the problem himself. Giving such poor answers is kind of insulting.
The problem is that although the documentation says:
Each class has its own log named according to the class's fully qualified name.
For example the class HttpClient has a log named org.apache.commons.httpclient.HttpClient.
Since all classes follow this convention it is possible to configure context logging for
all classes using the single log named org.apache.commons.httpclient.
it is simply not true.
Better than giving the answer is showing how to find it yourself. To find the solution, you have first to enable location in the log to see where the log happens. Then the logs will displays a line like:
2013-02-07 15:33:02,369 DEBUG [Some thread name] org.apache.commons.httpclient.Wire.wire(Wire.java:84) - << "[\r]"
This shows that logging is happening in class Wire.java, line 84. You may then open the sources in your favorite IDE and and you will see the following:
80 if (buffer.length() > 0) {
81 buffer.append("\"");
82 buffer.insert(0, "\"");
83 buffer.insert(0, header);
84 log.debug(buffer.toString()); // Log is happening here
85 }
The log variable holds the logger. Go to the place where this variables receives its value:
52 /** Log for any wire messages. */
53 private Log log;
54
55 private Wire(Log log) {
56 this.log = log;
57 }
All you have to do now is to put a break point at line 56 and run your application in the debugger. When it stops at line 56, read the log value. As it is an object of type Log, open it an look at its "name" property. You will see the name "httpclient". Obvioulsly, the Apache documentation is wrong.
Now you can disable this logger with:
<logger name="httpclient">
<level value="warn"/>
</logger>
The conclusion is:
When possible, learn to find answer to your own question instead of asking.
Do not believe what everybody says. Naming the loggers by the fully qualified class name is a convention. Like all conventions, nobody is obliged to follow it. An Apache do not.
Do not answer question when you don't know the answer. This is only noise.
You can adjust logging level per package. Here is example from http://wiki.apache.org/logging-log4j/Log4jXmlFormat:
<logger name="com.eatmutton.muttonsite.torque" additivity="false">
<level value="info" />
<appender-ref ref="local-torque" />
</logger>
So, even if your default level is "debug", for classes of com.eatmutton.muttonsite.torque package (and nested packages) the level would be "info"
So, you need to find out package to which HTTP client classes belong and add such record to your config.
Related
I want to log Request/Response of my server in log files. I am using Springboot + jersey 2.x + log4j2. I registered jersey's LoggingFeature like this -
jerseyConfig.register(
new LoggingFeature(
java.util.logging.Logger.getLogger(
LoggingFeature.DEFAULT_LOGGER_NAME),
java.util.logging.Level.SEVERE,
LoggingFeature.Verbosity.PAYLOAD_ANY,
Integer.MAX_VALUE)
);
log4j2.xml
<!-- Jersey logger -->
<AsyncLogger name="org.glassfish" level="all" additivity="false">
<AppenderRef ref="Console" level="off" />
<AppenderRef ref="RollingFileIO" level="error" />
</AsyncLogger>
In pattern, I am injecting transaction-id with help of log4j2's ThreadContext. I have log4j-jul 2.1 in my pom.xml, and I am running it with
-Djava.util.logging.manager=org.apache.logging.log4j.jul.LogManager .
Things are working fine, only problem is, in jersey's logs, I am unable to insert transaction id. I tried utils logging with my custom code, and I am able to put transaction-id in it. But by the time jersey writes these logs, ThreadContext gets cleared and transaction-id values comes empty.
If the log flow is JUL->log4j2->FooAppender->Layout->ThreadContext.pop then
Per Including the ThreadContext when writing logs:
The PatternLayout provides mechanisms to print the contents of the ThreadContext Map and Stack.
Use %X by itself to include the full contents of the Map.
Use %X{key} to include the specified key.
Use %x to include the full contents of the Stack.
If the flow is log4j2->JUL->FooHandler->Formatter->ThreadContext.pop then you have to install or create a formatter that is aware of the ThreadContext. You also have make sure in this configuration that log4j2->ThreadContext.pop->JUL->FooHandler->Formatter is not happening as that would forget all of the information before it gets to JUL.
All of the examples in the documentation show the ThreadContext is set prior to invoking the logger. Which means you have to set the ThreadContext prior to any Jersey code execution.
I haven't looked at Jersey in detail but from the problem description it seems that it has a thread model that makes working with ThreadContext difficult.
Fortunately Log4j 2.7 offers a facility to let you inject key-value pairs (like ID) into log events from another source than the ThreadContext. This was introduced to help with asynchronous frameworks like Finagle, so it may be useful for Jersey as well.
The Log4j2 manual briefly mentions this feature in the section on Custom ContextDataInjectors.
If you want to use this facility you need to write a custom ContextDataInjector and tell Log4j to use that injector instead of the default one by specifying a ContextDataInjectorFactory. Your custom injector needs to get the key-value pairs from somewhere. In Jersey's case, would RequestContext.getProperty and setProperty be appropriate?
I know there has been a lot of question related to this, but i couldn't find one that matches on the scenario that i'm looking at, so here's the question.
Current logging setup: logger coded using Slf4j with Log4j 1.2 bindings. DailyRollingAppender used.
The program: A multi-threading backend Java program processing data from a table and call relevant web services.
A new request came in to have the log file name be based on a certain data, lets call it match_code. With this, whenever a thread is processing say MatchA, then the log file the thread use should be set as MatchA.log
I'd googled for a while and understand that i will need to programmatically configure the Log4j configuration whenever the processes starts, the question is how should i change the log file name settings while not affecting others setting such as the Patterns.
I'm open to switch to Log4j 2.x if it means that can solve my problem, so far have no luck in finding samples for this.
Any suggestion is appreciated. Thank you.
UPDATE on what's tried
Tried using the System.setProperty way to dynamically set the log file. Here's the properties setting:
log4j.appender.file.File=/log/${logfile.name}.log
In main class, added these two lines before anything else:
static{
System.setProperty("logfile.name","output");
}
private static Logger logger = LoggerFactory.getLogger(Engine.class);
Added this right after the process found data to be process:
System.setProperty("logfile.name",match_code+"_output");
where match_code is a value from database such as 'MatchA'
The result is, the main class DID have the log named as output.log. However if i put in data to test, the log will still goes to output.log and there's no new log file created based on the data.
Dunno if I understand your problem: you want your same log message goes to different log file, depending on the data you are processing?
if you use LogBack, you can do it by combination of MDC + SiftingAppender. For example, in your code, you can do:
(in code)
MDC.put("match_code", "MatchA");
logger.debug("whatever message"); // just log it normally
(in logback.xml)
<appender name="SIFT" class="ch.qos.logback.classic.sift.SiftingAppender">
<discriminator>
<key>match_code</key>
<defaultValue>unknown</defaultValue>
</discriminator>
<sift>
<appender name="FILE-${match_code}" class="ch.qos.logback.core.FileAppender">
<file>${match_code}.log</file>
<layout class="ch.qos.logback.classic.PatternLayout">
<pattern>%d [%thread] %level %mdc %logger{35} - %msg%n</pattern>
</layout>
</appender>
</sift>
</appender>
Please note, here I am using LogBack as logging backend. There is no official sifting appender for Log4j 1. I kind of remember something similar in Log4j 2. Wish this can serve as your starting point of searching if you really insist to use Log4j
I'm looking for simplest way to trace execution time of SQL query generated by Hibernate.
Unfortunately it cannot be done in traditional way - just by setting show_sql or hibernate logger, because monitored application is multithread on production environment and sql times tracing should be done only for one service, which is mots problematic.
Service means some component running within Spring application. But in my case it is safe to tell, that it is thread - thread is not changed during invocation. Service implementation is a Java method and this method calls others methods, components, etc, everything i one thread. It is possible for me to change one method source and deploy it, but I cannot release application.
Unfortunately AspectJ cannot be used as is, because I cannot change whole application, recompile nor plug something into JVM.
Unfortunately (next) DB administrators cannot turn on sql queries tracing - they don't know how to do it.
Please help, how to tune Hibernate execution without digging the whole application? What is the simplest way?
Facts: Hibernate 3.x, Spring 2.x, java 1.5
Here is how I would do it, assuming you're using Logback as your logging framework.
Make sure you have scanning enabled on your logback configuration:
<?xml version="1.0" encoding="UTF-8"?>
<configuration debug="false" scan="true" scanPeriod="30 seconds" >
Make sure your file logger includes thread name in the output (%t):
<encoder class="ch.qos.logback.classic.encoder.PatternLayoutEncoder">
<pattern>%d{yyyy-MM-dd HH:mm:ss} %-5p %C{1} %t - %m%n</pattern>
</encoder>
Start with SQL logging turned off:
<logger name="org.hibernate.SQL" level="OFF">
<appender-ref ref="FILE_APPENDER"/>
</logger>
<logger name="sql-log" level="OFF">
<appender-ref ref="FILE_APPENDER"/>
</logger>
Once your application is up and running, and you're ready to execute your test, edit the logback.xml file of the deployed application, and change those levels to 'DEBUG'. Then execute your tests. When tests are done, set those levels back to 'OFF'.
Look through the log output, and identify the thread name of interest, then grep for that thread name:
grep "thread-1-pool-7" debug.log > sqldebug.log
A bit cumbersome, but it will work.
You are not very specific about filtering criteria: do you want to filter SQLs by thread/HTTP session or from a given service (sql times tracing should be done only for one service)?
Nevertheless everything can be done on logging framework level. First you need to enable logging of all queries and then filter out non-interesting ones. I am assuming you are using Logback (BTW Spring 2.x and Java 1.5.x are becoming obsolete...):
Per thread
Implement Logback filter and discard logs from not interesting thread. Alternatively use SiftingAppender with thread id as a key. All logs from a given thread will be dispatched to a separate file.
Per HTTP session
This is a bit tricky because you need to get access to HTTP session/session id from logging framework level. The easy way is to use MDC (see example: Logging user activity in web app). Having session id you can do filtering similar to Per thread section.
Per service
It's not obvious what do you mean. Do you only want to log SQL queries issued from a given class or from a class and all the methods and classes it calls? In both cases you need to examine a call stack while filtering, which isn't very effective. Also AspectJ has within directive - too heavyweight for you I guess.
If this is what you want to achive please clarify your question, I have some other ideas.
I'm using Hibernate's c3p0 connection pooling and standard Java 1.4 java.util.logging. Upon startup, my app sets up it's logging properties (including formatter and log levels) in static block. Every time I start my app, I see the following:
2011-04-16 17-43-51 [com.mchange.v2.log.MLog] INFO: {MLog.<clinit>) MLog clients using java 1.4+ standard logging.
2011-04-16 17-43-51 [com.mchange.v2.c3p0.C3P0Registry] INFO: {C3P0Registry.banner) Initializing c3p0-0.9.1 [built 16-January-2007 14:46:42; debug? true; trace: 10]
2011-04-16 17-43-51 [com.mchange.v2.c3p0.impl.AbstractPoolBackedDataSource] INFO: {AbstractPoolBackedDataSource.getPoolManager)
...
I've tried
Logger.getLogger("com.mchange").setLevel(Level.WARNING);
com.mchange.v2.log.MLog.getLogger().setLevel(MLevel.WARNING);
System.setProperty("com.mchange.v2.log.FallbackMLog.DEFAULT_CUTOFF_LEVEL", "WARNING");
but only way to prevent it that I found for now is
Logger.getLogger("").setLevel(Level.WARNING);
which affects everything - not a good side effect. Google didn't help. Could anyone help please?
The way I found is to set the system property
System.setProperty("com.mchange.v2.log.MLog", "com.mchange.v2.log.FallbackMLog");
in addition to
System.setProperty("com.mchange.v2.log.FallbackMLog.DEFAULT_CUTOFF_LEVEL", "WARNING");
I thought, that absence of any other logging system wil make that optional, but it seems, that I was wrong.
P.S.
Damn those wheel-reinvented custom logging implementations, like the one used by c3p0...
The way I found for achieving this
Create in your classpath a file called mchange-log.properties and put into it properties suggested by Frozen Spider.
com.mchange.v2.log.MLog=com.mchange.v2.log.FallbackMLog
com.mchange.v2.log.FallbackMLog.DEFAULT_CUTOFF_LEVEL=WARNING
Thats work fine even when you are not able to set system properties directly.
It appears that c3p0 logging defaults to DEBUG. That can result in a lot of noise.
By adding a line like this to log4j.properties, you are telling the logger not to bother you with c3p0 messages - unless it's something important:
log4j.logger.com.mchange.v2=WARN
Do you not want to see any c3p0 logging?
If so try:
Logger.getLogger("com.mchange.v2.c3p0").setLevel(Level.WARNING);
OR, if you don't even want to see the first line of the log:
Logger.getLogger("com.mchange.v2").setLevel(Level.WARNING);
This is probably really late, but according to the c3p0 project website it is possible to configure the logging inside the mchange-log.properties so that you can capture the information using slf4j or log4j (and thus also with Logback).
The link http://www.mchange.com/projects/c3p0/#configuring_logging provides this information that in your mchange-log.properties file set the property com.mchange.v2.log.MLog to equal com.mchange.v2.log.slf4j.Slf4jMLog then in your logback.xml you can provide a logger like this:
<logger name="com.mchange" level="warn" additivity="false">
<appender-ref ref="c3p0-log" />
</logger>
Note: you will need to create a logback appender called c3p0-log before you can use this exact piece of code.
create a file called log4j.properties in your root classpath
set the following in there,
# Configure the name of the file for the LOGGER appender
log4j.appender.LOGGER=org.apache.log4j.ConsoleAppender
log4j.appender.LOGGER.layout=org.apache.log4j.PatternLayout
log4j.appender.LOGGER.layout.ConversionPattern=%d{MM-dd#HH:mm:ss} %-5p (%13F:%L) %3x - %m%n
log4j.appender.LOGGER.append=false
# this line logs everything from hibernate package at info level, you can refine this to include only some pachages like log4j.logger.org.hibernate.hql etc.,
log4j.logger.org.hibernate=INFO, LOGGER
log4j.logger.org.jboss.cache=INFO, LOGGER
this is a much better way of implementing the logging because if you set the logging strategy programmatically, then the config sometimes might not take effect at all (like in your case).. if you use the log4j.properties file ,the config is applied at application startup & everything works smoothly.
This only happens on older c3p0 version. So it might also be worth checking if you can just update to a newer version.
I am using a jar file in a java program and it generates warnings during runtime. But I don't want that my customer sees these warnings.
How can I disable these warnings.
The warning is as below:
Sep 25, 2009 10:10:33 PM com.gargoylesoftware.htmlunit.IncorrectnessListenerImpl notify
WARNING: Expected content type of 'application/javascript' or 'application/ecmascript' for remotely loaded JavaScript element at 'http://www.craigslist.org/js/jquery.js', but got 'application/x-javascript'.
From the appearance of the message, you are using HtmlUnit which uses Commons Logging for logging messages. Unless you configure Commons Logging to write to a file, the log messages will get logged by the simple logger of Commons Logging which writes out onto the console.
If you want to make the error messages go away you could adopt either of the options:
Configure Commons Logging to write to a file on disk (using log4j).
Redirect the console output to /dev/null or its equivalent, as sal pinpointed.
A much easier way, without having to add Log4j as a dependency, is to simply redirect STDERR.
System.setErr(new PrintStream("/dev/null"));
That's all you really need.
Note: Make sure you reset the stream after you are done with HtmlUnit:
final PrintStream err = new PrintStream(System.err);
System.setErr(new PrintStream("/dev/null"));
// ...
System.setErr(err);
Just copy first lines from the link Vineet posted:
If you don't explicitly configure commons logging to use LOG4J or another logging framework then it will use the simple logger. When using the simple logger, you can change the default logging level by setting the following system property:
System.getProperties().put("org.apache.commons.logging.simplelog.defaultlog","fatal");
Add this code somewhere in the beginning of the program.
Assuming these are log messages, you could configure the logger to write everything to null or /dev/null
Putting a file like this in the path might help
<!DOCTYPE log4j:configuration SYSTEM "log4j.dtd" >
<log4j:configuration xmlns:log4j="http://jakarta.apache.org/log4j/">
<appender name="NULL" class="org.apache.log4j.FileAppender">
<param name="File" value="/dev/null"/>
</appender>
<logger name="com.gargoylesoftware.htmlunit">
<level value="FATAL"/>
<appender-ref ref="NULL"/>
</logger>
</log4j:configuration>
Since the OP keeps asking how to redirect to /dev/null:
You can achieve a similar effect by calling System.setOut and System.setErr, passing in a PrintStream that does nothing with the output it's given.
This is a terrible hack, and the previous answers are far far cleaner.
I found that HtmlUnit does not include the log4j implementation, only the commons logging "interface" (and abstract classes). Once you toss log4j.jar on the path, HtmlUnit behaves itself much better, and honors its configs.