7.1.1.2.1. Output of Failure Log

In the framework, the failure log is output by the exception handler for each process architecture. The log is output in the application if a subsequent process is continued in the case of a failure during a batch process.

7.1.1.2.1.1. Output policy of failure log

The log monitoring tool is assumed to monitor and detect failures, the failure notification log is output to a dedicated failure notification file with the logger name. The failure analysis log is output to an application log that outputs the log of the entire application.

Output policy of failure log
Log type Log level Logger name
Failure notification log FATAL, ERROR MONITOR
Failure analysis log FATAL, ERROR Class name

A configuration example of the log output for the above mentioned output policy is shown below

Configuration example of log.properties
writerNames=monitorLog,appLog

# Output destination of failure notification log
writer.monitorLog.className=nablarch.core.log.basic.FileLogWriter
writer.monitorLog.filePath=/var/log/app/monitor.log
writer.monitorLog.formatter.className=nablarch.core.log.basic.BasicLogFormatter
writer.monitorLog.formatter.format=$date$ -$logLevel$- $runtimeLoggerName$ [$executionId$] boot_proc = [$bootProcess$] proc_sys = [$processingSystem$] req_id = [$requestId$] usr_id = [$userId$] $message$

# Output destination of application log
writer.appLog.className=nablarch.core.log.basic.FileLogWriter
writer.appLog.filePath=/var/log/app/app.log
writer.appLog.maxFileSize=10000
writer.appLog.formatter.className=nablarch.core.log.basic.BasicLogFormatter
writer.appLog.formatter.format=$date$ -$logLevel$- $runtimeLoggerName$ [$executionId$] boot_proc = [$bootProcess$] proc_sys = [$processingSystem$] req_id = [$requestId$] usr_id = [$userId$] $message$$information$$stackTrace$

availableLoggersNamesOrder=MON,ROO

# Configure application log
loggers.ROO.nameRegex=.*
loggers.ROO.level=INFO
loggers.ROO.writerNames=appLog

# Output configuration of failure notification log
loggers.MON.nameRegex=MONITOR
loggers.MON.level=ERROR
loggers.MON.writerNames=monitorLog
Configuration example of app-log.properties
# FailureLogFormatter
#failureLogFormatter.className=
failureLogFormatter.defaultFailureCode=MSG99999
failureLogFormatter.defaultMessage=an unexpected exception occurred.
failureLogFormatter.language=ja
failureLogFormatter.notificationFormat=fail_code = [$failureCode$] $message$
failureLogFormatter.analysisFormat=fail_code = [$failureCode$] $message$\nInput Data :\n$data$
#failureLogFormatter.contactFilePath=
#failureLogFormatter.fwFailureCodeFilePath=

Tip

In large scale systems, when there are multiple contacts during failure, contact information for each request ID can be included in the log by using Add contact information to failure log.

7.1.1.2.1.2. How to use

7.1.1.2.1.2.1. Output failure log

For failure log output, use FailureLogUtil.

try {
    // Business process
} catch (UserNotFoundException e) {
    // Specify the exception caught, process target data and failure code.
    FailureLogUtil.logError(e, inputData, "USER_NOT_FOUND");
}

In batch process and messaging, it may be necessary to output the failure log and terminate the business process when a failure is detected. In such cases, TransactionAbnormalEnd or ProcessAbnormalEnd is thrown, and a request is sent to the exception handler (Global Error Handler or Loop Control Handler in Request Thread) to output the failure log.

// When an own exception is generated
if (user == null) {
    // Specify the exit code and failure code.
    throw new TransactionAbnormalEnd(100, "USER_NOT_FOUND");
}

// If an exception is caught
try {
    // Business process
} catch (UserNotFoundException e) {
    // Specify the exit code, caught exception and failure code.
    throw new ProcessAbnormalEnd(100, e, "USER_NOT_FOUND");
}

Tip

As in the above example, failure code is specified in the failure log output to identify the failure content from the log. Specify a code system for failure code in every project.

Message output to the failure log

