Quieting individual ant tasks - ant

Is there a way to get individual ant tasks to run quietly? I know of the -q switch, but that applies globally.

You could try implementing your own Ant logger.
One idea, using the existing listeners, would be to pipe all output to log4j and then implement a logging message filter that suppresses certain log messages
ant -listener org.apache.tools.ant.listener.Log4jListener
The log4j appender configuration would look something like:
<appender name=".." class="..">
..
..
<filter class="org.apache.log4j.varia.StringMatchFilter">
<param name="StringToMatch" value="ANT output to suppress" />
<param name="AcceptOnMatch" value="false" />
</filter>
</appender>

Related

Log4j unstructured log parser in Java or Scala

Question
How to parse the unstructured Log4J log in Java/Scala.
Background
There are multiple questions on how to parse Log4J logs but mostly they recommend using XML or JSON appender to output structured outputs to parse. However need to parse already generated unstructured log files programmatically, not using tools such as logstash, chainsaws GUI.
Help with LogFilePatternReceiver shows the way but it requires "plugin" support which was supposed to be implemented in Log4J 1.3 but Log4J 1.x discontinued with 1.2.x. It looks Log4J 2 does not have LogFilePatternReceiver.
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE log4j:configuration >
<log4j:configuration xmlns:log4j="http://jakarta.apache.org/log4j/" debug="true">
<appender name="CONSOLE" class="org.apache.log4j.ConsoleAppender">
<layout class="org.apache.log4j.SimpleLayout"/>
<filter class="org.apache.log4j.filter.ExpressionFilter">
<param name="Expression" value="msg ~= 'SPECIFY CASE-INSENSITIVE MSG MATCH HERE'" />
<param name="AcceptOnMatch" value="true"/>
</filter>
<filter class="org.apache.log4j.filter.DenyAllFilter"/>
</appender>
<plugin name="LOGFILE" class="org.apache.log4j.varia.LogFilePatternReceiver">
<param name="fileURL" value="file:///c:/some.log"/>
<param name="timestampFormat" value="yyyy-MM-dd HH:mm:ss,SSS"/>
<param name="logFormat" value="TIMESTAMP LEVEL [LOGGER] MESSAGE"/>
<param name="name" value="my log file"/>
<param name="tailing" value="true"/>
</plugin>
<root>
<level value="DEBUG"/>
<appender-ref ref="CONSOLE"/>
</root>
</log4j:configuration>
There is a class LogFileParser in org.apache.log4j.lf5.util.LogFileParse package but not sure how to use it. There is a tool OtrosLogViewer but prefer not having 3rd party dependencies if possible.
Options
Re: Extract log info from each output log line on the console suggests refering to the Chainsaw code. Read the code and implement similar would be the option but if there is already a known way to parse logs, would like to know it first.
References
Parse a log4j log file
Class LogFilePatternReceiver
Found a way by using log4j and extras 1.2 jars, although not work with Log4J 2.
Java
import org.apache.log4j.Logger;
import org.apache.log4j.spi.LoggingEvent;
import org.apache.log4j.receivers.varia.LogFilePatternReceiver;
public class LogParser extends LogFilePatternReceiver {
final static Logger logger = Logger.getLogger(LogParser.class);
public void doPost(LoggingEvent event) {
System.out.println(event.getTimeStamp());
System.out.println(event.getMessage());
}
public static void main(String[] args) {
(new LogParser()).run();
}
private void run(){
LogFilePatternReceiver r = new LogParser();
r.setLogFormat("TIMESTAMP LEVEL [THREAD] CLASS (FILE:LINE) - MESSAGE");
r.setFileURL("file:///tmp/log");
r.setTimestampFormat("yyyy-MM-dd HH:mm:ss,SSS");
r.setTailing(true);
r.setLoggerRepository(logger.getLoggerRepository());
r.activateOptions();
}
}
log4j.xml
<?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="Target" value="System.out"/>
<layout class="org.apache.log4j.PatternLayout">
<param name="ConversionPattern" value="%d %-5p [%t] %C{2} (%F:%L) - %m%n"/>
</layout>
</appender>
<root>
<priority value ="debug" />
<appender-ref ref="console" />
</root>
</log4j:configuration>
Sample log file
2017-12-02 16:53:42,618 DEBUG [main] LogParser (LogParser.java:15) - message 1
2017-12-02 16:53:42,624 DEBUG [main] LogParser (LogParser.java:16) - message 2
Result
2017-12-02 19:21:31,633 INFO [main] spi.Log4JULogger (Log4JULogger.java:104) - activateOptions
2017-12-02 19:21:31,652 DEBUG [LogFilePatternReceiver-plugin] spi.Log4JULogger (Log4JULogger.java:58) - regexp is (\S+-\S+-\S+ \S+:\S+:\S+,\S+)[ ]+(\S*\s*?)[ ]+\[(.*?)\][ ]+(.*?)[ ]+\((.*?):(.*?)\)[ ]+\-[ ]+(.*)
2017-12-02 19:21:31,652 INFO [LogFilePatternReceiver-plugin] spi.Log4JULogger (Log4JULogger.java:104) - attempting to load file: file:///tmp/log
1512194022618
message 1
1512194022624
message 2
2017-12-02 19:21:33,656 DEBUG [LogFilePatternReceiver-plugin] spi.Log4JULogger (Log4JULogger.java:58) - tailing file
2017-12-02 19:21:35,660 DEBUG [LogFilePatternReceiver-plugin] spi.Log4JULogger (Log4JULogger.java:58) - tailing file

