开发者

Logback dbAppender Custom SQL

开发者 https://www.devze.com 2023-04-10 15:07 出处:网络
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

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开发者_JAVA百科 executed when inserting the log to the database.


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.


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.


You need to implement ch.qos.logback.classic.db.names.DBNameResolver and use it in the configuration:

<appender name="DB" class="ch.qos.logback.classic.db.DBAppender">
  <dbNameResolver class="com.example.MyDBNameResolver"/>
  <!-- ... -->
</appender>


<appender name="CUSTOM_DB_APPENDER" class="com.....MyDbAppender">
        <filter class="com......MyFilter"/>
        <param name="jndiLocation" value="java:/comp/env/jdbc/....MyPath"/> 
</appender>

And your java MyDbAppender should have a string jndiLocation with setter. Now do a jndi lookup (see the solution answered in Oct 17 '11 at 16:03)

0

精彩评论

暂无评论...
验证码 换一张
取 消