A FileAppender can forward messages sent to the log to a separate file, using formatting options to label messages with dates, logging levels, etc. Here's an example setup script demonstrating how to set up a FileAppender to write to a simple text file (you can download a starter project containing all this code here):
import org.apache.log4j.FileAppender import org.apache.log4j.PatternLayout //Define the layout to use def pLayout = new PatternLayout("%d{DATE} : %m%n") //Create FileAppender in context using layout we just defined context.customLogger = new FileAppender(pLayout,"C:\\Temp\\CustomLog\\CustomLog.txt", false) //Add the appender to the existing log log.addAppender(context.customLogger)
Remember, there's no need to add any additional jars to SoapUI's ext folder in this case; we're using the log4j package that's already part of its libraries. However, we do need to import the FileAppender and PatternLayout classes at the top of our script.
After the import statements, a new PatternLayout is created for use with the FileAppender:
def pLayout = new PatternLayout("%d{DATE} : %m%n")
The string that's passed into the PatternLayout constructor (
"%d{DATE} : %m%n"
) is used to describe how we'd like information formatted in the log file. For a detailed list of the special formatting indicators (generally demarcated by the % character), see the javadoc for the log4j PatternLayout class. In the meantime, here's a table showing some example patterns and how the line log.info("Simple Test Message One")
is rendered in a custom log (starting with the pattern used in our script):Pattern | Output | Notes |
---|---|---|
%d{DATE} : %m%n |
14 Sep 2015 21:51:21,223 : Simple Test Message One |
- %d indicates a date, with {DATE} specifying a log4j pre-canned date format - %m indicates where the actual message content will be shown - %n indicates a new line character |
%-15d{ABSOLUTE}%p : %m%n |
16:25:33,000 INFO : Simple Test Message One |
- {ABSOLUTE} is used with %d to specify another log4j pre-canned date format-- this one prints only the time component of the {DATE} default format used in the first example. - The -15 at the beginning of the date pads the expression, reserving 15 characters for the date and right-padding with spaces if the date is less than 15 characters long. - %p indicates the priority level of the message (e.g., INFO, DEBUG, etc.). |
%26d{ISO8601} : %m%n |
2015-09-19 16:50:08,095 : Simple Test Message One |
- {ISO8601} is the last of the log4j pre-canned date formats, printing the date portion with numeric year, month, and day. ISO8601 is also the default format used if none is specified. - The 26 at the beginning of the date format expression pads the date expression like -15 in the previous example, but the positive value pads the left instead of the right (note the leading spaces in the output). |
%d{MM-dd-yyyy HH:mm:ss.SSS} : %.10m%n |
09-19-2015 17:31:10.976 : essage One |
- In this case we're using a custom format for the date; this one prints the date with numeric month, then day, then year, then prints the time using a decimal point as the divider between seconds and nanoseconds. You can find out more about the date and time pattern characters to use for a custom date format here. According to the log4j javadocs, using a custom format like this could result in a performance hit; they encourage you to use the pre-canned formats instead. - The .10 before the message specifier is another spacing indicator; this one specifies that if the message is longer than 10 characters, it should be truncated from the front (which is why you only see the last 10 characters in the output). |
Once we have our PatternLayout created, we can create our FileAppender, using the PatternLayout as an argument in its constructor. We put it in context to manage disposing its resources later on in the tear down script:
context.customlogger = new FileAppender(pLayout, "C:\\Temp\\CustomLog\\CustomLog.txt", false)
The first two arguments should be self-explanatory: the first is the layout we want the FileAppender to use and the second is a string giving the path and name of the text file where we want the FileAppender to forward messages-- feel free to change this path as you see fit. Remember that "\" has a special meaning in string in Java; that's why we have to use the escape sequence "\\" here instead. The final argument specifies whether we want the messages appended to the text file. When set to true, any content in the text file generated in previous runs is preserved and information from this run is added to the end of the file. In this example we're setting the argument to false, so each time we run our suite a new log is created.
The final line in the setup script registers the appender with the default SoapUI log.
log.addAppender(context.customLogger)
Once everything is configured and the appender is registered with the log object, there's nothing special you have to do to send messages to this custom log file-- anything sent to the log within your script is sent to the FileAppender's underlying stream.
As indicated in the table above, the line
log.info("Simple Test Message One")
in our script results in this output in the custom log file:14 Sep 2015 21:51:21,223 : Simple Test Message One
Within our tear down script (or whenever we're done with the appender), we have to release the resources being used by the appender, closing the underlying file and the appender itself:
I encourage you to play around with the provided starter project to see what can be done with a file appender. In particular, try making changes to the pattern layout string to see how it controls formatting and affects the custom log's output.
context.customLogger.closeFile() context.customLogger.close()
I encourage you to play around with the provided starter project to see what can be done with a file appender. In particular, try making changes to the pattern layout string to see how it controls formatting and affects the custom log's output.
Excellent!!!
ReplyDeleteFound many similar solutions but none worked the way I wanted and none explained the code as good as done here. Especially no one ever mentioned how to cleanly close the opened resources while exiting the test. Finally got my answer here.
ReplyDeleteThanks!