Browse Source

AnsiColorLogger is an extension of DefaultLogger. It provides colorized

messages based on the message level.


git-svn-id: https://svn.apache.org/repos/asf/ant/core/trunk@271022 13f79535-47bb-0310-9956-ffa450edef68
master
Magesh Umasankar 23 years ago
parent
commit
dc060b5ab0
5 changed files with 424 additions and 27 deletions
  1. +4
    -2
      WHATSNEW
  2. +96
    -15
      docs/manual/listeners.html
  3. +16
    -10
      src/main/org/apache/tools/ant/DefaultLogger.java
  4. +265
    -0
      src/main/org/apache/tools/ant/listener/AnsiColorLogger.java
  5. +43
    -0
      src/main/org/apache/tools/ant/listener/defaults.properties

+ 4
- 2
WHATSNEW View File

@@ -129,8 +129,10 @@ Other changes:
* <fail> no supports builds to fail based on conditions via if and * <fail> no supports builds to fail based on conditions via if and
unless attributes. unless attributes.


* Ant now comes with a BuildLogger implementation that can send emails
containing a log of the build process (MailLogger).
* Ant now comes with two new BuildLogger implementations - one that
can send emails containing a log of the build process (MailLogger);
the other that colorizes the output based on message levels using
ANSI color code escape sequences (AnsiColorLogger).


* A "package" mapper type has been added to allow package directory * A "package" mapper type has been added to allow package directory
names replaced with the dotted form. names replaced with the dotted form.


+ 96
- 15
docs/manual/listeners.html View File

@@ -10,7 +10,7 @@


<h2><a name="Overview">Overview</a></h2> <h2><a name="Overview">Overview</a></h2>


<p>Ant has two related features to allow the build process to be monitored:
<p>Ant has two related features to allow the build process to be monitored:
listeners and loggers.</p> listeners and loggers.</p>


<h3><a name="Listeners">Listeners</a></h3> <h3><a name="Listeners">Listeners</a></h3>
@@ -32,7 +32,7 @@ listeners and loggers.</p>
<p>Loggers extend the capabilities of listeners and add the following features:</p> <p>Loggers extend the capabilities of listeners and add the following features:</p>


<ul> <ul>
<li>Receives a handle to the standard output and error print streams and
<li>Receives a handle to the standard output and error print streams and
therefore can log information to the console or the -logfile specified file.</li> therefore can log information to the console or the -logfile specified file.</li>
<li>Logging level (-quiet, -verbose, -debug) aware</li> <li>Logging level (-quiet, -verbose, -debug) aware</li>
<li>Emacs-mode aware</li> <li>Emacs-mode aware</li>
@@ -48,7 +48,7 @@ listeners and loggers.</p>
</tr> </tr>
<tr> <tr>
<td width="33%"><code><a href="#DefaultLogger">org.apache.tools.ant.DefaultLogger</a></code></td> <td width="33%"><code><a href="#DefaultLogger">org.apache.tools.ant.DefaultLogger</a></code></td>
<td width="33%">The logger used implicitly unless overridden with the
<td width="33%">The logger used implicitly unless overridden with the
<code>-logger</code> command-line switch.</td> <code>-logger</code> command-line switch.</td>
<td width="34%">BuildLogger</td> <td width="34%">BuildLogger</td>
</tr> </tr>
@@ -61,10 +61,16 @@ listeners and loggers.</p>
<tr> <tr>
<td width="33%"><code><a href="#MailLogger"> <td width="33%"><code><a href="#MailLogger">
org.apache.tools.ant.listener.MailLogger</a></code></td> org.apache.tools.ant.listener.MailLogger</a></code></td>
<td width="33%">Extends DefaultLogger such that output is still generated
<td width="33%">Extends DefaultLogger such that output is still generated
the same, and when the build is finished an e-mail can be sent.</td> the same, and when the build is finished an e-mail can be sent.</td>
<td width="34%">BuildLogger</td> <td width="34%">BuildLogger</td>
</tr> </tr>
<tr>
<td width="33%"><code><a href="#AnsiColorLogger">
org.apache.tools.ant.listener.AnsiColorLogger</a></code></td>
<td width="33%">Colorifies the build output.</td>
<td width="34%">BuildLogger</td>
</tr>
<tr> <tr>
<td width="33%"><code><a href="#Log4jListener"> <td width="33%"><code><a href="#Log4jListener">
org.apache.tools.ant.listener.Log4jListener</a></code></td> org.apache.tools.ant.listener.Log4jListener</a></code></td>
@@ -99,8 +105,8 @@ listeners and loggers.</p>


