Sign Up

Sign Up to our social questions and Answers Engine to ask questions, answer people’s questions, and connect with other people.

Have an account? Sign In

Have an account? Sign In Now

Sign In

Login to our social questions & Answers Engine to ask questions answer people’s questions & connect with other people.

Sign Up Here

Forgot Password?

Don't have account, Sign Up Here

Forgot Password

Lost your password? Please enter your email address. You will receive a link and will create a new password via email.

Have an account? Sign In Now

You must login to ask a question.

Forgot Password?

Need An Account, Sign Up Here

Please briefly explain why you feel this question should be reported.

Please briefly explain why you feel this answer should be reported.

Please briefly explain why you feel this user should be reported.

Sign InSign Up

The Archive Base

The Archive Base Logo The Archive Base Logo

The Archive Base Navigation

  • SEARCH
  • Home
  • About Us
  • Blog
  • Contact Us
Search
Ask A Question

Mobile menu

Close
Ask a Question
  • Home
  • Add group
  • Groups page
  • Feed
  • User Profile
  • Communities
  • Questions
    • New Questions
    • Trending Questions
    • Must read Questions
    • Hot Questions
  • Polls
  • Tags
  • Badges
  • Buy Points
  • Users
  • Help
  • Buy Theme
  • SEARCH
Home/ Questions/Q 8242273
In Process

The Archive Base Latest Questions

Editorial Team
  • 0
Editorial Team
Asked: June 7, 20262026-06-07T21:06:40+00:00 2026-06-07T21:06:40+00:00

I have database logging in place using the AdoNetAppender. What I’d like to do

  • 0

I have database logging in place using the AdoNetAppender. What I’d like to do is log the user identity on each log statement. However, I don’t want to use the standard log4net %identity parameter for two reasons:

  1. log4net warn that its extremely slow as it has to look up the context identity.
  2. In some service components the standard identity is a service account but we have already captured the user identity in a variable and I’d like to use that.

I have seen code where some people use the log4net.ThreadContext to add additional properties but I understand that this is ‘unsafe’ due to thread interleaving (and it is also a performance drain).

My approach has been to extend the AdoNetAppenderParameter class thus:

public class UserAdoNetAppenderParameter : AdoNetAppenderParameter
{

    public UserAdoNetAppenderParameter()
    {
        DbType = DbType.String;
        PatternLayout layout = new PatternLayout();
        Layout2RawLayoutAdapter converter = new Layout2RawLayoutAdapter(layout);
        Layout = converter;
        ParameterName = "@username";
        Size = 255;
    }


    public override void Prepare(IDbCommand command)
    {            
        command.Parameters.Add(this);
    }


    public override void FormatValue(IDbCommand command, LoggingEvent loggingEvent)
    {            
        string[] data = loggingEvent.RenderedMessage.Split('~');
        string username = data[0];
        command.Parameters["@username"] = username;
    }

}

and then programmatically add this to the current appender like so:

ILog myLog = LogManager.GetLogger("ConnectionService");
IAppender[] appenders = myLog.Logger.Repository.GetAppenders();
AdoNetAppender appender = (AdoNetAppender)appenders[0];                    

appender.AddParameter(new UserAdoNetAppenderParameter());

myLog.InfoFormat("{0}~{1}~{2}~{3}", userName, "ClassName", "Class Method", "Message");

The intention here is to use a standard format for messages and parse the first part of the string which should always be the username. The FormatValue() method of the custom appender parameter should then use only that part of the string so that it can be written to a separate field in the log database.

My problem is that no log statements are written to the database. Oddly, when debugging, a breakpoint in the FormatValue() method is only hit when I stop the service.

I’ve trawled through loads of stuff relating to this but haven’t yet found any answers.
Has anyone managed to do this, or am I on the wrong trail.
P.S. I’ve also tried extending the AdoNetAppender but it doesnt give you access to set the parameter values.

  • 1 1 Answer
  • 0 Views
  • 0 Followers
  • 0
Share
  • Facebook
  • Report

Leave an answer
Cancel reply

You must login to add an answer.

Forgot Password?

Need An Account, Sign Up Here

1 Answer

  • Voted
  • Oldest
  • Recent
  • Random
  1. Editorial Team
    Editorial Team
    2026-06-07T21:06:42+00:00Added an answer on June 7, 2026 at 9:06 pm

    After some experimentation, I finally got this to work. Ensuring that log4net’s internal logging helped identify the errors and downloading the log4net source code and reviewing the AdoNetAppenderParameter class showed how the FormatValue() method should be used. So, here’s the amended custom appender parameter:

    public class UserAdoNetAppenderParameter : AdoNetAppenderParameter
    {        
    
        public override void FormatValue(IDbCommand command, LoggingEvent loggingEvent)
        {            
            string[] data = loggingEvent.RenderedMessage.Split('~');
            string username = string.Empty;
            if (data != null && data.Length >= 1)
                username = data[0];
    
            // Lookup the parameter
            IDbDataParameter param = (IDbDataParameter)command.Parameters[ParameterName];
    
            // Format the value
            object formattedValue = username;
    
            // If the value is null then convert to a DBNull
            if (formattedValue == null)
            {
                formattedValue = DBNull.Value;
            }
    
            param.Value = formattedValue;
        }
    
    }
    

    And to use this, I add it in the log4net config file like this:

    <parameter type="MyAssembly.Logging.UserAdoNetAppenderParameter, MyAssembly">
     <parameterName value="@username" />
     <dbType value="String" />
     <size value="255" />
     <layout type="log4net.Layout.PatternLayout" value="%message" />  
    </parameter>
    

    And by convention, my log statements will be something like this:

    if (log.IsDebugEnabled)
        log.DebugFormat("{0}~{1}~{2}", username, someOtherParameter, message);
    

    If you look at the class, it uses data[0] as the username, so it is dependant on following the convention. It does, however, get the username into its own parameter and into a separate field in the log database table, without resorting to stuffing it temporarily into the unsafe ThreadContext.

    • 0
    • Reply
    • Share
      Share
      • Share on Facebook
      • Share on Twitter
      • Share on LinkedIn
      • Share on WhatsApp
      • Report

Sidebar

Related Questions

I have a database where the primary user logging into the database has no
I have a database with LDAP login enabled. It works fine when logging in
I have a class that saves logging information to the database (in an NServiceBus
I have a console application that should do best effort logging to a database
I have database application, I want to allow the user to restore the deleted
I have Database with date field. I see the time like: 1900-01-01 13:38:00.000 How
i have database table like this +-------+--------------+----------+ | id | ip | date |
how can I enable database logging in my ASP.net application? I am using VS2010
We have jboss logging enabled in our application. Currently we are using the 'Rotating-file-handler'
I have a log4net ado appender writing to a SQL Server database. I like

Explore

  • Home
  • Add group
  • Groups page
  • Communities
  • Questions
    • New Questions
    • Trending Questions
    • Must read Questions
    • Hot Questions
  • Polls
  • Tags
  • Badges
  • Users
  • Help
  • SEARCH

Footer

© 2021 The Archive Base. All Rights Reserved
With Love by The Archive Base

Insert/edit link

Enter the destination URL

Or link to existing content

    No search term specified. Showing recent items. Search or use up and down arrow keys to select an item.