My official account: MarkerHub, Java website: Markerhub.com

For more selected articles, please click: Java Notes Complete.md

Small Hub read:

Different log levels should be used separately, and parameter variables should be isolated with [].


  • Sigma’s blog
  • t.cn/E9BkD7a

Use slf4j

  1. The facade logging framework helps maintain and unify the log processing of each class

  2. Unified implementation: Logback framework

The correct way to log

When should I log in

  1. When you encounter a problem, you can only use the debug function to determine the problem, you should consider logging, good system, is able to use the log to determine the problem.

  2. When you meet if… For branches like else or switch, a log is printed on the first line of the branch to determine which branch was entered

  3. Often feature centered development, you should be sure to see the flow through the log before you commit code

The basic format

Parameterized information must be used:

logger.debug("Processing trade with id:[{}] and symbol : [{}] ", id, symbol);

Copy the code

Before using debug logs, check whether the log level is DEBUG:

if (logger.isDebugEnabled()) {
    logger.debug("Processing trade with id: " +id + " symbol: " + symbol);
}

Copy the code

Do not concatenate strings, as this will create a lot of strings, which will take up space and affect performance.

Counterexample (don’t do this):

logger.debug("Processing trade with id: " + id + " symbol: " + symbol);

Copy the code

Use [] for parameter variable isolation

If there are parameter variables, they should be written as follows:

logger.debug("Processing trade with id:[{}] and symbol : [{}] ", id, symbol);

Copy the code

This format is more readable and more helpful for troubleshooting problems.

Different levels of use

ERROR:

The basic concept

Exceptions that affect the normal operation of the program and the normal operation of the current request:

  1. Failed to open the configuration file. Procedure

  2. All third-party connection exceptions (including error codes returned by third parties)

  3. All exceptions that affect the use of functionality, including: SQLException and all exceptions except business exceptions (runtimeExceptions and Exceptions)

What should not happen:

  1. For example, you want to use Azure to upload pictures, but Azure does not respond

If there is Throwable information, the completed stack information needs to be recorded:

Log. error(" failed to get user info from [{}] ",userName,e);Copy the code

instructions

If an exception is thrown, do not record the error log and let the final handler handle it:

Counterexample (don’t do this):

try{
    ....
}catch(Exception ex){
  String errorMessage=String.format("Error while reading information of user [%s]",userName);
  logger.error(errorMessage,ex);
  throw new UserServiceException(errorMessage,ex);
}

Copy the code

WARN

The basic concept

Exceptions that should not occur but do not affect the normal operation of the current request:

  1. An error condition that occurs when a fault tolerance mechanism is in place

  2. The configuration file could not be found, but the system can create the configuration file automatically

When approaching a critical value, for example:

  1. Cache pool usage reaches warning line

Record business exceptions, such as:

  1. When the interface throws a business exception, it should be logged

INFO:

The basic concept

System Running Information

  1. Changes to system/business state in the Service method

  2. Steps in major logic

External interface part

  1. Client request Parameters (REST/WS)

  2. Call parameters and call results when invoking a third party

instructions

1. Not all services record inbound and outbound entries. A single service is meaningless (except job, whose start and end are recorded).

Counterexample (don’t do this):

Public List listByBaseType(Integer baseTypeId) {log.info(" start query base "); BaseExample ex=new BaseExample(); BaseExample.Criteria ctr = ex.createCriteria(); ctr.andIsDeleteEqualTo(IsDelete.USE.getValue()); Optionals.doIfPresent(baseTypeId, ctr::andBaseTypeIdEqualTo); Log.info (" Base query completed "); return baseRepository.selectByExample(ex); }Copy the code

** For complex business logic, logging and buried logging are required, such as order placing logic in e-commerce systems and OrderAction operations (business state changes).

3. For the interface (REST/WS) provided by the entire system, use info to record input parameters

4. If all services are SOA architectures, they can be considered as an external interface provider and must be entered.

5. When calling other third-party services, all outgoing and incoming parameters must be logged (because it is difficult to trace problems with third-party modules).

DEBUG

The basic concept

  1. You can fill in all the relevant information you want to know (but it does not mean that you can write it freely. The debug information should be meaningful and relevant parameters are better)

  2. Disable debugging information in the production environment

  3. If you need to enable the DEBUG function in production, you need to use the DEBUG function to manage the function.

instructions

This can be optimized if the following code appears in your code:

//1. Obtain user's basic salary //2. Obtain user's vacation status //3. Calculate the user's salaryCopy the code

Optimized code:

Logger. The debug (" start getting employees [{}] [{}] "year basic salary, the employee, year); Logger. The debug (" get employees [{}] [{}] years of basic salary for [{}] ", the employee, year, basicSalary); Logger. The debug (" start getting employees [{}] [{}] on [] {} "about vacations, employee, year, month); Logger. The debug (" employees [{}] [{}] [{}] month annual leave/sick leave/personal leave for [{}] / [{}] / [] {} ", the employee, year, month, annualLeaveDays, sickLeaveDays, noPayLeaveDays) ; Logger. The debug (" start count employees [{}] [{}] on [{}] deserve compensation ", the employee, year, month); Logger. The debug (" employees [{}] [{}] on [{}] deserve compensation for [{}] ", the employee, year, month, actualSalary);Copy the code

TRACE

The basic concept

Do not use detailed system operation completion information in business code (use DEBUG level instead unless specifically intended).

Specifications Example Description

@Override @Transactional public void createUserAndBindMobile(@NotBlank String mobile, @NotNull User user) throws CreateConflictException{ boolean debug = log.isDebugEnabled(); Args [mobile=[{}],user=[{}]]", mobile, logobjects.tostring (user); } try { user.setCreateTime(new Date()); user.setUpdateTime(new Date()); userRepository.insertSelective(user); InsertedUser =[{}]", logobjects.tostring (user)); } UserMobileRelationship relationship = new UserMobileRelationship(); relationship.setMobile(mobile); relationship.setOpenId(user.getOpenId()); relationship.setCreateTime(new Date()); relationship.setUpdateTime(new Date()); userMobileRelationshipRepository.insertOnDuplicateKey(relationship); Relationship =[{}]", logobjects.tostring (relationship)); if(relationship) {log.debug(" Relationship =[{}]", logobjects.tostring (relationship)); } the info (" create user and bind the mobile phone number. UserId = ({}), openId = ({}), mobile = ({}) ", the user. The getId (), the user. The getOpenId (), mobile). }catch(DuplicateKeyException e){log.info(" openId=[{}],mobile=[{}]", user.getopenid (),mobile); Throw new CreateConflictException(" Create user conflict, openId =[%s]", user.getopenId ()); }}Copy the code

Recommended reading

Java Notes Complete.md

Great, this Java site, everything! https://markerhub.com

The UP master of this B station, speaks Java really good!