Настоящий бой! 15 полезных советов по печати журналов

Java задняя часть спецификация кода

предисловие

Привет всем, ямаленький мальчик собирает улиток. Журналы — хороший помощник для быстрого поиска проблем, дарвать и сбрасыватьоружие! Очень важно хорошо распечатать журнал. давай поговорим сегодняпечать журнала15 хороших предложений ~

  • публика:маленький мальчик собирает улиток

1. Выберите соответствующий уровень журнала

Существует пять общих уровней ведения журнала, а именно ошибка, предупреждение, информация, отладка и трассировка. В ежедневной разработке нам нужно выбрать соответствующий уровень журнала, а не просто печатать информацию слева ~

  • ошибка: журнал ошибок, который относится к серьезным ошибкам, влияющим на нормальную работу, и должен бытьМониторинг конфигурации эксплуатации и технического обслуживания;
  • warn: журнал предупреждений, общая ошибка, мало влияет на бизнес, но требуетсязабота о развитии;
  • info: информационный журнал, в который записывается ключевая информация для устранения неполадок, такая как время звонка, входные и выходные параметры и т.д.;
  • отладка: данные времени выполнения в ключевой логике для разработки DEBUG;
  • трассировка: самая подробная информация, как правило, эта информация записывается только в лог-файл.

2. В логе должны быть распечатаны входные и выходные параметры метода

Нам не нужно печатать много журналов, нам просто нужно распечататьЭффективные журналы для быстрого обнаружения проблем. Эффективное бревно — мощный инструмент для сброса банка!

Что считаетсяДействующий ключбревно? Например, когда приходит метод, напечатайтеВход. И затем, когда метод возвращается, этораспечатать параметры, возвращаемое значение. В случае с женьшенем, как правило,ключ, такой как userId или bizSeqИнформация. Например:

public String testLogMethod(Document doc, Mode mode){
   log.debug(“method enter param:{}”,userId);
   String id = "666";
   log.debug(“method exit param:{}”,id);
   return id;
}

3. Выберите подходящий формат журнала

Идеальный формат журнала должен включать самую основную информацию: например, когдапредыдущая отметка времени(нормальная миллисекундная точность),уровень журнала,имя темыи Т. Д. Логбэк-лог можно настроить следующим образом:

<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> 

Если наш формат журнала не записывает даже текущее время, тоЯ даже не знаю время запроса.?

4. При возникновении таких условий, как if...else..., попробуйте распечатать журнал в первой строке каждой ветки.

когда вы сталкиваетесьесли...иначе...или переключитьсяПри таких условиях лог можно распечатать на первой строке ветки, чтобы при устранении неполадок можно было по логу определить, в какую ветку вы вошли, логика кода понятнее, да и устранять неполадки удобнее .

Положительный пример:

if(user.isVip()){
  log.info("该用户是会员,Id:{},开始处理会员逻辑",user,getUserId());
  //会员逻辑
}else{
  log.info("该用户是非会员,Id:{},开始处理非会员逻辑",user,getUserId())
  //非会员逻辑
}

5. Когда уровень журнала относительно низкий, выполните оценку переключения журнала.

Для более низких уровней журнала, таких как трассировка/отладка, необходимо выполнить оценку переключения уровня журнала.

Положительный пример:

User user = new User(666L, "公众号", "捡田螺的小男孩");
if (log.isDebugEnabled()) {
    log.debug("userId is: {}", user.getId());
}

Потому что в настоящее время есть следующий код журнала:

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

еслиНастроенный уровень журнала — предупреждение, приведенный выше журнал не будет распечатан, но будет выполнена операция конкатенации строк, еслиsymbolявляется объектом, также будет выполнятьtoString()метод тратит системные ресурсы, выполняет вышеуказанные операции, но окончательный журнал не печатается, поэтому рекомендуетсяДобавить решение о переключении журнала.

6. API в системе логирования (Log4j, Logback) нельзя использовать напрямую, но можно использовать API в фреймворке логирования SLF4J.

SLF4J — это платформа ведения журналов в фасадном режиме, которая способствует унификации методов обслуживания и обработки журналов различных классов и может легко заменить базовую структуру ведения журналов без изменения кода.

Положительный пример:

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

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

7. Рекомендуется использовать заполнитель параметра {} вместо сплайсинга +.

Пример счетчика:

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

В приведенном выше примере используйте+Оператор выполняет конкатенацию строк, существуют определенныепотеря производительности.

Например:

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

