How do I stop the node from printing the node.conf in the logs?
I understand we can change the logging level since the node.conf is printed at INFO level, but I want to avoid that as much as possible since I still want some other information that is at INFO level to be printed out.
The contents of node.conf are printed at INFO level by the net.corda.node.services.config.ConfigHelper class. To prevent the contents of node.conf from being printed to the logs, you'd have to specify a custom logging configuration so that for the net.corda.node.services.config.ConfigHelper class, only messages at WARN or above should be printed to the logs.
The process for providing a custom Log4J2 logging configuration file for your node is documented here. You need to:
Create the custom logging file (e.g. test.xml)
Point your node to the custom logging file when starting the node (e.g. java -Dlog4j.configurationFile=test.xml -jar corda.jar)
Here's an example test.xml that prevents the contents of node.conf being printed to the logs:
<?xml version="1.0" encoding="UTF-8"?>
<Configuration status="INFO">
<Properties>
<Property name="log-path">logs</Property>
<Property name="log-name">node-${hostName}</Property>
<Property name="archive">${log-path}/archive</Property>
</Properties>
<Appenders>
<Console name="Console-Appender" target="SYSTEM_OUT">
<PatternLayout pattern="%highlight{%level{length=1} %d{HH:mm:ss} %T %c{1}.%M - %msg%n}{INFO=white,WARN=red,FATAL=bright red blink}"/>
</Console>
<RollingFile name="RollingFile-Appender"
fileName="${log-path}/${log-name}.log"
filePattern="${archive}/${log-name}.%d{yyyy-MM-dd}-%i.log.gz">
<PatternLayout pattern="[%-5level] %d{ISO8601}{GMT+0} [%t] %c{1} - %msg%n"/>
<Policies>
<TimeBasedTriggeringPolicy/>
<SizeBasedTriggeringPolicy size="10MB"/>
</Policies>
<DefaultRolloverStrategy min="1" max="10">
<Delete basePath="${archive}" maxDepth="1">
<IfFileName glob="${log-name}*.log.gz"/>
<IfLastModified age="60d">
<IfAny>
<IfAccumulatedFileSize exceeds="10 GB"/>
</IfAny>
</IfLastModified>
</Delete>
</DefaultRolloverStrategy>
</RollingFile>
</Appenders>
<Loggers>
<Root level="error">
<AppenderRef ref="Console-Appender"/>
<AppenderRef ref="RollingFile-Appender"/>
</Root>
<Logger name="net.corda" level="error" additivity="false">
<AppenderRef ref="Console-Appender"/>
<AppenderRef ref="RollingFile-Appender"/>
</Logger>
<Logger name="net.corda.node.services.config.ConfigHelper" level="warn" additivity="false">
<AppenderRef ref="RollingFile-Appender"/>
</Logger>
</Loggers>
</Configuration>
Note the final Logger block. We specify that any messages from net.corda.node.services.config.ConfigHelper (e.g. the contents of node.conf) should only be printed if they are at level WARN or above.
#Joel is there any way to point all the nodes to one custom logging file? I.e, when executing runnodes.jar, could you pass a single logfile as a paramater, i.e:
java -jar -Dlog4j.configurationFile=/Users/username/Desktop/Prototype/config/dev/log4j2.xml runnodes.jar
This doesn't seem to work... so curious.
Related
I have a configuration problem regarding enabling spring related logging in my application as I'm using EclipseLink,JPA 2.0 & Spring 4.0, I need to verify when the entity manager is closed or cleaned up while doing transactions.
My application is JTA enabled so everything is controlled by my container (Websphere).Here is my log4j.xml
<?xml version="1.0"?>
<!DOCTYPE log4j:configuration SYSTEM "log4j.dtd">
<log4j:configuration debug="true" xmlns:log4j="http://jakarta.apache.org/log4j/">
<!-- CONSOLE normally used in desktop environment -->
<appender name="console" class="org.apache.log4j.ConsoleAppender">
<param name="Encoding" value="UTF-8" />
<param name="Threshold" value="DEBUG"/>
<param name="Target" value="System.out" />
<layout class="org.apache.log4j.PatternLayout">
<param name="ConversionPattern" value="%d [%-8X{context}] %-5p %-40.40c{2} - %m%n"/>
</layout>
</appender>
<appender name="FILE_APPENDER" class="org.apache.log4j.DailyRollingFileAppender">
<param name="File" value="C:\\proj\\was\\logs\\spring.log"/>
<param name="DatePattern" value="'-'yyyy-MM-dd'.txt'"/>
<param name="Threshold" value="DEBUG"/>
<layout class="org.apache.log4j.PatternLayout">
<param name="ConversionPattern" value="%d{yyyy-MM-dd HH:mm:ss} %-4p [%t] %C{2} - %m%n"/>
</layout>
</appender>
<!-- Spring -->
<logger name="org.springframework.transaction" additivity="false">
<level value="DEBUG" />
<appender-ref ref="FILE_APPENDER"/>
</logger>
<logger name="org.springframework.orm.jpa.EntityManagerFactoryUtils" additivity="false">
<level value="DEBUG" />
<appender-ref ref="FILE_APPENDER"/>
</logger>
<logger name="org.springframework.orm.jpa" additivity="false">
<level value="DEBUG" />
<appender-ref ref="FILE_APPENDER"/>
</logger>
<root>
<level value="DEBUG" />
<appender-ref ref="console" />
<appender-ref ref="FILE_APPENDER" />
</root>
</log4j:configuration>
I have also tried many solutions like this, but it didn't help.Please help me where I'm going wrong?
From your comment, it seems that you not have the adapter slf4j to log4j. Or have another adapter.
To check the adapter in use, use the code:
StaticLoggerBinder binder = StaticLoggerBinder.getSingleton();
System.out.println(binder.getLoggerFactoryClassStr());
If it is not the log4j12 adapter showing:
Check on the war, you should have a slf4j-api-xxxx.jar in WEB-INF/lib.
put the slf4j-log4j12-xxxx.jar (same version) into WEB-INF/lib
if there is logback-xxxxx.jar remove it, else slf4j will take it to log
if there is log4j-over-slf4j-xxxx.jar remove it, else it is possible that log4j log will be redirected to slf4j that will redirect to log4j and so on..
there is perhaps another adapter (slf4j-jcl-xxxx.jar for instance) that need to be removed.
Logger Hierarchy
In most logging systems, logger has the parent and child relationship, in which children inherit
Level
Appender
ResourceBoudle
from father logger. And the root logger exists at the top of inheritance. The children will send log event to father logger depending on additivity. False means it will not send log to father logger.
So, from your original config, you didn't allow Spring related logger to send log to your root logger.
Suggestions
So, now we understand that we should set additivity to true and change the log4j config into like following:
<logger name="org.springframework.transaction" additivity="true"/>
<logger name="org.springframework.orm.jpa.EntityManagerFactoryUtils" additivity="true"/>
<logger name="org.springframework.orm.jpa" additivity="true"/>
<root>
<level value="DEBUG" />
<appender-ref ref="console" />
<appender-ref ref="FILE_APPENDER" />
</root>
More
Here and here are the blog posts I write about slf4j & log4j & logback, which Spring uses, and you can read to enhance the understanding of logging;
If you change the additivity and still can't see the log in console/file, I suggest you set a breakpoint at any logging line in EntityManagerFactoryUtils, then step in code to see what's wrong;
Update
The logger of EntityManagerFactoryUtils, as we can from source code, is not slf4j or log4j. It is commons logging. So your log4j config about this class will not work.
import org.apache.commons.logging.Log;
private static final Log logger = LogFactory.getLog(EntityManagerFactoryUtils.class);
In order to make your config work, you should make some bridge work:
exclude commons-logging.jar from spring-orm
add jcl-over-slf4j.jar
make sure you have slf4j-api & slf4j-log4j
By looking at the Jars on your classpath some cleaning is probably required, but in order to do so we need to understand what each of the Jars do.
log4j-1.2.9.jar
Is the implementation of Log4j. This one is required in order to log anything using Log4j and of course reading your log4j configuration file.
slf4j.api-1.6.1.jar
Is the Slf4j API library, Only required if you or some of your third-party dependencies use Slf4j for logging, which seem quite likely as you already have it on your classpath. This allows you to write to the logs through Slf4J API, e.g:
private static final Logger LOG = org.slf4j.LoggerFactory.getLogger(MyLoggingClass.class);
slf4j.jdk14-1.6.1.jar
Is a JDK 1.4, also known as java.util.logging binding for Slf4j used to use java.util.logging as the logging engine when Slf4j is used. Obviously we're going to use log4j as the logging implementation and not java.util.logging meaning this should be removed.
slf4j-log4j12-1.7.12.jar
Is a log4j 1.2 binding for Slf4j, required to route logs from Slf4j to your Log4j implementation. This one is only required if slf4j.api-1.6.1.jar was required. However, versions should be harmonized in order to avoid conflicts.
commons-logging-1.1.1.jar and
commons-logging.jar
As far as I can tell those are both the commons logging framework. This is the logging framework used by Spring. However, you should only have one of those on your classpath, where I recommend using the one which reveals it's version.
Having the correct Jars on your classpath, commons logging should be able to pick up the correct logging implementation for you (which in your case is Log4j). If that's not the case, explicitly put a file named commons-logging.properties on the root of your classpath and add the following line to it:
org.apache.commons.logging.Log=org.apache.commons.logging.impl.Log4jLogger
forcing it to use Log4j as the logging implementation.
In my cartridge I use an external library that logs with java.util.logging. I want to redirect the log to SLF4J/logback, but somehow this does not work as I would expect it (logs are empty). Here is the relevant logback configuration:
<appender name="PayPal_LogFile" class="ch.qos.logback.core.rolling.RollingFileAppender">
<filter class="ch.qos.logback.classic.filter.ThresholdFilter">
<level>TRACE</level>
</filter>
<File>${intershop.logfile.Directory}/paypal-${intershop.logfile.NamePostfix}.log</File>
<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
<FileNamePattern>${intershop.logfile.Directory}/paypal-${intershop.logfile.NamePostfix}.%d{yyyy-MM-dd}.log</FileNamePattern>
</rollingPolicy>
<encoder>
<pattern>
[%date{yyyy-MM-dd HH:mm:ss.SSS Z}] %-5level ${intershop.HostName} ${intershop.InstallationID} ${intershop.ServerName} [%mdc{requestsite}] [%mdc{requestapplication}] %logger [%marker] [%mdc{request.type}] [%mdc{session.id}] [%mdc{request.uuid}] "%thread" %msg %ex%n
</pattern>
</encoder>
</appender>
<logger name="com.paypal" additivity="false">
<level value="TRACE" />
<appender-ref ref="Error" />
<appender-ref ref="PayPal_LogFile" />
</logger>
JUL logs in DEBUG level, DEBUG level is allowed for com.paypal and I believe that this should be translated to INFO in SLF4J. What's wrong?
I'll answer my own question.
The reason for the trouble is the additivity="false" property of the logger.
Background: Routing from other logging frameworks to SLF4J is generally easy via the so called bridges unless we speak about JUL. See the details here. ICM implements its own bridge between JUL and SLF4J and there is a subtle bug inside. The logging handler of the ICM is attached to the root level and any appender with additivity="false" won't work because it will never reach the root level.
The bug seems to be here com.intershop.beehive.core.internal.log.JavaLoggingAdapter:
handler = new JavaLoggingHandler();
handler.setLevel(Level.ALL);
Logger root = LogManager.getLogManager().getLogger("");
root.addHandler(handler);
I've changed the additivity to true although I'm not very happy about this and now I can explore the third party logs.
I have installed gremlin (v. 2.6.0) and ArangoDB (v. 2.8.11) and when I run any request through the gremlin.sh shell I get all the debug messages like
11:17:39.713 [main] DEBUG com.arangodb.http.HttpManager - [REQ]http-GET: url=http://localhost:8529/_api/gharial/myDB/edge/E/12712, headers={}
11:17:39.716 [main] DEBUG com.arangodb.http.HttpManager - [RES]http-GET: statusCode=200
11:17:39.716 [main] DEBUG com.arangodb.http.HttpManager - [RES]http-GET: text={"error":false,"code":200,"edge":{"_id":"E/12712"," . . .
I see those are DEBUG messages, so I want to suppress in order not to be flooded by those and only get important messages, like errors or warnings.
To reduce logging one has to change the log level on both server and client side.
Complete steps to fix this:
create config PATH_TO/confs/ directory with inside:
a. file confs/arangod.conf
b. file confs/logback.xml
set env. variable CLASSPATH:
export CLASSPATH=PATH_TO/confs
you can start arangod as follows:
arangod --daemon --pid-file /etc/arangodb/arangodb.pid -c PATH_TO/confs/arangod.conf
The content of confs/arangod.conf should contain:
[log]
## info, warning, or error
level = info
file = PATH_TO/logs/arangodb.log
The content of the confs/logback.xml
<configuration>
<!-- Arango log4j conf -->
<appender name="CONSOLE"
class="ch.qos.logback.core.ConsoleAppender">
<!-- deny all events with a level below INFO, that is TRACE and DEBUG -->
<filter class="ch.qos.logback.classic.filter.ThresholdFilter">
<level>INFO</level>
</filter>
<encoder>
<pattern>
%-4relative [%thread] %-5level %logger{30} - %msg%n
</pattern>
</encoder>
</appender>
<root level="DEBUG">
<appender-ref ref="CONSOLE" />
</root>
</configuration>
Not sure if it is a right place, but will try here.
I have a Spring MVC app deployed on Amazon Elastic Beantalk, using log4j2.
Locally, the logs work well.
this is the config:
<?xml version="1.0" encoding="UTF-8"?>
<Configuration>
<Appenders>
<Console name="STDOUT" target="SYSTEM_OUT">
<PatternLayout pattern="%d %-5p [%t] %C{2} (%F:%L) - %m%n"/>
</Console>
<RollingFile
name="MyFile"
fileName="${sys:catalina.home}/logs/log4j2.log"
filePattern="${sys:catalina.home}/logs/log4j2-%d{MM-dd-yyyy}-%i.log"
immediateFlush="true">
<PatternLayout pattern="%d{yyy-MM-dd HH:mm:ss.SSS} [%t] %-5level %logger{36} - %msg%n"/>
<Policies>
<SizeBasedTriggeringPolicy size="5 MB"/>
</Policies>
<DefaultRolloverStrategy max="2000"/>
</RollingFile>
</Appenders>
<Loggers>
<Logger name="org.apache.log4j.xml" level="debug"/>
<Root level="info">
<AppenderRef ref="STDOUT"/>
<AppenderRef ref="MyFile"/>
</Root>
</Loggers>
</Configuration>
But on EC2 amazon instance, where the ElasticBeanstalk app is running, no appenders working. even SYSTEM_OUT doesn't logged into catalina.out. Absolutely no clue why can that happens :(
Btw before i have experience using ElasticBeanstalk, and usually hadprobs with File appender, but at least log is appended to catalina.out .
Any idea what should i check?
More than often DynamoDB Local does not show descriptive error messages, in order to see internal errors you need to enable logging.
What are the steps to enable DynamoDB Local logging on the standard output?
Go to the directory that has the DynamoDBLocal.jar
Create a file called log4j2.xml with these contents:
<?xml version="1.0" encoding="UTF-8"?>
<Configuration status="WARN">
<Appenders>
<Console name="Console" target="SYSTEM_OUT">
<PatternLayout pattern="%d{HH:mm:ss.SSS} [%t] %-5level %logger{36} - %msg%n"/>
</Console>
</Appenders>
<Loggers>
<Logger name="com.amazonaws.services.dynamodbv2.local" level="DEBUG">
<AppenderRef ref="Console"/>
</Logger>
<Logger name="com.amazonaws.services.dynamodbv2.local.shared.access.sqlite.SQLiteDBAccess" level="INFO">
<AppenderRef ref="Console"/>
</Logger>
<Root level="WARN">
<AppenderRef ref="Console"/>
</Root>
</Loggers>
</Configuration>
Remove the existing log4j2.xml from the jar
zip -d DynamoDBLocal.jar log4j2.xml
Add the created log4j2.xml to the jar
zip -u DynamoDBLocal.jar log4j2.xml
or simply edit the log4j2.xml in the DynamoDBLocal.jar using 7-Zip etc. and overwrite it with the xml above and skip the steps 2-4.
Change to the directory with DynamoDBLocal.jar
Create a new file called log4j.properties with the contents:
log4j.rootLogger=DEBUG, stdout
log4j.appender.stdout=org.apache.log4j.ConsoleAppender
log4j.appender.stdout.layout=org.apache.log4j.PatternLayout
log4j.appender.stdout.layout.ConversionPattern=LOG%d %p [%c] - %m%n
Remove the existing log4j.properties files from the jar (there might be two)
zip -d DynamoDBLocal.jar log4j.properties
zip -d DynamoDBLocal.jar log4j.properties
Add the new properties file to the jar
zip -u DynamoDBLocal.jar log4j.properties
Source: https://gist.github.com/mdaley/aaf9b62d90f6817eb72a