前言:自定义写入日志,需要注意多线程下文件读取写入时异常问题处理:下面列举了2种优化方案:

废话不多说,直接上代码:

很简单:将类复制到项目中,最后在配置文件上配置一下:logUrl即可。 默认保存在:项目/temp/log

 自定义日志类1:

  1. /// <summary>
  2. /// 日志类
  3. /// </summary>
  4. /// <remarks>Creator: v-lxh CreateTime: 2016/7/26 11:18:09</remarks>
  5. /// <Description></Description>
  6. public class Log
  7. {
  8. /// <summary>
  9. /// 写入日志.
  10. /// </summary>
  11. /// <param name="strList">The STR list.</param>
  12. /// <remarks>Creator: v-lxh CreateTime: 2016/7/26 11:18:09</remarks>
  13. /// <Description></Description>
  14. public static void WriteLog(params object[] strList)
  15. {
  16. //判断是否开启日志模式
  17. //if (!LogModel) return;
  18. if (strList.Count() == ) return;
  19. //日志文件路径
  20. string strDicPath = "";
  21. try
  22. {
  23. strDicPath = HttpContext.Current.Server.MapPath("~/temp/log/");
  24. if (strDicPath == null || strDicPath == "")
  25. {
  26. strDicPath = System.Configuration.ConfigurationManager.AppSettings["logUrl"] + "/temp/log/";
  27. }
  28. }
  29. catch (Exception e)
  30. {
  31. strDicPath = System.Configuration.ConfigurationManager.AppSettings["logUrl"] + "/temp/log/";
  32. }
  33. string strPath = strDicPath + string.Format("{0:yyyy年-MM月-dd日}", DateTime.Now) + "日志记录.txt";
  34. if (!Directory.Exists(strDicPath))
  35. {
  36. Directory.CreateDirectory(strDicPath);
  37. }
  38. if (!File.Exists(strPath))
  39. {
  40. using (FileStream fs = File.Create(strPath)) { }
  41. }
  42. string str = File.ReadAllText(strPath);
  43. StringBuilder sb = new StringBuilder();
  44. foreach (var item in strList)
  45. {
  46. sb.Append("\r\n" + DateTime.Now.ToString() + "-----" + item + "");
  47. }
  48. File.WriteAllText(strPath, sb.ToString() + "\r\n-----z-----\r\n" + str);
  49. }
  50.  
  51. }

 初稿1--优化1-使用Lock锁定资源:

  1. /// <summary>
  2. /// 日志类
  3. /// </summary>
  4. /// <remarks>Creator: lixh CreateTime: 2017/3/23 11:18:09</remarks>
  5. /// <Description></Description>
  6. public class Log
  7. {
  8. //日期文件夹路径
  9. public static string strDicPath = "";
  10.  
  11. //静态方法todo:在处理话类型之前自动调用,去检查日志文件夹是否存在
  12. static Log()
  13. {
  14. //todo:通过当前http请求上下文获取的服务器相对路径下的物理路径--非静态资源--占用资源
  15. //string strDicPath = System.Web.HttpContext.Current.Server.MapPath("~/temp/log/");
  16.  
  17. //静态类型--获取应用所在的物理路径--节省资源
  18. //strDicPath = System.Web.HttpRuntime.AppDomainAppPath + "\\temp\\logs\\";
           //winform等非web程序可使用以下方法:
           strDicPath = System.Threading.Thread.GetDomain().BaseDirectory.Replace("\\bin\\Debug", "") + "\\temp\\logs\\";
  19. //创建文件夹
  20. if (!Directory.Exists(strDicPath))
  21. {
  22. Directory.CreateDirectory(strDicPath);
  23. }
  24. }
  25.  
  26. /// <summary>
  27. /// 写入日志.
  28. /// </summary>
  29. /// <param name="strList">The STR list.</param>
  30. /// <remarks> </remarks>
  31. /// <Description></Description>
  32. public static void WriteLog(params object[] strList)
  33. {
  34. if (strList.Count() == ) return;
  35. string strPath = ""; //文件路径
  36. try
  37. {
  38. strPath = strDicPath + string.Format("{0:yyyy年-MM月-dd日}", DateTime.Now) + "日志记录.txt";
  39. }
  40. catch (Exception e)
  41. {
  42. strDicPath = "C:\\temp\\log\\";
  43. strPath = strDicPath + string.Format("{0:yyyy年-MM月-dd日}", DateTime.Now) + "日志记录.txt";
  44. }
  45.  
  46. //todo:自动创建文件(但不能创建文件夹),并设置文件内容追加模式,使用using会自动释放FileSteam资源
  47. using (FileStream stream = new FileStream(strPath, FileMode.Append))
  48. {
  49. lock (stream) //锁定资源,一次只允许一个线程写入
  50. {
  51. StreamWriter write = new StreamWriter(stream);
  52. string content = "";
  53. foreach (var str in strList)
  54. {
  55. content += "\r\n" + DateTime.Now.ToString() + "-----" + str;
  56. }
  57. content += "\r\n-----z-----\r\n";
  58. write.WriteLine(content);
  59.  
  60. //关闭并销毁流写入文件
  61. write.Close();
  62. write.Dispose();
  63. }
  64. }
  65. }
  66.  
  67. /// <summary>
  68. /// 写入日志.
  69. /// </summary>
  70. /// <param name="strList">The STR list.</param>
  71. /// <remarks></remarks>
  72. /// <Description></Description>
  73. public static void WriteLog(Action DefFunc, Func<string> ErrorFunc = null)
  74. {
  75. try
  76. {
  77. DefFunc();
  78. }
  79. catch (Exception ex)
  80. {
  81. string strPath = strDicPath + string.Format("{0:yyyy年-MM月-dd日}", DateTime.Now) + "日志记录.txt";
  82.  
  83. //todo:自动创建文件(但不能创建文件夹),并设置文件内容追加模式,使用using会自动释放FileSteam资源
  84. using (FileStream stream = new FileStream(strPath, FileMode.Append))
  85. {
  86. lock (stream) //锁定资源,一次只允许一个线程写入
  87. {
  88. StreamWriter write = new StreamWriter(stream);
  89. string content = "\r\n" + DateTime.Now.ToString() + "-----" + ex.Message;
  90. content += "\r\n" + DateTime.Now.ToString() + "-----" + ex.StackTrace;
  91. content += "\r\n-----z-----\r\n";
  92. write.WriteLine(content);
  93.  
  94. //关闭并销毁流写入文件
  95. write.Close();
  96. write.Dispose();
  97. }
  98. }
  99. }
  100. }
  101. }

