Как переопределить имя метода в журнале Logback?

Я пытаюсь реализовать концепцию ведения журнала с помощью АОП, но при печати журнала мне нужно указать собственное имя метода вместо имени по умолчанию.

Обновление (на основе комментариев @glitch):

  • Я использую спецификатор преобразования %M, чтобы указать Logback включать имя метода в каждое событие журнала.

  • Я хочу заменить имя производного метода Logback для некоторых событий журнала, в частности; для событий журнала, выдаваемых моей точкой соединения AOP.

  • Я не хочу писать «фактическое имя метода» где-то еще в журнале событий; Я хочу, чтобы имя метода использовалось и было правильным, то есть представляло исходный метод, а не метод перехвата.


person Ashok Kumar N    schedule 19.10.2017    source источник
comment
Вы ссылаетесь на значение по умолчанию, означает ли это, что вы используете спецификатор преобразования %M в своем шаблоне журнала, чтобы позволить Logback получить имя метода? Вы хотите заменить это для всех событий журнала или только для выбранных событий журнала? Нужно ли его заменять или будет достаточно дополнительного имени метода, записанного где-то еще в сообщении журнала?   -  person glytching    schedule 19.10.2017
comment
Я использую ведение журнала двумя способами: один из них похож на обычное ведение журнала внутри метода и через аспектный АОП. для обычного метода ведения журнала имя печатается правильно, но для aop final Logger logger = LoggerFactory.getLogger(pjp.getSignature().getDeclaringTypeName()); logger.info(AppConstants.METHOD_START_DEBUG_MSG); этот регистратор печатает метод aop вместо точного метода, я использую ProceedingJoinPoint   -  person Ashok Kumar N    schedule 20.10.2017
comment
здесь я могу получить точное имя метода с помощью pjp.getSignature().getName() , но регистратор должен напечатать имя этого метода вместо имени метода aop, если это невозможно, могу ли я переопределить% M с помощью этого метода имя   -  person Ashok Kumar N    schedule 20.10.2017
comment
Что касается моих трех вопросов, я думаю, что ответы таковы: используете ли вы спецификатор преобразования %M в своем шаблоне журнала - - ДА; _Хотите ли вы заменить это для всех событий журнала или только для выбранных событий журнала? - ВЫБРАННЫЕ СОБЫТИЯ ЖУРНАЛА; Нужно ли его заменить или будет достаточно дополнительного имени метода, записанного где-то еще в сообщении журнала - ПОКА ОТВЕТА НЕТ.   -  person glytching    schedule 20.10.2017
comment
@glitch спасибо за ответ и терпение, это именно то, что мне нужно. на 3-й вопрос - ответ: мне нужно заменить имя метода в %M   -  person Ashok Kumar N    schedule 20.10.2017


Ответы (1)


Спецификатор преобразования %M реализован с помощью ch.qos.logback.classic.pattern.MethodOfCallerConverter. Реализация довольно проста:

public String convert(ILoggingEvent le) {
    StackTraceElement[] cda = le.getCallerData();
    if (cda != null && cda.length > 0) {
        return cda[0].getMethodName();
    } else {
        return CallerData.NA;
    }
}

Таким образом, вы можете предоставить собственную реализацию. Что-то вроде этого, пожалуй...

public class CustomMethodOfCallerConverter extends ClassicConverter {

    public String convert(ILoggingEvent le) {
        StackTraceElement[] cda = le.getCallerData();
        if (cda != null && cda.length > 0) {
            if (le.getMDCPropertyMap().containsKey("CUSTOM_METHOD_NAME_KEY")) {
                String methodName = le.getMDCPropertyMap().get("CUSTOM_METHOD_NAME_KEY");
                // remove the MDC entry since we are only using MDC to pass the custom method name into this converter
                le.getMDCPropertyMap().remove("CUSTOM_METHOD_NAME_KEY");
                return methodName;
            } else {
                return cda[0].getMethodName();
            }
        } else {
            return CallerData.NA;
        }
    }
}

... который использует MDC для передачи фактического имени метода из вашей точки соединения. В вашей точке соединения вы должны указать значение MDC перед вызовом регистратора, например.

MDC.put("CUSTOM_METHOD_NAME_KEY", pjp.getSignature().getName()));

Но ... Logback не дает вам возможности объявить свой собственный конвертер. Преобразователи, используемые Logback, объявлены в статическом инициализаторе на ch.qos.logback.classic.PatternLayout, и это не является расширяемым/переопределяемым. Итак, я думаю, что ваши варианты:

  1. Создайте класс ch.qos.logback.classic.pattern.MethodOfCallerConverter в своей собственной кодовой базе, т. е. замените собственный MethodOfCallerConverter Logback своим собственным. Вы можете использовать пример, который я привел выше, и - если вы поместите значение CUSTOM_METHOD_NAME_KEY в MDC перед вызовом регистратора - он будет делать то, что вы хотите.

  2. Продолжайте использовать спецификатор %M, но для перехваченных методов AOP добавьте дополнительный атрибут MDC для отображения фактического имени метода. Это приведет к тому, что имя метода Logback появится во всех выходных данных журнала, а имя метода Actula также появится (если доступно). Например:

    // put the actual method name in MDC
    MDC.put("actualMethodName", pjp.getSignature().getName());
    
    // specify your pattern - in logback.xml - to include the actual method name
    %d{yyyy-MM-dd HH:mm:ss}|[%thread]|%-5level|%logger{36}|%M%X{actualMethodName:-}|%msg%n
    
  3. Прекратите использовать спецификатор %M и регистрируйте все имена методов через MDC. Это приведет к появлению правильного имени метода, но потребует от вас обновления MDC в каждом методе (что звучит довольно неловко). Например:

    // put the actual method name in MDC
    MDC.put("actualMethodName", pjp.getSignature().getName());
    
    // specify your pattern - in logback.xml - to include the actual method name
    %d{yyyy-MM-dd HH:mm:ss}|[%thread]|%-5level|%logger{36}|%X{actualMethodName}|%msg%n
    
person glytching    schedule 20.10.2017
comment
Поскольку Logback не предоставляет ловушку для регистрации вашего собственного спецификатора преобразования %M, вы «расширяете» Logback, имитируя его MethodOfCallerConverter. Этот подход работает, но он нестандартен и может быть ненадежным; если будущая версия Logback изменит имя или пространство имен для MethodOfCallerConverter, вам также придется изменить свою версию MethodOfCallerConverter. Просто надо иметь в виду.... - person glytching; 20.10.2017