1 В избранное 0 Ответвления 0

OSCHINA-MIRROR/xsxgit-slf4j-spring-boot-starter

Присоединиться к Gitlife
Откройте для себя и примите участие в публичных проектах с открытым исходным кодом с участием более 10 миллионов разработчиков. Приватные репозитории также полностью бесплатны :)
Присоединиться бесплатно
Клонировать/Скачать
Внести вклад в разработку кода
Синхронизировать код
Отмена
Подсказка: Поскольку Git не поддерживает пустые директории, создание директории приведёт к созданию пустого файла .keep.
Loading...
README.md

slf4j-spring-boot-starter

Введение

Компонент, который упрощает работу с логированием, используя аннотации. Помогает избежать необходимости писать код для логирования в разных местах. Также позволяет определять местоположение кода.

Архитектура программного обеспечения

Зависит от spring-boot-starter-aop.

Принцип работы

AOP + Reflect.

Область применения

Любые методы, вызываемые из spring.

Текущая версия 1.4.10.

Инструкция по установке

mvn clean install

Использование

1. Подготовка

  1. Добавьте зависимость:
<dependency>
    <groupId>wiki.xsx</groupId>
    <artifactId>slf4j-spring-boot-starter</artifactId>
    <version>1.4.10</version>
</dependency>
  1. Включите логирование:

yml:

logging:
  level:
    wiki.xsx.core: 对应级别
  # 日志组件配置(按需配置)
  slf4j:
   # 全局综合日志级别
   global-log-level: debug
   # 全局综合日志代码定位
   global-log-position: unknown
   # 全局综合日志格式化
   global-log-formatter: wiki.xsx.core.log.DefaultLogFormatter
   # 全局综合日志回调
   global-log-callback: wiki.xsx.core.log.VoidLogCallback
   # 全局参数日志级别
   global-param-log-level: debug
   # 全局参数日志代码定位
   global-param-log-position: unknown
   # 全局参数日志格式化
   global-param-log-formatter: wiki.xsx.core.log.DefaultParamLogFormatter
   # 全局参数日志回调
   global-param-log-callback: wiki.xsx.core.log.VoidLogCallback
   # 全局结果日志级别
   global-result-log-level: debug
   # 全局结果日志代码定位
   global-result-log-position: unknown
   # 全局结果日志格式化
   global-result-log-formatter: wiki.xsx.core.log.DefaultResultLogFormatter
   # 全局结果日志回调
   global-result-log-callback: wiki.xsx.core.log.VoidLogCallback
   # 全局异常日志回调
   global-throwing-log-callback: wiki.xsx.core.log.VoidLogCallback

properties:

logging.level.wiki.xsx.core=对应级别
# 日志组件配置(按需配置)
# 全局综合日志级别 
logging.slf4j.global-log-level=debug
# 全局综合日志代码定位
logging.slf4j.global-log-position=unknown
# 全局综合日志格式化
logging.slf4j.global-log-formatter=wiki.xsx.core.log.DefaultLogFormatter
# 全局综合日志回调
logging.slf4j.global-log-callback=wiki.xsx.core.log.VoidLogCallback
# 全局参数日志级别 
logging.slf4j.global-param-log-level=debug
# 全局参数日志代码定位
logging.slf4j.global-param-log-position=unknown
# 全局参数日志格式化
logging.slf4j.global-param-log-formatter=wiki.xsx.core.log.DefaultParamLogFormatter
# 全局参数日志回调
logging.slf4j.global-param-log-callback=wiki.xsx.core.log.VoidLogCallback
# 全局结果日志级别 
logging.slf4j.global-result-log-level=debug
# 全局结果日志代码定位
logging.slf4j.global-result-log-position=unknown
# 全局结果日志格式化
logging.slf4j.global-result-log-formatter=wiki.xsx.core.log.DefaultResultLogFormatter
# 全局结果日志回调
logging.slf4j.global-result-log-callback=wiki.xsx.core.log.VoidLogCallback
# 全局异常日志回调
logging.slf4j.global-throwing-log-callback=wiki.xsx.core.log.VoidLogCallback

2. Начало использования (в режиме DEBUG)

Пример использования @ParamLog:
  1. Маркировка с помощью аннотаций:
