参考了ABP的代码,我也用依赖注入的原则,设计了日志模块。

与abp不同之处在于:1)DI容器使用的是.net core自带的注入容器,2)集成了excetpionless日志模块,3)不依赖于abp

主要的思想就是,1)定义日志操作接口 2)使用log4net实现日志接口,3)实现注入  4)使用日志

1)定义日志接口,这里直接使用了castle的日志接口

2)使用log4net实现日志接口

  1. [Serializable]
  2. public class Log4NetLogger :
  3. MarshalByRefObject,
  4. ILogger
  5. {
  6. private static readonly Type DeclaringType = typeof(Log4NetLogger);
  7.  
  8. private log4net.Core.ILogger _logger;
  9. private Log4NetLoggerFactory _factory;
  10. public Log4NetLogger()
  11. {
  12. _factory = new Log4NetLoggerFactory();
  13. _logger = _factory.GetLogger("cislog");
  14. }
  15.  
  16. public bool IsDebugEnabled
  17. {
  18. get { return _logger.IsEnabledFor(Level.Debug); }
  19. }
  20.  
  21. public bool IsErrorEnabled
  22. {
  23. get { return _logger.IsEnabledFor(Level.Error); }
  24. }
  25.  
  26. public bool IsFatalEnabled
  27. {
  28. get { return _logger.IsEnabledFor(Level.Fatal); }
  29. }
  30.  
  31. public bool IsInfoEnabled
  32. {
  33. get { return _logger.IsEnabledFor(Level.Info); }
  34. }
  35.  
  36. public bool IsWarnEnabled
  37. {
  38. get { return _logger.IsEnabledFor(Level.Warn); }
  39. }
  40.  
  41. public override string ToString()
  42. {
  43. return _logger.ToString();
  44. }
  45.  
  46. public void Debug(string message)
  47. {
  48. if (IsDebugEnabled)
  49. {
  50. _logger.Log(DeclaringType, Level.Debug, message, null);
  51. }
  52. }
  53.  
  54. public void Debug(Func<string> messageFactory)
  55. {
  56. if (IsDebugEnabled)
  57. {
  58. _logger.Log(DeclaringType, Level.Debug, messageFactory.Invoke(), null);
  59. }
  60. }
  61.  
  62. public void Debug(string message, Exception exception)
  63. {
  64. if (IsDebugEnabled)
  65. {
  66. _logger.Log(DeclaringType, Level.Debug, message, exception);
  67. }
  68. }
  69.  
  70. public void DebugFormat(string format, params Object[] args)
  71. {
  72. if (IsDebugEnabled)
  73. {
  74. _logger.Log(DeclaringType, Level.Debug, new SystemStringFormat(CultureInfo.InvariantCulture, format, args), null);
  75. }
  76. }
  77.  
  78. public void DebugFormat(Exception exception, string format, params Object[] args)
  79. {
  80. if (IsDebugEnabled)
  81. {
  82. _logger.Log(DeclaringType, Level.Debug, new SystemStringFormat(CultureInfo.InvariantCulture, format, args), exception);
  83. }
  84. }
  85.  
  86. public void DebugFormat(IFormatProvider formatProvider, string format, params Object[] args)
  87. {
  88. if (IsDebugEnabled)
  89. {
  90. _logger.Log(DeclaringType, Level.Debug, new SystemStringFormat(formatProvider, format, args), null);
  91. }
  92. }
  93.  
  94. public void DebugFormat(Exception exception, IFormatProvider formatProvider, string format, params Object[] args)
  95. {
  96. if (IsDebugEnabled)
  97. {
  98. _logger.Log(DeclaringType, Level.Debug, new SystemStringFormat(formatProvider, format, args), exception);
  99. }
  100. }
  101.  
  102. public void Error(string message)
  103. {
  104. if (IsErrorEnabled)
  105. {
  106. _logger.Log(DeclaringType, Level.Error, message, null);
  107. }
  108. }
  109.  
  110. public void Error(Func<string> messageFactory)
  111. {
  112. if (IsErrorEnabled)
  113. {
  114. _logger.Log(DeclaringType, Level.Error, messageFactory.Invoke(), null);
  115. }
  116. }
  117.  
  118. public void Error(string message, Exception exception)
  119. {
  120. if (IsErrorEnabled)
  121. {
  122. _logger.Log(DeclaringType, Level.Error, message, exception);
  123. }
  124. }
  125.  
  126. public void ErrorFormat(string format, params Object[] args)
  127. {
  128. if (IsErrorEnabled)
  129. {
  130. _logger.Log(DeclaringType, Level.Error, new SystemStringFormat(CultureInfo.InvariantCulture, format, args), null);
  131. }
  132. }
  133.  
  134. public void ErrorFormat(Exception exception, string format, params Object[] args)
  135. {
  136. if (IsErrorEnabled)
  137. {
  138. _logger.Log(DeclaringType, Level.Error, new SystemStringFormat(CultureInfo.InvariantCulture, format, args), exception);
  139. }
  140. }
  141.  
  142. public void ErrorFormat(IFormatProvider formatProvider, string format, params Object[] args)
  143. {
  144. if (IsErrorEnabled)
  145. {
  146. _logger.Log(DeclaringType, Level.Error, new SystemStringFormat(formatProvider, format, args), null);
  147. }
  148. }
  149.  
  150. public void ErrorFormat(Exception exception, IFormatProvider formatProvider, string format, params Object[] args)
  151. {
  152. if (IsErrorEnabled)
  153. {
  154. _logger.Log(DeclaringType, Level.Error, new SystemStringFormat(formatProvider, format, args), exception);
  155. }
  156. }
  157.  
  158. public void Fatal(string message)
  159. {
  160. if (IsFatalEnabled)
  161. {
  162. _logger.Log(DeclaringType, Level.Fatal, message, null);
  163. }
  164. }
  165.  
  166. public void Fatal(Func<string> messageFactory)
  167. {
  168. if (IsFatalEnabled)
  169. {
  170. _logger.Log(DeclaringType, Level.Fatal, messageFactory.Invoke(), null);
  171. }
  172. }
  173.  
  174. public void Fatal(string message, Exception exception)
  175. {
  176. if (IsFatalEnabled)
  177. {
  178. _logger.Log(DeclaringType, Level.Fatal, message, exception);
  179. }
  180. }
  181.  
  182. public void FatalFormat(string format, params Object[] args)
  183. {
  184. if (IsFatalEnabled)
  185. {
  186. _logger.Log(DeclaringType, Level.Fatal, new SystemStringFormat(CultureInfo.InvariantCulture, format, args), null);
  187. }
  188. }
  189.  
  190. public void FatalFormat(Exception exception, string format, params Object[] args)
  191. {
  192. if (IsFatalEnabled)
  193. {
  194. _logger.Log(DeclaringType, Level.Fatal, new SystemStringFormat(CultureInfo.InvariantCulture, format, args), exception);
  195. }
  196. }
  197.  
  198. public void FatalFormat(IFormatProvider formatProvider, string format, params Object[] args)
  199. {
  200. if (IsFatalEnabled)
  201. {
  202. _logger.Log(DeclaringType, Level.Fatal, new SystemStringFormat(formatProvider, format, args), null);
  203. }
  204. }
  205.  
  206. public void FatalFormat(Exception exception, IFormatProvider formatProvider, string format, params Object[] args)
  207. {
  208. if (IsFatalEnabled)
  209. {
  210. _logger.Log(DeclaringType, Level.Fatal, new SystemStringFormat(formatProvider, format, args), exception);
  211. }
  212. }
  213.  
  214. public void Info(string message)
  215. {
  216. if (IsInfoEnabled)
  217. {
  218. _logger.Log(DeclaringType, Level.Info, message, null);
  219. }
  220. }
  221.  
  222. public void Info(Func<string> messageFactory)
  223. {
  224. if (IsInfoEnabled)
  225. {
  226. _logger.Log(DeclaringType, Level.Info, messageFactory.Invoke(), null);
  227. }
  228. }
  229.  
  230. public void Info(string message, Exception exception)
  231. {
  232. if (IsInfoEnabled)
  233. {
  234. _logger.Log(DeclaringType, Level.Info, message, exception);
  235. }
  236. }
  237.  
  238. public void InfoFormat(string format, params Object[] args)
  239. {
  240. if (IsInfoEnabled)
  241. {
  242. _logger.Log(DeclaringType, Level.Info, new SystemStringFormat(CultureInfo.InvariantCulture, format, args), null);
  243. }
  244. }
  245.  
  246. public void InfoFormat(Exception exception, string format, params Object[] args)
  247. {
  248. if (IsInfoEnabled)
  249. {
  250. _logger.Log(DeclaringType, Level.Info, new SystemStringFormat(CultureInfo.InvariantCulture, format, args), exception);
  251. }
  252. }
  253.  
  254. public void InfoFormat(IFormatProvider formatProvider, string format, params Object[] args)
  255. {
  256. if (IsInfoEnabled)
  257. {
  258. _logger.Log(DeclaringType, Level.Info, new SystemStringFormat(formatProvider, format, args), null);
  259. }
  260. }
  261.  
  262. public void InfoFormat(Exception exception, IFormatProvider formatProvider, string format, params Object[] args)
  263. {
  264. if (IsInfoEnabled)
  265. {
  266. _logger.Log(DeclaringType, Level.Info, new SystemStringFormat(formatProvider, format, args), exception);
  267. }
  268. }
  269.  
  270. public void Warn(string message)
  271. {
  272. if (IsWarnEnabled)
  273. {
  274. _logger.Log(DeclaringType, Level.Warn, message, null);
  275. }
  276. }
  277.  
  278. public void Warn(Func<string> messageFactory)
  279. {
  280. if (IsWarnEnabled)
  281. {
  282. _logger.Log(DeclaringType, Level.Warn, messageFactory.Invoke(), null);
  283. }
  284. }
  285.  
  286. public void Warn(string message, Exception exception)
  287. {
  288. if (IsWarnEnabled)
  289. {
  290. _logger.Log(DeclaringType, Level.Warn, message, exception);
  291. }
  292. }
  293.  
  294. public void WarnFormat(string format, params Object[] args)
  295. {
  296. if (IsWarnEnabled)
  297. {
  298. _logger.Log(DeclaringType, Level.Warn, new SystemStringFormat(CultureInfo.InvariantCulture, format, args), null);
  299. }
  300. }
  301.  
  302. public void WarnFormat(Exception exception, string format, params Object[] args)
  303. {
  304. if (IsWarnEnabled)
  305. {
  306. _logger.Log(DeclaringType, Level.Warn, new SystemStringFormat(CultureInfo.InvariantCulture, format, args), exception);
  307. }
  308. }
  309.  
  310. public void WarnFormat(IFormatProvider formatProvider, string format, params Object[] args)
  311. {
  312. if (IsWarnEnabled)
  313. {
  314. _logger.Log(DeclaringType, Level.Warn, new SystemStringFormat(formatProvider, format, args), null);
  315. }
  316. }
  317.  
  318. public void WarnFormat(Exception exception, IFormatProvider formatProvider, string format, params Object[] args)
  319. {
  320. if (IsWarnEnabled)
  321. {
  322. _logger.Log(DeclaringType, Level.Warn, new SystemStringFormat(formatProvider, format, args), exception);
  323. }
  324. }
  325.  
  326. public ILogger CreateChildLogger(string loggerName)
  327. {
  328. throw new NotImplementedException();
  329. }
  330. }
  1. public class Log4NetLoggerFactory : AbstractLoggerFactory
  2. {
  3. internal const string DefaultConfigFileName = "log4net.config";
  4. private readonly ILoggerRepository _loggerRepository;
  5.  
  6. public Log4NetLoggerFactory()
  7. : this(DefaultConfigFileName)
  8. {
  9. }
  10.  
  11. public Log4NetLoggerFactory(string configFileName)
  12. {
  13. _loggerRepository = LogManager.CreateRepository(
  14. typeof(Log4NetLoggerFactory).GetAssembly(),
  15. typeof(log4net.Repository.Hierarchy.Hierarchy)
  16. );
  17.  
  18. XmlConfigurator.Configure(_loggerRepository, new FileInfo("log4net.config"));
  19. }
  20.  
  21. public log4net.Core.ILogger GetLogger(string name)
  22. {
  23. return LogManager.GetLogger(_loggerRepository.Name, name).Logger;
  24. }
  25.  
  26. public override ILogger Create(string name)
  27. {
  28. if (name == null)
  29. {
  30. throw new ArgumentNullException(nameof(name));
  31. }
  32.  
  33. return new Log4NetLogger();
  34. }
  35.  
  36. public override ILogger Create(string name, LoggerLevel level)
  37. {
  38. throw new NotSupportedException("Logger levels cannot be set at runtime. Please review your configuration file.");
  39. }
  40. }
  41.  
  42. public static class TypeExtensions
  43. {
  44. public static Assembly GetAssembly(this Type type)
  45. {
  46. return type.GetTypeInfo().Assembly;
  47. }
  48. }