For output of the message to the failure log, use Message Management and acquire the message corresponding to the failure code. If the Message Management cannot be found in the message, an exception is thrown. When an exception occurs in the message acquisition process, in addition to the failure log, WARN level log of the exception in the message acquisition process is output and the following message is output in the failure log.

failed to get the message to output the failure log. failureCode = [<Failure code>]

When a failure code is not specified, such as an exception or error captured by the framework exception handler, the default failure code and message specified by the configuration are output.

7.1.1.2.1.2.2. Configure the failure log

The failure log is configured in the property file described in Configure various logs.

Description rules

failureLogFormatter.className
This class implements failureLogFormatter.className FailureLogFormatter. Specify to replace.
failureLogFormatter.defaultFailureCode required
Default failure code. Use when there is no failure code specified, like in cases where an error is captured by the exception handler.
failureLogFormatter.defaultMessage required
Default message. This message is output when a default failure code is used.
failureLogFormatter.language
The language used to acquire the message from the failure code. If it is not specified, the language configured in ThreadContext will be used.
failureLogFormatter.notificationFormat

Format for failure notification log.

Placeholders that can be specified for the format

Item名 Placeholder Description
Failure code $failureCode$ A code that uniquely identifies the failure. Used to identify the nature of the failure.
Message $message$ The message corresponding to the failure code. Used to identify the nature of the failure.
Data to be processed $data$ Used to identify the data targeted by the process in which the failure occurred. Outputs by calling the toString method of the data object read using the data reader.
Contact $contact$ Used to identify the contacts.
Default format
fail_code = [$failureCode$] $message$
failureLogFormatter.analysisFormat
Format of failure analysis log. Placeholders that can be specified for the format and default format are same as format for failure notification log.
failureLogFormatter.contactFilePath
Path to the property file that specifies the contact information of the failure. Specify to output the contact information of the failure. For details, see Add contact information to failure log.
failureLogFormatter.fwFailureCodeFilePath
Path to the property file that specifies the information change of the failure code in the framework. Specify when changing the failure code of the framework at the time of failure log output. For details, see Change the framework failure codes.

Important

When output of personal, confidential information, etc. is not allowed even in the failure analysis log due to security requirements of the system, refer to Customize the output process for placeholders and customize the project.

Tip

Derived source run time information can be output to the failure log by output of the process target data. When the data from the web has to be linked to the batch process, runtime information (request ID or run time ID etc.) during execution of the screen process is the derived source run time information in the batch process. For information on how to output the derived source run time information, Output the derived source run time information.

Example of the description
failureLogFormatter.className=nablarch.core.log.app.FailureLogFormatter
failureLogFormatter.defaultFailureCode=UNEXPECTED_ERROR
failureLogFormatter.defaultMessage=an unexpected exception occurred.
failureLogFormatter.language=en
failureLogFormatter.notificationFormat=fail_code = [$failureCode$] $message$
failureLogFormatter.analysisFormat=fail_code = [$failureCode$] $message$
failureLogFormatter.derivedRequestIdPropName=insertRequestId
failureLogFormatter.derivedUserIdPropName=updatedUserId
failureLogFormatter.contactFilePath=classpath:failure-log-contact.properties
failureLogFormatter.fwFailureCodeFilePath=classpath:failure-log-fw-codes.properties

7.1.1.2.1.2.3. Add contact information to failure log

The contact information may have to be included in the failure log, like in the case with multiple contacts during failure of large scale systems. Therefore, a function that specifies the contact information for each request ID should be provided in the output failure log.

Addition of the contact information should be specified in the property file.Specify the request ID as the key and contact information as the value. Request ID specified as the key is searched using prefix match with the request ID acquired from ThreadContext. Therefore, after reading the contents of the property file, sort in the descending order of the key name length for retrieval using limited request ID.

An example of adding the contact information is shown below.

First, prepare a property file. A file with the name failure-log-contact.properties that is placed directly under the class path.

Configuration example of failure-log-contact.properties
# Request ID= Contact information
/users/=USRMGR999
/users/index=USRMGR300
/users/list=USRMGR301
/users/new=USRMGR302
/users/edit=USRMGR303

