Java Process Not Able To Write Logs To Console - java

I am implementing log4j2 in my java application where I trying to write data to console using log4j2 configuration file. I have created a jar called Interface.jar . Soft Links are created for this jar and are run with different arguments . 2 soft links created are Interface1 and Interface2 with different arguments . Interface1 and Interface2 have different log4j2 configuration file path.
System.setProperty("log4j.configurationFile", System.getenv("LOG4J_INTERFACE1"));
System.setProperty("log4j.configurationFile", System.getenv("LOG4J_INTERFACE2"));
Log4j Configuration File For Interface1 is :
status = warn
appenders=console
property.LOG_PATTERN = %d{yyyy-MM-dd} %d{HH:mm:ss,SSS zzz}|%p|INTERFACE1||||||%m%n
appender.console.type = Console
appender.console.name = LogToConsole
appender.console.layout.type = PatternLayout
appender.console.layout.pattern = ${LOG_PATTERN}
logger.Log4JExample.name = Log4JExample
logger.Log4JExample.level = debug
logger.Log4JExample.additivity = false
logger.Log4JExample.appenderRef.console.ref = LogToConsole
rootLogger.level = info
rootLogger.appenderRef.stdout.ref = LogToConsole
Log4j Configuration File For Interface2 is :
status = warn
appenders=console
property.LOG_PATTERN = %d{yyyy-MM-dd} %d{HH:mm:ss,SSS zzz}|%p|INTERFACE2||||||%m%n
appender.console.type = Console
appender.console.name = LogToConsole2
appender.console.layout.type = PatternLayout
appender.console.layout.pattern = ${LOG_PATTERN}
logger.Log4JExample.name = Log4JExample
logger.Log4JExample.level = debug
logger.Log4JExample.additivity = false
logger.Log4JExample.appenderRef.console.ref = LogToConsole2
rootLogger.level = info
rootLogger.appenderRef.stdout.ref = LogToConsole2
The issue is that when I start both the process , Interface1 is able to write to console but Interface2 is not able to do so. Both the process are running fine. One challenge I see is that both these jars have save main class Interface.class .
LogManager.getLogger(Interface.class);
Can anyone shed some light on how can I stream the data to console from multiple processes using soft links.

Need to have 2 appenders. You can use give all the appenders with comma separated.
I can see both loggers have different format and both needs to write the console. In those cases you need to use Marker filter for different loggers.
below is the sample log4j2.properties file
appenders = console, console1
appender.console.type = Console
appender.console.name = LogToConsole
appender.console.layout.type = PatternLayout
appender.console.layout.pattern = %d{yyyy-MM-dd} %d{HH:mm:ss,SSS zzz}|%p|INTERFACE1||||||%m%n
appender.console1.type = Console
appender.console1.name = LogToConsole2
appender.console1.layout.type = PatternLayout
appender.console1.layout.pattern = %d{yyyy-MM-dd} %d{HH:mm:ss,SSS zzz}|%p|INTERFACE2||||||%m%n
loggers = rolling, interface2
logger.rolling.name = org.apache.logging.log4j.core.appender.rolling
#configure rootLogger and attach all the appenders to it
rootLogger.level = info
rootLogger.appenderRef.console.ref = LogToConsole
logger.interface2.name = Interface2
logger.interface2.additivity = false
logger.interface2.level = debug
logger.interface2.appenderRef.console1.ref = LogToConsole2

It seems you are setting a system property like so:
System.setProperty("log4j.configurationFile", System.getenv("LOG4J_INTERFACE1"));
while you should be setting log4j2.configurationFile.
Notice the log4j2 prefix.
I also recommend setting another system property
java -Dlog4j2.debug=true ...
just to see more what log4j2 is doing. You can turn it off once you are happy.

Related

how to implement profiles for log4j2 for spring 5