What are consequences of specifying different listeners in different parts of TestNG configuration?

Problem description:
The setup is executing Ant build script with TestNG target, which then loads testng.xml file. There is a possibility to specify listeners in both Ant file and testng.xml.
The questions arising are following:
Will both set up ways be supported? Will all the listeners specified in both configuration location be used during test execution?
Will any of listeners be prioritized over another? If yes, how?
Sample set up:
Ant file:
<project>
<property name="classes.dir" path="<my_classes_dir>" />
<property name="test.dir" path="<my_test_dir>" />
<target name="run-test">
<testng useDefaultListeners="false"
listeners="org.testng.reporters.EmailableReporter, org.testng.reporters.XMLReporter, com.example.MyCustomReporter">
<classpath>
<path path="${classes.dir}" />
</classpath>
<xmlfileset dir="${test.dir}" includes="testng.xml" />
</testng>
</target>
</project>
TestNG.xml:
<suite name="MyTestSuite">
<listeners>
<listener class-name="com.example.MyListener" />
<listener class-name="org.testng.reporters.FailedReporter" />
</listeners>
<test name="MyTest1">
<classes>
<class name="com.example.MyTest1" />
</classes>
</test>
</suite>
Background:
I have to support existing project which uses set up similar to the one described above. The Ant build file disables default reporters. Without touching Ant build file, I would like to specify additional report listeners (FailedReporter and/or any custom ones) for my tests in testng.xml.
I believe all listeners should be run, in your build file as well as in your testng.xml.
The testng.xml listeners would be executed second.
If the same listener is listed in both, build file and testng.xml, it would be executed twice.
This is based on my experience with Maven, but I guess, with ant it should be the same.
Also the order of listeners specified in testng.xml cannot be guaranteed in case both are implementing the same set of interfaces.
Hope it helps.

Can't control Struts2 log level using log4j.xml

I am playing around with a Struts2 webapp (Struts 2.2.3.1) running on Tomcat 6.
As seen in several tutorials, I have the following bit in my log4j.xml, which is deployed in the webapp's WEB-INF/classes directory:
<logger name="com.opensymphony">
<level value="DEBUG" />
</logger>
<logger name="org.apache.struts2">
<level value="DEBUG" />
</logger>
After setting the property log4j.debug=true in my Tomcat confiuration, I find (as expected) the following output in the Tomcat log:
log4j: DocumentBuilderFactory is: com.sun.org.apache.xerces.internal.jaxp.DocumentBuilderFactoryImpl
log4j: debug attribute= "null".
log4j: Ignoring debug attribute.
log4j: Threshold ="null".
log4j: Retreiving an instance of org.apache.log4j.Logger.
log4j: Setting [com.opensymphony] additivity to [true].
log4j: Level value for com.opensymphony is [DEBUG].
log4j: com.opensymphony level set to DEBUG
log4j: Retreiving an instance of org.apache.log4j.Logger.
log4j: Setting [org.apache.struts2] additivity to [true].
log4j: Level value for org.apache.struts2 is [DEBUG].
log4j: org.apache.struts2 level set to DEBUG
log4j: Level value for root is [DEBUG].
log4j: root level set to DEBUG
However, no Struts debugging messages can be found at all in any logfile.
My log4j version is 1.2.14.
How can I properly control Struts' logging?
If i am correct you have to define some sort of Appender in order to redirect the log output to the log file.
in default case struts2 log will be getting displayed on the console.Define something like this in your log4j file
<appender name="FA" class="org.apache.log4j.FileAppender">
<param name="File" value="sample.log"/>
<param name="Threshold" value="INFO"/>
<layout class="org.apache.log4j.PatternLayout">
<param name="ConversionPattern" value="%-4r [%t] %-5p %c %x - %m%n" />
</layout>
</appender>
You have to tell log4j where to redirect the logout

ant: best way to setup system-dependent properties?

