Доступ к пользователю сеанса в config.groovy внутри приложений log4j

Я настроил приложения log4j в своем приложении для отправки писем в случае каких-либо исключений.

Код в Config.groovy выглядит следующим образом:

log4j = {
    appenders {
    String currentUrl = grails.serverURL
    String currentEnv = 'Production'
    if (Environment.isDevelopmentMode()) {
        currentEnv = 'Development'
    } else if (currentUrl.indexOf('test') > -1) {
        currentEnv = 'Testing'
    }
    console name: 'stdout', layout: pattern(conversionPattern: '[%r] %c{2} %m%n')
    // if real password is needed, please contact IT department
    def patternLayout = new PatternLayout()
    patternLayout.setConversionPattern("[%r] %c{2} %m%n")
    def mailAppender = new SMTPAppender()
    mailAppender.setSMTPUsername('[email protected]')
    mailAppender.setSMTPPassword('password')
    mailAppender.setFrom("[email protected]")
    mailAppender.setTo("[email protected]")
    mailAppender.setSubject("A log4j error has been generated in the [${currentEnv}] environment.")
    mailAppender.setSMTPHost("smtp.elasticemail.com")
    mailAppender.setSMTPPort(2525)
    mailAppender.setBufferSize(4096)
    mailAppender.setLayout(patternLayout)
    appender name: 'mail', mailAppender

    root {
        error 'stdout', 'mail'
        additivity = true
     }
   }
 }

Я хочу включить в тему текущего пользователя входа в систему, из-за которого возникает ошибка экрана. Я использую плагин безопасности Spring, а версия Grails 1.3.7.

У меня есть следующий код:

def user
grails.plugins.springsecurity.onInteractiveAuthenticationSuccessEvent = { e, appCtx ->
   user = org.abc.com.Person.get(appCtx.springSecurityService.currentUser.id)
}

за пределами log4j и используется экземпляр пользователя в теме, но возвращает значение null.

Есть ли у них какой-либо другой способ получить текущего пользователя в теме.

Любой способ сделать это? Пожалуйста, предложите

Также есть ли способ отправлять почту асинхронно?


person Charu Jain    schedule 27.08.2014    source источник
comment
Конфиг читается один раз при запуске. user изменяется во время выполнения. Итак, если вы хотите отправить имя пользователя по электронной почте, вам следует сделать это во время выполнения (какой-нибудь контроллер или сервис и т. д.)   -  person wwarlock    schedule 27.08.2014
comment
Эти приложения log4j записываются только в файл config.groovy. поэтому нет возможности зайти внутрь контроллера или службы.   -  person Charu Jain    schedule 27.08.2014
comment
Да, я это знаю и писал об этом. Перейдите к своему контроллеру и напишите что-то вроде log.debug "session id: ${sessionId}, user: ${currentUser}". И этот журнал будет отправлен по электронной почте, как вы настроили в Config.groovy   -  person wwarlock    schedule 27.08.2014
comment
ладно, это можно было сделать. Но так как это приложение работает как для обработанных (помеченных try/catch), так и для необработанных исключений. Для обработанных исключений мне нужно написать log.error, чтобы разрешить рассылку. и ваше решение будет работать идеально в этом случае. Но что делать в случае необработанного исключения? Ваше решение потребует, чтобы я обрабатывал исключение везде в коде и везде говорил имя пользователя log.error, чего я не хочу   -  person Charu Jain    schedule 27.08.2014


Ответы (2)


Основываясь на указателе от Джошуа, я нашел замечательную запись в блоге Берта по той же проблеме.

http://burtbeckwith.com/blog/?p=521

Это точный ответ на проблему, которую я искал.

person Charu Jain    schedule 28.08.2014

Ключевым моментом здесь будет использование вложенных диагностических контекстов log4j. В документации для log4j описан ваш вариант использования.

Чтобы проиллюстрировать это, давайте возьмем пример сервлета, доставляющего контент многочисленным клиентам. Сервлет может построить NDC в самом начале запроса перед выполнением другого кода. Контекстной информацией может быть имя хоста клиента и другая информация, присущая запросу...

Перевести это в Grails не так уж сложно. Создайте фильтр, который будет применяться ко всем запросам, заполняет NDC соответствующей информацией before при вызове любого контроллера и действия, а затем очищает его after при вызове.

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

Это правильный способ решения этой проблемы.

person Joshua Moore    schedule 27.08.2014
comment
Спасибо Джошуа за подсказку, я реализовал решение в Grails на основе вашей подсказки. - person Charu Jain; 28.08.2014