How to better play the log function to promote the Java Enterprise Open process

Source: Internet
Author: User
Tags stack trace time and date unique id websphere application server log4j

In the enterprise-level development process, we inevitably encounter a lot of problems, if you want to be able to effectively catch bugs at the end of the development process, you need an effective logging strategy. However, in an enterprise application to achieve effective logging, you need to plan and design some guidelines. In this article, consultant Charles Chan will introduce you to some of the best practices to help you write useful log code from the start of a project.

If you're a developer, you probably already have this experience: you've developed some code and some test cases. The application has undergone a rigorous QA test, and you are confident that the code can be fully tailored to your business needs. However, when the application is finally delivered to the end-user's hand, there are some unexpected problems. If there is no proper log message, it may take several days to diagnose these problems. Unfortunately, most projects don't have a clear strategy for logging. Without this strategy, the log messages generated by the system may not be conducive to the analysis and resolution of the problem. In this article, we will discuss various aspects of the enterprise Application log. You will see a java& #8482; Overview of the log API on the platform, learn some of the best practices for writing log codes, and learn what to do if you need to reorder the verbose logs in a product environment.

Select Log API

When you use the Java Platform for development, you can use the two main log api:apache log4j and Java Logging APIs, which are available in the 1.4 and later versions of the Java platform. Compared with the Java Logging API, log4j is more mature and richer in features. The implementation of both logs uses a similar design pattern (as shown in Figure 1). Unless your company restricts the use of Third-party libraries, I strongly recommend using LOG4J. If you cannot decide which API to use, you can use the Apache Commons Logging API, which encapsulates the underlying log implementation. Theoretically, this allows you to switch log implementations without modifying the code. In fact, however, you rarely switch the implementation of the log, so I don't recommend using the Apache Commons Logging API because its complexity does not give you other features.


Log Overview

The log4j and Java Logging APIs use similar design and usage patterns (shown in Figure 1 and listing 1). The message is created first and then passed to a log object with a specific priority. The purpose and format of these messages are determined by the output handler and its layout.



Listing 1. Instantiation and use of log objects

Import Org.apache.log4j.Logger;

