我正在尝试使用Grails 2.4.3上的JDBCAppender设置log4j,我尝试使用H2,MySQL和PostgreSQL,但它会为每个驱动程序抛出一个ClassNotFoundException异常。
我测试了用户和密码凭据信息,我的意思是,我可以通过Datasource.groovy文件连接到这些数据库。
log4j = {
appenders {
jdbc name: "db",
databaseURL: "jdbc:h2:mem:devDb;MVCC=TRUE;LOCK_TIMEOUT=10000;DB_CLOSE_ON_EXIT=FALSE",
user: "sa",
password: "",
driverClassName: "org.h2.Driver",
sql: "INSERT INTO event_log (log_date, log_message) VALUES ('%d{yyyy.MM.dd HH:mm:ss}', '[%-5p]. Category: %c. Message: %m. User: %X{sessionUserName} DU:[%X{sessionUserDU}]');"
}
root {
info 'grails.app.controller','db'
}
}
log4j = {
appenders {
jdbc name: "db",
URL: "jdbc:postgresql://localhost/grailsTestDB",
user: "userDB",
password: "*******",
driver: "org.postgresql.Driver",
layout: pattern(conversionPattern: "[%t] %-5p %c{2} %x - %m%n - %X{username}'"),
sql: "INSERT INTO event_log (accion,nivel,req,logString,usuario) VALUES('%c{2} %x','%-5p','[%t]','%m%n','%X{username}');"
}
root {
info 'grails.app.controller','db'
}
}
下一个代码来自Grails 1.3.8应用程序,在该应用程序中,此代码可以正常工作。
log4j = {
appenders {
appender new JDBCAppender(
name: "db",
databaseURL: "jdbc:mysql://dbdevsie.db.hostname.com/dbdevsie",
driver: "com.mysql.jdbc.Driver",
user: "dbdevsie231",
password: "********",
layout: pattern(conversionPattern: "[%t] %-5p %c{2} %x - %m%n - %X{username}'"),
sql: "INSERT INTO activity_log (accion,nivel,req,logString,usuario) VALUES('%c{2} %x','%-5p','[%t]','%m%n','%X{username}');"
)
}
root {
info 'grails.app.controller','db'
}
}
dependencies {
runtime 'mysql:mysql-connector-java:5.1.29'
runtime 'org.postgresql:postgresql:9.3-1101-jdbc41'
test "org.grails:grails-datastore-test-support:1.0-grails-2.4"
}
当我测试h2时,它会抛出com.mysql.jdbc.Driver异常。
当我测试Mysql时,会抛出sun.jdbc.odbc.JdbcOdbcDriver异常。
当我测试Postgresql时,它会抛出org.postgresql.Driver异常。
| Error log4j:ERROR Failed to load driver
| Error java.lang.ClassNotFoundException: sun.jdbc.odbc.JdbcOdbcDriver
| Error at java.net.URLClassLoader$1.run(URLClassLoader.java:366)
| Error at java.net.URLClassLoader$1.run(URLClassLoader.java:355)
| Error at java.security.AccessController.doPrivileged(Native Method)
| Error at java.net.URLClassLoader.findClass(URLClassLoader.java:354)
| Error at java.lang.ClassLoader.loadClass(ClassLoader.java:425)
| Error at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:308)
| Error at java.lang.ClassLoader.loadClass(ClassLoader.java:358)
| Error at java.lang.Class.forName0(Native Method)
| Error at java.lang.Class.forName(Class.java:191)
| Error at org.apache.log4j.jdbc.JDBCAppender.setDriver(JDBCAppender.java:391)
| Error at org.apache.log4j.jdbc.JDBCAppender.getConnection(JDBCAppender.java:248)
| Error at org.apache.log4j.jdbc.JDBCAppender.execute(JDBCAppender.java:215)
| Error at org.apache.log4j.jdbc.JDBCAppender.flushBuffer(JDBCAppender.java:289)
| Error at org.apache.log4j.jdbc.JDBCAppender.append(JDBCAppender.java:186)
| Error at org.apache.log4j.AppenderSkeleton.doAppend(AppenderSkeleton.java:251)
我还测试下载log4j 1.2.17,PostgreSQL 9.3和MySQL 5.1.34 jar文件并将它们放在lib文件夹中,但我的结果相同。
有人可以帮我解决这个问题吗?
提前感谢。
此问题在Mac OS中显示,但我在linux中运行相同的代码并且没有问题。
答案 0 :(得分:1)
使用DSL而不是实例化内联的appender是正确的;当您的代码在Config.groovy中运行时,依赖关系和类路径尚未得到解决,因此您需要一些方法来延迟appender的实际初始化,直到发生这种情况并且DSL配置是一个不错的选择。
我有这个工作,但有不同的失败。在我的情况下,H2和MySQL在早期可靠地崩溃了我的1.7 JVM,但是当我切换到1.8时它起作用,现在它甚至在删除了几乎所有东西之后也工作在1.7。尝试通过注释掉这些配置更改来独立解析依赖项,然后在启用它们的情况下重新启动。这也可能是由于分叉 - 我几乎总是通过删除BuildConfig.groovy中的整个grails.project.fork
块来禁用它 - 如果没有其他工作,看看是否有帮助。
这就是我在Config.groovy
中所拥有的:
log4j.main = {
appenders {
jdbc name: 'jdbcAppender', driver: 'com.mysql.jdbc.Driver', user: '...',
password: '...', URL: 'jdbc:mysql://localhost/<dbname>',
layout: pattern(conversionPattern:
"insert into logs(log_date, logger, log_level, message) " +
"values('%d{yyyy-MM-dd HH:mm:ss}','%c','%p','%m')")
}
root {
info 'stdout', 'jdbcAppender'
}
error 'org.codehaus.groovy.grails',
'org.springframework',
'org.hibernate',
'net.sf.ehcache.hibernate'
}
我创建了这个表来登录:
create table logs (
log_date datetime not null,
log_level varchar(10) not null,
logger varchar(100) not null,
message varchar(1000) not null
) ENGINE=InnoDB;
答案 1 :(得分:0)
我们使用了一个解决方法,其中我们使用了dataSource作为jdbc appender
在Datasource.groovy中添加日志数据源:
dataSource_log {
url = "jdbc:sqlserver://DBServer:1433;databaseName=Logs;integratedSecurity=true"
dialect = "org.hibernate.dialect.SQLServerDialect"
driverClassName = "com.microsoft.sqlserver.jdbc.SQLServerDriver"
}
然后覆盖JDBCAppender获取其连接的位置
public class DataSourceAppender extends JDBCAppender {
SessionFactory sessionFactory;
protected java.sql.Connection getConnection() throws java.sql.SQLException {
SessionImplementor imp = (SessionImplementor) sessionFactory.getCurrentSession();
return imp.getJdbcConnectionAccess().obtainConnection();
}
}
在Bootstrap.groovy中将此自定义appender添加到log4j:
def grailsApplication
def sessionFactory_log
def init = { servletContext ->
def sqlAppender = new DataSourceAppender(
grailsApplication.config.dataSourceAppender
)
sqlAppender.sessionFactory = sessionFactory_log
Logger.getRootLogger().addAppender(sqlAppender)
}
虽然愿意看到真正的解决方案。