2

Is there a simple way to log (using nlog, e.g. log.Debug(…)) the selected route in an ASP.NET Core MVC application? I use HttpGet/HttpPost attributes to define my routes, and I am looking for a simple way to log the route that MVC chooses to handle for each incoming request.

Note: Similar questions have been answered, but they relate to debugging and analyzing routes:

For my purposes, though, I just want to know which route MVC chose to handle for the request and have it logged. (And, ideally, I don't want to add a log to each controller method; there must be some way to do this once generically for all incoming requests.)

Community
  • 1
  • 1
shelbypereira
  • 2,097
  • 3
  • 27
  • 50
  • 1
    In .NET Core, you can follow this tutorial to achieve what you want: https://www.tutorialsteacher.com/core/aspnet-core-logging – Rahul Sharma Oct 18 '19 at 05:47
  • 1
    thanks, yes, this works, so to clarify for others, once NLog or other logger is setup, I found the information in the Microsoft logger named Microsoft.AspNetCore.Routing.Matching.DfaMatcher – shelbypereira Oct 18 '19 at 05:50

2 Answers2

2

a simple generic way of logging all request is using a registered middleware component.

    public class PerformanceMiddleware
    {
        private readonly RequestDelegate _next;

        public PerformanceMiddleware(RequestDelegate requestDelegate)
        {
            _next = requestDelegate;
        }

        public Task Invoke(HttpContext httpContext)
        {
            var watch = new Stopwatch();
            watch.Start();

            var nextTask = _next.Invoke(httpContext);
            nextTask.ContinueWith(t =>
            {
                var time = watch.ElapsedMilliseconds;
                var requestString = $"[{httpRequest.Method}]{httpRequest.Path}?{httpRequest.QueryString}";
                if (t.Status == TaskStatus.RanToCompletion)
                {
                    .. log.Info ..($"{time}ms {requestString}");
                }
                else
                {
                    .. log.Warn ..($"{time}ms [{t.Status}] - {requestString}", t.Exception?.InnerException);
                }
            });
            return nextTask;
        }
    }

this also logs the execution time

In your startup you register it as the first, before UseMvc and any other middleware components.

            app.UseMiddleware<PerformanceMiddleware>();
Frank Nielsen
  • 1,546
  • 1
  • 10
  • 17
  • 2
    The httpRequest object referenced here is actually from httpContext.Request. You can populate it by saying: var httpRequest = httpContext.Request; – Jack Apr 11 '21 at 23:34
-4

On IIS, you can use the web.config file. In this file, by default, there is an option stdoutLogEnabled=false. Switch it to true. A log will be generated with the info you want.

Edit : Updated my answer to specify it's only correct for IIS according to the comments below

An0d
  • 213
  • 2
  • 12
  • Are you sure about that? – Rahul Sharma Oct 18 '19 at 05:45
  • Yes I used that option in my last Web Api written in .NET Core 2.2 – An0d Oct 18 '19 at 05:49
  • Not sure this helps, comment from Rahul in the question works. – shelbypereira Oct 18 '19 at 05:50
  • @An0d NET Core you should have a web.config file? Is this correct? I don't see a web.config file in my .NET Core project. – Rahul Sharma Oct 18 '19 at 05:52
  • In my last 3 ASP.NET Core projects. A web.config file was included which look like this https://gist.github.com/An0d/a8be6b88e9ba4983c2ff25edad525a9d you can see the options `stdoutLogEnabled="false" stdoutLogFile=".\logs\stdout"` With those options, no change in code needed to log some informations about routes etc... – An0d Oct 18 '19 at 06:05
  • ASP.NET Core Configuration with web.config is documented here [MSDN](https://learn.microsoft.com/en-us/aspnet/core/host-and-deploy/aspnet-core-module?view=aspnetcore-3.0#configuration-with-webconfig) – An0d Oct 18 '19 at 06:58
  • That is on IIS during deployment specifically for the `ASP.NET Core Module`. – Rahul Sharma Oct 18 '19 at 07:24
  • 1
    ASP.NET Core doesn't use web.config. It's produced as part of the publish just in case you happen to deploy to IIS, and `stdoutLogFile` would only be applicable in that one specific scenario. This is not the solution. – Chris Pratt Oct 18 '19 at 16:49
  • Ok thanks for the clarification. But when deployed on Azure App Service the web.config is taken into account. You can specify the environment variable ASPNETCORE_ENVIRONMENT through web.config for example. So I did not think that web.config was just for IIS. As I only deployed my applications on IIS or on Azure App Service I thought it was a correct solution. Sorry – An0d Oct 18 '19 at 17:06
  • Edited my answer to specify it's only correct for IIS – An0d Oct 18 '19 at 17:11