public class MyClass {
  /
   * * Obtain a logger for a message category. In this case, the message category is
   * The fully qualified class name of MyClass.
   *
  private static final Logger Logger = Logger.getlogger (MyClass.class.getName ());
  ...
  public void MyMethod () {
    ...
    if (logger.isdebugenabled ()) {
      logger.debug ("Executing with parameters:" + param1 + ":" + param2);
    }
}




A good log implementation provides a number of different output handlers, the most common file output handler, and the terminal output handler. LOG4J also provides a number of handlers for publishing messages to a JMS topic or inserting messages into a database table. Although it is not difficult to write a custom add-on, the overall cost of writing and maintaining this code should not be underestimated. The format of the message can be configured through the Layout object. The most common layout object is patternlayout, which formats the message according to the mode provided.

Listing 2 shows a log4j sample configuration file that is responsible for configuring Fileappender. In this configuration, the error message in the Com.ambrosesoft.log.MyClass class is sent to Fileappender, which writes it to a file named Log.txt. These messages are formatted according to the layout (in this case, patternlayout) associated with this additive.


Listing 2. log4j XML Configuration Sample file

<?xml version= "1.0" encoding= "UTF-8"?> log4j:configuration
 SYSTEM "LOG4J.DTD" >


        
  
    
    
    
      
    
  

  
    
    
  

  
    
    
  




Log Best Practices

One of the most important choices you can make about logging is to determine a pattern that assigns each log message to a specific category. A common practice is to use the full name of each class, which is recorded as a message category in the log (as we see in Listing 1), because it lets developers record the settings for each class more granular. However, this works well only if you are using log messages to track the execution process. In an enterprise-class application, there are many other types of log messages. For example, a log message might be generated for a security advisor, and another log message might be created to help with performance tuning. If the two messages are concerned with the same class, they are assigned to the same category, which makes it difficult to differentiate between the results of the log output.

To avoid this problem, the application should have a dedicated set of logging programs, all of which are uniquely categorized, as shown in Listing 3. Each logger can configure its own priority and output handlers. For example, the security logger can encrypt a message before it is written to the destination. Sometimes the designer of an application should work with users who use the journal (such as security Advisor) to negotiate the output format of the log to better control the message.


Listing 3. A dedicated logging program

Import Org.apache.log4j.Logger;

Public interface Loggers {
  Logger performance = Logger.getlogger ("performance");
  Logger Security = Logger.getlogger ("security");
  Logger business = Logger.getlogger ("Business");
}
...
public class MyClass {
  ....
  if (Loggers.security.isWarnEnabled ()) {
    Loggers.security.warn ("Access denied:username [+ Username +] ..."); 
  }
  ...
}




Select the level of the log

Messages in a category, such as security, can have different priorities. Some messages are generated for debugging, some for warnings, and some for errors. The different priorities of a message can be generated by record level. The most common log levels are:

Debug: This level of messages contains a wide range of contextual information. Typically used for problem diagnosis.

Info: These messages contain contextual messages that help track execution in a product environment (granular).

Warning: A warning message stating that there may be a problem in the system. For example, if the message category is about security, a warning message should be generated if a dictionary attack is detected.

Error: A bad message indicates that a serious problem has occurred in the system. Such problems are usually unrecoverable and require human intervention.
The standard Java Logging API and Apache log4j provide some logging levels outside this. The primary goal of the logging level is to help you filter the noise in useful information. To prevent the use of errors and reduce the usefulness of log messages, you must provide a clear guideline for developers before you start coding.

format of log Messages

Once you have selected the logger and established the log level, you are ready to start building the log message. In doing so, it is important to include as many contextual information as possible, such as user-supplied parameters, and state information for other applications. One way to log objects is to convert them to XML. Third-party libraries, such as xstream (see Resources), can automatically convert Java objects to XML. Although this is a very powerful mechanism, we must consider a balance between speed and verbosity. In addition to typical application state information, you should record the following information:

Thread ID: Enterprise-class applications are usually run in a multithreaded environment. With thread ID information, you can separate multiple requests.

The identity of the caller: the identity of the caller is also very important information. Because different users have different privileges, their execution paths can vary greatly. Placing the user's identity in a log message is a great help for security-sensitive applications.

Timestamp: Typically, a user can only approximate how long the problem occurs. If there is no time stamp, it is difficult to let others judge the cause of the problem.

Source code information: This includes the class name, method name, and line number. Unless you are very concerned about security, I recommend that you keep the debug tag (-G), even when you are compiling a product. Without a debug tag, the Java compiler deletes all line number information, which greatly reduces the availability of log messages.
The information above (except the caller ID) is automatically retrieved by the log implementation. In order to include this information in the message, you only need to configure an appropriate layout mode for the output handler. To capture the identity of the caller, you can take advantage of the diagnostic context attribute in log4j (see Resources for more information). The diagnostic context allows you to associate contextual information with the currently running thread. This information can be included in each message while formatting the output.

In the Java EE Web application, the best place for the application logic to save the user identity to the diagnostic context is in a servlet filter. The necessary code to implement this functionality is shown in Listing 4. It uses the mapping diagnostic Context class (MDC) provided in Log4j 1.3 alpha. You can use the nested diagnostic context (NDC) provided in LOG4J 1.2 to achieve the same functionality. For more general information about servlet filters, see the information in resources.


Listing 4. Using the diagnostic context in a servlet filter

import javax.servlet.Filter; import javax.servlet.http.HttpServletRequest; import
Javax.servlet.http.HttpSession;

Import Org.apache.log4j.MDC; public class Loggerfilter implements Filter {public void Dofilter (ServletRequest request, Servletresponse Respon  SE, Filterchain chain) throws IOException, Servletexception {//retrieves the session object
        From the current request.
        
        HttpSession session = ((httpservletrequest) request). GetSession ();
        Put the username in the diagnostic context.
        Use%x{username} in the layout pattern to include this information.
        
        Mdc.put ("username", Session.getattribute ("username"));
        Continue processing the rest of the filter chain.
        
        Chain.dofilter (request, response);
        Remove the username from the diagnostic context.
    Mdc.remove ("username"); }
    ...
}




using AspectJ to track execution

It is often helpful to track the execution of a program when troubleshooting a problem. You can continue to send log messages in different places where your program executes. For example, the entry function and export function of the method. This is an old problem and there are no good solutions until AspectJ. With AspectJ, you can execute code snippets in different parts of your application. In AspectJ, these places are called point cut, and the code that executes in the spot cut is called advice. Point cut and advice collectively aspect.

About AspectJ, one thing is amazing, aspect can be applied to the entire application without much effort. For more information on AspectJ, see Resources. Listing 5 shows an example of a AspectJ source file that is used to log the entry and exit functions of the method. In this example, the trace log program logs a log every time a common method of entering or exiting a Com.ambrosesoft package is entered or exited.


Listing 5. Entry and exit using AspectJ logging method

Import Org.apache.log4j.Logger;

Import Java.lang.reflect.Field;
    