下面是扩展方法,这里实现注入:

  1. public static class Log4NetLoggerExtensions
  2. {
  3. public static IServiceCollection UseExceptionless(this IServiceCollection services)
  4. {
  5. services.AddTransient<ILogger, Log4NetLogger>();
  6.  
  7. return services;
  8. }
  9. }

然后就可以在startup中使用了

  1. public void ConfigureServices(IServiceCollection services)
  2. {
  3. services.AddMvc();
  4. services.UseExceptionless();
  5. }

比如我们在HomeController中使用:

  1. public class HomeController : Controller
  2. {
  3. private ILogger _logger;
  4.  
  5. public HomeController(ILogger logger)
  6. {
  7. _logger = logger;
  8. }
  9. public IActionResult Index()
  10. {
  11. // throw new Exception("快点来!!!!!!!!!!!!!!!!!!");
  12. _logger.Info("index view");
  13. _logger.Debug("出错了!,快点来,!!");
  14. _logger.Error("Controller Error");
  15. return View();
  16. }
  17. }

最后是配置文件:

最重要的是注意exceptionless的配置

  1. <?xml version="1.0" encoding="utf-8" ?>
  2. <configuration>
  3. <!-- This section contains the log4net configuration settings -->
  4. <log4net>
  5. <appender name="ConsoleAppender" type="log4net.Appender.ConsoleAppender">
  6. <layout type="log4net.Layout.PatternLayout" value="%date [%thread] %-5level %logger - %message%newline" />
  7. </appender>
  8. <appender name="RollingLogFileAppender" type="log4net.Appender.RollingFileAppender">
  9. <file value="Logs/" />
  10. <appendToFile value="true" />
  11. <rollingStyle value="Composite" />
  12. <staticLogFileName value="false" />
  13. <datePattern value="yyyy-MM-dd'.log'" />
  14. <maxSizeRollBackups value="10" />
  15. <maximumFileSize value="1MB" />
  16. <layout type="log4net.Layout.PatternLayout">
  17. <conversionPattern value="%date [%thread] %-5level %logger [%property{NDC}] - %message%newline" />
  18. </layout>
  19. </appender>
  20. <appender name="Exceptionless" type="Exceptionless.Log4net.ExceptionlessAppender,Exceptionless.Log4net">
  21. <apiKey value="d5qna1t9qTUVwrRzLFz1T3z8wSUeO3xNtxOGMHLf" />
  22. <serverUrl value="http://10.117.130.150:9001" />
  23. <layout type="log4net.Layout.PatternLayout">
  24. <conversionPattern value="%-4timestamp [%thread] %-5level %logger %ndc - %message%newline"/>
  25. </layout>
  26. </appender>
  27. <!-- Setup the root category, add the appenders and set the default level -->
  28. <root>
  29. <level value="ALL" />
  30. <appender-ref ref="ConsoleAppender" />
  31. <appender-ref ref="RollingLogFileAppender" />
  32. <appender-ref ref="Exceptionless"/>
  33. </root>
  34. </log4net>
  35. </configuration>

