Oliver,

I'd be interested in seeing the code that implements this -- I'm still a little vague on how some of the interfaces interact.
I'll first make some comments on your JDBCAppender and at the end I'll talk a little about how I put mine together.

Question:
What happens to the connection the JDBCConnectionHandler passes?  Is it held, closed, ...?

Plusses:
I really like that you can read a table definition and build an appropriate SQL statement.
I like the column definition stuff.

Minuses:
It seems rather more complicated than necessary (compare with my JDBCAppender) though I could be missing some vital functionality that I don't use.
I don't see any mechanism for making use of a connection pool.
Splitting up the LoggingEvent message into different columns isn't possible without source code -- you'd have to override JDBCAppender.append(LoggingEvent event) which is sufficiently central that you'll need to read the source in order to not lose functionality.

Suggestions:
Would it make sense to roll JDBCLogger into the Appender?
Change some of the Exception throws to SQLException throws where appropriate.
Have an getSQL(LoggingEvent event) call that can be overriden to mutate the SQL statement based on the event.*
Add putConnection(java.sql.Connection con) to JDBCConnectionHandler to allow it to handle the connection after use.
Have JDBCConnectionHandler execute the SQL -- replace the getConnection methods with executeSQL(String sql)
Remove JDBCConnectionHandler entirely, and let subclasses of JDBCLogger/JDBCAppender handle proper connection handling and statement execution.

My stuff:
I assumed from the beginning that everyone will have a different schema for log events in their database and in particular that information about the event may going in different columns or tables (one column for the message, one for the thread name, one for stack trace, etc.)  Additionally many developers will have different ways of accessing the database -- through JDBC wrappers, application servers, EJBs -- and that source for the access classes may not be availible (making adding interface implementations impossible or requiring an annoying little wrapper).  My solution to this was to assume that the appender will be subclassed to provide those parts of the implementation.  Then the JDBCAppender tries to make it's subclasses very easy to write (only overriding the two environment specific methods).  I also wanted to provide a default implementation that would work "out of the box", so I decided on calling a stored procedure which can be written by the deployer.  I think that this method is a lot simpler than yours, and a bit more flexible in some areas.  It's also missing a lot of good functionality that you have, and the ability to figure out a table.

* about events -- in log4j 1.1 the Appender and Layout will have access to the original object sent to the Category.  An override of getSQL will be able to make good use of this feature.  For example I plan to generate SQL based on the class of the object sent -- regular log events go into LogTable, audit events go into LogTable + AuditOld + AuditNew, etc. -- so it's important to allow the sql to be generated dynamically.

Kevin
 
 

"Komoll, Oliver" wrote:

 Hi,we have also build an JDBC-Appender for our  project (its not the final release - but i think its good for a discussion)You will find the javadoc under http://support.klopotek.de/log4j/jdbc/index.htmlAnybody is invited to discuss about the interface. Also, if its helpfull, it can be integrated to log4jOliver Oliver KomollKlopotek & Partner GmbHE-Commerce

Reply via email to