The above-mentioned property file is sorted as follows and is used for the search in order from the top.

# If the key names have the same length, the order changes each time they are executed.
/users/index=USRMGR300
/users/list=USRMGR301
/users/edit=USRMGR303
/users/new=USRMGR302
/users/=USRMGR999

Next, specify the placeholder $contact$ that represents the contact information in the failure log format. Specify the property file path.

Configuration example of app-log.properties
# Configuration of FailureLogFormatter
failureLogFormatter.defaultFailureCode=UNEXPECTED_ERROR
failureLogFormatter.defaultMessage=an unexpected exception occurred.
failureLogFormatter.notificationFormat=[$failureCode$:$message$] <$contact$>
failureLogFormatter.analysisFormat=fail_code = [$failureCode$] $message$ <$contact$>

# Specify the property file path.
failureLogFormatter.contactFilePath=classpath:failure-log-contact.properties

Contact information is output for every request ID based on the above mentioned configuration. An output example of failure that occurred for the request ID /users/new is shown below. USRMGR302 is output to the location (enclosed in <>) where $contact$ is specified.

# Failure notification log
2011-02-15 15:09:57.691 -FATAL- [APUSRMGR0001201102151509320020009] R[/users/new] U[0000000001] [UNEXPECTED_ERROR:an unexpected exception occurred.] <USRMGR302>

# Failure analysis log
2011-02-15 15:09:57.707 -FATAL- [APUSRMGR0001201102151509320020009] R[/users/new] U[0000000001] fail_code = [UNEXPECTED_ERROR] an unexpected exception occurred. <USRMGR302>
# Stack trace is omitted.

Outputs null when the contact information corresponding to the request ID cannot be found.

7.1.1.2.1.2.4. Change the framework failure codes

A RuntimeException exception is thrown when an unexpected error occurs in the framework. As a result, for all the exceptions thrown by the framework, default failure code is used and output to the failure log. In failure monitoring, since there may be cases where filtering the monitoring target based on the failure code may be required, a function should be provided to specify the framework failure code in the output of the failure log.

Framework failure code can be specified for every class name that throws an exception. The “class in which the exception is thrown” is the root element for the stack trace. For example, the class is nablarch.core.message.StringResourceHolder for the following stack trace.

Stack Trace Information :
java.lang.RuntimeException: ValidateFor method invocation failed. targetClass = java.lang.Class, method = validateForRegisterUser
    at nablarch.core.validation.ValidationManager.validateAndConvert(ValidationManager.java:202)
    # Omits stack trace in the middle.
Caused by: nablarch.core.message.MessageNotFoundException: message was not found. message id = MSG00010
    at nablarch.core.message.StringResourceHolder.get(StringResourceHolder.java:40)
    # Subsequent stack trace is omitted.(Caused by does not appear subsequently)

However, it is not realistic to configure failure codes for every framework class as the classification will become too detailed. Basically, it is possible to determine which function of the framework threw an exception by specifying the failure code for the package name unit.

The failure code of the framework is specified in the property file. Specify the framework package name as the key and failure code as value in the property file. The package name specified as the key is used with prefix match to search the FQCN (fully qualified class name) of the class which threw an exception obtained from stack trace. Therefore, after reading the contents of the property file, sort in the descending order of the key name length for retrieval using limited package name.

An example for changing the framework failure code is shown below

First, prepare a property file. A file with the name failure-log-fw-codes.properties that is placed directly under the class path. By specifying the nablarch package name, failure codes can be specified for all the packages to which the failure codes have not been specified separately.

Configuration example of failure-log-fw-codes.properties
# Framework package name = Failure code
nablarch=FW_ERROR
nablarch.core.cache=FW_CACHE_ERROR
nablarch.core.date=FW_DATE_ERROR
nablarch.core.db=FW_DB_ERROR
nablarch.core.message=FW_MESSAGE_ERROR
nablarch.core.repository=FW_REPOSITORY_ERROR
nablarch.core.transaction=FW_TRANSACTION_ERROR

The above-mentioned property file is sorted as follows and is used for the search in order from the top.