мы использовали фигурные скобки{}в качестве заполнителя в журнале вместо использования+оператор, который является более элегантным и лаконичным. и,относительно контрпримера, использование заполнителей — это только замещающее действие, которое может эффективно повысить производительность.

8. Рекомендуется использовать асинхронный способ вывода логов.

  • Журнал в конечном итоге будет выведен в файл или другой поток вывода, и потребуется производительность ввода-вывода. Если он асинхронный, он может значительно повысить производительность ввода-вывода.
  • Если нет особых требований, рекомендуется использовать асинхронный способ вывода журнала. Возьмем в качестве примера logback, настроить асинхронность очень просто, просто используйте AsyncAppender
<appender name="FILE_ASYNC" class="ch.qos.logback.classic.AsyncAppender">
    <appender-ref ref="ASYNC"/>
</appender>

9. Не используйте e.printStackTrace()

Пример счетчика:

try{
  // 业务代码处理
}catch(Exception e){
  e.printStackTrace();
}

Положительный пример:

try{
  // 业务代码处理
}catch(Exception e){
  log.error("你的程序有异常啦",e);
}

причина:

  • Журнал стека, распечатываемый e.printStackTrace(), перемежается с журналом бизнес-кода, и обычно неудобно проверять ненормальный журнал.
  • Строка, сгенерированная оператором e.printStackTrace(), записывает информацию о стеке.Если информация слишком длинная, в блоке памяти, где находится пул строковых констант, нет места, то есть память заполнена, то запрос пользователя будет застрять~

10. Не просто введите половину журнала исключений, а выведите все сообщения об ошибках

Противоположный пример 1:

try {
    //业务代码处理
} catch (Exception e) {
    // 错误
    LOG.error('你的程序有异常啦');
} 

  • Ни одно из исключений e не печатается, поэтому неизвестно, какой тип исключения был сгенерирован.

Противоположный пример 2:

try {
    //业务代码处理
} catch (Exception e) {
    // 错误
    LOG.error('你的程序有异常啦', e.getMessage());
} 
  • e.getMessage()Подробная информация об исключении стека не будет записана, будет записана только информация об основном описании ошибки, что не способствует устранению неполадок.

Положительный пример:

try {
    //业务代码处理
} catch (Exception e) {
    // 错误
    LOG.error('你的程序有异常啦', e);
} 

11. Запрещено включать отладку в онлайн-среде

Очень важно отключить отладку в онлайн-среде.

Поскольку в общей системе много журналов отладки, а различные платформы также часто используют журналы отладки, онлайн-отладка может вскоре заполнить диск, что повлияет на нормальную работу бизнес-системы.

12. Не логируйте исключения и не выбрасывайте их снова

Обратное выглядит следующим образом:

log.error("IO exception", e);
throw new MyException(e);
  • Эта реализация обычно печатает информацию о стеке дважды. Это связано с тем, что при перехвате MyException оно будет напечатано снова.
  • Такое логирование, или обертывание с последующим выбрасыванием, не используйте и то, и другое! В противном случае ваши журналы будут выглядеть запутанными.

13. Избегайте повторной печати журналов

Избегайте повторной печати журнала, Jiangzi будет тратить место на диске. Если у вас уже есть строка журнала, которая ясно выражает смысл,Избегайте избыточной печати, наоборот:

if(user.isVip()){
  log.info("该用户是会员,Id:{}",user,getUserId());
  //冗余,可以跟前面的日志合并一起
  log.info("开始处理会员逻辑,id:{}",user,getUserId());
  //会员逻辑
}else{
  //非会员逻辑
}

Если вы используете структуру ведения журналов log4j, обязательноlog4j.xmlУстановите additivity=false в , чтобы избежать повторной печати журнала.

Положительный пример:

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

14. Разделение файла журнала

  • Мы можем разделить разные типы журналов, например, access.log или error.log уровня ошибок, которые можно распечатать в файл отдельно.
  • Конечно, его также можно распечатать в разные файлы журналов в соответствии с разными бизнес-модулями, чтобы нам было удобнее устранять проблемы и вести статистику данных.

15. Для основных функциональных модулей рекомендуется распечатать более полный журнал

  • В нашей повседневной разработке, если ядром или логикой является сложный код, рекомендуется добавлять подробные комментарии и более подробные журналы.
  • Насколько подробным должен быть журнал? Подумайте об этом, если в вашей основной программе есть ошибка, вы можете найти ее через журнал, тогда вы сможете.