<h3><a name="MailLogger">MailLogger</a></h3> <h3><a name="MailLogger">MailLogger</a></h3>


<p>The MailLogger captures all output logged through DefaultLogger (standard Ant
output) and will send success and failure messages to unique e-mail lists, with
<p>The MailLogger captures all output logged through DefaultLogger (standard Ant
output) and will send success and failure messages to unique e-mail lists, with
control for turning off success or failure messages individually.</p> control for turning off success or failure messages individually.</p>
<p>Properties controlling the operation of MailLogger:</p> <p>Properties controlling the operation of MailLogger:</p>
<table border="1" cellspacing="1" width="100%" id="AutoNumber2"> <table border="1" cellspacing="1" width="100%" id="AutoNumber2">
@@ -161,22 +167,97 @@ control for turning off success or failure messages individually.</p>


</blockquote> </blockquote>


<h3><a name="AnsiColorLogger">AnsiColorLogger</a></h3>

<p>The AnsiColorLogger adds color to the standard Ant output
by prefixing and suffixing ANSI color code escape sequences to
it. It is just an extension of <a href="#DefaultLogger">DefaultLogger</a>
and hence provides all features that DefaultLogger does.</p>
<p>AnsiColorLogger differentiates the output by assigning
different colors depending upon the type of the message.</p>
<p>If used with the -logfile option, the output file
will contain all the necessary escape codes to
display the text in colorized mode when displayed
in the console using applications like cat, more, etc.</p>
<p>This is designed to work on terminals that support ANSI
color codes. It works on XTerm, ETerm, Win9x Console
(with ANSI.SYS loaded.), etc.</p>
<p><Strong>NOTE:</Strong>
It doesn't work on WinNT even when a COMMAND.COM console loaded with
ANSI.SYS is used.</p>
<p>If the user wishes to override the default colors
with custom ones, a file containing zero or more of the
custom color key-value pairs must be created. The recognized keys
and their default values are shown below:</p><code><pre>
AnsiColorLogger.ERROR_COLOR=2;31
AnsiColorLogger.WARNING_COLOR=2;35
AnsiColorLogger.INFO_COLOR=2;36
AnsiColorLogger.VERBOSE_COLOR=2;32
AnsiColorLogger.DEBUG_COLOR=2;34</pre></code>
<p>Each key takes as value a color combination defined as
<b>Attribute;Foreground;Background</b>. In the above example, background
value has not been used.</p>
<p>This file must be specfied as the value of a system variable
named ant.logger.defaults and passed as an argument using the -D
option to the <b>java</b> command that invokes the Ant application.
An easy way to achieve this is to add -Dant.logger.defaults=
<i>/path/to/your/file</i> to the ANT_OPTS environment variable.
Ant's launching script recognizes this flag and will pass it to
the java command appropriately.</p>
<p>Format:</p><pre>
AnsiColorLogger.*=Attribute;Foreground;Background

Attribute is one of the following:
0 -> Reset All Attributes (return to normal mode)
1 -> Bright (Usually turns on BOLD)
2 -> Dim
3 -> Underline
5 -> link
7 -> Reverse
8 -> Hidden

Foreground is one of the following:
30 -> Black
31 -> Red
32 -> Green
33 -> Yellow
34 -> Blue
35 -> Magenta
36 -> Cyan
37 -> White

