An Introduction to ABP Series (3): Adding Logging Components and Dependency Injection Services

2020年9月16日 50点热度 0人点赞 0条评论
内容目录

Copyright © Author: whuanle. Reprint of this article in WeChat public account requires consent from "NCC Open Source Community".

In the previous two articles, we built a basic, simple web program with a unified response format. This article contains less content, focusing on adding some necessary component functionalities.

Since the framework has already been established in the prior articles, we can directly use it to gradually add functionalities. Subsequent articles in this series will progressively explain various aspects.

Source code address: https://github.com/whuanle/AbpBaseStruct

The framework project is located in src/2/AbpBase.

Automatic Dependency Injection

In the AbpBase.Web's AbpBaseWebModule, add a function:

This function is used to scan services in the module and automatically add them to the container, eliminating the need to add them manually.

        /// <summary>
        /// Automatically scan all services and perform dependency injection
        /// </summary>
        /// <param name="context"></param>
        private void ConfigureAutoIoc(ServiceConfigurationContext context)
        {
            context.Services.AddAssemblyOf<IoTCenterApplicationModule>();
            context.Services.AddAssemblyOf<IoTCenterWebModule>();
        }

Then, in ConfigureServices, add:

            // Configure dependency injection services
            ConfigureAutoIoc(context);

Types inheriting from the ITransientDependency interface in these modules will be automatically injected into the DI container.

Adding Logging Dependency

ABP wraps Serilog as the logging component. You can install the Volo.Abp.AspNetCore.Serilog package version 3.1.2 using NuGet in the AbpBase.Web project.

Since the web is at the top layer, Volo.Abp.AspNetCore.Serilog has already been encapsulated, but its functionality is not enough, so we need to continue adding extensions provided by Serilog.

Since the AbpBase.Application module is a service provisioning module and also needs to use logging functionality, we need to add two packages using NuGet in AbpBase.Application:

  • Serilog.AspNetCore, version 3.4.0;
  • Serilog.Sinks.Async, version 1.4.0;

Then, in AbpBaseApplicationModule, add an injection:

        public override void ConfigureServices(ServiceConfigurationContext context)
        {
            context.Services.AddSingleton<Serilog.ILogger>(Serilog.Log.Logger);
        }

Adding Logging Functionality

Logging often needs to be categorized and recorded by date, so we configure a simple categorized logging configuration here.

In Program.cs, add a function:

        private static void ConfigLog()
        {
            Serilog.Log.Logger = new LoggerConfiguration()
#if DEBUG
                .MinimumLevel.Debug()
#else
                .MinimumLevel.Information()
#endif
                .MinimumLevel.Override("Microsoft", LogEventLevel.Information)
                .MinimumLevel.Override("Microsoft.EntityFrameworkCore", LogEventLevel.Warning)
                .Enrich.FromLogContext()
                .WriteTo.Async(c => c.File($"Logs/{DateTime.Now.ToString("yyyy-MM-dd", System.Globalization.CultureInfo.CurrentCulture)}-logs.txt"))
                .WriteTo.Logger(log =>
                        log.Filter.ByIncludingOnly(evt => evt.Level == LogEventLevel.Fatal)
                            .WriteTo.File(
                                $"Logs/{(DateTime.Now.ToString("yyyy-MM-dd", System.Globalization.CultureInfo.CurrentCulture) + "-Fatal.txt")}",
                                fileSizeLimitBytes: 83886080),
                    LogEventLevel.Fatal)
                .WriteTo.Logger(log =>
                        log.Filter.ByIncludingOnly(evt => evt.Level == LogEventLevel.Error)
                            .WriteTo.File(
                                $"Logs/{(DateTime.Now.ToString("yyyy-MM-dd", System.Globalization.CultureInfo.CurrentCulture) + "-Error.txt")}",
                                fileSizeLimitBytes: 83886080),
                    LogEventLevel.Fatal)
                .WriteTo.Console()
                .CreateLogger();
        }

This function configures the Serilog output. We categorize logs into three levels: Error.txt, Fatal.txt, and logs.txt, and set files to be created daily, with each log file capped at 8 MB.

Readers can adjust it according to their circumstances.

Then add the following after CreateHostBuilder:

        public static IHostBuilder CreateHostBuilder(string[] args) =>
            Host.CreateDefaultBuilder(args)
                .ConfigureWebHostDefaults(webBuilder =>
                {
                    webBuilder.UseStartup<Startup>();
                })
            .UseAutofac()
            .UseSerilog();

Finally, modify the Main method to:

        public static int Main(string[] args)
        {
            try
            {
                ConfigLog();
                Serilog.Log.Information("Starting web host.");
                CreateHostBuilder(args).Build().Run();
                return 0;
            }
            catch (Exception ex)
            {
                Serilog.Log.Fatal("Host terminated unexpectedly!");
                return 1;
            }
            finally
            {
                Serilog.Log.CloseAndFlush();
            }
        }

After this, we will have a web program with logging functionality.

Dependency Injection

If you need to use the logging service, you can reference using Serilog;

Then use the following format to utilize the injected service:

        private readonly ILogger _ILogger;

        public CustomerExceptionHandler(ILogger logger)
        {
            _ILogger = logger;
        }

After completion, the source code can be referenced at https://github.com/whuanle/AbpBaseStruct/tree/master/src/3/AbpBase

痴者工良

高级程序员劝退师

文章评论