//初稿2-优化-使用微软提供的读写锁:

  1. //读写锁,当资源处于写入模式时,其他线程写入需要等待本次写入结束之后才能继续写入
  2. private static ReaderWriterLockSlim LogWriteLock = new ReaderWriterLockSlim();
  3. /// <summary>
  4. /// 写入日志.
  5. /// </summary>
  6. /// <param name="strList">The STR list.</param>
  7. /// <remarks> </remarks>
  8. /// <Description></Description>
  9. public static void WriteLog(params object[] strList)
  10. {
  11. if (strList.Count() == ) return;
  12. string strPath = ""; //文件路径
  13. try
  14. {
  15. strPath = strDicPath + string.Format("{0:yyyy年-MM月-dd日}", DateTime.Now) + "日志记录.txt";
  16. }
  17. catch (Exception e)
  18. {
  19. strDicPath = "C:\\temp\\log\\";
  20. strPath = strDicPath + string.Format("{0:yyyy年-MM月-dd日}", DateTime.Now) + "日志记录.txt";
  21. }
  22.  
  23. try
  24. {
  25. //todo:自动创建文件(但不能创建文件夹),并设置文件内容追加模式,使用using会自动释放FileSteam资源
  26. LogWriteLock.EnterWriteLock();
  27.  
  28. using (FileStream stream = new FileStream(strPath, FileMode.Append))
  29. {
  30. StreamWriter write = new StreamWriter(stream);
  31. string content = "";
  32. foreach (var str in strList)
  33. {
  34. content += "\r\n" + DateTime.Now.ToString() + "-----" + str;
  35. }
  36. content += "\r\n-----z-----\r\n";
  37. write.WriteLine(content);
  38.  
  39. //关闭并销毁流写入文件
  40. write.Close();
  41. write.Dispose();
  42. }
  43. }
  44. catch (Exception)
  45. {
  46.  
  47. }
  48. finally {
  49. LogWriteLock.ExitWriteLock();
  50. }
  51. }

