Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Logback dbAppender Custom SQL

Is there a way to change the tables that logback writes its data to using the dbAppender, It has three default tables that must be created before using dbAppender, but I want to customise it to write to one table of my choosing. Something similar to Log4J where I can specify the SQL that gets executed when inserting the log to the database.

like image 885
Magezy Avatar asked May 20 '26 22:05

Magezy


2 Answers

Tomasz, maybe I'm missing something but I don't see how just using custom DBNameResolver could be the answer to what Magezy asked. DBNameResolver is used by DBAppender via SQLBuilder to construct 3 SQL insert querys - via DBNameResolve one can only affect names of tables and columns where data will be inserted, but can not limit inserting to just one table, not to mention that by just implementing DBNameResolver there are no means to control what actually gets inserted.

To match log4j's JDBCAppender IMO one has to extend logback's DBAppender, or DBAppenderBase, or maybe even implement completely new custom Appender.

like image 79
Stevo Slavić Avatar answered May 22 '26 15:05

Stevo Slavić


The easiest way for me was to make an appender from scratch. I'm appending to a single table, using Spring JDBC. It works something like this:

public class MyAppender extends AppenderBase<ILoggingEvent>
{
  private String _jndiLocation;
  private JDBCTemplate _jt;

  public void setJndiLocation(String jndiLocation)
  {
    _jndiLocation = jndiLocation;
  }

  @Override
  public void start()
  {
    super.start();

    if (_jndiLocation == null)
    {
      throw new IllegalStateException("Must have the JNDI location");
    }
    DataSource ds;
    Context ctx;
    try
    {
      ctx = new InitialContext();
      Object obj = ctx.lookup(_jndiLocation);
      ds= (DataSource) obj;

      if (ds == null)
      {
        throw new IllegalStateException("Failed to obtain data source");
      }
      _jt = new JDBCTemplate(ds);
    }
    catch (Exception ex)
    {
      throw new IllegalStateException("Unable to obtain data source", ex);
    }

  }

  @Override
  protected void append(ILoggingEvent e)
  {
    // log to database here using my JDBCTemplate instance
  }
}

I ran into trouble with SLF4J - the substitute logger error described here: http://www.slf4j.org/codes.html#substituteLogger

This thread on multi-step configuration enabled me to work around that issue.

like image 38
Paul Avatar answered May 22 '26 13:05

Paul