You are viewing a plain text version of this content. The canonical link for it is here.
Posted to log4net-dev@logging.apache.org by Cliff Burger <cl...@gmail.com> on 2006/06/21 19:56:09 UTC

Re: [ANN] log4net 1.2.10 Released

Questions about ADONetAppender

I'm considering creating a MSSQLAppender for my company's use, as we are
primarily an MS Shop. General questions:

Is anyone else already working on this?
Are the issues I'm addressing valid?
Should some of the changes I want to make be promoted into the general
purpose ADONetAppender?

Save cost of reflected object creation.
The ADONEt appender appears to create a
System.Data.SqlClient.SqlConnectionobject via reflection each time it
sends the buffer. In my experience,
reflection is a little slow. Given that we use this in non-lossy mode, it
must create a connection using reflection every time a message is sent.
Avoiding this cost requires a  MSSQLAppender in the current implementation.
Are my assumptions about the performance of the Activator correct or
incorrect?

Another option that would work in a ADONETAppender case is to create the
connection object and leave the instance around, using Open / Close rather
than dispose. Object would be disposed would only in "OnClose". Rathering
than incurring costs of creating an object via reflection for each message,
we only incur the cost once, during the creation of the Appender. Does this
run the risk that configurations are changed during a running program, and
not picked up by the appender, or is the appender instance recreated in this
case?

Connection behavior:
ADONetAppender currently creates a new connection object and opens it each
time a buffer is sent. It holds onto the instance and open connection until
1) the logger is "Closed" or 2) A message is sent. It has a somewhat silly
behavior of closing and reopening the connection right before sending the
message - but not closing it after the message is sent. We don't get the
benefit of avoiding cost of re-opening a connection, but also don't get the
benefit of keeping connections closed when not in use.

Option a: The most performant behavior for unpooled connections would be:
Keep the connection object open until the logger is closed. Before a message
is sent, check that the connection is open ... but don't reopen if a
connection object is present and open. This (like the current behavior) is
slightly un-safe if transactions are used ... I've previously had problems
with this appender leaving uncommitted transactions and locking tables.

Option B: The most sensible behavior for pooled connections (and safest)
would be: Open connection, send buffered messages, and close the connection.
This gives fine performance with pooled connections where connection isn't
really reopened/ closed, it's just returned to the pool. This would incur a
performance costs in non-pooled connections, but is no different from
current behavior. Closing the connection ensures that any hanging
transactions are committed or rolled back.

The safe behavior is to use option B - this is also the behavior which will
make our DBA happiest. The best solution might be to control the behavior of
connections via configuration to optimize for pooled / nonpooled scenarios -
but I probably won't take the time for this in my extension of this
appender.

Transaction behavior:
When transactions are used with this appender, it sometimes results in
locking the log table - the transactions were left hanging uncommitted. The
default behavior is to use transactions. I haven't had time to determine
exactly what causes the problem. Given that the risk exists, and when it
occurs the consequences are severe (can't do anything at all with the log
table), I'd like to set the default behavior to NOT use transactions.