c#自定义日志记录的更多相关文章

  1. Windows server2012 IIs 8 自定义日志记录

    问题: 通过CDN加速的网站,记录日志时无法追踪源IP,日志的IP都为CDN节点ip. 分析: 1.在解析记录header时,CDN实际会把源IP以其它header的形式回传,如网宿为[Cdn-Src ...

  2. shell脚本中自定义日志记录到文件

    自定义日志函数和前期变量 # adirname - return absolute dirname of given file adirname() { odir=`pwd`; cd `dirname ...

  3. 基于.NetCore3.1系列 —— 日志记录之自定义日志组件

    一.前言 回顾:日志记录之日志核心要素揭秘 在上一篇中,我们通过学习了解在.net core 中内置的日志记录中的几大核心要素,在日志工厂记录器(ILoggerFactory)中实现将日志记录提供器( ...

  4. IIS 7完全攻略之日志记录配置(摘自网络)

    IIS 7完全攻略之日志记录配置 作者:泉之源 [IT168 专稿]除了 Windows 提供的日志记录功能外,IIS 7.0 还可以提供其他日志记录功能.例如,可以选择日志文件格式并指定要记录的请求 ...

  5. ASP.NET MVC自定义Module记录管道事件执行顺序

    1. 在Visual Studio 新建项目,模板为空,下面结构选择MVC. 2. 在项目中新建一个类MyModule,实现IHttpModule接口 namespace SimpleApp.Infr ...

  6. 如何自行给指定的SAP OData服务添加自定义日志记录功能

    有的时候,SAP标准的OData实现或者相关的工具没有提供我们想记录的日志功能,此时可以利用SAP系统强大的扩展特性,进行自定义日志功能的二次开发. 以SAP CRM Fiori应用"My ...

  7. 基于.NetCore3.1系列 —— 日志记录之初识Serilog

    一.前言 对内置日志系统的整体实现进行了介绍之后,可以通过使用内置记录器来实现日志的输出路径.而在实际项目开发中,使用第三方日志框架(如: Log4Net.NLog.Loggr.Serilog.Sen ...

  8. 如何定制.NET6.0的日志记录

    在本章中,也就是整个系列的第一部分将介绍如何定制日志记录.默认日志记录仅写入控制台或调试窗口,这在大多数情况下都很好,但有时需要写入到文件或数据库,或者,您可能希望扩展日志记录的其他信息.在这些情况下 ...

  9. ASP.NET全局错误处理和异常日志记录以及IIS配置自定义错误页面

    应用场景和使用目的 很多时候,我们在访问页面的时候,由于程序异常.系统崩溃会导致出现黄页.在通常的情况下,黄页对于我们来说,帮助是极大的,因为它可以帮助我们知道问题根源,甚至是哪一行代码出现了错误.但 ...

随机推荐

  1. CYQ.Data V5 数据库读写分离功能介绍

    前言 好多年没写关于此框架的新功能的介绍了,这些年一直在默默地更新,从Nuget上的记录就可以看出来: 这几天在看Java的一些东西,除了觉的Java和.NET的相似度实在太高之外,就是Java太原始 ...

  2. 初探ReactJS.NET 开发

    ReactJS通常也被称为"React",是一个刚刚在这场游戏中登场的新手.它由Facebook创建,并在2013年首次发布.Facebook认为React在处理SPA问题上可以成 ...

  3. 一步步学习javascript基础篇(2):作用域和作用域链

    作用域和作用域链 js的语法用法非常的灵活,且稍不注意就踩坑.这集来分析下作用域和作用域链.我们且从几道题目入手,您可以试着在心里猜想着答案. 问题一. if (true) { var str = & ...

  4. AngularJS 中的Promise --- $q服务详解

    先说说什么是Promise,什么是$q吧.Promise是一种异步处理模式,有很多的实现方式,比如著名的Kris Kwal's Q还有JQuery的Deffered. 什么是Promise 以前了解过 ...

  5. Redhat环境下编译安装Google Bazel

    Redhat环境下编译安装bazel 作者:Jack47 目前Google Bazel没有提供各个操作系统下的二进制安装包,只提供源代码,需要我们自己编译安装,详情可以见我翻译的中文版Google B ...

  6. 三周,用长轮询实现Chat并迁移到Azure测试

    公司的OA从零开始进行开发,继简单的单点登陆.角色与权限.消息中间件之后,轮到在线即时通信的模块需要我独立去完成.这三周除了逛网店见爱*看动漫接兼职,基本上都花在这上面了.简单地说就是用MVC4基于长 ...

  7. ASP.NET MVC Routing学习笔记(一)

    Routing在ASP.NET MVC中是非常核心的技术,属于ASP.NET MVC几大核心技术之一,在使用Routing之前,得先引入System.Web.Routing,但其实不用这么麻烦,因为在 ...

  8. Java基础-输入输出-2.编写IoDemo.java的Java应用程序,程序完成的功能是:首先读取text.txt文件内容,再通过键盘输入文件的名称为iodemo.txt,把text.txt的内容存入iodemo.txt

    2.编写IoDemo.java的Java应用程序,程序完成的功能是:首先读取text.txt文件内容,再通过键盘输入文件的名称为iodemo.txt,把text.txt的内容存入iodemo.txt ...

  9. Jetty Maven Plugin配置

    官方文档:http://www.eclipse.org/jetty/documentation/current/jetty-maven-plugin.html#maven-config-https 1 ...

  10. 谈谈php里的DAO Model AR

    这次要谈的3个关键字:DAO.Model.AR,是我们在做web应用时常见的几个概念,也被称作设计模式(design pattern),先简单看看它们的全拼和中文: DAO:Data Access O ...