Background is one of the following:
40 -> Black
41 -> Red
42 -> Green
43 -> Yellow
44 -> Blue
45 -> Magenta
46 -> Cyan
47 -> White</pre>

<blockquote>

<p><code>ant -logger org.apache.tools.ant.listener.AnsiColorLogger</code></p>

</blockquote>

<h3><a name="Log4jListener">Log4jListener</a></h3> <h3><a name="Log4jListener">Log4jListener</a></h3>


<p>Passes build events to Log4j, using the full classname's of the generator of
<p>Passes build events to Log4j, using the full classname's of the generator of
each build event as the category:</p> each build event as the category:</p>


<ul> <ul>
<li>build started / build finished - org.apache.tools.ant.Project</li> <li>build started / build finished - org.apache.tools.ant.Project</li>
<li>target started / target finished - org.apache.tools.ant.Target</li> <li>target started / target finished - org.apache.tools.ant.Target</li>
<li>task started / task finished - the fully qualified classname of the task</li> <li>task started / task finished - the fully qualified classname of the task</li>
<li>message logged - the classname of one of the above, so if a task logs a
<li>message logged - the classname of one of the above, so if a task logs a
message, its classname is the category used, and so on.</li> message, its classname is the category used, and so on.</li>
</ul> </ul>


<p>All start events are logged as INFO.&nbsp; Finish events are either logged as
INFO or ERROR depending on whether the build failed during that stage. Message
events are logged according to their Ant logging level, mapping directly to a
<p>All start events are logged as INFO.&nbsp; Finish events are either logged as
INFO or ERROR depending on whether the build failed during that stage. Message
events are logged according to their Ant logging level, mapping directly to a
corresponding Log4j level.</p> corresponding Log4j level.</p>


<blockquote> <blockquote>
@@ -187,7 +268,7 @@ corresponding Log4j level.</p>


<h3><a name="XmlLogger">XmlLogger</a></h3> <h3><a name="XmlLogger">XmlLogger</a></h3>


<p>Writes all build information out to an XML file named log.xml, or the value
<p>Writes all build information out to an XML file named log.xml, or the value
of the XmlLogger.file property if present.</p> of the XmlLogger.file property if present.</p>


<blockquote> <blockquote>
@@ -198,18 +279,18 @@ of the XmlLogger.file property if present.</p>


<h2><a name="dev">Writing your own</a></h2> <h2><a name="dev">Writing your own</a></h2>


<p>See the <a href="develop.html#buildevents">Build Events</a> section for
<p>See the <a href="develop.html#buildevents">Build Events</a> section for
developers.</p> developers.</p>


<p>Notes:</p> <p>Notes:</p>


<ul> <ul>
<li>A listener or logger should not write to standard output or error - Ant
<li>A listener or logger should not write to standard output or error - Ant
captures these internally and may cause an infinite loop.</li> captures these internally and may cause an infinite loop.</li>
</ul> </ul>


<hr> <hr>
<p align="center">Copyright &copy; 2001 Apache Software Foundation. All rights
<p align="center">Copyright &copy; 2002 Apache Software Foundation. All rights
Reserved.</p> Reserved.</p>


</body> </body>


+ 16
- 10
src/main/org/apache/tools/ant/DefaultLogger.java View File