i want to implement spring 5 with log4j2 profile, like dev, qa and prod.
At present, This is how i run my spring 5 with log4j2, i load the log4j2 properties in command line:
mvn tomcat8:run -Dlog4j.configurationFile=file:%path_to_log4j2_prop%/log4j2.properties
and this is my log4j2 properties:
status = debug
name = PropertiesConfig
#Make sure to change log file path as per your need
property.environment=D:/WhiteCoats-New-Workspace/spring-5
property.servicesfilename = ${environment}/wc.out
filters = threshold
filter.threshold.type = ThresholdFilter
filter.threshold.level = debug
appenders = services
appender.services.type = RollingFile
appender.services.name = ServiceFile
appender.services.fileName = ${servicesfilename}
appender.services.filePattern = ${environment}/wc.out-%d{yyyy-MM-dd}-%i
appender.services.layout.type = PatternLayout
appender.services.layout.pattern = [ %d{yyyy-MMM-dd HH:mm:ss a} ] - [%t] %-5level %logger{36} - %msg%n
appender.services.policies.type = Policies
appender.services.policies.time.type = TimeBasedTriggeringPolicy
appender.services.policies.time.interval = 1
appender.services.policies.time.modulate = true
appender.services.policies.size.type = SizeBasedTriggeringPolicy
appender.services.policies.size.size=5MB
appender.services.strategy.type = DefaultRolloverStrategy
appender.services.strategy.max = 10
loggers = services
#services logs
logger.services.name = com.vm
logger.services.level = debug
logger.services.additivity = false
logger.services.appenderRef.services.ref = ServiceFile
rootLogger.level = info
rootLogger.appenderRef.stdout.ref = ServiceFile
In spring 3, i used log4j and configured the path in web.xml.
how do i implement profiles for log4j2 for spring 5?
In Spring Boot, if you need to change the property log4j.configurationFile it is very simple within the application.yml. You define the default, and the override value in case you use a profile. For example:
log4j:
configurationFile: %path_to_log4j2_prop%
---
spring:
profiles: development
log4j:
configurationFile: %path_to_dev_log4j2_prop%
---
spring:
profiles: production
log4j:
configurationFile: %path_to_prod_log4j2_prop%
If you use Spring only, than you can use #Configuration with #Profile and #PropertySource to load different property files according to your profile, and in those files you can set your log4j.configurationFile property based on your needs.

log4j2 properties file for a custom appender

I created a custom appender and it's not getting called when I run my test. Here's what the properties look like:
name=config
appenders=console, myCustomAppender
appender.console.type=Console
appender.console.name=STDOUT
appender.console.layout.type=PatternLayout
#appender.console.layout.pattern =%d{HH:mm:ss} [%t] %c{1} [%-5level] - %msg%n
appender.console.layout.pattern=%d{dd-MM-yyyy HH:mm:ss} [%-5p] (%F:%L) - %m%n
appender.myCustomAppender = com.myCompany.logging.log4j.WindowsEventLogAppender
appender.myCustomAppender.name = WindowsEventLogAppender
appender.myCustomAppender.type = WindowsEventLogAppender
rootLogger.level=info
rootLogger.appenderRefs=stdout, myCustomAppender
rootLogger.appenderRef.stdout.ref=STDOUT
My appender is called a WindowsEventLogAppender. Any idea what's wrong with my properties file? I see the console test messages but none of the messages from my appender. Right now I'm just doing a System.out.println in my custom appender to verify it's getting called.
BTW, I've found lot's of XML examples out there for log4j2 configurations with custom appenders but none for using a properties file for configuration.
Thanks,
-Mike
I might be quite late here, but I think my answer can help other people looking for answers. Please accept this as an answer if this is correct!
If you have created a custom appender having annotation like this:
#Plugin(name = "MyCustomAppender", category = "Core",
elementType = "appender", printObject = true)
public final class MyCustomAppenderImpl extends AbstractAppender {
// other code for the plugin....
}
The log4j2 manual about Configuring Appenders states that:
"An appender is configured either using the specific appender plugin's name or with an appender element and the type attribute containing the appender plugin's name"
Meaning the type for appender should be Appender Plugin's Name attribute value.
Which in above case is MyCustomAppender (appender.identifierName.type=MyCustomAppender)
So, the Properties file configuration for this to work should be:
(Note : I have added a stdout(console) appender just to show
relevance/similarity of usage with OOTB appenders, and 2 example
usages with RootLogger and a custom logger)
# this packages attribute is important, please put comma seperated package(s) to the
# plugin(s) you have created
packages = com.package.to.your.plugin
# Example: Declare and Define OOTB Console appender, which sends log events to stdout
appender.console.name = stdout
appender.console.type = Console
# Declare and define the custom appender like this
# Note that the "abc" in "appender.abc.type" can be anything
# and the value for "appender.abc.type" should be the same as
# "Name" attribute value given in custom appender plugin which is "MyCustomAppender"
appender.abc.name=arbitrary_name
appender.abc.type=MyCustomAppender
rootLogger.appenderRef.stdout.ref = stdout
rootLogger.appenderRef.abc.ref = arbitrary_name
logger.loggeridentifier.name = com.test.SomeClass
logger.loggeridentifier.appenderRef.stdout.ref = stdout
logger.loggeridentifier.appenderRef.abc.ref = arbitrary_name
# Also note that the value of appenderRef should be the same name given to your
# appender in properties file, which in this case is "arbitrary_name" (as given above)
Try adding the packages property.
Like: packages = com.myCompany
You haven't included the package info
try the below configuration.
name=config
appenders=console, myCustomAppender
appender.console.type=Console
appender.console.name=STDOUT
appender.console.layout.type=PatternLayout
#appender.console.layout.pattern =%d{HH:mm:ss} [%t] %c{1} [%-5level] - %msg%n
appender.console.layout.pattern=%d{dd-MM-yyyy HH:mm:ss} [%-5p] (%F:%L) - %m%n
appender.myCustomAppender = com.myCompany.logging.log4j.WindowsEventLogAppender
appender.myCustomAppender.name = WindowsEventLogAppender
appender.myCustomAppender.type = WindowsEventLogAppender
rootLogger.level=info
rootLogger.appenderRefs=stdout, myCustomAppender
rootLogger.appenderRef.stdout.ref=STDOUT
rootLogger.com.mycompany.example=INFO,STDOUT

