How to use aspnet-session pattern layout?

2019-04-15 17:15发布

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条回答
Viruses.
2楼-- · 2019-04-15 17:55

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;
        }
    }
查看更多
女痞
3楼-- · 2019-04-15 17:59

/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.

查看更多
Luminary・发光体
4楼-- · 2019-04-15 18:12

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.
查看更多
姐就是有狂的资本
5楼-- · 2019-04-15 18:18

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.

查看更多
登录 后发表回答