@@ -164,9 +164,9 @@ public class DefaultLogger implements BuildLogger {


String msg = message.toString(); String msg = message.toString();
if (error == null) { if (error == null) {
out.println(msg);
printMessage(msg, out, Project.MSG_VERBOSE);
} else { } else {
err.println(msg);
printMessage(msg, err, Project.MSG_ERR);
} }
log(msg); log(msg);
} }
@@ -174,7 +174,7 @@ public class DefaultLogger implements BuildLogger {
public void targetStarted(BuildEvent event) { public void targetStarted(BuildEvent event) {
if (Project.MSG_INFO <= msgOutputLevel) { if (Project.MSG_INFO <= msgOutputLevel) {
String msg = StringUtils.LINE_SEP + event.getTarget().getName() + ":"; String msg = StringUtils.LINE_SEP + event.getTarget().getName() + ":";
out.println(msg);
printMessage(msg, out, event.getPriority());
log(msg); log(msg);
} }
} }
@@ -186,8 +186,9 @@ public class DefaultLogger implements BuildLogger {
public void taskFinished(BuildEvent event) {} public void taskFinished(BuildEvent event) {}


public void messageLogged(BuildEvent event) { public void messageLogged(BuildEvent event) {
int priority = event.getPriority();
// Filter out messages based on priority // Filter out messages based on priority
if (event.getPriority() <= msgOutputLevel) {
if (priority <= msgOutputLevel) {


StringBuffer message = new StringBuffer(); StringBuffer message = new StringBuffer();
// Print out the name of the task if we're in one // Print out the name of the task if we're in one
@@ -205,10 +206,10 @@ public class DefaultLogger implements BuildLogger {


message.append(event.getMessage()); message.append(event.getMessage());
String msg = message.toString(); String msg = message.toString();
if (event.getPriority() != Project.MSG_ERR) {
out.println(msg);
if (priority != Project.MSG_ERR) {
printMessage(msg, out, priority);
} else { } else {
err.println(msg);
printMessage(msg, err, priority);
} }
log(msg); log(msg);
} }
@@ -223,19 +224,24 @@ public class DefaultLogger implements BuildLogger {
return Long.toString(minutes) + " minute" return Long.toString(minutes) + " minute"
+ (minutes == 1 ? " " : "s ") + (minutes == 1 ? " " : "s ")
+ Long.toString(seconds%60) + " second" + Long.toString(seconds%60) + " second"
+ (seconds%60 > 1 ? "s" : "");
+ (seconds%60 == 1 ? "" : "s");
} }
else { else {
return Long.toString(seconds) + " second" return Long.toString(seconds) + " second"
+ (seconds%60 > 1 ? "s" : "");
+ (seconds%60 == 1 ? "" : "s");
} }


} }


protected void printMessage(final String message,
final PrintStream stream,
final int priority) {
stream.println(message);
}

/** /**
* Empty implementation which allows subclasses to receive the * Empty implementation which allows subclasses to receive the
* same output that is generated here. * same output that is generated here.
*/ */
protected void log(String message) {} protected void log(String message) {}

} }

+ 265
- 0
src/main/org/apache/tools/ant/listener/AnsiColorLogger.java View File

@@ -0,0 +1,265 @@
/*
* The Apache Software License, Version 1.1
*
* Copyright (c) 2002 The Apache Software Foundation. All rights
* reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* 3. The end-user documentation included with the redistribution, if
* any, must include the following acknowlegement:
* "This product includes software developed by the
* Apache Software Foundation (http://www.apache.org/)."
* Alternately, this acknowlegement may appear in the software itself,
* if and wherever such third-party acknowlegements normally appear.
*
* 4. The names "The Jakarta Project", "Ant", and "Apache Software
* Foundation" must not be used to endorse or promote products derived
* from this software without prior written permission. For written
* permission, please contact apache@apache.org.
*
* 5. Products derived from this software may not be called "Apache"
* nor may "Apache" appear in their names without prior written
* permission of the Apache Group.
*
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
* ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
* USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
* OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
* ====================================================================
*
* This software consists of voluntary contributions made by many
* individuals on behalf of the Apache Software Foundation. For more
* information on the Apache Software Foundation, please see
* <http://www.apache.org/>.
*/
package org.apache.tools.ant.listener;

import java.io.FileInputStream;
import java.io.InputStream;
import java.io.IOException;
import java.io.PrintStream;
import java.util.Properties;

import org.apache.tools.ant.DefaultLogger;
import org.apache.tools.ant.Project;