I have a number of file/executable locations that are likely to be different depending on which computer I am running them on, and I would like to abstract these out through ant properties somehow. What's the best way to do this? Is there a system-wide ant setup script that gets called? Or can I make such a script?
In addition to Vladimir's solution you might have a default properties file for each of the OS or other you might deploy your build system on. Use the ${os.name} (and other Java system properties) to set up a path. For example
<property file="build-${os.name}.properties">
These files can be maintained and checked in into your version control system as well.
I use the more or less standard build.properties and build-local.properties files.
The first contains default values, common to all environments, the second only the exceptions. The first one is checked into subversion while the other is not.
EDIT : copy/pasting Akr's excellent idea
In addition you might have a default properties file for each of the OS or other you might deploy your build system on. These files can be checked in into your version control system as well.
The Ant script would then include all the files as follow (remember: in Ant the first definition wins):
<property file="build-local.properties"/>
<property file="build.properties"/>
<property file="build-${os.name}.properties">
Setup an ant build file called properties.xml, in which you should define the properties that you want to customize.
Here is properties.xml boilerplate I am using for my projects ( I've adapted it from one of the books on Ant ):
<?xml version="1.0" encoding="UTF-8"?>
<project
name="workspace-properties"
>
<dirname
property="workspace-properties.basedir"
file="${ant.file.workspace-properties}"
/>
<!--
==========================================================
Load Environment Variables
==========================================================
-->
<!-- #Load environment variables -->
<property environment="env" />
<!-- this is here to deal with the fact that an IntelliJ IDEA build
has no ant home
-->
<property
name="ant.home"
value="${env.ANT_HOME}"
/>
<!-- get Unix hostname, and set to Windows comparable name -->
<!-- #Trick to get host name x-platform -->
<property
name="env.COMPUTERNAME"
value="${env.HOSTNAME}"
/>
<!--
==========================================================
Load property files
Note: the ordering is VERY important.
==========================================================
-->
<!-- #Allow even users property file to relocate -->
<property
name="user.properties.file"
location="${user.home}/.build.properties"
/>
<!-- Load the application specific settings -->
<!-- #Project specific props -->
<property file="build.properties" />
<!--
==========================================================
Define your custom properties here.
You can overwrite them through build.properties and
${user.home}/.build.properties
==========================================================
-->
<property name="myexec1" location="/usr/bin/myexec1"/>
<property name="myexec2" location="/usr/bin/myexec2"/>
</project>
Important thing here is to come up with as many useful default property values as possible, then you may even never come up with custom build.properties files.
Then you just <import> this file in your project's build.xml.
<project
name="my-project"
>
<!-- this is done, so you may import my-project somewhere else -->
<dirname
property="my-project.basedir"
file="${ant.file.my-project}"
/>
<import file="${my-project.basedir}/relative/path/to/properties.xml"/>
<target name="using.myexec1">
<echo message="myexec1=${myexec1}"/>
</target>
</project>
If you want a custom value for myexec1 in my-project, just drop a custom flat build.properties file in the same directory where build.xml is located.
The build.properties file may look like this:
myexec1=c:/custom/path/to/myexec1.exe

How to define suppressions-definitions for checkstyle, that work with both ant and eclipse

I use in a project checkstyle and I have defined a SuppressionFilter in my checkstyle-configuration. I use Apache ant to make automatic builds via Continuous Integration.
My problems comes from the following situation: I don't want to fill to much files into the project-basedir, so the checkstyle.xml and the suppressions.xml are both in a subdirectory named conf (for configuration for build). Now Ant and Eclipse work differently for finding the suppressions.xml.
Ant use the project-basedir as basedir for finding the suppressions.xml, after I declared an ant-task to find the checkstyle.xml with the base-configuration of checkstyle. This checkstyle.xml now contains the following:
<module name="SuppressionFilter">
<property name="file" value="conf/suppressions.xml"/>
</module>
This way the ant-build finds the suppressions.xml, because the basedir of the build is the project-directory.
Now using the checkstyle-plugin for Eclipse brings a problem. It looks for the suppressions.xml starting with the path the checkstyle.xml has (conf). For Eclipse the declaration had to look like this, to work:
<module name="SuppressionFilter">
<property name="file" value="suppressions.xml"/>
</module>
EDIT: Even that doesn't work, Eclipse seems to need always an absolute path.
I want to know a way, that both Eclipse and Ant can work with the same checkstyle-configuration. Someone knows a solution to this problem? Absolute paths are no solution, because every developer and the CI-Server have different paths for the project-directory.
This question is pretty old, but I've found a better way to do it using the Checkstyle Advanced properties:
For the Eclipse Checkstyle plugin, the ${samedir} property expands to the directory that the configuration file is located within:
In your case, your module configuration would look like this:
<module name="SuppressionFilter">
<property name="file" value="${samedir}/conf/suppressions.xml" />
</module>
The Ant target would also set the samedir property:
<checkstyle config="${checkstyle.tool.dir}/checks.xml" failOnViolation="false">
<fileset dir="${src.dir}" includes="**/*.java" />
<property key="samedir" value="${checkstyle.tool.dir}/conf" />
</checkstyle>
Use Checkstyle's property expansion functionality. In your checkstyle.xml declare your SupressionFilter as:
<module name="SuppressionFilter">
<property name="file" value="${checkstyle.suppressions.file}" default="suppressions.xml"/>
</module>
Then modify your Checkstyle task in your Ant build script to include a nested property:
<checkstyle config="conf/checkstyle.xml">
<fileset dir="src" includes="**/*.java"/>
<property key="checkstyle.suppressions.file" value="conf/suppressions.xml"/>
</checkstyle>

Resources