preface

Hello, everyone. I am a little boy picking up field snails. Log is a good helper to quickly locate problems, is a sharp weapon to quarrel and shake the pot! It is very important to print a good log. Today we are going to talk about 15 good tips for journaling

  • Public number: a boy picking up snails

1. Select a proper log level

There are five log levels: Error, WARN, INFO, DEBUG, and Trace. In daily development, we need to choose the appropriate log level and do not backhand print info

  • Error: indicates serious errors that affect normal services and need to be monitored by O&M configuration.
  • Warn: Warning logs, which are common errors that have little impact on services but require development attention.
  • Info: Information log, which records key information about troubleshooting, such as call time, outgoing and incoming parameters.
  • Debug: Runtime data for developing debug key logic;
  • Trace: Indicates the most detailed information. Generally, this information is only recorded in a log file.

2. Log the input and output parameters of the method

We don’t need to print lots and lots of logs, just valid logs that can quickly locate problems. Effective log, is a sharp weapon!

What are the key logs that are valid? For example, when a method comes in, print the input parameter. And then, when the method returns, it prints out the parameter and returns the value. The key information is usually userId or bizSeq. For example:

Public String testLogMethod(Document doc, Mode Mode){log.debug(" method Enter param: {} ",userId); String id = "666"; Log.debug (" Method exit param: {} ",id); return id; }Copy the code

3. Select a proper log format

The ideal log format should include such basic information as the current timestamp (typically millisecond accurate), log level, thread name, and so on. Logback logs can be configured as follows:

<appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
    <encoder>
        <pattern>%d{HH:mm:ss.SSS} %-5level [%thread][%logger{0}] %m%n</pattern>
    </encoder>
</appender> 
Copy the code

If our log format does not even record the current time, then we do not even know the request point in time?

4. Meet the if… else… Logs are printed at the first line of each branch

When you meet if… else… Or for conditions such as switch, logs can be printed at the first line of the branch. In this way, during troubleshooting, logs can be used to determine which branch is entered. The code logic is clearer, and troubleshooting is more convenient.

Is:

If (user. IsVip ()) {the info (" the user is a member Id: {}, start working with the member logic ", the user, getUserId ()); Else {log.info(" this user is a non-member,Id:{}, start processing non-member logic ",user,getUserId()) // Non-member logic}Copy the code

5. If the log level is low, enable or disable the log function

For low log levels such as trace and DEBUG, check whether the log level is enabled or disabled.

Is:

User User = new User(666L, "public number "," little boy "); if (log.isDebugEnabled()) { log.debug("userId is: {}", user.getId()); }Copy the code

Because there is currently the following logging code:

logger.debug("Processing trade with id: " + id + " and symbol: " + symbol);
Copy the code

If the log level is set to WARN, the above log will not be printed, but string concatenation will be performed. If symbol is an object, the toString() method will be executed, wasting system resources.

6. You cannot use the API of logging system (Log4j, Logback) directly, but use the API of logging framework SLF4J.

SLF4J is a facade logging framework, which is conducive to unified maintenance and log processing of each class, and can easily achieve the replacement of the underlying logging framework without modifying the code.

Is:

import org.slf4j.Logger; 
import org.slf4j.LoggerFactory;

private static final Logger logger = LoggerFactory.getLogger(TianLuoBoy.class);
Copy the code

7. It is recommended to use parameter placeholder {} instead of + concatenation.

Example:

logger.info("Processing trade with id: " + id + " and symbol: " + symbol);
Copy the code

In the above example, concatenating strings using the + operator has a performance penalty.

For example:

logger.info("Processing trade with id: {} and symbol : {} ", id, symbol); 
Copy the code

We use curly braces {} as placeholders in the log, which is more elegant and concise than using the + operator. And, as opposed to counterexamples, using placeholders is just a substitution action, which can significantly improve performance.

8. You are advised to output logs asynchronously.

  • Logs will eventually be output to files or other output streams, and IO performance will be required. If it is asynchronous, I/O performance can be significantly improved.
  • Unless special requirements are met, you are advised to output logs asynchronously. Using logback as an example, it is easy to configure asynchrony using AsyncAppender
<appender name="FILE_ASYNC" class="ch.qos.logback.classic.AsyncAppender">
    <appender-ref ref="ASYNC"/>
</appender>
Copy the code

9. Do not use e.printStackTrace()

Example:

Try {// business code handling}catch(Exception e){e.printStackTrace(); }Copy the code

Is:

Try {// business code handler}catch(Exception e){log.error(" your program has an Exception ",e); }Copy the code

Reason:

  • E.printstacktrace () prints a stack log that is interleaved with the business code log, making it inconvenient to check the exception log.
  • The e.printStackTrace() statement produces a string that keeps track of the stack. If the string is so long that there is no room in the block where the string constant pool is located, the user’s request is stuck

10. Do not type only half of the exception log. Output all error messages

Example 1:

Try {// business code handling} catch (Exception e) {// error log.error (' your program has an Exception '); }Copy the code
  • None of the exception E is printed, so we don’t know what kind of exception is being detected.

Example 2:

Try {// business code handling} catch (Exception e) {// error log.error (' LLDB ', LLDB message ()); }Copy the code
  • e.getMessage()It does not record detailed stack exception information but only basic error description, which is not helpful for troubleshooting.

Is:

Try {// business code handling} catch (Exception e) {// error log.error (' your program has an Exception ', e); }Copy the code

11. Do not enable debugging in the online environment

It is important to disable debugging in your online environment.

Common systems have a large number of debug logs, and various frameworks also use a large number of DEBUG logs. After debugging is enabled online, disks may fill up, affecting the normal running of the service system.

12. Do not throw an exception after logging it

For example:

log.error("IO exception", e);
throw new MyException(e);
Copy the code
  • This is usually done by printing the stack information twice. This is because where MyException is caught, it is printed again.
  • Such logging, or packaging and then throw, do not use both! Otherwise your log will look confusing.

13. Do not print logs repeatedly

Avoid reprinting logs, which can waste disk space. If you already have a log line that makes sense, avoid printing it out redundantly.

If (user. IsVip ()) {the info (" the user is a member, Id: {} ", the user, getUserId ()); Log.info (" start processing member logic,id:{}",user,getUserId()); // member logic}else{// non-member logic}Copy the code

If you are using the log4j logging framework, be sure to set additivity=false in log4j.xml to avoid printing logs repeatedly

Is:

<logger name="com.taobao.dubbo.config" additivity="false"> 
Copy the code

14. Log file separation

  • We can separate different types of logs, such as access.log, or error level error.log, into a separate file.
  • Of course, it can also be printed to different log files according to different business modules, so that when we troubleshoot problems and do data statistics, it will be more convenient.

15. For core function modules, it is recommended to print more complete logs

  • In our daily development, if the core or logic complex code, it is suggested to add detailed notes, as well as more detailed log.
  • How detailed should the log be? Imagine that if something goes wrong in your core program, you can log it and find it.