/**
* Uses ANSI Color Code Sequences to colorize messages
* sent to the console.
*
* If used with the -logfile option, the output file
* will contain all the necessary escape codes to
* display the text in colorized mode when displayed
* in the console using applications like cat, more,
* etc.
*
* This is designed to work on terminals that support ANSI
* color codes. It works on XTerm, ETerm, Mindterm, etc.
* It also works on Win9x (with ANSI.SYS loaded.)
*
* NOTE:
* It doesn't work on WinNT's COMMAND.COM even with
* ANSI.SYS loaded.
*
* The default colors used for differentiating
* the message levels can be changed by editing the
* /org/apache/tools/ant/listener/defaults.properties
* file.
* This file contains 5 key/value pairs:
* AnsiColorLogger.ERROR_COLOR=2;31
* AnsiColorLogger.WARNING_COLOR=2;35
* AnsiColorLogger.INFO_COLOR=2;36
* AnsiColorLogger.VERBOSE_COLOR=2;32
* AnsiColorLogger.DEBUG_COLOR=2;34
*
* Another option is to pass a system variable named
* ant.logger.defaults, with value set to the path of
* the file that contains user defined Ansi Color
* Codes, to the <B>java</B> command using -D option.
*
* To change these colors use the following chart:
*
* <B>ANSI COLOR LOGGER CONFIGURATION</B>
*
* Format for AnsiColorLogger.*=
* Attribute;Foreground;Background
*
* Attribute is one of the following:
* 0 -> Reset All Attributes (return to normal mode)
* 1 -> Bright (Usually turns on BOLD)
* 2 -> Dim
* 3 -> Underline
* 5 -> link
* 7 -> Reverse
* 8 -> Hidden
*
* Foreground is one of the following:
* 30 -> Black
* 31 -> Red
* 32 -> Green
* 33 -> Yellow
* 34 -> Blue
* 35 -> Magenta
* 36 -> Cyan
* 37 -> White
*
* Background is one of the following:
* 40 -> Black
* 41 -> Red
* 42 -> Green
* 43 -> Yellow
* 44 -> Blue
* 45 -> Magenta
* 46 -> Cyan
* 47 -> White
*
* @author <a href="mailto:umagesh@apache.org">Magesh Umasankar</a>
*/
public final class AnsiColorLogger extends DefaultLogger {

private static final int ATTR_NORMAL = 0;
private static final int ATTR_BRIGHT = 1;
private static final int ATTR_DIM = 2;
private static final int ATTR_UNDERLINE = 3;
private static final int ATTR_BLINK = 5;
private static final int ATTR_REVERSE = 7;
private static final int ATTR_HIDDEN = 8;

private static final int FG_BLACK = 30;
private static final int FG_RED = 31;
private static final int FG_GREEN = 32;
private static final int FG_YELLOW = 33;
private static final int FG_BLUE = 34;
private static final int FG_MAGENTA = 35;
private static final int FG_CYAN = 36;
private static final int FG_WHITE = 37;

private static final int BG_BLACK = 40;
private static final int BG_RED = 41;
private static final int BG_GREEN = 42;
private static final int BG_YELLOW = 44;
private static final int BG_BLUE = 44;
private static final int BG_MAGENTA = 45;
private static final int BG_CYAN = 46;
private static final int BG_WHITE = 47;

private static final String PREFIX = "\u001b[";
private static final String SUFFIX = "m";
private static final char SEPARATOR = ';';
private static final String END_COLOR = PREFIX + SUFFIX;

private String errColor = PREFIX + ATTR_DIM + SEPARATOR + FG_RED + SUFFIX;
private String warnColor = PREFIX + ATTR_DIM + SEPARATOR + FG_MAGENTA + SUFFIX;
private String infoColor = PREFIX + ATTR_DIM + SEPARATOR + FG_CYAN + SUFFIX;
private String verboseColor = PREFIX + ATTR_DIM + SEPARATOR + FG_GREEN + SUFFIX;
private String debugColor = PREFIX + ATTR_DIM + SEPARATOR + FG_BLUE + SUFFIX;

private boolean colorsSet = false;

private final void setColors() {
String userColorFile = System.getProperty("ant.logger.defaults");
String systemColorFile =
"/org/apache/tools/ant/listener/defaults.properties";

InputStream in = null;

try {
Properties prop = new Properties();

if (userColorFile != null) {
in = new FileInputStream(userColorFile);
} else {
in = getClass().getResourceAsStream(systemColorFile);
}

if (in != null) {
prop.load(in);
}

String err = prop.getProperty("AnsiColorLogger.ERROR_COLOR");
String warn = prop.getProperty("AnsiColorLogger.WARNING_COLOR");
String info = prop.getProperty("AnsiColorLogger.INFO_COLOR");
String verbose = prop.getProperty("AnsiColorLogger.VERBOSE_COLOR");
String debug = prop.getProperty("AnsiColorLogger.DEBUG_COLOR");
if (err != null) {
errColor = PREFIX + err + SUFFIX;
}
if (warn != null) {
warnColor = PREFIX + warn + SUFFIX;
}
if (info != null) {
infoColor = PREFIX + info + SUFFIX;
}
if (verbose != null) {
verboseColor = PREFIX + verbose + SUFFIX;
}
if (debug != null) {
debugColor = PREFIX + debug + SUFFIX;
}
} catch (IOException ioe) {
//Ignore - we will use the defaults.
} finally {
if (in != null) {
try {
in.close();
} catch (IOException e) {
//Ignore - We do not want this to stop the build.
}
}
}
}

protected final void printMessage(final String message,
final PrintStream stream,
final int priority) {
if (!colorsSet) {
setColors();
colorsSet = true;
}

final StringBuffer msg = new StringBuffer(message);
switch (priority) {
case Project.MSG_ERR:
msg.insert(0, errColor);
msg.append(END_COLOR);
break;
case Project.MSG_WARN:
msg.insert(0, warnColor);
msg.append(END_COLOR);
break;
case Project.MSG_INFO:
msg.insert(0, infoColor);
msg.append(END_COLOR);
break;
case Project.MSG_VERBOSE:
msg.insert(0, verboseColor);
msg.append(END_COLOR);
break;
case Project.MSG_DEBUG:
msg.insert(0, debugColor);
msg.append(END_COLOR);
break;
}
final String strmessage = msg.toString();
stream.println(strmessage);
}
}

