aliozgur / Serilog.Enrichers.HttpContextData

Apache License 2.0
25 stars 10 forks source link

Logger not enriching output #6

Closed xantari closed 7 years ago

xantari commented 7 years ago

How are you supposed to use this?

Here is what I have in Application_Start:

var smtpSection = (SmtpSection)ConfigurationManager.GetSection("system.net/mailSettings/smtp");`

//Init serilog
Log.Logger = new LoggerConfiguration()
.Enrich.WithHttpContextData()
.WriteTo.RollingFile(EdWebAppSettingsConfig.SerilogErrorLoggingFilePattern)
.WriteTo.Email(new EmailConnectionInfo()
    {
        FromEmail = EdWebAppSettingsConfig.ErrorEmailFrom,
        EnableSsl = smtpSection.Network.EnableSsl,
        EmailSubject = "Edweb Admin Error",
        IsBodyHtml = true,
        MailServer = smtpSection.Network.Host,
        NetworkCredentials = !(string.IsNullOrEmpty(smtpSection.Network.UserName)) ? new NetworkCredential(smtpSection.Network.UserName, smtpSection.Network.Password) : null,
        Port = smtpSection.Network.Port,
        ToEmail = EdWebAppSettingsConfig.ErrorOperatorEmail
    }, batchPostingLimit: 100,
    period: new TimeSpan(0, 0, 1, 0),  //Email max of every 1 minute
    restrictedToMinimumLevel: LogEventLevel.Error)
.CreateLogger();

Here is what is in Application_Error:

Log.Error(Server.GetLastError(), @"Username: {UserName}<br/>", HttpContext.Current.User.Identity.Name);

Here is what is in the log however:

2017-08-10 08:27:01.674 -05:00 [Error] Username: "johnsmith"<br/>
System.Web.HttpUnhandledException (0x80004005): Exception of type 'System.Web.HttpUnhandledException' was thrown. ---> System.Exception: This is a TEST!
   at ARRT.EdWeb.Admin.Web.ProgramLetters.Page_Load(Object sender, EventArgs e) in C:\TFS\TFS_SVN2\ARRT.Sln.EdWeb\ARRT.EdWeb.Admin.Web\ProgramLetters.aspx.cs:line 14
   at System.Web.UI.Control.OnLoad(EventArgs e)
   at System.Web.UI.Control.LoadRecursive()
   at System.Web.UI.Page.ProcessRequestMain(Boolean includeStagesBeforeAsyncPoint, Boolean includeStagesAfterAsyncPoint)
   at System.Web.UI.Page.HandleError(Exception e)
   at System.Web.UI.Page.ProcessRequestMain(Boolean includeStagesBeforeAsyncPoint, Boolean includeStagesAfterAsyncPoint)
   at System.Web.UI.Page.ProcessRequest(Boolean includeStagesBeforeAsyncPoint, Boolean includeStagesAfterAsyncPoint)
   at System.Web.UI.Page.ProcessRequest()
   at System.Web.UI.Page.ProcessRequest(HttpContext context)
   at ASP.programletters_aspx.ProcessRequest(HttpContext context) in c:\Windows\Microsoft.NET\Framework64\v4.0.30319\Temporary ASP.NET Files\root\fbe1907b\797db4d4\App_Web_mfv15ok4.5.cs:line 0
   at System.Web.HttpApplication.CallHandlerExecutionStep.System.Web.HttpApplication.IExecutionStep.Execute()
   at System.Web.HttpApplication.ExecuteStep(IExecutionStep step, Boolean& completedSynchronously)

As you can see it is missing all the HttpContext data that is supposed to be enriched.

xantari commented 7 years ago

I think I found the solution.

It appears your enricher does not support ASP .NET Webforms, which does not use HttpContextBase.

See here: https://techblog.dorogin.com/asp-net-httpcontext-vs-httpcontextbase-dc7ac82b0ff1

I was able to get around this by putting the following:

            HttpContextBase abstractContext = new HttpContextWrapper(this.Context);
            var ctxData = new HttpContextData(abstractContext);
            var dto = ctxData.ToDto();
            Log.Error(Server.GetLastError(), @"Username: {UserName}<br/>{@dto}", HttpContext.Current.User.Identity.Name, dto);
aliozgur commented 7 years ago

@xantari please take a look at AddLogEventProperties method. I use the exact same HttpContextWrapper. I suspect you might have another issue.

xantari commented 7 years ago

Maybe I am miss understanding how to use Enrichers.

Do you have to know the magic strings to put in to the log string?

For example. In the Log.Error do I have to know what the magic strings are to put into the message template such as: Log.Error("{HttpContext.IPAddress} {HttpContext.UrlReferrer}" or something?

I was thinking enrichers just automatically append on all data to the end of your message template, but the documentation on the subject is scarce.

aliozgur commented 7 years ago

@xantari good point. As far as I'm aware of you need to align your output template bıoth for your rolling file and email sinks. Please see this Serilog Wiki page

xantari commented 7 years ago

Are you saying to not write in text, but force it to use the JSON formatter, so that all these "hidden" properties from httpcontext get written as a JSON object to log?

aliozgur commented 7 years ago

Not exactly. You should include the fields injected by the enricher into your rolling file output template configuration. JSON formatter is yet another way to format output in the afermentioned Serilog Wiki page

xantari commented 7 years ago

How would I know what fields to include? Can you give me an example that includes all fields?

aliozgur commented 7 years ago

You can inspect the code found here to know what are the names of the fields injected by the enricher

xantari commented 7 years ago

I'm a bit more confused then. How would I know all types of query string variables to include in my logger output?

sv = ctx.QueryStringSerializable; foreach (var v in sv) { propertyFactory.CreateProperty("qs: " + v.Name, v.Value).AddIfAbsent(logEvent); }

So you are saying I would have to know ahead of time all query string parameter names?

Log.Error("{qs:param1} {qs:param2}") ?

aliozgur commented 7 years ago

Specifying the fields in Log.Error is not needed. You can configure the sink output (rolling file, smtp etc) in your web.config or app.config.

xantari commented 7 years ago

Yeah, I guess that is where I am stuck. What am I missing from the configuration code to enable this in the above example code I published?

xantari commented 7 years ago

I think I found the answer on the glitter serilog forum. Apparently property enrichment that enrichers do are only good for logging storage mechanisms like Seq. It doesn't help when you log to flat file. When you log to flat file you have to do the var dto = ctxData.ToDto(); option

aliozgur commented 7 years ago

@xantari can we close this one?

xantari commented 7 years ago

Sure

On Aug 23, 2017, at 4:32 AM, Ali Özgür notifications@github.com wrote:

@xantari can we close this one?

— You are receiving this because you were mentioned. Reply to this email directly, view it on GitHub, or mute the thread.