还有一点非常重要,记得引用,否则在exceptionless中也看不到日志

效果如图:

最后,提一点:

现在容器技术很火,如果把这套代码放在容器中运行肯定是不行,因为在配置文件中配置了apikey和url, 所以要稍做修改如下:

添加一个类:

  1. public class ExceptionlessOption
  2. {
  3. /// <summary>
  4. /// 日志应用标识,从Exceptionless面板获取
  5. /// </summary>
  6. public string ApiKey { get; set; }
  7.  
  8. /// <summary>
  9. /// 日志应用接口地址
  10. /// </summary>
  11. public string Url { get; set; }
  12. }
  1. services.AddMvc();
  2.  
  3. services.UseExceptionless(() =>
  4. {
  5. return new ExceptionlessOption {
  6. ApiKey = "234na1t9qTU234234234z8wSUeO3x234234HLf",
  7. Url = "http://100.11.13.10:9001" };
  8. });
  1. public Log4NetLoggerFactory(ExceptionlessOption _option, string configFileName)
  2. {
  3. _loggerRepository = LogManager.CreateRepository(
  4. typeof(Log4NetLoggerFactory).GetAssembly(),
  5. typeof(log4net.Repository.Hierarchy.Hierarchy)
  6. );
  7. //读取配置
  8. XmlConfigurator.Configure(_loggerRepository, new FileInfo("log4net.config"));
  9.  
  10. //TODO这里修改
  11. ExceptionlessClient.Default.Configuration.ApiKey = _option.ApiKey ?? "d5qna1t9qTUVwrRzLFz1T3z8wSUeO3xNtxOGMHLf";
  12. ExceptionlessClient.Default.Configuration.ServerUrl = _option.Url ?? "http://10.117.130.150:9001";
  13.  
  14. }