@RestController
public class TestParamLogController {

    @ParamLog(value = "ParamLog-test1")
    @GetMapping("/paramLogTest1")
    public Map<String, Object> logTest1(HttpServletRequest request, Map<String, Object> param) {
        Map<String, Object> result = new HashMap<>(3);
        result.put("code", 200);
        result.put("msg", "success");
        result.put("data", param);
        return result;
    }

    @ParamLog(value = "ParamLog-test2", paramFilter = {"request"})
    @GetMapping("/paramLogTest2")
    public Map<String, Object> logTest2(HttpServletRequest request, Map<String, Object> param) {
        Map<String, Object> result = new HashMap<>(3);
        result.put("code", 200);
        result.put("msg", "success");
        result.put("data", param);
        return result;
    }

    @ParamLog(value = "ParamLog-test3", paramFilter = {"request"}, callback = LogTestCallback.class)
    @GetMapping("/paramLogTest3")
    public Map<String, Object> logTest3(HttpServletRequest request, List<Object> param) {
        Map<String, Object> result = new HashMap<>(3);
        result.put("code", 200);
        result.put("msg", "success");
        result.put("data", param);
``` 1. **Аннотация @ResultLog**:

* Пример использования аннотации для маркировки методов контроллера:

    * *@RestController*  аннотация, которая помечает класс как контроллер;

    * *public class TestResultLogController*  класс контроллера;

    * *value = «ResultLog-test1»*  значение ключа аннотации, которое будет использоваться при логировании;

    * *@GetMapping(«/resultLogTest1»)*  метод контроллера, который принимает запросы на получение данных с адреса /resultLogTest1;

    * *Map<String, Object> logTest1(HttpServletRequest request, Map<String, Object> param)*  метод, в котором происходит обработка запроса и формирование ответа;

    * *return result;*  возврат сформированного ответа.

* Второй метод контроллера:

    * *@ResultLog(value = «ResultLog-test2», callback = LogTestCallback.class)*  использование аннотации с указанием значения ключа и класса, реализующего интерфейс *LogCallback*.

2. **Интерфейс LogCallback**:

* *public interface LogCallback*  интерфейс, который определяет метод *callback* для обработки логов;

* *void callback(Annotation annotation, MethodInfo methodInfo, Map<String, Object> paramMap, Object result)*  метод интерфейса, который получает информацию о методе, параметрах и результате выполнения метода и выводит сообщение в лог.

3. **Тестирование**:

* В данном разделе представлен тестовый класс *TestResultLogControllerTest*, который проверяет работу методов контроллера *logTest1* и *logTest2*.

4. **Пример вывода логов**:

В этом разделе представлены примеры сообщений из лога, которые содержат информацию о вызовах методов *logTest1*, *logTest2* и *logTest3*.

5. **@ResultLog**  пример использования:

* Представлен пример использования аннотации *@ResultLog* для методов контроллера.

Это перевод исходного текста. Если у вас есть дополнительные вопросы или уточнения, пожалуйста, дайте мне знать. **Перевод текста на русский язык:**

#####

4. Эффект печати журнала:

2020-01-16 22:09:15.873 DEBUG 9280 --- [ main] wiki.xsx.core.log.LogProcessor : Вызов метода: [wiki.xsx.log.controller.TestResultLogController.logTest1(TestResultLogController.java:23)], название бизнес-операции: [ResultLog-test1], результат возврата: [{msg=success, data={key1=hello-world, key2=11, key3=11.11, key4=[hello, world], key5=[111, 112, 113]}, code=200}] 2020-01-16 22:09:15.874 DEBUG 9280 --- [ main] wiki.xsx.core.log.LogProcessor : Вызов метода: [wiki.xsx.log.controller.TestResultLogController.logTest2(TestResultLogController.java:33)], название бизнес-операции: [ResultLog-test2], результат возврата: [{msg=success, data=[test-list, {key1=hello-world, key2=11, key3=11.11, key4=[hello, world], key5=[111, 112, 113]}], code=200}] 2020-01-16 22:09:15.874 INFO 9280 --- [ main] wiki.xsx.log.controller.LogTestCallback : Метод wiki.xsx.log.controller.TestResultLogController.logTest2 успешно выполнил функцию обратного вызова


##### Пример аннотации @ThrowingLog:

1. Маркировка аннотацией журнала:
```java
@RestController
public class TestThrowingLogController {

    @ThrowingLog(value = "ThrowingLog-test1")
    @GetMapping("/throwingLogTest1")
    public Map<String, Object> logTest1(HttpServletRequest request, Map<String, Object> param) {
        Map<String, Object> result = new HashMap<>(3);
        result.put("code", 200);
        result.put("msg", "success");
        result.put("data", 1/0);
        return result;
    }

    @ThrowingLog(value = "ThrowingLog-test2", callback = LogTestCallback.class)
    @GetMapping("/throwingLogTest2")
    public Map<String, Object> logTest2(HttpServletRequest request, Map<String, Object> param) {
        Map<String, Object> result = new HashMap<>(3);
        result.put("code", 200);
        result.put("msg", "success");
        result.put("data", 1/0);
        return result;
    }
}
  1. Объявление обратного вызова журнала (реализация интерфейса wiki.xsx.core.log.LogCallback):
// Добавление в контейнер IOC, иначе вызов завершится неудачно
@Component
@Slf4j
public class LogTestCallback implements LogCallback {
    @Override
    public void callback(Annotation annotation, MethodInfo methodInfo, Map<String, Object> paramMap, Object result) {
        log.info(methodInfo.getClassAllName()+"."+methodInfo.getMethodName()+" метод обратного вызова успешно выполнен");
    }
}
  1. Тестирование:
@RunWith(SpringRunner.class)
@SpringBootTest(classes = Application.class)
public class TestThrowingLogControllerTest {

    @Autowired
    private TestThrowingLogController testThrowingLogController;

    @Test
    public void test() {
        List<Object> list = new ArrayList<>(2);
        list.add("test-list");
        Map<String, Object> paramMap = new LinkedHashMap<>(5);
        paramMap.put("key1", "hello-world");
        paramMap.put("key2", 11);
        paramMap.put("key3", 11.11D);
        paramMap.put("key4", new String[]{"hello", "world"});
        paramMap.put("key5", new Number[]{111, 112, 113});
        list.add(paramMap);
        try {
            this.testThrowingLogController.logTest1(null, paramMap);
        }catch (Exception e) {

        }
        try {
            this.testThrowingLogController.logTest2(null, paramMap);
        }catch (Exception e) {

        }
    }
}
  1. Эффект печати журнала:
2020-01-16 22:13:58.226 ERROR 22184 --- [           main] wiki.xsx.core.log.LogProcessor           : Вызов метода: [wiki.xsx.log.controller.TestThrowingLogController.logTest1], название бизнес-операции: [ThrowingLog-test1], информация об ошибке:

java.lang.ArithmeticException: / by zero
...
2020-01-16 22:13:58.227 ERROR 22184 --- [           main] wiki.xsx.core.log.LogProcessor           : Вызов метода: [wiki.xsx.log.controller.TestThrowingLogController.logTest2], название бизнес-операции: [ThrowingLog-test2], информация об ошибке:

java.lang.ArithmeticException: / by zero
...
2020-01-16 22:13:58.228  INFO 22184 --- [           main] wiki.xsx.log.controller.LogTestCallback  : Метод wiki.xsx.log.controller.TestThrowingLogController.logTest2 успешно выполнил функцию обратного вызова
``` **Аннотация @Log: пример использования**

1. **Аннотации для маркировки журнала:**

```java
@RestController
public class TestLogController {

    @Log(value = "Log-test1")
    @GetMapping("/logTest1")
    public Map<String, Object> logTest1(HttpServletRequest request, Map<String, Object> param) {
        Map<String, Object> result = new HashMap<>(3);
        result.put("code", 200);
        result.put("msg", "success");
        result.put("data", param);
        return result;
    }

    @Log(value = "Log-test2", paramFilter = {"request"})
    @GetMapping("/logTest2")
    public Map<String, Object> logTest2(HttpServletRequest request, Map<String, Object> param) {
        Map<String, Object> result = new HashMap<>(3);
        result.put("code", 200);
        result.put("msg", "success");
        result.put("data", param);
        return result;
    }

    @Log(value = "Log-test3", paramFilter = {"request"}, callback = LogTestCallback.class)
    @GetMapping("/logTest3")
    public Map<String, Object> logTest3(HttpServletRequest request, List<Object> param) {
        Map<String, Object> result = new HashMap<>(3);
        result.put("code", 200);
        result.put("msg", "success");
        result.put("data", param);
        return result;
    }
}
  1. Объявление обратного вызова журнала (реализует интерфейс wiki.xsx.core.log.LogCallback):
// 加入IOC容器,否则 вызов не удастся
@Component
@Slf4j
public class LogTestCallback implements LogCallback {
    @Override
    public void callback(Annotation annotation, MethodInfo methodInfo, Map<String, Object> paramMap, Object result) {
        log.info(methodInfo.getClassAllName() + "." + methodInfo.getMethodName() + "метод обратного вызова успешно выполнен");
    }
}
  1. Тестирование:
@RunWith(SpringRunner.class)
@SpringBootTest(classes = Application.class)
public class TestLogControllerTest {

    @Autowired
    private TestLogController testLogController;

    @Test
    public void test() {
        List<Object> list = new ArrayList<>(2);
        list.add("test-list");
        Map<String, Object> paramMap = new LinkedHashMap<>(5);
        paramMap.put("key1", "hello-world");
        paramMap.put("key2", 11);
        paramMap.put("key3", 11.11D);
        paramMap.put("key4", new String[]{"hello", "world"});
        paramMap.put("key5", new Number[]{111, 112, 113});
        list.add(paramMap);
        this.testLogController.logTest1(null, paramMap);
        this.testLogController.logTest2(null, paramMap);
        this.testLogController.logTest3(null, list);
    }
}
  1. Вывод журнала:
2020-01-16 22:16:25.736 DEBUG 8304 --- [           main] wiki.xsx.core.log.LogProcessor           : Вызов метода: [wiki.xsx.log.controller.TestLogController.logTest1 (TestLogController.java:23)], бизнес-имя: [Log-test1], получение параметров: [{request=null, param={key1=hello-world, key2=11, key3=11.11, key4=[hello, world], key5=[111, 112, 113]}}], возврат результата: [{msg=success, data={key1=hello-world, key2=11, key3=11.11, key4=[hello, world], key5=[111, 112, 113]}, code=200}], затраченное время: 50 мс
2020-01-16 22:16:25.744 DEBUG 8304 --- [           main] wiki.xsx.core.log.LogProcessor           : Вызов метода: [wiki.xsx.log.controller.TestLogController.logTest2 (TestLogController.java:33)], бизнес-имя: [Log-test2], получение параметров: [{param={key1=hello-world, key2=11, key3=11.11, key4=[hello, world], key5=[111, 112, 113]}}], возврат результата: [{msg=success, data={key1=hello-world, key2=11, key3=11.11, key4=[hello, world], key5=[111, 112, 113]}, code=200}], затраченное время: 30 мс
2020-01-16 22:16:25.744 DEBUG 8304 --- [           main] wiki.xsx.core.log.LogProcessor           : Вызов метода: [wiki.xsx.log.controller.TestLogController.logTest3 (TestLogController.java:43)], бизнес-имя: [Log-test3], получение параметров: [{параметр=[test-list, {key1=hello-world, key2=11, key3=11.11, key4=[hello, world], key5=[111, 112, 113]}]]}, возврат результата: [{msg=успех, данные=[test-список, {key1=привет-мир, key2=11, key3=11.11, key4=[привет, мир], key5=[111, 112, 113]}], код=200}], затраченное время: 40 мс
2020-01-16 22:16:25.744 INFO 8304 --- [           main] wiki.xsx.log.controller.LogTestCallback  : Метод wiki.xsx.log.controller.TestLogController.logTest3 успешно выполнил обратный вызов
``` **Позиция**: код-позиционирование, по умолчанию DEFAULT.

**paramFilter**: фильтр параметров по имени, по умолчанию {}.

**formatter**: форматирование, для разных типов журналов используются разные реализации (реализация соответствует интерфейсу и должна быть помещена в IOC-контейнер).

**callback**: лог-обратный вызов, по умолчанию VoidLogCallback.class (реализует интерфейс wiki.xsx.core.log.LogCallback и должен быть помещён в IOC-контейнер). 

#### Журналы
1. **DEBUG (по умолчанию)**: уровень отладки.
2. **INFO**: информационный уровень.
3. **WARN**: уровень предупреждения.
4. **ERROR**: уровень ошибки.

#### Описание интерфейса комплексного форматирования журналов
```java
public interface LogFormatter {

    /**
     * Форматирование
     * @param log объект журнала
     * @param level уровень журнала
     * @param busName название бизнес-процесса
     * @param methodInfo информация о методе
     * @param args список параметров
     * @param filterParamNames список фильтруемых параметров
     * @param result результат
     */
    void format(
            Logger log,
            Level level,
            String busName,
            MethodInfo methodInfo,
            Object[] args,
            String[] filterParamNames,
            Object result
    );
}

Описание интерфейса форматирования параметров журнала

public interface ParamLogFormatter {

    /**
     * Форматирование
     * @param log объект журнала
     * @param level уровень журнала
     * @param busName название бизнес-процесса
     * @param methodInfo информация о методе
     * @param args список параметров
     * @param filterParamNames список фильтруемых параметров
     */
    void format(
            Logger log,
            Level level,
            String busName,
            MethodInfo methodInfo,
            Object[] args,
            String[] filterParamNames
    );
}

Описание интерфейса форматирования результатов журнала

public interface ResultLogFormatter {

    /**
     * Форматирование
     * @param log объект журнала
     * @param level уровень журнала
     * @param busName название бизнес-процесса
     * @param methodInfo информация о методе
     * @param result результат
     */
    void format(
            Logger log,
            Level level,
            String busName,
            MethodInfo methodInfo,
            Object result
    );
}

Описание обратного вызова

public interface LogCallback {

    /**
     * Метод обратного вызова
     * @param annotation используемая аннотация
     * @param methodInfo информация о методе
     * @param paramMap словарь параметров
     * @param result результат вызова метода
     */
    void callback(
            Annotation annotation,
            MethodInfo methodInfo,
            Map<String, Object> paramMap,
            Object result
    );
}

Особые указания

  1. Если уровень журнала — DEBUG, то код-позиционирование включается по умолчанию для удобства отладки.

  2. Для других уровней код-позиционирование отключается по умолчанию, чтобы уменьшить ненужные расходы. При необходимости его можно включить вручную (position=Position.ENABLED).

Тестирование производительности (только для справки)

Конфигурация компьютера

CPU AMD Athlon(tm) II X4 640 Processor(3000 Mhz)
Память 8.00 GB (1333 MHz)
Жёсткий диск Apacer A S510S 128GB SATA Disk Device
Инструмент тестирования Apache JMeter 5.1.1
Способ тестирования HTTP-запрос, тест на печать журнала, цикл 5 раз, берётся последний результат

Результаты теста

С включённой функцией позиционирования кода:

Тип журнала Количество параллельных запросов Среднее время одного запроса (мс) Пропускная способность (запросов в секунду)
@ParamLog 1000 136 484
@ResultLog 1000 86 417
@Log 1000 29 425

С отключённой функцией позиционирования кода:

Тип журнала Количество параллельных запросов Среднее время одного запроса (мс) Пропускная способность (запросов в секунду)
@ParamLog 1000 274 491
@ResultLog 1000 66 519
@Log 1000 108 483

Комментарии ( 0 )

Вы можете оставить комментарий после Вход в систему

Введение

Один комментарий определяет компонент журнала, также можно определить местоположение кода. Развернуть Свернуть
Apache-2.0
Отмена

Обновления (2)

все

Участники

все

Недавние действия

Загрузить больше
Больше нет результатов для загрузки
1
https://api.gitlife.ru/oschina-mirror/xsxgit-slf4j-spring-boot-starter.git
git@api.gitlife.ru:oschina-mirror/xsxgit-slf4j-spring-boot-starter.git
oschina-mirror
xsxgit-slf4j-spring-boot-starter
xsxgit-slf4j-spring-boot-starter
master