I wrote a custom database appender and I just extended AppenderBase<ILoggingEvent>.  In the start() method I get the DataSource from a JNDI lookup.  Since I'm using Spring JDBC under the hood I use the DataSource to instantiate a JDBCTemplate which is used in the append() method.
 
Paul


 
On Sun, Oct 16, 2011 at 7:51 PM, Stevo Slavić <sslavic@gmail.com> wrote:
Hello Logback users,

As subject states, I'm trying to migrate a project from log4j to
logback, and need to replace log4j JDBCAppender.

I've found following related stackoverflow questions:

- http://stackoverflow.com/questions/1364322/log-to-a-database-using-log4j/1366684#1366684
- http://stackoverflow.com/questions/7659837/logback-dbappender-custom-sql

DBAppender is nice, but it's not 1-to-1 replacement for log4j's
JDBCAppender, since it mandates what gets logged, db layout (number of
tables and columns) and thus SQL statements number and layout (number
of and indexes of parameters).

Trying now to implement custom extension of DBAppenderBase to achieve the goal.

It would be great if in the logback DB appender hierarchy was
additional level, before DBAppenderBase which would abstract away just
ConnectionSource related logic, so without subAppend,
secondarySubAppend, or selectEventId.

Also, to support using to-be-append logging event when generating
insert SQL (e.g. using PatternLayout) it would be good if getInsertSQL
would receive ILoggingEvent.

Now when implementing JDBCAppender which extends DBAppenderBase I have
lots of abstract methods "do-nothing" implementations, pattern layout
configured with insert statement SQL and following relevant code:


       protected Layout<ILoggingEvent> layout;

       protected void setLayout(Layout<ILoggingEvent> layout) {
               this.layout = layout;
       }

       protected String getInsertSQL(ILoggingEvent event) {
               return layout.doLayout(event);
       }

       @Override
       public void append(ILoggingEvent eventObject) {
               Connection connection = null;
               try {
                       connection = connectionSource.getConnection();
                       connection.setAutoCommit(false);
                       PreparedStatement insertStatement;

                       insertStatement = connection
                                       .prepareStatement(getInsertSQL(eventObject));

                       int updateCount = insertStatement.executeUpdate();
                       if (updateCount != 1) {
                             addWarn("Failed to insert loggingEvent");
                       }

                       // we no longer need the insertStatement
                       close(insertStatement);
                       insertStatement = null;

                       connection.commit();
               } catch (Throwable sqle) {
                       addError("problem appending event", sqle);
               } finally {
                       DBHelper.closeConnection(connection);
               }
       }



What do you think about improvement requests? Should I log them in JIRA?

Any thoughts on this JDBCAppender replacement? What will be the
penalty for generating insert statement SQL for every logging event
using Layout?

Regards,
Stevo.
_______________________________________________
Logback-user mailing list
Logback-user@qos.ch
http://mailman.qos.ch/mailman/listinfo/logback-user