Log4j JDBCAppender для регистрации трассировки стека - PullRequest
2 голосов
/ 18 июля 2011

Используя org.apache.log4j.jdbc.JDBCAppender, как я могу получить трассы, зарегистрированные с warn и error в PatternLayout.

Я регистрируюсь как

logger.warn("warning description", e);
logger.error("error description", e);

Я получаю описания String в таблицу, но теперь находится стековая трассировка Throwable. Есть ли другой параметр, к которому я могу получить доступ через PatternLayout. В настоящее время я использую

"INSERT INTO app_logs (app, log_date, log_level, location, loc, message) VALUES ('my-apps-name', '%d{ISO8601}','%p', '%C.java', '%C{1}.java:%L', '%m')" 

в стол

TABLE `app_logs` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `app` varchar(255) DEFAULT NULL,
  `log_date` varchar(255) DEFAULT NULL,
  `log_level` varchar(255) DEFAULT NULL,
  `location` varchar(255) DEFAULT NULL,
  `loc` varchar(255) DEFAULT NULL,
  `message` text, 
  PRIMARY KEY (`id`)
)

Ответы [ 4 ]

11 голосов
/ 18 июля 2011

Я нашел решение.

Заменить класс PatternLayout на класс EnhancedPatternLayout.

org.apache.log4j.EnhancedPatternLayout

Вам также необходимо включить зависимость apache-log4j-extra

Или включите его в свой помп :

<dependency>
  <groupId>log4j</groupId>
  <artifactId>apache-log4j-extras</artifactId>
  <version>1.1</version>
</dependency>

Теперь у вас есть доступ к% throwable

%throwable{short} или %throwable{1} выведет первую строку стека след. throwable{none} или throwable{0} будут подавлять трассировку стека. %throwable{n} выведет n строк трассировки стека, если положительное целое число или пропустите последние строки -n, если отрицательное целое число.

Я добавил к своему столу,

TABLE `app_logs` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `app` varchar(255) DEFAULT NULL,
  `log_date` varchar(255) DEFAULT NULL,
  `log_level` varchar(255) DEFAULT NULL,
  `location` varchar(255) DEFAULT NULL,
  `loc` varchar(255) DEFAULT NULL,
  `message` text,
  `throwable` text,
  `stacktrace` text,
  PRIMARY KEY (`id`)
)

И обновил мой шаблон для заполнения этих столбцов.

"INSERT INTO app_logs (app, log_date, log_level, location, loc, message, throwable, stacktrace) VALUES ('my-apps-name', '%d{ISO8601}','%p', '%C.java', '%C{1}.java:%L', '%m', '%throwable{short}', '%throwable{100}')"
3 голосов
/ 08 марта 2013

Чтобы расширить ответ MikeNereson, вот log4j.properties, который работал:

log4j.rootLogger=DEBUG,DB
log4j.appender.DB.driver=com.mysql.jdbc.Driver
log4j.appender.DB=org.apache.log4j.jdbc.JDBCAppender
log4j.appender.DB.URL=jdbc:mysql://server/db
log4j.appender.DB.user=user
log4j.appender.DB.password=pwd
log4j.appender.DB.layout.ConversionPattern=INSERT INTO app_logs (app, log_date, log_level, location, loc, message, throwable, stacktrace) VALUES ('appname', '%d{ISO8601}','%p', '%C.java', '%C{1}.java:%L', '%m', '%throwable{short}', '%throwable{100}')
log4j.appender.DB.layout=org.apache.log4j.EnhancedPatternLayout
log4j.category.ke.co=ERROR
log4j.category.ke.co.appender-ref=DB
3 голосов
/ 21 ноября 2012

Решение заключается в том, что нам нужно использовать макет EnhancedPattern, с помощью которого мы можем записать всю трассировку стека в БД. Но есть одна проблема, если мы используем это, если Stacktrace содержит запятую (,), сообщение не будет зарегистрировано. Я решил эту проблему, переписав getLogStatement (), который доступен в приложении JDBC.

Выполните следующие шаги

  1. Скачать Log4j1.2.17 . Расширенное расположение шаблонов доступно в log41.2.16 ver

  2. Редактировать файл свойств log4j

    log4j.rootLogger = WARN, DB
    log4j.appender.DB=abc.xyz.MyJdbcAppender
    log4j.appender.DB.URL=jdbc:mysql://localhost/DBNAME
    log4j.appender.DB.driver=com.mysql.jdbc.Driver
    log4j.appender.DB.user=user_name
    log4j.appender.DB.password=password
    log4j.appender.DB.layout=org.apache.log4j.EnhancedPatternLayout
    log4j.appender.DB.conversionPattern=Insert into MylogFile(logid,loglevel,logcriteria,message,stacktrace,date) values (mysequence.nextval,’%p’,’%c’,
    ‘%m’,’%throwable{40},’%d{ABSOLUTE}’)
    
  3. Теперь создайте новый класс, который будет расширять JDBCappender и перезаписывать getLogStatement():

    Public MyJdbcAppender extends JDBCAppender{
    protected String getLogStatement(LoggingEvent event) {
    if(null!=event.getThrowableInformation() && event.getThrowableInformation().getThrowable() instance of SQLException){
    SQLException myexce= new SQLException(event.
    getThrowableInformation().getThrowable().getMessage().
    replaceAll(“’”,” “),event.getThrowableInformation().getThrowable());
      LoggingEvent clone = new LoggingEvent(
        event.fqnOfCategoryClass,
        LogManager.getLogger(event.getLoggerName()),
        event.getLevel(),
    event.getLevel(),event.getMessage(),myexce); 
     return getLayout().format(clone);
    }
    return getLayout().format(event)
    }
    }
    
2 голосов
/ 10 января 2013

log4j 1.2.16+ EnhancedPatternLayout не работает! потому что он расширяет org.apache.log4j.Layout, а не org.apache.log4j.PatternLayout, но в JDBCAppender:

public void setSql(String s) {
    sqlStatement = s;
    if (getLayout() == null) {
        this.setLayout(new PatternLayout(s));
    }
    else {
        ((PatternLayout)getLayout()).setConversionPattern(s);  //Point1
    }
}

Так что, если вы используете JDBCAppender следующим образом:

log4j.appender.JDBC=org.apache.log4j.jdbc.JDBCAppender    
log4j.appender.JDBC.layout=org.apache.log4j.EnhancedPatternLayout
log4j.appender.JDBC.sql=INSERT INTO email_send_error(insert_date, level, location, message, stacktrace) VALUES (now(), '%p', '%C,%L', '%m', '%throwable{short}')

сгенерирует исключение ClassCastException в Point1:

Причина: java.lang.ClassCastException: org.apache.log4j.EnhancedPatternLayout нельзя преобразовать в org.apache.log4j.PatternLayout
в org.apache.log4j.jdbc.JDBCAppender.setSql (JDBCAppender.java:330)



РЕДАКТИРОВАТЬ (после углубленного исследования):
Используйте log4j.appender.JDBC.layout.ConversionPattern вместо log4j.appender.JDBC.sql , избегая выше ClassCastException:

 log4j.appender.JDBC.layout.ConversionPattern=INSERT INTO email_send_error(insert_date, level, location, message, stacktrace) VALUES (now(), '%p', '%C,%L', '%m', '%throwable{short}')

и не забудьте записать выданное исключение в логгер:

logger.error(String errorMsg, Throwabe e); // Dont forget e
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...