+ 43
- 0
src/main/org/apache/tools/ant/listener/defaults.properties View File

@@ -0,0 +1,43 @@
####################################################
#
# ANSI COLOR LOGGER CONFIGURATION
#
# Format for AnsiColorLogger.*=
# Attribute;Foreground;Background
#
# Attribute is one of the following:
# 0 -> Reset All Attributes (return to normal mode)
# 1 -> Bright (Usually turns on BOLD)
# 2 -> Dim
# 3 -> Underline
# 5 -> link
# 7 -> Reverse
# 8 -> Hidden
#
# Foreground is one of the following:
# 30 -> Black
# 31 -> Red
# 32 -> Green
# 33 -> Yellow
# 34 -> Blue
# 35 -> Magenta
# 36 -> Cyan
# 37 -> White
#
# Background is one of the following:
# 40 -> Black
# 41 -> Red
# 42 -> Green
# 43 -> Yellow
# 44 -> Blue
# 45 -> Magenta
# 46 -> Cyan
# 47 -> White
#
####################################################

AnsiColorLogger.ERROR_COLOR=2;31
AnsiColorLogger.WARNING_COLOR=2;35
AnsiColorLogger.INFO_COLOR=2;36
AnsiColorLogger.VERBOSE_COLOR=2;32
AnsiColorLogger.DEBUG_COLOR=2;34

Loading…
Cancel
Save