Showing posts with label log4j. Show all posts
Showing posts with label log4j. Show all posts

Tuesday, May 22, 2012

Example of log4.xml to separate your selenium framework's logs from ones generated by webdriver

It is usefull to track the log messages generated as by your framework as by the selenium itself. Here is the example on how to separate the log streams so it is convenient to collect and to review
.
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE log4j:configuration SYSTEM "log4j.dtd">
<log4j:configuration xmlns:log4j='http://jakarta.apache.org/log4j/'>
 <appender name="CONSOLE" class="org.apache.log4j.ConsoleAppender">
  <param name="Threshold" value="INFO"/>
  <layout class="org.apache.log4j.PatternLayout">
   <param name="ConversionPattern" value="%-5p [%d] [%c{1}] %x - %m%n" />
  </layout>
 </appender>
 <!-- Famework generated log files -->
 <appender name="FILE_DEBUG" class="org.apache.log4j.RollingFileAppender">
  <param name="Threshold" value="DEBUG"/>
  <param name="File" value="your.framework.debug.log" />
  <param name="append" value="true" />
  <layout class="org.apache.log4j.PatternLayout">
   <param name="ConversionPattern" value="%-5p [%d] [%c{1}] %x - %m%n" />
  </layout>
 </appender>
 <appender name="FILE_INFO" class="org.apache.log4j.RollingFileAppender">
  <param name="Threshold" value="INFO"/>
  <param name="File" value="your.framework.info.log" />
  <param name="append" value="true" />
  <layout class="org.apache.log4j.PatternLayout">
   <param name="ConversionPattern" value="%-5p [%d] [%c{1}] %x - %m%n" />
  </layout>
 </appender>
 <!-- Selenium generated log files -->
 <appender name="FILE_DEBUG_SEL" class="org.apache.log4j.RollingFileAppender">
  <param name="Threshold" value="DEBUG"/>
  <param name="File" value="selenium.debug.log" />
  <param name="append" value="true" />
  <layout class="org.apache.log4j.PatternLayout">
   <param name="ConversionPattern" value="%-5p [%d] [%c{1}] %x - %m%n" />
  </layout>
 </appender>
 <appender name="FILE_INFO_SEL" class="org.apache.log4j.RollingFileAppender">
  <param name="Threshold" value="INFO"/>
  <param name="File" value="selenium.info.log" />
  <param name="append" value="true" />
  <layout class="org.apache.log4j.PatternLayout">
   <param name="ConversionPattern" value="%-5p [%d] [%c{1}] %x - %m%n" />
  </layout>
 </appender>
 <!-- Mapping of the classes -->
 <logger name="com.your.framework.automation">
  <level value="DEBUG" />
  <appender-ref ref="FILE_INFO" />
  <appender-ref ref="FILE_DEBUG" />
  <appender-ref ref="CONSOLE" />
 </logger>
 <logger name="org.apache">
  <level value="DEBUG" />
  <appender-ref ref="FILE_INFO_SEL" />
  <appender-ref ref="FILE_DEBUG_SEL" />
 </logger>
</log4j:configuration>

.
Here we starts from describing separate appenders just to target them to separate files on the hard drive. We'd like to have here four files described. To keep INFO and DEBUG level messages of framework and to keep the same information got from WebDriver.
The area under the last comment means that we push all the DEBUG messages generated under the package (aka namespace com.your.framework.automation.*) to the appenders targeted to framework log files (they are filtered then according to the desired log level) and all the messages from org.apache.* to selenium's related logs in the same way.

Note that to make it work properly you should follow the pattern like

Logger logger = Logger.getLogger(YourClassThatGeneratesLogMessage.class);

as the fully qualified name of the specified class is used to finally determine the target file of the message generated by the logger object.

Thursday, October 20, 2011

Ant replaceregexp example against the requirement to customize log4j e-mails

Check new series of the articles. Review and user experience on test management systems. Functionality and usability.
-------------------

Requirement:
- to customize log4j.xml so that all the e-mails are changed to some custom one
- facility: ANT tool

However there was lack of examples of replaceregexp ant task on the ant official page. So here is one extra example that addresses the following functional requirements
- replace all the entities like
old@yourdomain.com
so that old is replaced with new
- replace all the entities like
so that old is replaced with new

The solution is below:

  <target name="customize">
   <replaceregexp byline="true">
    <fileset dir="${BUILD_ROOT}" id="build_root_dir">
     <include name="**/log4j.xml" />
    </fileset>
    <regexp pattern="(.*?&gt;).+?(@yourdomain\.com.*)"/>
    <substitution expression="\1${reciever-alias-to-substitute}\2" />
   </replaceregexp>
   <replaceregexp byline="true">
    <fileset dir="${BUILD_ROOT}" id="build_root_dir">
     <include name="**/log4j.xml" />
    </fileset>
    <regexp pattern="(.*?value\=&quot;).+?(@yourdomain\.com&quot;.*)"/>
    <substitution expression="\1${reciever-alias-to-substitute}\2" />
   </replaceregexp>
  </target>

As you can see here it is used two replaceregexp tasks. It is done because unfortunately replaceregexp does not support several patterns inside, so once we need to process the files with two different patterns we should use two different replaceregexp tasks.

The one more thing it is useful to know is that you should use backslash symbol to specify which group (for the set located by your regular expression) you are going to use. In the example above I use two groups. The whole part of the string before original e-mail and the one after that. Then I'm saying to Ant that I'd like to preserve those strings \1 and \2 but change only the string between them.

Thanks

Wednesday, June 22, 2011

How to hide some data in log4j log you consider to be secured

Once we get the requirement saying the customer does not want some data gets transfered to the log file since it looks secure for them. We even should have the capability of choosing whether to show such data in logs. The quick way to address the requirement is to override one method in PatternLayout class. This will look like:

import org.apache.log4j.PatternLayout;
import org.apache.log4j.spi.LoggingEvent;

public class SecureLayout extends PatternLayout{

                static String pattern;
                
                public static void setPattern(String pattern){
                                SecureLayout.pattern = pattern;
                }

                @Override
                public String format(LoggingEvent event) {
                                String string = super.format(event);
                                return pattern == null ?  string : string.replaceAll(pattern, "NotForYourEyes");
                }

}

Such the way will allow us to set which data we consider to be secured from any place of the code. So you should only place the class under the classpath and use the following construction in log4j.xml

    <appender name="FILE" class="org.apache.log4j.RollingFileAppender">
        <param name="File" value="logfile.log"/>
        <param name="Append" value="true"/>
        <param name="MaxFileSize" value="1000KB"/>
        <param name="MaxBackupIndex" value="1000"/>
        <layout class="some.package.SecureLayout">
            <param name="ConversionPattern" value="%-5p [%d{ISO8601}] - %m%n"/>
        </layout>
    </appender>

However such solution of described engineering problem has some drawback. It means we are not capable to hide the data in exception description as exceptions are handled in another way. However that problem can be solved by introducing the changes in Exception class.