Article From:https://www.cnblogs.com/lwqlun/p/9683482.html

to use the built-in log provider provided by the system.

log levelCommon sceneTraceRecord some useful information for programmer debugging problems.
It may contain some sensitive information, so it should be avoided.
Trace log enabled in production environmentDebugRecord some useful short time changes during the development and commissioning phase.
Quantity (Short-term usefulness), so unless the production environment is temporarily excluded.
Developers should avoid Debug logs in production environment as far as possible.InformationRecord some processes of the application, for example, record the URL of the current API request.WarningRecord abnormal or unexpected event information in the application.
These messages may contain error messages or conditions for errors, such as files not found.ErrorRecord errors and exception information generated by an operation in the application.CriticalRecord some problems that need immediate repair. For example, data loss and insufficient disk space.

Then we useILoggerInterface providedLogInformationThe method adds a Information type log “[Test Log]Getting items”.

Note:ILoggerIn order to provide 6 available output logging methods, corresponding to 6 different log levels, respectively.

  • LogTrace
  • LogDebug
  • LogInformation
  • LogWarning
  • LogError
  • LogCritical!

Next we use the Kestral server to start the project.

The logs generated by the project are as follows: the logs we manually output appear in the console.

default log provider

When we create a new ASP.NET Core WebApi project, we usually see the following code in Program.cs.

    public class Program
    {
        public static void Main(string[] args)
        {
            CreateWebHostBuilder(args).Build().Run();
        }

        public static IWebHostBuilder CreateWebHostBuilder(string[] args) =>
            WebHost.CreateDefaultBuilder(args)
                .UseStartup<Startup>();
    }

Let’s take a look at the source code of WebHost.CreateDefaultBuilder.

    public static IWebHostBuilder CreateDefaultBuilder(string[] args)
    {
        var builder = new WebHostBuilder()
            .UseKestrel()
            .UseContentRoot(Directory.GetCurrentDirectory())
            .ConfigureAppConfiguration((hostingContext, config) =>
            {
                var env = hostingContext.HostingEnvironment;

                config.AddJsonFile("appsettings.json", optional: true, reloadOnChange: true)
                      .AddJsonFile($"appsettings.{env.EnvironmentName}.json", optional: true, reloadOnChange: true);

                if (env.IsDevelopment())
                {
                    var appAssembly = Assembly.Load(new AssemblyName(env.ApplicationName));
                    if (appAssembly != null)
                    {
                        config.AddUserSecrets(appAssembly, optional: true);
                    }
                }

                config.AddEnvironmentVariables();

                if (args != null)
                {
                    config.AddCommandLine(args);
                }
            })
            .ConfigureLogging((hostingContext, logging) =>
            {
                logging.UseConfiguration(hostingContext.Configuration.GetSection("Logging"));
                logging.AddConsole();
                logging.AddDebug();
            })
            .UseIISIntegration()
            .UseDefaultServiceProvider((context, options) =>
            {
                options.ValidateScopes = context.HostingEnvironment.IsDevelopment();
            })
            .ConfigureServices(services =>
            {
                services.AddTransient<IConfigureOptions<KestrelServerOptions>, KestrelServerOptionsSetup>();
            });

        return builder;
    }

You will find the code passed.logging.AddConsoleandlogging.AddDebugConsole and Debug type log providers are configured by default, which is why we didn’t inject any log providers, but logs were generated properly.

> configuration file and log level filtering

ASP.NET CoreBy default, the log configuration is read from the Logging property in appSetting. JSON (and you can also read the configuration from other files), where the lowest log level is set for different log providers, such as the following.

{
  "Logging": {
    "Debug": {
      "LogLevel": {
        "Default": "Information"
      }
    },
    "Console": {
      "LogLevel": {
        "Microsoft.AspNetCore.Mvc.Razor.Internal": "Warning",
        "Microsoft.AspNetCore.Mvc.Razor.Razor": "Debug",
        "Microsoft.AspNetCore.Mvc.Razor": "Error",
        "Default": "Trace"
      }
    },
    "LogLevel": {
      "Default": "Debug"
    }
  }
}

The Debug in the above code represents the Debug log provider, the Console represents the Console log provider, and the last LogLevel represents the other log providers in general.
DebugDefault in Debug is set to Information, which means that the lowest level of logs generated in Debug is Information, and logs below the Information level are not exported. The configuration in Console is the same.

Write a custom style console log component

Here we want to add a log output from the console, but the difference from the built-in Console type log is that we set different colors for different log types.

First, we create a new Api project, ColoredConsoleLoggerSample.