nablarch.core.transaction=FW_TRANSACTION_ERROR
nablarch.core.repository=FW_REPOSITORY_ERROR
nablarch.core.message=FW_MESSAGE_ERROR
nablarch.core.cache=FW_CACHE_ERROR
nablarch.core.date=FW_DATE_ERROR
nablarch.core.db=FW_DB_ERROR
nablarch=FW_ERROR

Next, specify the property file path in the configuration of FailureLogFormatter.

Configuration example of app-log.properties
failureLogFormatter.defaultFailureCode=UNEXPECTED_ERROR
failureLogFormatter.defaultMessage=an unexpected exception occurred.
failureLogFormatter.notificationFormat=[$failureCode$:$message$]
failureLogFormatter.analysisFormat=fail_code = [$failureCode$] $message$
# Specify the property file path.
failureLogFormatter.fwFailureCodeFilePath=classpath:failure-log-fw-codes.properties

The framework failure code is changed based on the above configuration. Some output examples of the failure notification log is shown below

When exception is thrown with nablarch.core.date.BasicBusinessDateProvider class
# Applicable when nablarch.core.date of property file = FW_DATE_ERROR.
2011-02-15 16:48:54.993 -FATAL- [APUSRMGR0001201102151648315060002] R[/login] U[9999999999] fail_code = [FW_DATE_ERROR] segment was not found. segment:00.
Stack Trace Information :
java.lang.IllegalStateException: segment was not found. segment:00.
    at nablarch.core.date.BasicBusinessDateProvider.getDate(BasicBusinessDateProvider.java:103)
    # Subsequent stack trace is omitted.
When exception is thrown withnablarch.core.message.StringResourceHolder class
# Applicable when nablarch.core.message of property file = FW_MESSAGE_ERROR.
2011-02-15 16:54:06.413 -FATAL- [APUSRMGR0001201102151653476260011] R[/users/edit] U[0000000001] fail_code = [FW_MESSAGE_ERROR] ValidateFor method invocation failed. targetClass = java.lang.Class, method = validateForRegisterUser
Stack Trace Information :
java.lang.RuntimeException: ValidateFor method invocation failed. targetClass = java.lang.Class, method = validateForRegisterUser
    at nablarch.core.validation.ValidationManager.validateAndConvert(ValidationManager.java:202)
    # Omits stack trace in the middle.
Caused by: nablarch.core.message.MessageNotFoundException: message was not found. message id = MSG00010
    at nablarch.core.message.StringResourceHolder.get(StringResourceHolder.java:40)
    # Subsequent stack trace is omitted.
When exception is thrown withnablarch.common.authentication.PasswordAuthenticator class
# Applicable when nablarch of property file =FW_ERROR.
2011-02-15 16:59:03.076 -FATAL- [APUSRMGR0001201102151658551890017] R[/login] U[9999999999] fail_code = [FW_ERROR] authentication failed.
Stack Trace Information :
nablarch.common.authentication.AuthenticationFailedException
    at nablarch.common.authentication.PasswordAuthenticator.authenticate(PasswordAuthenticator.java:302)
    # Subsequent stack trace is omitted.

7.1.1.2.1.2.5. Output the derived source run time information

When the data from the web has to be linked to the batch, runtime information during execution of the screen process is the derived source run time information in the batch process. Hereinafter, when data is linked between the process architectures, the side that performs the process first is referred to as the pre-stage process, and the side that performs the process later is referred to as the post-stage process. When a failure occurs in the post-stage process, derived source run time information is output to reduce the tracking work of the pre-stage process.

The placeholder “$data$” of this function can be used to output the derived source run time information. When the placeholder “$data$” is specified, the data read using the data reader is output in the failure log. If derived source run time information is included in advance in the pre-stage process by using this function, when a failure occurs in post-stage process , derived source run time information of the pre-stage process is output as the process target data.

An output example of the derived source run time information in the data link using the database is shown here. The run time information is configured with the following column names in the pre-stage process.

