How to use aspnet-session pattern layout?

4.8k views Asked by At

I have adonet appender and I defined additional column. I want to get the userId from the asp.net session and do log.

According to this page there is %aspnet-session{key} pattern which I use like this:

<parameter>
    <parameterName value="@userId" />
    <dbType value="String" />
    <size value="255" />
    <layout type="log4net.Layout.PatternLayout">
      <conversionPattern value="%aspnet-session{current_member}" />
    </layout>
  </parameter>

and I got the following result in the database:

/LM/W3SVC/1/ROOT/trunk-1-129718741958458380spnet-session{current_member}

What I am doing wrong here?

4

There are 4 answers

0
mynkow On BEST ANSWER

I found a solution to my problem.

I just refactored it to serve my needs:

public class Log4NetAspNetProperty
    {
        private const string PropertyNamePrefix = "log4net_app_";
        private const string PropertyDefaultValue = null;

        private readonly string propertyName;
        private readonly object propertyValue;

        public string Name { get { return propertyName; } }

        private Log4NetAspNetProperty(string propertyName, object propertyValue)
        {
            if (String.IsNullOrWhiteSpace(propertyName)) throw new ArgumentNullException("propertyName");

            this.propertyName = propertyName;
            this.propertyValue = propertyValue;

            if (HttpContext.Current != null)
                HttpContext.Current.Items[GetPrefixedPropertyName()] = propertyValue;
        }

        public override string ToString()
        {
            if (HttpContext.Current == null)
                return PropertyDefaultValue;

            var item = HttpContext.Current.Items[GetPrefixedPropertyName()];
            return item != null ? item.ToString() : PropertyDefaultValue;
        }

        private static string GetPrefixedPropertyName()
        {
            return String.Format("{0}{1}", PropertyNamePrefix, PropertyDefaultValue);
        }

        public static void CurrentUserId(object userId)
        {
            var property = new Log4NetAspNetProperty("CurrentUserId", userId);
            log4net.ThreadContext.Properties[property.Name] = property;
        }

        public static void CurrentUrl(object url)
        {
            var property = new Log4NetAspNetProperty("CurrentUrl", url);
            log4net.ThreadContext.Properties[property.Name] = property;
        }
    }
0
cobolstinks On

/LM/W3SVC/1/ROOT/trunk-1-129718741958458380spnet-session{current_member} is getting logged because in your log4net definition you have something like this right?

<parameter>
        <parameterName value="@user" />
        <dbType value="String" />
        <layout type="log4net.Layout.PatternLayout">
          <conversionPattern value="%aspnet-session{current_memeber}" />
        </layout>
      </parameter>

and log4net is taking "%a" out of "%aspnet-session{current_memeber}" and thinking you want the application domain. %a is the log4net pattern that converts to the application domain. This is really annoying and i recently ran into this and do not know a way around it.

See here: https://logging.apache.org/log4net/log4net-1.2.13/release/sdk/log4net.Layout.PatternLayout.html

Found a solution to this problem. If you use log4net 1.2.11 or greater declaring your parameter like this should work.

<parameter>
        <parameterName value="@session" />
        <dbType value="String" />
        <size value="2147483647"/>
        <layout type="log4net.Layout.PatternLayout">
          <converter>
            <name value ="AspNetSessionPatternConverter"/>
            <type value="log4net.Layout.Pattern.AspNetSessionPatternConverter"/>
          </converter>
          <conversionPattern value="%aspnet-session{gwsession}" />
        </layout>
      </parameter>

I don't know if %a being short circuited to appdomain is a bug or if you're supposed to declare your params like this with the aspnetsessionpatternconverter, but it would be nice if the log4net documentation was updated. Hope this helps someone else.

3
ENOTTY On

As of log4net version 1.2.11.0, you can use %aspnet-request{ASP.NET_SessionId} of the ASP.NET pattern layout converters like so:

<conversionPattern value="%date %level %logger [%aspnet-request{ASP.NET_SessionId}] - %message%newline" />

See the release notes:

  • [LOG4NET-87] - Support ASP.Net related PatternConverters to allow items from the HttpContext.Current.Session, Cache, Request, etc. to be captured.
0
Matthew Lock On

You need to use log4net 1.2.11 or higher to get access to the ASP.NET pattern converters.

You'll get the LM/W3SVC/1/ROOT/trunk-1-129718741958458380spnet-session{current_member} message when you use an older version of log4net.