How to disable error logs being printed to the console during unit tests execution with log4j2?

After upgrading to Log4j2, error logs are printing to console during unit tests execution.
I tried to add status=FATAL in the configuration file to avoid error printing on console.
# ----------------------------------------------------------------
# LOGGING
# ----------------------------------------------------------------
# Note - this section is similar to the log4j2 properties syntax
# https://logging.apache.org/log4j/2.x/manual/configuration.html#Properties
status=FATAL;
test.*.log4j2.rootLogger.level=INFO;
*.*.log4j2.rootLogger.level=INFO;
*.*.log4j2.rootLogger.appenderRefs=(APPLICATION);
*.*.log4j2.appenders=(APPLICATION);
*.*.log4j2.appender.APPLICATION.type=AmazonRollingRandomAccessFile;
*.*.log4j2.appender.APPLICATION.name=APPLICATION;
*.*.log4j2.appender.APPLICATION.filePattern="var/output/logs/$APP.%d{yyyy-MM-dd-HH}";
*.*.log4j2.appender.APPLICATION.layout.type=PatternLayout;
# Standard log format but with the purchase id appended after the message.
# This location is to not break rtla processing, which parses everything up-to & including the logger (%c)
*.*.log4j2.appender.APPLICATION.layout.pattern="%d{DATE} [%p] %X{RequestId} (%t) %c: %m [Purchase: %X{PurchaseId}]%n";
The reference doc.
But seems it is not taking status into consideration and it is still printing logs on console.
I tried with all the options below as well, but no luck:
status=FATAL; ..log4j2.status=INFO; ..log4j2.status=ERROR;
The status of the Configuration only relates to the internal logging of log4j2 itself, i.e. you can use it to debug your configuration of log4j2, but it is not used for your actual application.
If you want to disable all logging for your application, you can set the ThresholdFilter of your configuration to off:
filter.threshold.type = ThresholdFilter
filter.threshold.level = off
or you can set your root logger to level = off (provided you don't have any other loggers defined):
rootLogger.level = off
A complete example of something that would work:
status = warn
name = TestConfig
filter.threshold.type = ThresholdFilter
filter.threshold.level = off
appender.list.type = List
appender.list.name = List
appender.list.filter.threshold.type = ThresholdFilter
appender.list.filter.threshold.level = trace
logger.whatever.name = com.relentlesscoding.logging
logger.whatever.level = trace
logger.whatever.additivity = false
logger.whatever.appenderRef.whatever.ref = List
rootLogger.level = trace

Make embedded Tomcat log to certain file with log4j in Maven project

Introduction
I've been looking for this fix for some time now but no luck so far. I'm building a Java webapp which uses embedded Tomcat as servlet. I have set log4j as my main logger and the logs post to the file specified successfully. Because the Tomcat is embedded I cannot find this catalina.out file that I've seen in so many answers through SO and other forums.
Problem
What I want is to make Tomcat log with log4j to the same file I use for logging for the whole webapp. How can I do this? Is there a way to do this programmatically?
P.S. :
I'm using Windows as an OS and the Tomcat version is 8.0.30
By default tomcat uses [CATALINA_HOME]/conf/logging.properties. In there edit the below properties:
1catalina.org.apache.juli.AsyncFileHandler.level = FINE
1catalina.org.apache.juli.AsyncFileHandler.directory = **YOUR_PATH_HERE**
1catalina.org.apache.juli.AsyncFileHandler.prefix = catalina.
Turns out it was way simpler than I thought, so I'm just leaving the answer here for anyone who might have the same problem.
I made a function initializeLogging()
private static void initializeLogging()
{
//Getting the current timestamp to use in log file naming
Calendar calendar = Calendar.getInstance();
java.text.DateFormat df = new java.text.SimpleDateFormat("yyMMddHHmmss");
String timestamp = df.format(calendar.getTime());
ConfigurationBuilder< BuiltConfiguration> builder = ConfigurationBuilderFactory.newConfigurationBuilder();
builder.setStatusLevel(Level.ALL);
builder.setConfigurationName("RollingBuilder");
// create a console appender
AppenderComponentBuilder appenderBuilder = builder.newAppender("Stdout", "CONSOLE").addAttribute("target",
ConsoleAppender.Target.SYSTEM_OUT);
appenderBuilder.add(builder.newLayout("PatternLayout")
.addAttribute("pattern", "<%d{yyyy/MM/dd HH:mm:ss}> %p (%t). %m%n"));
builder.add(appenderBuilder);
// create a rolling file appender
LayoutComponentBuilder layoutBuilder = builder.newLayout("PatternLayout")
.addAttribute("pattern", "<%d{yyyy/MM/dd HH:mm:ss}> %p (%t). %m%n");
ComponentBuilder triggeringPolicy = builder.newComponent("Policies")
.addComponent(builder.newComponent("SizeBasedTriggeringPolicy").addAttribute("size", "100M"));
//specifying log file name as well ss log file name if the first exceeds maximum size => 100M
appenderBuilder = builder.newAppender("rolling", "RollingFile")
.addAttribute("fileName", "logs/myLogging" + "_" + timestamp + ".log")
.addAttribute("FilePattern","logs/myLogging"+"_"+ timestamp + "%d{yyyyMMddHHmmss}" + ".log")
.add(layoutBuilder)
.addComponent(triggeringPolicy);
builder.add(appenderBuilder);
// create the new logger
builder.add(builder.newLogger("myLogger", Level.ALL)
.add(builder.newAppenderRef("rolling"))
.addAttribute("additivity", false));
builder.add(builder.newRootLogger(Level.ALL)
.add(builder.newAppenderRef("rolling")));
LoggerContext ctx = Configurator.initialize(builder.build());
}
so what this function does is to give a pattern at each entry to the logs and direct the logs to a file specified by me. Now every time I want to log something I just have to call Logger logger = LogManager.getLogger('myLogger)
So there it is a quick programmatic only log4j initialization.

Log4j configured with a properties file doesn´t create a file

I am new configuring log4j for a project, I have used it several times, but it´s the first time i have to configure it.
I am configuring my Log4j, I have imported the log4j-1.2.17.jar library, and I have created a properties that look like this:
log4j.appender.consola = org.apache.log4j.ConsoleAppender
log4j.appender.consola.threshold = INFO
log4j.appender.consola.target = System.out
log4j.appender.consola.layout = org.apache.log4j.EnhancedPatternLayout
log4j.appender.consola.layout.ConversionPattern = %d{dd MMM yyyy - HH:mm:ss} [%-5p] %c{2} - %m%n
log4j.appender.archivo = org.apache.log4j.FileAppender
log4j.appender.archivo.file = archivo.log
log4j.appender.archivo.layout = org.apache.log4j.PatternLayout
log4j.appender.archivo.layout.ConversionPattern = %d [%-5p] %c{2} - %m%n
log4j.rootLogger=TRACE, consola
log4j.logger.com.javatutoriales.log4j.configuracion=WARN, archivo
This properties file called log4j.properties is created in the default package of the project.
When I used this configuration in a class, it returns me the console log properly. I used the following code In a class:
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public class PruebaLog {
/** * Logger. */
private static final Logger logger = LoggerFactory.getLogger(PruebaLog.class);
public static void main (String args[]){
logger.trace("mensaje de trace");
logger.debug("mensaje de debug");
logger.info("mensaje de info");
logger.warn("mensaje de warn");
logger.error("mensaje de error");
}
}
The problem is that this class returns me the console out, but doesn´t create the file archivo.log in the path of my project.
Anybody know the reason of why it doesn´t create this log file???
Or anybody could help me with the configuration of this file in order to have a log of the diferent classes of my project in a log file???
You are not using the file appender as you have set the console appender for the root logger:
log4j.rootLogger=TRACE, consola
You need this instead to use the file appender:
log4j.rootLogger=INFO, archivo
Learn more about the appenders and different log4j properties from the official document:
http://logging.apache.org/log4j/1.2/manual.html
in you properties, you need to add rootLogger file
log4j.rootLogger=INFO, archivo
For more details you can refer to log4j.properties config

Categories