Item Column name
Request ID INSERT_REQUEST_ID
Run time ID INSERT_EXECUTION_ID
User ID UPDATED_USER_ID
Configuration example of app-log.properties
failureLogFormatter.defaultFailureCode=UNEXPECTED_ERROR
failureLogFormatter.defaultMessage=an unexpected exception occurred.
failureLogFormatter.notificationFormat=fail_code = [$failureCode$] $message$
# Specify the placeholder "data" of process target data in the format of the failure analysis log.
failureLogFormatter.analysisFormat=fail_code = [$failureCode$] $message$\nInput Data :\n$data$
Output example of failure analysis log
# Failure analysis log
2011-09-26 21:06:35.745 -FATAL- root [EXECUTION_ID_0000000123456789] boot_proc = [] proc_sys = [] req_id = [RB11AC0160] usr_id = [batchuser1] fail_code = [USER_REGISTER_FAILED] Registration of user information failed.
Input Data :
{MOBILE_PHONE_NUMBER_AREA_CODE=002, KANJI_NAME=Yamamoto Taro, USER_INFO_ID=00000000000000000113, INSERT_EXECUTION_ID=EXECUTION_ID_2000000123456789, MAIL_ADDRESS=yamamoto@sample.com, MOBILE_PHONE_NUMBER_CITY_CODE=0003, UPDATED_USER_ID=batch_user, MOBILE_PHONE_NUMBER_SBSCR_CODE=0004, KANA_NAME= Yamamoto Taro, EXTENSION_NUMBER_BUILDING=13, LOGIN_ID=12345678901234567890, EXTENSION_NUMBER_PERSONAL=1235, INSERT_REQUEST_ID=RB11AC0140}
Stack Trace Information :
[100 TransactionAbnormalEnd] Registration of user information failed.
    at nablarch.sample.ss11AC.B11AC016Action.handle(B11AC016Action.java:73)
    at nablarch.sample.ss11AC.B11AC016Action.handle(B11AC016Action.java:1)
    at nablarch.fw.action.BatchAction.handle(BatchAction.java:1)
    # Subsequent stack trace is omitted.
The following run time information is output in the process target data (“Input Data:” of output example).
INSERT_REQUEST_ID=RB11AC0140
INSERT_EXECUTION_ID=EXECUTION_ID_2000000123456789
UPDATED_USER_ID=batch_user

7.1.1.2.1.2.6. Customize the output process for placeholders

Since all the data items of the process target data ($data$) are output with the toString method by default, in some cases masking certain specific items based on the project security requirements may be necessary. When the output process for the placeholder has to be customized, perform the following operation.

A customization example of the output process corresponding to the process target data ($data$) is shown here.

Create a class that implements LogItem

Create a class that provides output contents corresponding to the process target data ($data$). Create a class by inheriting DataItem provided by the framework and implement such that mask processing is performed only for Map type of process target data.

// Defined as an inner class in the extension class of FailureLogFormatter.
private static final class CustomDataItem extends DataItem {

    /** Mask character */
    private static final char MASKING_CHAR = '*';

    /** Pattern to be masked */
    private static final Pattern[] MASKING_PATTERNS
            = new Pattern[] { Pattern.compile(".*MOBILE_PHONE_NUMBER.*"),
                              Pattern.compile(".*MAIL.*")};

    /**
     * Editor for masking map values.
     * Map editing utility provided by the framework.
     */
    private MapValueEditor mapValueEditor
        = new MaskingMapValueEditor(MASKING_CHAR, MASKING_PATTERNS);

    @Override
    @SuppressWarnings("unchecked")
    public String get(FailureLogContext context) {

        // Call getData method of FailureLogContext and acquire process target data.
        Object data = context.getData();

        // If it is not Map, call the default implementation of the framework.
        if (!(data instanceof Map)) {
            return super.get(context);
        }

        // Returns a string with the Map masked.
        Map<String, String> editedMap = new TreeMap<String, String>();
        for (Map.Entry<Object, Object> entry : ((Map<Object, Object>) data).entrySet()) {
            String key = entry.getKey().toString();
            editedMap.put(key, mapValueEditor.edit(key, entry.getValue()));
        }
        return editedMap.toString();
    }
}
Create a class that inherits FailureLogFormatter and add a placeholder