然后你就可以在startup中通过读取配置文件,实现参数的传入了。

asp.net core + log4net+exceptionles+DI的更多相关文章

  1. Asp.net Core + Log4net + ELK 搭建日志中心

    原文:Asp.net Core + Log4net + ELK 搭建日志中心 Docker中一键安装ELK 对于这种工具类的东西,第一步就直接到docker的hub中查找了,很幸运,不仅有Elasti ...

  2. 浅谈ASP.NET Core中的DI

    DI的一些事 传送门马丁大叔的文章 什么是依赖注入(DI: Dependency Injection)?     依赖注入(DI)是一种面向对象的软件设计模式,主要是帮助开发人员开发出松耦合的应用程序 ...

  3. asp.net core 四 IOC&DI Autofac

    其实关于IOC,DI已经有了很多的文章,但是自己在使用中还是有很多困惑,而且相信自己使用下,印象还是会比较深刻的 关于这段时间一直在学习.net core,但是这篇文章是比较重要的,也是我自己觉得学习 ...

  4. 在Asp.Net Core中使用DI的方式使用Hangfire构建后台执行脚本

    最近项目中需要用到后台Job,原有在Windows中我们会使用命令行程序结合计划任务或者直接生成Windows Service,现在.Net Core跨平台了,虽然Linux下也有计划任务,但跟原有方 ...

  5. ASP.NET Core 依赖注入(DI)

    ASP.NET Core的底层设计支持和使用依赖注入.ASP.NET Core 应用程序可以利用内置的框架服务将服务注入到启动类的方法中,并且应用程序服务也可以配置注入.由ASP.NET Core 提 ...

  6. ASP.NET Core依赖注入(DI)

    ASP.NET Core允许我们指定注册服务的生存期.服务实例将根据指定的生存时间自动处理.因此,我们无需担心清理此依赖关系,他将由ASP.NET Core框架处理.有如下三种类型的生命周期. 关于依 ...

  7. asp.net core 内置DI容器的一点小理解

    DI容器本质上是一个工厂,负责提供向它请求的类型的实例. .net core内置了一个轻量级的DI容器,方便开发人员面向接口编程和依赖倒置(IOC). 具体体现为Micorosoft.Extensio ...

  8. Asp.net core 学习笔记 ( DI 依赖注入 )

    比起 Angular 的依赖注入, core 的相对简单许多, 容易明白 所有 provider 都在 startup 里配置. public void ConfigureServices(IServ ...

  9. Asp.Net Core Log4Net 配置分多个文件记录日志(不同日志级别)

    本文所有配置都是在core3.1环境下. 首先看看最终的效果. 请求监控:对每次请求的相关信息做一个记录. 全局异常:我不想我的错误信息,跟其他的信息混合在一起,查看的时候不大方便. 应用日志:这个主 ...

随机推荐

  1. ActiveMQ 详解

    1. 如何同步索引库 方案一: 在taotao-manager中,添加商品的业务逻辑中,添加一个同步索引库的业务逻辑; 缺点:业务逻辑耦合度高,业务拆分不明确; 方案二: 业务逻辑在taotato-s ...

  2. 【npm start 启动失败】ubuntu 将node和npm同时更新到最新的稳定版本

    https://blog.csdn.net/u010277553/article/details/80938829 npm start 启动失败,报错如下 错误提示 make sure you hav ...

  3. 漫谈JS 的继承方式

    一.原型链原型链的基本思想是利用原型让一个引用类型继承另一个引用类型的属性和方法.每一个构造函数都有一个原型对象,原型对象都包含一个指向构造函数的指针,而实例都包含一个指向原型对象的指针.如果:我们让 ...

  4. 爬虫之FileCookieJar

    简介 虽然CookieJar模块能够做到给请求设置cookie,但是它的cookie是保存在内存里的,每次用都需要重新设置, 这就衍生了一个它的子类---FileCookieJar,它可以将cooki ...

  5. Django-vue之emement-ui,绑定图片,页面挂载,路由跳转

    一  emement-ui使用 首先在终端下载安装:npm install element-ui 在vue项目中的main.js下: import ElementUI from 'element-ui ...

  6. ROC与AUC学习

    全文转自:https://www.cnblogs.com/gatherstars/p/6084696.html#commentform 这篇真的讲的清楚明白!要多复习!加深记忆! 1.概述 AUC(A ...

  7. javascript 类型 内存 对象

    var box =0 function test() { alert(box) //全局 }

  8. 基于bootstrap metronic-responsive-admin-dashboard-template 开发管理后台

    简单介绍 我们这个系统是基于bootstrap metronic-responsive-admin-dashboard-template 这个模板开发的.版本用的是metronic_v4.5.2 效果 ...

  9. 开源BBS论坛软件推荐

    七款开源BBS论坛软件推荐(1) 本文介绍了七个开源的BBS论坛软件(在英文界一般叫做Forum).可能国内的朋友们比较熟悉Discuz!和PHPwind,但其实我们的选择还是很多的,而且下面介绍的这 ...

  10. SpringCloud Config Server中{application}等占位符使用场景设置默认拉去分支

    Spring Cloud Config服务器支持一个Git仓库URL,其中包含{application}和{profile}(以及{label})的占位符. 1.各个占位符所代表的含义 applica ...