Then we create a font color configuration class for different log levels.ColoredConsoleLoggerConfiguration, The code is as follows

    public class ColoredConsoleLoggerConfiguration
    {
        public LogLevel LogLevel { get; set; } = LogLevel.Warning;
        public ConsoleColor Color { get; set; } = ConsoleColor.Yellow;
    }

This class defines different font colors for different log types.

Then we create a log class.ColoredConsoleLogger, It is implementedILoggerInterface, the code is as follows

    public class ColoredConsoleLogger : ILogger
    {
        private readonly string _name;
        private readonly ColoredConsoleLoggerConfiguration _config;

        public ColoredConsoleLogger(string name, ColoredConsoleLoggerConfiguration config)
        {
            _name = name;
            _config = config;
        }

        public IDisposable BeginScope<TState>(TState state)
        {
            return null;
        }

        public bool IsEnabled(LogLevel logLevel)
        {
            return logLevel == _config.LogLevel;
        }

        public void Log<TState>(LogLevel logLevel, EventId eventId, TState state, Exception exception, Func<TState, Exception, string> formatter)
        {
            if (!IsEnabled(logLevel))
            {
                return;
            }
            
            var color = Console.ForegroundColor;
            Console.ForegroundColor = _config.Color;
            Console.WriteLine($"{logLevel.ToString()} - {_name} - {formatter(state, exception)}");
            Console.ForegroundColor = color;
        }
    }

Code interpretation

  • ColoredConsoleLoggerOnly for one log level
  • Logs are output only if the current generated log level is the same as the log level defined in Colored ConsoleLogger, and here we useIsEnableMethod judgement
  • LogIt is the method defined in the ILogger interface. We export the log in this method.
  • Here we record the original font color of the current console before entering the log, and when the output log is complete, we restore the font color to its original color

Then we add a Logger provider class.ColoredConsoleLoggerProvider,The code is as follows

    public class ColoredConsoleLoggerProvider : ILoggerProvider
    {
        private readonly ColoredConsoleLoggerConfiguration _config;

        public ColoredConsoleLoggerProvider(ColoredConsoleLoggerConfiguration config)
        {
            _config = config;
        }

        public ILogger CreateLogger(string categoryName)
        {
            return new ColoredConsoleLogger(categoryName, _config);
        }

        public void Dispose()
        {

        }
    }

Code interpretation

  • ColoredConsoleLoggerProviderOnly for one log level
  • CreateLoggeryesILoggerProviderThe method defined in the interface is used to return a log generator.

Finally, we modify the Configure method in Startup.cs. The code is as follows

    public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory)
    {
        if (env.IsDevelopment())
        {
            app.UseDeveloperExceptionPage();
        }
        
        loggerFactory.AddProvider(new ColoredConsoleLoggerProvider(new ColoredConsoleLoggerConfiguration
        {
            LogLevel = LogLevel.Information,
            Color = ConsoleColor.Blue
        }));
        loggerFactory.AddProvider(new ColoredConsoleLoggerProvider(new ColoredConsoleLoggerConfiguration
        {
            LogLevel = LogLevel.Debug,
            Color = ConsoleColor.Gray
        }));

        app.UseMvc();
    }

Here we add two log providers for Information level logging and Debug level logging

Our log is displayed correctly according to our preset font color.

Then we create a LogHub class, which is integrated from the Hub class. The code is as follows

    public class LogHub : Hub
    {
        public async Task WriteLog(Log log)
        {
            await Clients.All.SendAsync("showLog", log);
        }
    }

    public class Log
    {
        public LogLevel Level { get; set; }

        public string Content { get; set; }
    }

Code interpretation

  • Here we create a logging method that pushes the log to all clients connected to the SignalR server and invokes the client’s showLog method to display the pushed log information.

Then we modify the Startup.cs file, the code is as follows

    public class Startup
    {
        public Startup(IConfiguration configuration)
        {
            Configuration = configuration;
        }

        public IConfiguration Configuration { get; }

        // This method gets called by the runtime. Use this method to add services to the container.
        public void ConfigureServices(IServiceCollection services)
        {
            services.AddCors();
            services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_2_1);
            
            services.AddSignalR();
        }

        // This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
        public void Configure(IApplicationBuilder app, IHostingEnvironment env)
        {
            if (env.IsDevelopment())
            {
                app.UseDeveloperExceptionPage();
            }
            app.UseCors(p => p.AllowAnyOrigin().AllowAnyMethod().AllowAnyHeader().AllowCredentials());
            app.UseSignalR(routes =>
            {
                routes.MapHub<LogHub>("/logHub");
            });

            

            app.UseMvc();
        }
    }

Code interpretation

  • We passed throughservice.AddSignalRRegistered SignalR services
  • We passed throughapp.UserSignalRMethod to register a logHub
  • We have enabled CORS here because we need to provide cross domain access.