Override FailureLogFormatter#getLogItems and configure CustomDataItem for placeholder $data$.

public class CustomDataFailureLogFormatter extends FailureLogFormatter {

    @Override
    protected Map<String, LogItem<FailureLogContext>> getLogItems(Map<String, String> props) {

        Map<String, LogItem<FailureLogContext>> logItems = super.getLogItems(props);

        // Overwrite by configuring $data$ with CustomDataItem.
        logItems.put("$data$", new CustomDataItem());

        return logItems;
    }

    private static final class CustomDataItem extends DataItem {
        // Omitted
    }
 }
Configure such that a class that inherits FailureLogFormatter is used

Configure in app-log.properties such that CustomDataFailureLogFormatter is used as the formatter for failure log.

# Specify CustomDataFailureLogFormatter.
failureLogFormatter.className=nablarch.core.log.app.CustomDataFailureLogFormatter
failureLogFormatter.defaultFailureCode=UNEXPECTED_ERROR
failureLogFormatter.defaultMessage=an unexpected exception occurred.
failureLogFormatter.notificationFormat=fail_code = [$failureCode$] $message$
failureLogFormatter.analysisFormat=fail_code = [$failureCode$] $message$\nInput Data :\n$data$

7.1.1.2.1.2.7. Output as a structured log in JSON format

Logs can be output in JSON format by using Output as a structured log in JSON format setting, but FailureLogFormatter outputs each item of the failure log as a string in the message value.

To output each item in the failure log as a JSON value as well, use the FailureJsonLogFormatter. You can configure in the property file described in Configure various logs.

Description rules

The properties to be specified when using FailureJsonLogFormatter are as follows.

failureLogFormatter.className required
To output logs in JSON format, specify FailureJsonLogFormatter.
failureLogFormatter.defaultFailureCode required
Default fault code. Use when there is no failure code specified, like in cases where an error is captured by the exception handler.
failureLogFormatter.defaultMessage required
Default message. This message is output when a default failure code is used.
failureLogFormatter.language
The language used to acquire the message from the failure code. If it is not specified, the language configured in ThreadContext will be used.
failureLogFormatter.notificationTargets

Output items of failure notification log. Separated by comma.

Output items that can be specified and default output items

Item name Output item Description Default output
Failure code failureCode A code that uniquely identifies the failure. Used to identify the nature of the failure. YES
Message message The message corresponding to the failure code. Used to identify the nature of the failure. YES
Data to be processed data Used to identify the data targeted by the process in which the failure occurred. Outputs by calling the toString method of the data object read using the data reader.  
Contact contact Used to identify the contacts.  
failureLogFormatter.analysisTargets
Output item of failure analysis log. Separated by comma. Items that can be specified for the targets and default items are same as targets for failure notification log.
failureLogFormatter.contactFilePath
Path to the property file that specifies the contact information of the failure. Specify to output the contact information of the failure. For details, see Add contact information to failure log.
failureLogFormatter.fwFailureCodeFilePath
Path to the property file that specifies the information change of the failure code in the framework. Specify when changing the failure code of the framework at the time of failure log output. For details, see Change the framework failure codes.
failureLogFormatter.structuredMessagePrefix
A marker string given at the beginning of a message to identify that the message string after formatting has been formatted into JSON format. If the marker string at the beginning of the message matches the marker string set in JsonLogFormatter, JsonLogFormatter processes the message as JSON data. The default is "$JSON$". If you change it, set the same value in JsonLogFormatter using LogWriter’s structuredMessagePrefix property (see Configure log output for LogWriter properties).
Example of the description
failureLogFormatter.className=nablarch.core.log.app.FailureJsonLogFormatter
failureLogFormatter.structuredMessagePrefix=$JSON$
failureLogFormatter.notificationTargets=failureCode,message,contact
failureLogFormatter.analysisTargets=failureCode,message,data
failureLogFormatter.defaultFailureCode=UNEXPECTED_ERROR
failureLogFormatter.defaultMessage=an unexpected exception occurred.