I'm working on a spring-based application which has to communicate with a SQL database through mybatis: all right but the logs destination.
For some reason mybatis logs to the wrong file, could you help me to figure out why? Here's my configuration:
log4j.properties:
### Appenders
# Console appender
log4j.appender.console=org.apache.log4j.ConsoleAppender
log4j.appender.console.Threshold=WARN
log4j.appender.console.layout=org.apache.log4j.PatternLayout
# Application file appender
log4j.appender.main=org.apache.log4j.RollingFileAppender
log4j.appender.main.File=logs/app.log
log4j.appender.main.layout=org.apache.log4j.PatternLayout
log4j.appender.main.MaxFileSize=10MB
log4j.appender.main.MaxBackupIndex=15
# Libs file appender
log4j.appender.libs=org.apache.log4j.RollingFileAppender
log4j.appender.libs.File=logs/app_libs.log
log4j.appender.libs.layout=org.apache.log4j.PatternLayout
log4j.appender.libs.MaxFileSize=10MB
log4j.appender.libs.MaxBackupIndex=15
### Loggers & additivity
# Application
log4j.additivity.our.company.basepackage=false
log4j.logger.our.company.basepackage=TRACE,main,console
# Root logger
log4j.rootLogger=INFO,libs
pom.xml snippet
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
<version>1.7.5</version>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>jcl-over-slf4j</artifactId>
<version>1.7.5</version>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-log4j12</artifactId>
<version>1.7.5</version>
</dependency>
<dependency>
<groupId>log4j</groupId>
<artifactId>log4j</artifactId>
<version>1.2.17</version>
<scope>runtime</scope>
</dependency>
I find TRACE-level rows of mybatis ("org.apache.ibatis.logging.jdbc.BaseJdbcLogger.trace(BaseJdbcLogger.java:145)") in the file "app.log".
I excluded commons-logging from spring-core, and with a dependency tree I don't see commons-logging. Why isn't mybatis logging to the file "app_libs.log"? Why does mybatis not respect the specified level?
Thank you.
Edit 1
The code with which the database gets queried has been generated with mybatis-generator, and the generated code lives somewhere under the package "our.company.basepackage".
Since the question was posted, I didn't stop to think about this, until now: I found the reason of that behaviour.
The decisive suggestion is that "the code has been generated with mybatis-generator", and it has been generated in the same subpackage of the application: this means that the *Mapper classes, used for querying the databaes, effectively are in the application package and so their logs are treated as logs of "our.company.basepackage" and not as logs of "org.apache.ibatis".
The "org.apache.ibatis" in logs rows was misleading me.
After this small insight, I added the following to my log4j.properties:
log4j.additivity.our.company.basepackage.persistence.mybatis=false
log4j.logger.our.company.basepackage.persistence.mybatis=INFO,libs
With these 2 more lines, everything works properly, i.e. no more "org.apache.ibatis" rows in app.log.
I hope that this can be useful to someone other using mybatis-generator.
Related
I have existing project with very standart Logback implementation.
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
class SomeClass{
Logger log = LoggerFactory.getLogger(getClass());
void someMethod(){
log.info("some log message");
}
}
This is used in many places and in code I dont have sources. ch.qos.logback.classic.Logger is used as implementation.
I want to use my own implementation of Logger (I wanted to extend ch.qos.logback.classic.Logger but it's final) and use it applicatio wide without modifying the code (which I don't have anyway).
I would expect that configuration of LoggerFactory in logback.xml would be possible, but it doesn't seem so.
I'm using maven artifacts
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
<version>1.7.30</version>
</dependency>
<dependency>
<groupId>ch.qos.logback</groupId>
<artifactId>logback-classic</artifactId>
<version>1.2.3</version>
</dependency>
I could not find straight way of doing it. I came over XLogger and logback-ext but it seems I would need to modify all factory usages.
When doing:
new MiniDFSCluster.Builder(config).build()
I get this exception:
java.lang.UnsatisfiedLinkError: org.apache.hadoop.io.nativeio.NativeIO$Windows.access0(Ljava/lang/String;I)Z
at org.apache.hadoop.io.nativeio.NativeIO$Windows.access0(Native Method)
at org.apache.hadoop.io.nativeio.NativeIO$Windows.access(NativeIO.java:557)
at org.apache.hadoop.fs.FileUtil.canWrite(FileUtil.java:996)
at org.apache.hadoop.hdfs.server.common.Storage$StorageDirectory.analyzeStorage(Storage.java:490)
at org.apache.hadoop.hdfs.server.namenode.FSImage.recoverStorageDirs(FSImage.java:308)
at org.apache.hadoop.hdfs.server.namenode.FSImage.recoverTransitionRead(FSImage.java:202)
at org.apache.hadoop.hdfs.server.namenode.FSNamesystem.loadFSImage(FSNamesystem.java:1020)
at org.apache.hadoop.hdfs.server.namenode.FSNamesystem.loadFromDisk(FSNamesystem.java:739)
at org.apache.hadoop.hdfs.server.namenode.NameNode.loadNamesystem(NameNode.java:536)
at org.apache.hadoop.hdfs.server.namenode.NameNode.initialize(NameNode.java:595)
at org.apache.hadoop.hdfs.server.namenode.NameNode.<init>(NameNode.java:762)
at org.apache.hadoop.hdfs.server.namenode.NameNode.<init>(NameNode.java:746)
at org.apache.hadoop.hdfs.server.namenode.NameNode.createNameNode(NameNode.java:1438)
at org.apache.hadoop.hdfs.MiniDFSCluster.createNameNode(MiniDFSCluster.java:1107)
at org.apache.hadoop.hdfs.MiniDFSCluster.createNameNodesAndSetConf(MiniDFSCluster.java:978)
at org.apache.hadoop.hdfs.MiniDFSCluster.initMiniDFSCluster(MiniDFSCluster.java:807)
at org.apache.hadoop.hdfs.MiniDFSCluster.<init>(MiniDFSCluster.java:467)
at org.apache.hadoop.hdfs.MiniDFSCluster$Builder.build(MiniDFSCluster.java:426)
I want to use the Hadoop Minicluster to test my Hadoop HDFS (which does not throw this exception, see java.lang.UnsatisfiedLinkError: org.apache.hadoop.io.nativeio.NativeIO$Windows.createDirectoryWithMode0).
In my Maven pom.xml I have these dependencies:
<dependency>
<groupId>org.apache.hadoop</groupId>
<artifactId>hadoop-common</artifactId>
<version>2.6.0</version>
</dependency>
<!-- for unit testing -->
<dependency>
<groupId>org.apache.hadoop</groupId>
<artifactId>hadoop-common</artifactId>
<version>2.6.0</version>
<type>test-jar</type>
</dependency>
<dependency>
<groupId>org.apache.hadoop</groupId>
<artifactId>hadoop-hdfs</artifactId>
<version>2.6.0</version>
</dependency>
<!-- for unit testing -->
<dependency>
<groupId>org.apache.hadoop</groupId>
<artifactId>hadoop-hdfs</artifactId>
<version>2.6.0</version>
<scope>test</scope>
<classifier>tests</classifier>
</dependency>
I understood, I do not need to the specific 'hadoop-minicluster' dependency as it already comes with the above included hadoop-hdfs.
I am trying to build the MiniDFSCluster in my #BeforeAll.
I have used different configs for the builder:
config = new HdfsConfiguration(); / config = new Configuration();
And different ways to create a path for the baseDir:
config.set(miniDfsClusterHD.HDFS_MINIDFS_BASEDIR, baseDir);
Also, I downloaded the hadoop.dll and hdfs.dll and winuntils.exe in v2.6.0 and added the path to those in my environment variables.
I studied all the related issues I could find in stackoverflow (without success, obviously) and all guides and code examples I could find in the internet (there are a few and they all do it differently.)
Can somehow please help me, I am out of ideas.
UPDATE:
I am running the test with the following VM options (which should not be necessary, I think):
-Dhadoop.home.dir=C:/Temp/hadoop
-Djava.library.path=C:/Temp/hadoop/bin
I also tried to set the environment variables directly (which should not be necessary when using the VM options):
System.setProperty("hadoop.home.dir", "C:\\Temp\\hadoop-2.6.0");
System.setProperty("java.library.path", "C:\\Temp\\hadoop-2.6.0\\bin");
I have resolved this issue by downloading the source file (org.apache.hadoop.io.nativeio.NativeIO.java) and modifying line in
function access (in your case 557) from:
return access0(path, desiredAccess.accessRight());
to
return true;
Mongo java driver is verbose since v3.x.x, it's not very optimal to store a log of logs like this. Would like to hide some of them.
Here are my dependencies (maven / pom.xml)
<dependency>
<groupId>org.mongodb</groupId>
<artifactId>mongo-java-driver</artifactId>
<version>3.0.1</version>
</dependency>
<!-- LOGS -->
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
<version>1.7.5</version>
</dependency>
<dependency>
<groupId>log4j</groupId>
<artifactId>log4j</artifactId>
<version>1.2.17</version>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>jcl-over-slf4j</artifactId>
<version>1.7.5</version>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>jul-to-slf4j</artifactId>
<version>1.7.5</version>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-log4j12</artifactId>
<version>1.7.5</version>
</dependency>
I want to hide mongo java driver logs :
2015-05-16 10:43:22 023 DEBUG command:56 - Sending command {count : BsonString{value='skydatas'}} to database rizze on connection [connectionId{localValue:2, serverValue:9}] to server 127.0.0.1:27017
2015-05-16 10:43:22 041 DEBUG command:56 - Command execution completed
2015-05-16 10:43:22 042 DEBUG command:56 - Sending command {count : BsonString{value='skydatas'}} to database rizze on connection [connectionId{localValue:2, serverValue:9}] to server 127.0.0.1:27017
2015-05-16 10:43:22 060 DEBUG command:56 - Command execution completed
2015-05-16T10:49:34.448Z DEBUG Checking status of 127.0.0.1:27017 | | cluster:56
2015-05-16T10:49:34.452Z DEBUG Updating cluster description to {type=STANDALONE, servers=[{address=127.0.0.1:27017, type=STANDALONE, roundTripTime=1,3 ms, state=CONNECTED}] | | cluster:56
Thanks
You should be able to do this from your log4j configuration file.
The first thing I would do is temporarily add the fully-qualified class name to your log4j appender format (%C if you're using a formatter based on PatternLayout). That gives you the package and class names of the source of the logging statements you want to exclude.
Then follow the example from the log4j manual to specifically raise the logging level of the packages/classes you don't want to see (search the page for text from the snippet below to find it on the page for more context):
# Print only messages of level WARN or above in the package com.foo.
log4j.logger.com.foo=WARN
Don't forget to take the %C out of your pattern when you've excluded all the packages you don't want to see.
Here is a log4j configuration, I'm using with log4j:
# Log4J logger file
log = ./log4j
log4j.rootLogger = WARN, CONSOLE
log4j.logger.com.rizze.db=INFO
# Direct log messages to stdout
log4j.appender.CONSOLE=org.apache.log4j.ConsoleAppender
log4j.appender.CONSOLE.Target=System.out
log4j.appender.CONSOLE.layout=org.apache.log4j.PatternLayout
log4j.appender.CONSOLE.layout.ConversionPattern=%d{yyyy-MM-dd HH:mm:ss SSS} %-5p %m / %c{1}:%L %n
What is doing this work around
- show Logs with level >= INFO for package com.rizze.db
- show others Logs with level >= WARN
it is work for me.
add this line to you log4j configuration to fix this problem.
log4j.logger.org.mongodb.driver=ERROR
After adding quartz-scheduler to a project, Tomcat's server log is being spammed with the following message:
[INFO] [talledLocalContainer] 12:15:06.319
[DefaultQuartzScheduler_QuartzSchedulerThread] DEBUG
o.quartz.core.QuartzSchedulerThread - batch acquisition of 0 triggers
I'm trying to disable that log message, which repeats every 25-seconds or so. I've been through a number of other answers to this same question, such as:
Disable quartz logging
stop quartz debug logging log4j
Disabling Log4J Output in Java
...and none of the approaches suggested are working.
I have the following dependencies declared in pom.xml:
<dependency>
<groupId>org.quartz-scheduler</groupId>
<artifactId>quartz</artifactId>
<version>2.2.1</version>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-log4j12</artifactId>
<version>1.7.5</version>
</dependency>
And I've added the following log4j.properties settings to my project:
log4j.rootLogger=OFF
log4j.logger.quartz=OFF
log4j.logger.o.quartz=OFF
log4j.logger.org.quartz=OFF
...and also the following simplelogger.properties:
org.slf4j.simpleLogger.defaultLogLevel=error
In addition to attempting the programmatic solution suggested on one of the linked answers, which should disable all logging and goes roughly like:
List<Logger> loggers = Collections.<Logger>list(LogManager.getCurrentLoggers());
loggers.add(LogManager.getRootLogger());
for ( Logger logger : loggers ) {
logger.setLevel(Level.OFF);
}
That seems to disable everything except the log message from quartz when it runs.
Is there a way to get rid of the log message from quartz, short of modifying the quartz source-code to remove it?
The logging entry above doesn't look like Log4J. I think thats ACL or JUL. When you are using Slf4j to Log4J, you also need to redirect these frameworks to Slf4j. Add these dependencies to your project as well:
<!--Redirect Apache Commons Logging to Slf4J -->
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>jcl-over-slf4j</artifactId>
<version>1.7.5</version>
</dependency>
<!--Redirect Java Util Logging to Slf4J -->
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>jul-to-slf4j</artifactId>
<version>1.7.5</version>
</dependency>
Read this doc page about redirecting Jul to Slf4J, too. Be sure to exclude any existing commons-logging.jar files from your project, through Maven.
(From the Slf4J documentation page)
And if all else fails, try the following code:
//see if we can find the offending logger through slf4j's LoggerFactory
org.slf4j.Logger logger =
LoggerFactory.getLogger(Class.forName("org.quartz.core.QuartzSchedulerThread"));
if (logger != null && logger instanceof ch.qos.logback.classic.Logger) {
//the slf4j Logger interface doesn't expose any configuration API's, but
//we can cast to a class that does; so cast it and disable the logger
((ch.qos.logback.classic.Logger)logger).setLevel(
ch.qos.logback.classic.Level.OFF);
}
I am not able to get past this problem. Browsed through many forums. Pls help:
org.springframework.beans.factory.BeanDefinitionStoreException:
Unexpected exception parsing XML document from ServletContext resource
[/WEB-INF/applicationContext.xml]; nested exception is
javax.xml.parsers.FactoryConfigurationError: Provider for
javax.xml.parsers.DocumentBuilderFactory cannot be found.
I have included all the jar files in xerces bin.
Following is my WEB-INF/lib structure:
We have this problem also when upgrade spring and jpa/hibernate from 3 to 4. For us it is because hibernate-entitymanager 4.3.11 has a dependency on jdom which has a dependency on xml-apis which will conflict with the JRE’s rt.jar’s javax.xml stuff. We exclude it so that our spring xml config could be correctly parsed.
To solve the problem, we can just exclude the xml-apis from the dependency tree.
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-entitymanager</artifactId>
<exclusions>
<exclusion>
<groupId>xml-apis</groupId>
<artifactId>xml-apis</artifactId>
</exclusion>
</exclusions>
</dependency>
I also had this problem working with WebSphere Portal 8. I was recently using xalan 2.7.0 for accessing and parsing XML.
<dependency>
<groupId>xalan</groupId>
<artifactId>xalan</artifactId>
<version>2.7.0</version>
<exclusions>
<exclusion>
<groupId>xml-apis</groupId>
<artifactId>xml-apis</artifactId>
</exclusion>
</exclusions>
</dependency>
After removing the xml-apis (like Leon Li did) it worked fine.
I could resolve the above problem entirely, by setting the order in which classloader should load the xerces jar files (WAR->EAR->Server). The following link is taken from Xerces site at Apache. It helps to resolve the above issue for Websphere Portal/WAS:
http://www.ibm.com/developerworks/websphere/library/techarticles/0310_searle/searle.html
I was able to find a solution (by browsing through some forums):
Go to the location where your JRE is present.
For example, since I am using Websphere Portal JRE, I went to this location:C:\Program Files\IBM5\WebSphere\AppServer\java\jre\lib
Open the jaxb.properties file and modify the property javax.xml.parsers.DocumentBuilderFactory to suite your xml parser. In my case it is:
javax.xml.parsers.DocumentBuilderFactory=org.apache.xerces.jaxp.DocumentBuilderFactoryImpl
I have been promoted to the next problem :). I am getting a ClassCastException now. Following is the log:
Unexpected exception parsing XML document from ServletContext resource [/WEB-INF/applicationContext.xml]; nested exception is java.lang.ClassCastException: org.apache.xerces.jaxp.DocumentBuilderFactoryImpl
All help is welcome. Thank you