Then we create another ASP.NET Core WebApi project, SignalRLoggerSample

After the project was successfully created, we right-click on the item properties and set App URL to http://localhost:5001.

Then we use Package Console Manager to install Microsoft.AspNetCore.SignalR.Client.

PM> install-package Microsoft.AspNetCore.SignalR.Client

To create a SignalR log provider, we create a SignalRLogger class and a SignalRLoggerProvider class, respectively, as follows

SignalRLogger.cs

    public class SignalRLogger : ILogger
    {
        HubConnection connection;

        public SignalRLogger()
        {
            connection = new HubConnectionBuilder()
             .WithUrl("http://localhost:5000/LogHub")
             .Build();
        }

        public IDisposable BeginScope<TState>(TState state)
        {
            return null;
        }

        public bool IsEnabled(LogLevel logLevel)
        {
            return true;
        }

        public void Log<TState>(LogLevel logLevel, EventId eventId, TState state, Exception exception, Func<TState, Exception, string> formatter)
        {
            if (!IsEnabled(logLevel))
            {
                return;
            }

            connection.StartAsync().Wait();
            var task = connection.SendAsync("writeLog", new { Level = logLevel, Content = formatter(state, exception) });
            task.Wait();
        }
    }

SignalRLoggerProvider.cs

    public class SignalRLoggerProvider : ILoggerProvider
    {
        public SignalRLoggerProvider()
        {
        }

        public ILogger CreateLogger(string categoryName)
        {
            return new SignalRLogger();
        }

        public void Dispose()
        {

        }
    }

Code interpretation

  • Use hereHubConnectionBuilderCreated a SignalR connection.
  • After successful connection, we useconnection.SendAsyncMethod to send the currently generated log information to the SignalR server

After adding, we create an index. HTML in the wwwroot folder, where we import the JS libraries of jQuery and signalr, and specify that the signalR server to which we connect is http://localhost:5000/LogHub

index.html

<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8" />
    <title></title>
    <script src="jquery-1.10.2.min.js"></script>
    <script src="signalr.min.js"></script>
</head>
<body>
    <h1>Logs</h1>
    <div id="content" style="border:1px solid #0094ff">

    </div>
    <script type="text/javascript">
        var levels = [
            { level: 0, name: 'Trace', backgroundColor: 'gray' },
            { level: 1, name: 'Debug', backgroundColor: 'green' },
            { level: 2, name: 'Information', backgroundColor: 'blue' },
            { level: 3, name: 'Warning', backgroundColor: 'yellow' },
            { level: 4, name: 'Error', backgroundColor: 'orange' },
            { level: 5, name: 'Critical', backgroundColor: 'red' },
        ];

        function getLevelName(level) {
            return levels.find(function (o) {
                return o.level == level;
            }).name;
        }

        function getLevelColor(level) {
            return levels.find(function (o) {
                return o.level == level;
            }).backgroundColor;
        }

        var connection = new signalR.HubConnectionBuilder().withUrl("http://localhost:5000/logHub").build();

        connection.on("showLog", function (message) {
            var div = "<div style='background-color:" + getLevelColor(message.level)+"'>[" + getLevelName(message.level) + "]:" + message.content + "</div>";
            $("#content").append(div);
        });

        connection.start().catch(function (err) {
            return console.error(err.toString());
        });
    </script>
</body>
</html>

Then we modify the ValuesController file, the code is as follows

    [Route("api/[controller]")]
    [ApiController]
    public class ValuesController : ControllerBase
    {
        private ILogger<ValuesController> _logger = null;

        public ValuesController(ILogger<ValuesController> logger)
        {
            _logger = logger;
        }

        // GET api/values
        [HttpGet]
        public ActionResult<IEnumerable<string>> Get()
        {
            _logger.LogTrace("User call the /api/values api");
            _logger.LogDebug("User call the /api/values api");
            _logger.LogInformation("User call the /api/values api");
            _logger.LogWarning("User call the /api/values api");
            _logger.LogError("User call the /api/values api");
            _logger.LogCritical("User call the /api/values api");
            return new string[] { "value1", "value2" };
        }
    }

Code interpretation

  • We created a log of ValueController class.
  • When the user requests /api/values, we export 6 different levels of logs.

Finally, we modify the Configure method in Startup. CS to add the SignalRLoggerProvider to the pipeline using the method we described earlier

    public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory)
    {
        if (env.IsDevelopment())
        {
            app.UseDeveloperExceptionPage();
        }
        app.UseStaticFiles();

        loggerFactory.AddProvider(new SignalRLoggerProvider());

        app.UseMvc();


    }

This source code

Post Views: 1

Leave a Reply

Your email address will not be published. Required fields are marked *