zoukankan      html  css  js  c++  java
  • ABP.Net Core使用教程(三)记录数据库脚本日志

    可以跟踪数据库脚本能很好的帮助我们理解ABP , SQL Server Profiler当然是很好的工具 , 好像MySQL没有这么方便的工具

    这里我们讨论用日志记录的方法 

    1, 首先我们建两个类来记录EFCore产生的脚本日志

    EFLogger.cs

    using Microsoft.Extensions.Logging;
    using System;
    
    namespace AbpDemo.EntityFrameworkCore.Logger
    {
        public class EFLogger : ILogger
        {
            public Castle.Core.Logging.ILogger Logger { get; set; }
    
            private readonly string _categoryName;
    
            public EFLogger(string categoryName, Castle.Core.Logging.ILogger logger)
            {
                this._categoryName = categoryName;
                this.Logger = logger;
            }
    
            public bool IsEnabled(LogLevel logLevel) => true;
    
            public void Log<TState>(LogLevel logLevel, EventId eventId, TState state, Exception exception,
                Func<TState, Exception, string> formatter)
            {
                //ef core执行数据库查询时的categoryName为Microsoft.EntityFrameworkCore.Database.Command,日志级别为Information
                var logContent2 = formatter(state, exception);
                if (_categoryName == "Microsoft.EntityFrameworkCore.Database.Command"
                    && logLevel == LogLevel.Information)
                {
                    var logContent = formatter(state, exception);
                    Logger.Warn(logContent);
                }
            }
    
            public IDisposable BeginScope<TState>(TState state) => null;
        }
    }
    View Code

    EfLoggerProvider.cs

    using Microsoft.Extensions.Logging;
    
    namespace AbpDemo.EntityFrameworkCore.Logger
    {
        public class EfLoggerProvider : ILoggerProvider
        {
            public Castle.Core.Logging.ILogger Logger;
    
            public EfLoggerProvider(Castle.Core.Logging.ILogger logger)
            {
                Logger = logger;
            }
    
            public ILogger CreateLogger(string categoryName)
            {
                return new EFLogger(categoryName, Logger);
            }
    
            public void Dispose()
            {
            }
        }
    }
    View Code

    2, 修改AbpDemoDbContextConfigurer.cs

    using System.Data.Common;
    using Microsoft.EntityFrameworkCore;
    using Microsoft.Extensions.Logging;
    
    namespace AbpDemo.EntityFrameworkCore
    {
        public static class AbpDemoDbContextConfigurer
        {
            public static void Configure(DbContextOptionsBuilder<AbpDemoDbContext> builder, string connectionString,
                LoggerFactory loggerFactory)
            {
                builder.UseLoggerFactory(loggerFactory).UseSqlServer(connectionString);
                builder.EnableSensitiveDataLogging(); //日志显示脚本参数
            }
    
            public static void Configure(DbContextOptionsBuilder<AbpDemoDbContext> builder, DbConnection connection,
                LoggerFactory loggerFactory)
            {
                builder.UseLoggerFactory(loggerFactory).UseSqlServer(connection);
                builder.EnableSensitiveDataLogging(); //日志显示脚本参数
            }
        }
    }
    View Code

    3, 修改AbpDemoEntityFrameworkModule.cs   构建EfLoggerProvider类并提供给配置类使用

    using Abp.EntityFrameworkCore.Configuration;
    using Abp.Modules;
    using Abp.Reflection.Extensions;
    using Abp.Zero.EntityFrameworkCore;
    using AbpDemo.EntityFrameworkCore.Logger;
    using AbpDemo.EntityFrameworkCore.Seed;
    
    namespace AbpDemo.EntityFrameworkCore
    {
        [DependsOn(
            typeof(AbpDemoCoreModule),
            typeof(AbpZeroCoreEntityFrameworkCoreModule))]
        public class AbpDemoEntityFrameworkModule : AbpModule
        {
            /* Used it tests to skip dbcontext registration, in order to use in-memory database of EF Core */
            public bool SkipDbContextRegistration { get; set; }
    
            public bool SkipDbSeed { get; set; }
    
            public override void PreInitialize()
            {
                if (!SkipDbContextRegistration)
                {
                    Configuration.Modules.AbpEfCore().AddDbContext<AbpDemoDbContext>(options =>
                    {
                        if (options.ExistingConnection != null)
                        {
                            AbpDemoDbContextConfigurer.Configure(options.DbContextOptions, options.ExistingConnection,
                                DbLoggerFactory);
                        }
                        else
                        {
                            AbpDemoDbContextConfigurer.Configure(options.DbContextOptions, options.ConnectionString,
                                DbLoggerFactory);
                        }
                    });
                }
            }
    
            public override void Initialize()
            {
                IocManager.RegisterAssemblyByConvention(typeof(AbpDemoEntityFrameworkModule).GetAssembly());
            }
    
            public override void PostInitialize()
            {
                if (!SkipDbSeed)
                {
                    SeedHelper.SeedHostDb(IocManager);
                }
            }
    
            private static Microsoft.Extensions.Logging.LoggerFactory _loggerFactory; 
    
            private Microsoft.Extensions.Logging.LoggerFactory DbLoggerFactory
            {
                get
                {
                    if (null == _loggerFactory)
                    {
                        _loggerFactory = new Microsoft.Extensions.Logging.LoggerFactory();
                        //_loggerFactory.AddProvider(new EfLoggerProvider(IocManager.Resolve<Castle.Core.Logging.ILogger>()));
                        _loggerFactory.AddProvider(new EfLoggerProvider(Logger));
                    }
    
                    return _loggerFactory;
                }
            }
        }
    }
    View Code

    4, 修复AbpDemoDbContextFactory.cs 的报错,传入空日志类就可以了

    using Microsoft.EntityFrameworkCore;
    using Microsoft.EntityFrameworkCore.Design;
    using Microsoft.Extensions.Configuration;
    using AbpDemo.Configuration;
    using AbpDemo.Web;
    
    namespace AbpDemo.EntityFrameworkCore
    {
        /* This class is needed to run "dotnet ef ..." commands from command line on development. Not used anywhere else */
        public class AbpDemoDbContextFactory : IDesignTimeDbContextFactory<AbpDemoDbContext>
        {
            public AbpDemoDbContext CreateDbContext(string[] args)
            {
                var builder = new DbContextOptionsBuilder<AbpDemoDbContext>();
                var configuration = AppConfigurations.Get(WebContentDirectoryFinder.CalculateContentRootFolder());
    
                AbpDemoDbContextConfigurer.Configure(builder,
                    configuration.GetConnectionString(AbpDemoConsts.ConnectionStringName), null);
    
                return new AbpDemoDbContext(builder.Options);
            }
        }
    }
    View Code

    这样运行项目, 在Logs.txt中就会显示所有的数据库脚本了

    我对日志进行了分类存放, 下面是参考的 log4net.config

    <?xml version="1.0" encoding="utf-8" ?>
    <log4net>
    
      <!-- 全部的日志 DEBUG < INFO < WARN < ERROR < FATAL -->
      <appender name="Info" type="log4net.Appender.RollingFileAppender" >
        <file value="App_Data/Logs/Info" />
        <appendToFile value="true" />
        <rollingStyle value="Date" />
        <datePattern value="yyyyMM\'Info'yyyyMMdd'.txt'"/>
        <maxSizeRollBackups value="100" />
        <maximumFileSize value="10000KB" />
        <staticLogFileName value="false" />
        <layout type="log4net.Layout.PatternLayout">
          <conversionPattern value="%newline%date [%thread] [%-5level] %logger %newline%message%newline"/>
        </layout>
      </appender>
    
      <!-- SQL -->
      <appender name="Warn" type="log4net.Appender.RollingFileAppender" >
        <file value="App_Data/Logs/Warn" />
        <appendToFile value="true" />
        <rollingStyle value="Date" />
        <datePattern value="yyyyMM\'Warn'yyyyMMdd'.txt'"/>
        <maxSizeRollBackups value="100" />
        <maximumFileSize value="10000KB" />
        <staticLogFileName value="false" />
        <layout type="log4net.Layout.PatternLayout">
          <conversionPattern value="%newline%date [%thread] [%-5level] %logger %newline%message%newline"/>
        </layout>
        <filter type="log4net.Filter.LevelRangeFilter">
          <levelMin value="Warn" />
          <levelMax value="Warn" />
        </filter>
      </appender>
    
      <!-- Error -->
      <appender name="Error" type="log4net.Appender.RollingFileAppender" >
        <file value="App_Data/Logs/Error" />
        <appendToFile value="true" />
        <rollingStyle value="Date" />
        <datePattern value="yyyyMM/'Error'yyyyMMdd'.txt'"/>
        <maxSizeRollBackups value="100" />
        <maximumFileSize value="10000KB" />
        <staticLogFileName value="false" />
        <layout type="log4net.Layout.PatternLayout">
          <conversionPattern value="%newline%date [%thread] [%-5level] %logger property: [%property{NDC}] %newline%message%newline"/>
        </layout>
        <filter type="log4net.Filter.LevelRangeFilter">
          <levelMin value="Error" />
        </filter>
      </appender>
    
      <!-- 只有Debug -->
      <appender name="Debug" type="log4net.Appender.RollingFileAppender" >
        <file value="App_Data/Logs/Debug.txt" />
        <appendToFile value="true" />
        <rollingStyle value="Size" />
        <maxSizeRollBackups value="10" />
        <maximumFileSize value="10000KB" />
        <staticLogFileName value="true" />
        <layout type="log4net.Layout.PatternLayout">
          <conversionPattern value="%newline%date [%thread] [%-5level] %logger %newline%message%newline"/>
        </layout>
        <filter type="log4net.Filter.LevelRangeFilter">
          <levelMin value="Debug" />
          <levelMax value="Debug" />
        </filter>
      </appender>
    
      <!--输出到控制台-->
      <appender name="Console" type="log4net.Appender.ManagedColoredConsoleAppender">
        <mapping>
          <level value="ERROR">
            <foreColor value="Yellow,HighIntensity" />
          </level>
        </mapping>
        <layout type="log4net.Layout.PatternLayout">
          <conversionPattern value="%newline%date [%thread] [%-5level] %-40.40logger %newline%message%newline" />
        </layout>
        <filter type="log4net.Filter.LevelRangeFilter">
          <levelMin value="Error" />
        </filter>
      </appender>
    
      <root>
        <appender-ref ref="Warn" />
        <appender-ref ref="Info" />
        <appender-ref ref="Error" />
        <appender-ref ref="Debug" />
        <appender-ref ref="Console" />
        <level value="DEBUG" />
      </root>
    
      <logger name="NHibernate">
        <level value="WARN" />
      </logger>
    </log4net>
    View Code
  • 相关阅读:
    回发或回调参数无效。下拉菜单中使用ajax,联动菜单引起的问题解决方案
    jquery获取,赋值img的src值..
    jquery select set selectindex
    DateTime.ToString("dd/MM/yyyy");后,不能直接Convert.ToDateTime的解决:
    SQL Server根据查询结果,生成XML文件
    SQL生成XML
    SQLXML
    .net 点击刷新验证码问题
    C# 根据字节数截取字符串(区别汉字,英文,数字)
    c#中对xml文件的基本操作
  • 原文地址:https://www.cnblogs.com/dacaba/p/10075930.html
Copyright © 2011-2022 走看看