Question
Booking.com
NL
Last activity: 18 Jul 2017 10:43 EDT
How to create separate log file
Hi, I am trying to create separate (from PegaRULES.log) log file based on a condition. I was looking for some help in the PDN and i saw an article that suggested using different log4j appenders to create multiple log files. If anyone has some experience in doing this, could you please let me know how to do it? I am going to setup a special string in the log message and I would have to design an appender that when sees this string, put that log message in a separate file from the standard PRPC log files. How can I realize such condition?
***Updated by moderator: Lochan to close post***
This post has been archived for educational purposes. Contents and links will no longer be updated. If you have the same/similar question, please write a new post.
-
Like (0)
-
Share this page Facebook Twitter LinkedIn Email Copying... Copied!
Refer to the following PDN article: https://pdn.pega.com/system-operations/how-to-customize-logs-with-the-prloggingxml-file
Booking.com
NL
I read it, but didn't find information about custom conditions in appenders, that allow to log messages in separate log files.
Updated: 24 Jun 2015 12:13 EDT
Pegasystems Inc.
GB
I think the general outline to this would be (but I haven't done this, and I stand to be corrected).
1. Write a custom LOG4j Appender :
Write custom appenders for log4j | JavaWorld
java - How to create a own Appender in log4j? - Stack Overflowhttp://www.javaworld.com/article/2073104/learn-java/write-custom-appenders-for-log4j.html
This is probably where you are going to put the logic to examine the special string within the Logging Event - and decide whether to Log it, or throw it away.
You can filter 'higher-up' in log4j - but only ( I believe ) based on CATEGORY / LEVEL (like info,debug) - I don't believe (I could be wrong*) you can filter on any arbitary field within the Logging Event....
If you are logging to a file - you might be able to extend an existing File Appender - rather than having to re-implement the whole thing from scratch.
2. Package the compiled Appender into a JAR file.
3. Upload JAR to PRPC.
4. Edit your PRCONFIG.XML to configure your appender.
I think the general outline to this would be (but I haven't done this, and I stand to be corrected).
1. Write a custom LOG4j Appender :
Write custom appenders for log4j | JavaWorld
java - How to create a own Appender in log4j? - Stack Overflowhttp://www.javaworld.com/article/2073104/learn-java/write-custom-appenders-for-log4j.html
This is probably where you are going to put the logic to examine the special string within the Logging Event - and decide whether to Log it, or throw it away.
You can filter 'higher-up' in log4j - but only ( I believe ) based on CATEGORY / LEVEL (like info,debug) - I don't believe (I could be wrong*) you can filter on any arbitary field within the Logging Event....
If you are logging to a file - you might be able to extend an existing File Appender - rather than having to re-implement the whole thing from scratch.
2. Package the compiled Appender into a JAR file.
3. Upload JAR to PRPC.
4. Edit your PRCONFIG.XML to configure your appender.
AES uses a similar approach here - so you can use the following as a guide here - you would replace the classnames for your custom appender:
<appender name="ALERT-AES-SOAP" class="com.pega.pegarules.priv.util.SOAPAppenderPega"> <param name="EndPointURL" value="http://localhost:8888/prweb/PRSOAPServlet" /> <param name="Mode" value="ALERT" /> <layout class="com.pega.apache.log4j.PatternLayout"> <param name="ConversionPattern" value="%m%n" /> </layout> </appender>
So my areas of uncertainty (my "known unknowns" :-| ) are:
1. Since PRPC uses a extended / repackaged version of LOG4J - would a standard log4j APPENDER work OOTB ? Or do you have to extend the PRPC version of the Appender ?
EDIT: I had a sneaky look at the source code of the SOAPAppenderPega; it does this:
// package com.pega.pegarules.priv.util; import com.pega.apache.log4j.AppenderSkeleton; [...] public class SOAPAppenderPega extends AppenderSkeleton { [...] //
So probably you *could* extend the same PRPC class...whether this is the right thing to do is another question.... :-)
2. I assume it would be the right thing to upload the Appender Code to the DB...maybe you could (and maybe should?) package this as external JAR ?
* Possibly LOG4j 'Filters' could provide you a mechanism here....I have never used them - but maybe they could be used instead of you implemented the logic yourself ? dunno : https://logging.apache.org/log4j/2.0/manual/filters.html
EDIT2: Looks like you might be able to get away with not even having to implement an Appender to this - you might be able to configure an 'ExpressionFilter' right in your prlogging.xml....
See this link : http://blog.trifork.com/2011/08/23/filtering-specific-exceptions-when-using-log4j/
and this one : http://logging.apache.org/log4j/companions/apidocs/org/apache/log4j/filter/ExpressionFilter.html
I haven't tried this yet myself.....
Asurion
US
Here what we have done for this.
we have edited prlogging.xml and created custom appender
<appender-ref ref="CONSOLE"/> pega default
<appender-ref ref="PEGA"/> pega default
<appender-ref ref="Test-Log"/> custom
Then we log in the file using string match
<appender name="Test-Log" class="com.pega.pegarules.priv.util.DailySizeRollingFileAppenderPega">
<param name="FileNamePattern" value="'${test.location}/Testlog-${logging.clusterId}-'"/>
<param name="MaxFileSize" value="512000KB"/>
<layout class="com.pega.apache.log4j.PatternLayout">
<param name="ConversionPattern" value="%d [%20.20t] [%10.10X{pegathread}] [%20.20X{app}] (%30.30c{3}) %-5p %X{stack} %X{userid} - %m%n"/>
</layout>
<filter class="com.pega.apache.log4j.varia.StringMatchFilter">
<param name="StringToMatch" value="Entering activity"/>
<param name="AcceptOnMatch" value="true"/>
</filter>
<filter class="com.pega.apache.log4j.varia.LevelMatchFilter">
<param name="LevelToMatch" value="FATAL"/>
<param name="AcceptOnMatch" value="false"/>
</filter>
<filter class="com.pega.apache.log4j.varia.LevelMatchFilter">
<param name="LevelToMatch" value="ALERT"/>
Here what we have done for this.
we have edited prlogging.xml and created custom appender
<appender-ref ref="CONSOLE"/> pega default
<appender-ref ref="PEGA"/> pega default
<appender-ref ref="Test-Log"/> custom
Then we log in the file using string match
<appender name="Test-Log" class="com.pega.pegarules.priv.util.DailySizeRollingFileAppenderPega">
<param name="FileNamePattern" value="'${test.location}/Testlog-${logging.clusterId}-'"/>
<param name="MaxFileSize" value="512000KB"/>
<layout class="com.pega.apache.log4j.PatternLayout">
<param name="ConversionPattern" value="%d [%20.20t] [%10.10X{pegathread}] [%20.20X{app}] (%30.30c{3}) %-5p %X{stack} %X{userid} - %m%n"/>
</layout>
<filter class="com.pega.apache.log4j.varia.StringMatchFilter">
<param name="StringToMatch" value="Entering activity"/>
<param name="AcceptOnMatch" value="true"/>
</filter>
<filter class="com.pega.apache.log4j.varia.LevelMatchFilter">
<param name="LevelToMatch" value="FATAL"/>
<param name="AcceptOnMatch" value="false"/>
</filter>
<filter class="com.pega.apache.log4j.varia.LevelMatchFilter">
<param name="LevelToMatch" value="ALERT"/>
<param name="AcceptOnMatch" value="false"/>
</filter>
<filter class="com.pega.apache.log4j.varia.LevelMatchFilter">
<param name="LevelToMatch" value="INFO"/>
<param name="AcceptOnMatch" value="false"/>
</filter>
<filter class="com.pega.apache.log4j.varia.LevelMatchFilter">
<param name="LevelToMatch" value="ERROR"/>
<param name="AcceptOnMatch" value="false"/>
</filter>
</appender>
make sure you disable StringMatch in other appenders if you dont want to log in those files
<filter class="com.pega.apache.log4j.varia.StringMatchFilter">
<param name="StringToMatch" value="Entering activity"/>
<param name="AcceptOnMatch" value="false"/>
${logging.clusterId} and ${test.location} are websphere variables for location and to write seperate log file for each node
So when you log you have to add the string Entering activity in log message , the it will be logged in this file.
Booking.com
NL
I add to prlogging.xml custom appender and implement this filter, and then tried to log message with filetered string, but nothing changes. Maybe I must do some other manipulations? Or, for example, reboot environment?
Custom code:
<appender name="ASYNC" class="com.pega.apache.log4j.AsyncAppender">
<filter class="com.pega.apache.log4j.varia.LevelMatchFilter">
<param name="LevelToMatch" value="ALERT"/>
<param name="AcceptOnMatch" value="false"/>
</filter>
<appender-ref ref="CONSOLE"/>
<appender-ref ref="PEGA"/>
<appender-ref ref="ESB"/>
</appender>
<appender name="ESB" class="com.pega.pegarules.priv.util.DailyRollingFileAppender">
<param name="DatePattern" value="'.'yyyy-MM-dd"/>
<param name="File" value="${pega.log.location}/ESB.log"/>
<layout class="com.pega.apache.log4j.PatternLayout">
<param name="ConversionPattern" value="%d [%20.20t] [%10.10X{pegathread}] [%20.20X{app}] (%30.30c{3}) %-5p %X{stack} %X{userid} - %m%n"/>
</layout>
<filter class="com.pega.apache.log4j.varia.StringMatchFilter">
<param name="StringToMatch" value="[ESB]"/>
<param name="AcceptOnMatch" value="true"/>
</filter>
<filter class="com.pega.apache.log4j.varia.LevelMatchFilter">
I add to prlogging.xml custom appender and implement this filter, and then tried to log message with filetered string, but nothing changes. Maybe I must do some other manipulations? Or, for example, reboot environment?
Custom code:
<appender name="ASYNC" class="com.pega.apache.log4j.AsyncAppender">
<filter class="com.pega.apache.log4j.varia.LevelMatchFilter">
<param name="LevelToMatch" value="ALERT"/>
<param name="AcceptOnMatch" value="false"/>
</filter>
<appender-ref ref="CONSOLE"/>
<appender-ref ref="PEGA"/>
<appender-ref ref="ESB"/>
</appender>
<appender name="ESB" class="com.pega.pegarules.priv.util.DailyRollingFileAppender">
<param name="DatePattern" value="'.'yyyy-MM-dd"/>
<param name="File" value="${pega.log.location}/ESB.log"/>
<layout class="com.pega.apache.log4j.PatternLayout">
<param name="ConversionPattern" value="%d [%20.20t] [%10.10X{pegathread}] [%20.20X{app}] (%30.30c{3}) %-5p %X{stack} %X{userid} - %m%n"/>
</layout>
<filter class="com.pega.apache.log4j.varia.StringMatchFilter">
<param name="StringToMatch" value="[ESB]"/>
<param name="AcceptOnMatch" value="true"/>
</filter>
<filter class="com.pega.apache.log4j.varia.LevelMatchFilter">
<param name="LevelToMatch" value="FATAL"/>
<param name="AcceptOnMatch" value="false"/>
</filter>
<filter class="com.pega.apache.log4j.varia.LevelMatchFilter">
<param name="LevelToMatch" value="ALERT"/>
<param name="AcceptOnMatch" value="false"/>
</filter>
<filter class="com.pega.apache.log4j.varia.LevelMatchFilter">
<param name="LevelToMatch" value="INFO"/>
<param name="AcceptOnMatch" value="false"/>
</filter>
<filter class="com.pega.apache.log4j.varia.LevelMatchFilter">
<param name="LevelToMatch" value="ERROR"/>
<param name="AcceptOnMatch" value="false"/>
</filter>
</appender>
Pegasystems
IN
You have to restart the node for prlogging.xml changes to be reflected
Booking.com
NL
We restart the node with new prlogging configuration, and now it doesn't log messages in PegaRULES log, neither in my ESB.log. What am I doing wrong?
Asurion
US
Which version of PRPC you are using , this class class="com.pega.apache.log4j.DailyRollingFileAppender" is for pega 7. you should use class="com.pega.apache.log4j.DailyRollingFileAppender" for pega 6.x
Booking.com
NL
We use version 7.1.8.
Asurion
US
The value is not enclosed correctly in quotes
<param name="File" value="${pega.log.location}/ESB.log"/>
change llike below and try restarting the ystem
<param name="File" value="'${pega.log.location}/ESB.log'"/>
-
Som Venkata Kumar Rallapati
Booking.com
NL
I fix this mistake, but the problem stay. With this configuration there are no logging in PegaRULES.log and in ESB.log...
Asurion
US
Can you send a screen shot of how you are logging in activity. attach the full logging.xml if posibble. did ESB.log file got created in the corresponding path ?
Booking.com
NL
Screenshot of test logging activity:
prlogging.xml: https://dl.dropboxusercontent.com/u/16067783/prlogging.xml
ESB.log was created in the same directory, as PegaRULES.log.
Asurion
US
Use infoForced as logging level
Booking.com
NL
I tried all levels, including InfoForced, but it didn't help. The problem is absence of logging in PegaRULES.log too...The prlogging.xml configuration is correct?
Asurion
US
The Class you are using is the problem. here is the working logging.xml which we are using.
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE log4j:configuration SYSTEM "log4j.dtd">
<log4j:configuration xmlns:log4j="http://jakarta.apache.org/log4j/" debug="false">
<appender name="ASYNC" class="com.pega.apache.log4j.AsyncAppender">
<param name="BufferSize" value="1024"/>
<param name="Blocking" value="false"/>
<filter class="com.pega.apache.log4j.varia.LevelMatchFilter">
<param name="LevelToMatch" value="ALERT"/>
<param name="AcceptOnMatch" value="false"/>
</filter>
<appender-ref ref="CONSOLE"/>
<appender-ref ref="PEGA"/>
<appender-ref ref="Test"/>
</appender>
<appender name="ALERT-ASYNC" class="com.pega.apache.log4j.AsyncAppender">
<param name="BufferSize" value="512"/>
<param name="Blocking" value="false"/>
<filter class="com.pega.apache.log4j.varia.LevelMatchFilter">
<param name="LevelToMatch" value="ALERT"/>
<param name="AcceptOnMatch" value="true"/>
</filter>
<filter class="com.pega.apache.log4j.varia.DenyAllFilter"/>
<appender-ref ref="ALERT-PERFORMANCE"/>
The Class you are using is the problem. here is the working logging.xml which we are using.
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE log4j:configuration SYSTEM "log4j.dtd">
<log4j:configuration xmlns:log4j="http://jakarta.apache.org/log4j/" debug="false">
<appender name="ASYNC" class="com.pega.apache.log4j.AsyncAppender">
<param name="BufferSize" value="1024"/>
<param name="Blocking" value="false"/>
<filter class="com.pega.apache.log4j.varia.LevelMatchFilter">
<param name="LevelToMatch" value="ALERT"/>
<param name="AcceptOnMatch" value="false"/>
</filter>
<appender-ref ref="CONSOLE"/>
<appender-ref ref="PEGA"/>
<appender-ref ref="Test"/>
</appender>
<appender name="ALERT-ASYNC" class="com.pega.apache.log4j.AsyncAppender">
<param name="BufferSize" value="512"/>
<param name="Blocking" value="false"/>
<filter class="com.pega.apache.log4j.varia.LevelMatchFilter">
<param name="LevelToMatch" value="ALERT"/>
<param name="AcceptOnMatch" value="true"/>
</filter>
<filter class="com.pega.apache.log4j.varia.DenyAllFilter"/>
<appender-ref ref="ALERT-PERFORMANCE"/>
<appender-ref ref="ALERT-SECURITY"/>
</appender>
<appender name="ALERT-PERFORMANCE" class="com.pega.apache.log4j.AsyncAppender">
<param name="BufferSize" value="512"/>
<param name="Blocking" value="false"/>
<filter class="com.pega.pegarules.priv.MDCMatchFilter">
<param name="TagToMatch" value="alertType" />
<param name="StringToMatch" value="security" />
<param name="AcceptOnMatch" value="false"/>
</filter>
<appender-ref ref="ALERT"/>
</appender>
<appender name="ALERT-SECURITY" class="com.pega.apache.log4j.AsyncAppender">
<param name="BufferSize" value="512"/>
<param name="Blocking" value="false"/>
<filter class="com.pega.pegarules.priv.MDCMatchFilter">
<param name="TagToMatch" value="alertType" />
<param name="StringToMatch" value="security" />
<param name="AcceptOnMatch" value="true"/>
</filter>
<filter class="com.pega.apache.log4j.varia.DenyAllFilter"/>
<appender-ref ref="ALERTSECURITY"/>
</appender>
<appender name="Test" class="com.pega.pegarules.priv.util.DailySizeRollingFileAppenderPega">
<param name="FileNamePattern" value="'${log.location}/Test-${logging.clusterId}-'"/>
<param name="MaxFileSize" value="512000KB"/>
<param name="MaxBackupIndex" value="8"/>
<layout class="com.pega.apache.log4j.PatternLayout">
<param name="ConversionPattern" value="%d [%20.20t] [%10.10X{pegathread}] [%20.20X{app}] (%30.30c{3}) %-5p %X{stack} %X{userid} - %m%n"/>
</layout>
<filter class="com.pega.apache.log4j.varia.StringMatchFilter">
<param name="StringToMatch" value="Entering activity"/>
<param name="AcceptOnMatch" value="true"/>
</filter>
<filter class="com.pega.apache.log4j.varia.LevelMatchFilter">
<param name="LevelToMatch" value="FATAL"/>
<param name="AcceptOnMatch" value="false"/>
</filter>
<filter class="com.pega.apache.log4j.varia.LevelMatchFilter">
<param name="LevelToMatch" value="ALERT"/>
<param name="AcceptOnMatch" value="false"/>
</filter>
<filter class="com.pega.apache.log4j.varia.LevelMatchFilter">
<param name="LevelToMatch" value="INFO"/>
<param name="AcceptOnMatch" value="false"/>
</filter>
<filter class="com.pega.apache.log4j.varia.LevelMatchFilter">
<param name="LevelToMatch" value="ERROR"/>
<param name="AcceptOnMatch" value="false"/>
</filter>
</appender>
<appender name="CONSOLE" class="com.pega.apache.log4j.ConsoleAppender">
<layout class="com.pega.apache.log4j.PatternLayout">
<param name="ConversionPattern" value="%d [%20.20t] [%10.10X{pegathread}] [%20.20X{tenantid}] [%20.20X{app}] (%30.30c{3}) %-5p %X{stack} %X{userid} - %m%n"/>
</layout>
<filter class="com.pega.apache.log4j.varia.StringMatchFilter">
<param name="StringToMatch" value="Entering activity"/>
<param name="AcceptOnMatch" value="false"/>
</filter>
</appender>
<appender name="PEGA" class="com.pega.pegarules.priv.util.DailySizeRollingFileAppenderPega">
<param name="FileNamePattern" value="'${log.location}/PegaRULES-${logging.clusterId}-'"/>
<param name="MaxFileSize" value="50MB" />
<layout class="com.pega.apache.log4j.PatternLayout">
<param name="ConversionPattern" value="%d [%20.20t] [%10.10X{pegathread}] [%20.20X{tenantid}] [%20.20X{app}] (%30.30c{3}) %-5p %X{stack} %X{userid} - %m%n"/>
</layout>
<filter class="com.pega.apache.log4j.varia.StringMatchFilter">
<param name="StringToMatch" value="Entering activity"/>
<param name="AcceptOnMatch" value="false"/>
</filter>
</appender>
<appender name="ALERT" class="com.pega.pegarules.priv.util.DailySizeRollingFileAppenderPega">
<param name="FileNamePattern" value="'${log.location}/PegaRULES-ALERT-${logging.clusterId}-'"/>
<param name="MaxFileSize" value="50MB" />
<layout class="com.pega.apache.log4j.PatternLayout">
<param name="ConversionPattern" value="%m%n" />
</layout>
</appender>
<appender name="ALERTSECURITY" class="com.pega.pegarules.priv.util.DailySizeRollingFileAppenderPega">
<param name="FileNamePattern" value="'${log.location}/PegaRULES-ALERTSECURITY-${logging.clusterId}-'"/>
<param name="MaxFileSize" value="50MB" />
<layout class="com.pega.apache.log4j.PatternLayout">
<param name="ConversionPattern" value="%m%n" />
</layout>
</appender>
<appender name="BIX" class="com.pega.pegarules.priv.util.DailySizeRollingFileAppenderPega">
<param name="FileNamePattern" value="'${log.location}/PegaBIX-${logging.clusterId}-'"/>
<param name="MaxFileSize" value="50MB" />
<layout class="com.pega.apache.log4j.PatternLayout">
<param name="ConversionPattern" value="%d [%20.20t] [%20.20X{tenantid}] [%20.20X{app}] (%30.30c{3}) %-5p %X{stack} %X{userid} - %m%n"/>
</layout>
</appender>
<category name="com.pega.pegarules.data.internal.access.ExtractImpl" additivity="false">
<priority value="info"/>
<appender-ref ref="BIX"/>
</category>
<category name="com.pega.pegarules.data.internal.access.ExtractParameters" additivity="false">
<priority value="info"/>
<appender-ref ref="BIX"/>
</category>
<category name="com.pega.pegarules.data.internal.access.DatabaseUtilsCommonImpl" additivity="false">
<priority value="info"/>
<appender-ref ref="BIX"/>
</category>
<!-- Provided as an example for how to enable messaging for PRPC or java class.
<category name="Rule_Obj_Activity">
<priority value="info"/>
</category>
<category name="com.pega.pegarules.engine.context.InitialConfiguration">
<priority value="info"/>
</category>
-->
<!-- Provided as an example for how to enable logging for LookupLists in a separate file
<appender name="LOOKUPLIST-STAT" class="com.pega.pegarules.priv.util.FileAppenderPega">
<param name="FileNamePattern" value="'PegaRULES-LLCSTAT-'yyyy-MMM-dd'.csv'" />
<layout class="com.pega.apache.log4j.PatternLayout">
<param name="ConversionPattern" value="%m%n" />
</layout>
</appender>
<category
name="com.pega.pegarules.session.internal.stats.lookuplist.LookupListStats">
<priority value="info" />
<appender-ref ref="LOOKUPLIST-STAT" />
</category>
-->
<root>
<priority value="alert"/>
<appender-ref ref="ASYNC"/>
<appender-ref ref="ALERT-ASYNC"/>
</root>
</log4j:configuration>
Pegasystems Inc.
DE
The above sample works fine for me, I can successfully write to a custom log file using the string pattern match. Is there way to avoid that the log message is written to both the PegaRULES.log and my custom log?
If I understand properly, I'd need a category definintion having additivity set to false, but I'd like to write to the custom log file (and only to the custom log file) from any activity in any class, just based on the string pattern.
How would that category defintion look like for this?
Cheers
Armin