    Public aspect Autotrace {private static final Logger Logger = Logger.getlogger (Autotrace.class); Pointcut publicmethods (): Execution (public * Com.ambrosesoft ...

    *(..));
    
    Pointcut loggablecalls (): Publicmethods (); /** * Inspect the class and find its logger object.
     If None is found, use * the one defined here.  * * Private Logger GetLogger (Org.aspectj.lang.JoinPoint joinpoint) {try {* * * * try to 
             Discover the Logger object.
             * The Logger object must be a static field called logger.
            */Class DeclaringType = Joinpoint.getsignature (). Getdeclaringtype ();
            Field Loggerfield = Declaringtype.getfield ("logger");
            Loggerfield.setaccessible (TRUE);
        Return (Logger) loggerfield.get (null); catch (Nosuchfieldexception e) {/* Cannot find a logger object, uSe the internal one.
        * * return logger;
        catch (Exception e) {throw new RuntimeException (e);
     }/** * A aspect to log method entry. */Before (): Loggablecalls () {GetLogger (thisjoinpoint). Debug ("Entering ..." + thisjoinpoint.getsignature (). toSt
    Ring ());
     }/** * A aspect to log method exit. * After (): Loggablecalls () {GetLogger (thisjoinpoint). Debug ("Exiting ..." + thisjoinpoint.getsignature (). Tostri
    Ng ());  }
}




Logs in the product environment

Once your application is in a production environment, you typically need to turn off debugging or Infolog messages to optimize performance at run time. However, when something bad happens, and you can't reproduce the problem in the development environment, you may need to activate the debug message in the production environment. It is important to be able to modify the settings of the log without shutting down the server. The problem of diagnosing a product usually takes several hours, even if it doesn't take a few days for detailed research. During this time, developers need to activate or close the logs for different ranges of applications. If you need to restart the product application every time you modify the log settings, the situation becomes very unreliable.

Fortunately, LOG4J provides a simple mechanism to solve this problem. In Log4j 1.2, the Configureandwatch () method in Domconfigurator configures log4j and automatically monitors for changes in the log configuration file. This is illustrated in Listing 6. (Note that Domconfigurator is not recommended in log4j 1.3, which is still the alpha version, and it uses a more flexible implementation joranconfigurator.) )

To ensure that Configureandwatch () is invoked before log4j initialization, you should call it in the Startup class. Different application servers use different mechanisms to execute startup code (see Resources for more information). For more information, see the implementation of the application server. Some application servers may require you to place log4j libraries in the classpath of the server. The log profile should be saved to a location that the person who needs the log can access.


Listing 6. Using Domconfigurator configuration log4j

/

*
 * Configure log4j Library and periodically monitor log4j.xml for any update.
 * *
Domconfigurator.configureandwatch ("/apps/config/log4j.xml");




If your log profile is not easily accessible (for example, your product environment is maintained by a different organization), you must use a different policy. The standard approach is to use JMX, which provides a standard API to manage your application settings. In a modern JMX-compliant server, you can use management beans (or Mbeans) to extend the functionality of the application server's management terminal (for more information about using JMX and using JMX in WebSphere Application Server 6.0, see the parameter Test data section. Because the JMX approach is complex, if you need to use JMX for your situation, it should be used only for this purpose.

Record Sensitive data

In addition to technical challenges, there are a number of business issues that need to be overcome in documenting the logs in a product environment. For example, logging sensitive information can cause security problems. There are no restrictions to prevent you from saving a user's user name and password to a body file. You must also protect other sensitive information, such as e-mail addresses, phone numbers, and account information. Security consultants and designers have a responsibility to ensure that this information is not stored in the log without any processing. Using security-specific journaling programs for sensitive information can help reduce risk. You can configure this logger with a dedicated add-on that uses an encrypted format to save the message or save it to a secure location. However, the best way to prevent security risks is to set up the appropriate coding specifications before the project starts and to enforce these specifications when checking code.

extract useful information from an exception

When an unexpected exception occurs-for example, if the database connection suddenly fails, or if the system resource becomes very low-you must properly process it, or you lose useful information that is helpful in diagnosing the problem. First, you must record the exception and its stack trace condition. Second, you should identify the error page in a user-friendly manner, which is very helpful for both end users and technical support teams.

One of the challenges that technical support teams face when receiving a technical support call is to establish some kind of association between a user-reported problem and a particular log exception. A very useful simple technique is to record a unique ID for each exception. This ID can be told to the user, or it can be included in the problem report form that the end user fills out. This reduces the time that technical support team members can guess, allowing them to respond quickly to problems. The ID can be recycled periodically, considering the readability of the issue.

management of log files

Log files for a very busy application can quickly become very large. Large log files are difficult to use because they need to filter a lot of noise to find useful signals. The Log loop is a common practice that can help solve this problem. The log loop periodically archives the old log so that new messages can always be written to a relatively small file. Log messages reduce some utility to improve speed; You may rarely need to refer to log messages from a week ago. In Log4j 1.2, the Dailyrollingfileappender add-on can recycle log files based on the provided date pattern. (in log4j 1.3, this circular log file add-on has been redesigned.) Now you can provide a strategy to control how the loop is made. For example, Timebasedrollingpolicy defines a cycle pattern based on time and date. Listing 7 shows the configuration fragment that lets log4j loop through the log files at midnight every day.


Listing 7. Using Dailyrollingfileappender to recycle log files

<?xml version= "1.0" encoding= "UTF-8"?> log4j:configuration
 SYSTEM "Log4j.dtd" >


        
  
    
    
    
    
      
    
  
...




logs in a clustered environment

There are more and more enterprise-class applications that are deployed in a clustered or distributed environment. However, logs in a clustered environment require more planning because messages are generated from different sources (usually different machines). If you want to log on different machines, you must synchronize the timestamps of these machines, otherwise the order of the log messages will be confusing. An easy way to synchronize clocks between machines is to use a time server. There are two ways to set up a time server. You can specify an internal machine as a time server. The Network Time Protocol (NTP) can then be used by other machines to synchronize with the timestamp of the time server. In addition, you can use a time server available on the Internet (see Resources). On AIX, the xntpd daemon is used to synchronize the system time of different machines. When the machine has the same time, the log can be analyzed together.

Collecting log messages in a clustered environment also faces some challenges. An easy way to save log messages in this environment is to save them to a host-specific log file. This works well when the cluster is using the session affinity configuration-If the request for a particular user conversation is to be on the same server, and the EJB is deployed locally. In this configuration, the log files generated by the machines in the cluster can be analyzed independently. If this is not the case-in other words, if any given request can be handled by multiple machines-then parsing the log messages in different log files becomes more difficult. In this case, a good idea is to use System management software to manage log messages, such as IBM tivoli&reg; Software (see Resources for links). This software provides a comprehensive view of all log messages (called events in the terminology of system management software), making it easy for administrators to use them. The system management software can also trigger actions (such as sending e-mail messages or paging messages) depending on the type of event that is received.

Concluding remarks

In this article, we describe the issues you need to consider when planning your logging strategy. As is the case with programming, using a carefully considered plan from the outset can save more effort than planning at the same time. A good logging strategy can be a great help in diagnosing problems. Ultimately, end users can get better applications and get a quick response from a technical support team.
In-situ: http://www-128.ibm.com/developerworks/cn/java/j-logging/

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.