Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/database/9.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Database Logback dbAppender自定义SQL_Database_Logging_Logback - Fatal编程技术网

Database Logback dbAppender自定义SQL

Database Logback dbAppender自定义SQL,database,logging,logback,Database,Logging,Logback,是否有办法使用dbAppender更改logback将其数据写入的表,它有三个默认表,在使用dbAppender之前必须创建这些表,但我想定制它,将其写入我选择的一个表中。类似于Log4J的东西,我可以指定将日志插入数据库时执行的SQL。您需要实现ch.qos.logback.classic.db.names.dbnamesolver,并在配置中使用它: <appender name="DB" class="ch.qos.logback.classic.db.DBAppender">

是否有办法使用dbAppender更改logback将其数据写入的表,它有三个默认表,在使用dbAppender之前必须创建这些表,但我想定制它,将其写入我选择的一个表中。类似于Log4J的东西,我可以指定将日志插入数据库时执行的SQL。

您需要实现
ch.qos.logback.classic.db.names.dbnamesolver
,并在配置中使用它:

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

Tomasz,也许我遗漏了一些东西,但我不认为仅仅使用自定义DBNameResolver就可以回答Magezy的问题。DBNameResolver由DBAppender通过SQLBuilder来构造3个SQL插入查询-通过DBNameResolver,只能影响将插入数据的表和列的名称,但不能将插入限制为仅一个表,更不用说仅实现DBNameResolver无法控制实际插入的内容


要匹配log4j的JDBCAppender IMO,必须扩展logback的DBAppender或DBAppenderBase,甚至可能实现全新的自定义Appender。

对我来说,最简单的方法就是从头开始制作Appender。我使用SpringJDBC附加到一个表。它的工作原理如下:

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
  }
}
公共类MyAppender扩展AppenderBase
{
私有字符串位置;
私有JDBCTemplate_jt;
公共void setjndLocation(字符串jndLocation)
{
_jndiLocation=jndiLocation;
}
@凌驾
公开作废开始()
{
super.start();
if(_jndLocation==null)
{
抛出新的IllegalStateException(“必须具有JNDI位置”);
}
数据源ds;
上下文ctx;
尝试
{
ctx=新的InitialContext();
Object obj=ctx.lookup(_jndlocation);
ds=(数据源)obj;
如果(ds==null)
{
抛出新的IllegalStateException(“未能获取数据源”);
}
_jt=新JDBCTemplate(ds);
}
捕获(例外情况除外)
{
抛出新的IllegalStateException(“无法获取数据源”,ex);
}
}
@凌驾
受保护的空附加(ILOGINGEVENT e)
{
//在此使用我的JDBCTemplate实例登录到数据库
}
}
我遇到了SLF4J的问题-此处描述的替代记录器错误:

使我能够解决这个问题。


<appender name="CUSTOM_DB_APPENDER" class="com.....MyDbAppender">
        <filter class="com......MyFilter"/>
        <param name="jndiLocation" value="java:/comp/env/jdbc/....MyPath"/> 
</appender>
java MyDbAppender应该有一个带有setter的字符串jndiLocation。
现在进行jndi查找(参见10月17日11时16分03分回答的解决方案)

Hi的可能重复,谢谢您的回答,您知道在哪里有实现此功能的示例吗,我已经实现了DBNameresolver,但我不确定这些方法采用了什么以及它们返回了什么。默认情况下,此类采用
ch.qos.logback.classic.db.names.ColumnName的一个实例,并返回每个枚举值的名称。查看Logback分发中的两个可用实现。请提交问题以记录此功能。