• Orchard学习 01、orchard日志


    一、日志模块类图

    1、ILogger接口及实现
    2、ILoggerFactory接口及实现
    3、其他
    二、NullLogger类型
        NullLogger类型是实现ILogger接口的空类型。它的 IsEnabled 方法总是返回false;Log 方法是个空实现。在代码中要用到日志的地方设计1个 NullLogger属性 作为占位符,在代码运行时将这个对象替换为真正的日志对象。如果不替换,则代码也能编译成功,运行时也不会出错。
     1 publicclassNullLogger:ILogger
     2 {
     3 privatestaticreadonlyILogger _instance =newNullLogger();
     4 publicstaticILoggerInstance
     5 {
     6  get
     7 {
     8 return _instance;
     9 }
    10 }
    11 #region ILogger 成员
    12 
    13 public bool IsEnabled(LogLevel level)
    14 {
    15 returnfalse;
    16 }
    17 
    18 publicvoidLog(LogLevel level,Exception exception,string format,paramsobject[] args)
    19 {
    20 
    21 }
    22 
    23 #endregion
    24 }
    View Code
    三、和autofac的结合使用
        在orchard中,autofac的使用无处不在。日志模块也不例外。前面说过,NullLogger 类型相当于1个日志类型的占位符,在运行时可以被替换为真实的日志类型。那在运行时如何替换呢?这就要和autofac结合在一起使用
    1、LoggingModule类
        LoggingModule类继承了Module类型。Module类型是autofac的类型。
     1 publicclassLoggingModule:Module
     2 {
     3 privatereadonlyConcurrentDictionary<string,ILogger> _loggerCache;
     4 
     5 publicLoggingModule()
     6 {
     7  _loggerCache =newConcurrentDictionary<string,ILogger>();
     8 }
     9 
    10 protectedoverridevoidLoad(ContainerBuilder moduleBuilder)
    11 {
    12 // by default, use Orchard's logger that delegates to Castle's logger factory
    13  moduleBuilder.RegisterType<CastleLoggerFactory>().As<ILoggerFactory>().InstancePerLifetimeScope();
    14  moduleBuilder.RegisterType<OrchardLog4netFactory>().As<Castle.Core.Logging.ILoggerFactory>().InstancePerLifetimeScope().WithParameter(newNamedParameter("isFullTrust",false));
    15 
    16 // call CreateLogger in response to the request for an ILogger implementation
    17  moduleBuilder.Register(CreateLogger).As<ILogger>().InstancePerDependency();
    18 }
    19 
    20 protectedoverridevoidAttachToComponentRegistration(IComponentRegistry componentRegistry,IComponentRegistration registration)
    21 {
    22 var implementationType = registration.Activator.LimitType;
    23 
    24 // build an array of actions on this type to assign loggers to member properties
    25 var injectors =BuildLoggerInjectors(implementationType).ToArray();
    26 
    27 // if there are no logger properties, there's no reason to hook the activated event
    28 if(!injectors.Any())
    29 return;
    30 
    31 // otherwise, whan an instance of this component is activated, inject the loggers on the instance
    32  registration.Activated+=(s, e)=>
    33 {
    34 foreach(var injector in injectors)
    35  injector(e.Context, e.Instance);
    36 };
    37 }
    38 
    39 privateIEnumerable<Action<IComponentContext,object>>BuildLoggerInjectors(Type componentType)
    40 {
    41 // Look for settable properties of type "ILogger" 
    42 var loggerProperties = componentType
    43 .GetProperties(BindingFlags.SetProperty|BindingFlags.Public|BindingFlags.Instance)
    44 .Select(p =>new
    45 {
    46 PropertyInfo= p,
    47  p.PropertyType,
    48 IndexParameters= p.GetIndexParameters(),
    49 Accessors= p.GetAccessors(false)
    50 })
    51 .Where(x => x.PropertyType==typeof(ILogger))// must be a logger
    52 .Where(x => x.IndexParameters.Count()==0)// must not be an indexer
    53 .Where(x => x.Accessors.Length!=1|| x.Accessors[0].ReturnType==typeof(void));//must have get/set, or only set
    54 
    55 // Return an array of actions that resolve a logger and assign the property
    56 foreach(var entry in loggerProperties)
    57 {
    58 var propertyInfo = entry.PropertyInfo;
    59  yield return(ctx, instance)=>
    60 {
    61 string component = componentType.ToString();
    62 if(component != instance.GetType().ToString())
    63 {
    64 return;
    65 }
    66 var logger = _loggerCache.GetOrAdd(component, key => ctx.Resolve<ILogger>(newTypedParameter(typeof(Type), componentType)));
    67  propertyInfo.SetValue(instance, logger,null);
    68 };
    69 }
    70 }
    71 
    72 privatestaticILoggerCreateLogger(IComponentContext context,IEnumerable<Parameter> parameters)
    73 {
    74 // return an ILogger in response to Resolve<ILogger>(componentTypeParameter)
    75 var loggerFactory = context.Resolve<ILoggerFactory>();
    76 var containingType = parameters.TypedAs<Type>();
    77 return loggerFactory.CreateLogger(containingType);
    78 }
    79 }
    View Code
        
    1)   Load方法在 builder.Build()时会被调用,这里注册了 3个类型
    moduleBuilder.RegisterType<CastleLoggerFactory>().As<ILoggerFactory>().InstancePerLifetimeScope();
     
    moduleBuilder.RegisterType<OrchardLog4netFactory>().As<Castle.Core.Logging.ILoggerFactory>().InstancePerLifetimeScope().WithParameter(new NamedParameter("isFullTrust", false));
          
    moduleBuilder.Register(CreateLogger).As<ILogger>().InstancePerDependency();
     
    2) AttachToComponentRegistration方法也会在 builder.Build()时会被调用,它会调用BuildLoggerInjectors 方法。而 BuildLoggerInjectors方法会检查 类型 中的属性,如果属性是 ILogger接口,则会被替换为 CastleLogger或 OrchardLog4netLogger类。当然你也能注册为自定义的其他日志类型。
     
    四、log4net 设置
        orchard使用log4net作为日志的具体实现。配置如下
     1 <?xml version="1.0" encoding="utf-8"?>
     2 <log4net>
     3 <root>
     4 
     5 <priority value="ERROR"/>
     6 <appender-refref="error-file"/>
     7 </root>
     8 
     9 
    10 <logger name="NHibernate.Cache">
    11 <priority value="ERROR"/>
    12 </logger>
    13 
    14 <logger name="NHibernate.AdoNet.AbstractBatcher">
    15 <priority value="ERROR"/>
    16 </logger>
    17 
    18 <logger name="NHibernate.Util.ADOExceptionReporter">
    19 <priority value="ERROR"/>
    20 </logger>
    21 
    22 <appender name="error-file" type="Orchard.Logging.OrchardFileAppender">
    23 <file value="orchard-error"/>
    24 <appendToFile value="true"/>
    25 <immediateFlush value="false"/>
    26 <staticLogFileName value="false"/>
    27 <rollingStyle value="Date"/>
    28 <datepattern value="-yyyy.MM.dd'.log'"/>
    29 <lockingModel type="log4net.Appender.FileAppender+MinimalLock"/>
    30 <layout type="log4net.Layout.PatternLayout">
    31 <conversionPattern value="%date [%thread] %logger - %P{Tenant} - %message%newline %P{Url}%newline"/>
    32 </layout>
    33 </appender>
    34 </log4net>
    View Code
     
     
    五、orchard日志模块使用示例
    1、要使用日志的类型
    1.  1 /// <summary>
       2 /// 要使用日志的类型
       3 /// </summary>
       4 publicclassThing
       5 {
       6 publicThing()
       7 {
       8 Logger=NullLogger.Instance;
       9 }
      10 /// <summary>
      11 /// 设置类型为 ILogger 的属性
      12 /// </summary>
      13 publicILoggerLogger
      14 {
      15  get;
      16 set;
      17 }
      18 publicvoidTestMethod()
      19 {
      20 //这使用Log方法则 Logger属性 会被设置为 CastleLogger类;使用Error方法 Logger属性 会被设置为OrchardLog4netLogger类
      21 Logger.Log(Orchard.Logging.LogLevel.Error,newException("测试异常"),"测试异常使用CastleLogger类型");
      22 Logger.Error(newException("测试异常"),"测试异常使用OrchardLog4netLogger类型");
      23 }
      24 }
      View Code
    2、调用
    1. 1 publicvoidCreateTest()
      2 {
      3 var builder =newContainerBuilder();//构建autofac容器
      4 builder.RegisterModule(newLoggingModule());//注册LoggingModule
      5  builder.RegisterType<Thing>();//注册 Thing类型
      6 var container = builder.Build();//Build 容器
      7 var thing = container.Resolve<Thing>();//从容器中解析 Thing类型
      8 thing.TestMethod();//调用TestMethod方法,则会调用日志
      9 }
      View Code
     
     
        
     
     

     





  • 相关阅读:
    Spring Cloud(4):断路器(Hystrix)
    Spring Cloud(3):配置服务(Config)
    Spring Cloud(2):服务发现(Eureka)
    Docker常用命令
    Spring Cloud(1):概览
    Spring Cloud(0):目录
    Spring Boot JDBC:加载DataSource过程的源码分析及yml中DataSource的配置
    Java集合(7):散列与散列码
    [Linux]RabbitMQ
    [Linux]查看硬件及操作系统信息
  • 原文地址:https://www.cnblogs.com/matchcolor/p/4091995.html
Copyright © 2020-2023  润新知