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

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

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

 自定义日志类1:

/// <summary>
/// 日志类
/// </summary>
/// <remarks>Creator: v-lxh CreateTime: 2016/7/26 11:18:09</remarks>
/// <Description></Description>
public class Log
{
/// <summary>
/// 写入日志.
/// </summary>
/// <param name="strList">The STR list.</param>
/// <remarks>Creator: v-lxh CreateTime: 2016/7/26 11:18:09</remarks>
/// <Description></Description>
public static void WriteLog(params object[] strList)
{
//判断是否开启日志模式
//if (!LogModel) return;
if (strList.Count() == ) return;
//日志文件路径
string strDicPath = "";
try
{
strDicPath = HttpContext.Current.Server.MapPath("~/temp/log/");
if (strDicPath == null || strDicPath == "")
{
strDicPath = System.Configuration.ConfigurationManager.AppSettings["logUrl"] + "/temp/log/";
}
}
catch (Exception e)
{
strDicPath = System.Configuration.ConfigurationManager.AppSettings["logUrl"] + "/temp/log/";
}
string strPath = strDicPath + string.Format("{0:yyyy年-MM月-dd日}", DateTime.Now) + "日志记录.txt";
if (!Directory.Exists(strDicPath))
{
Directory.CreateDirectory(strDicPath);
}
if (!File.Exists(strPath))
{
using (FileStream fs = File.Create(strPath)) { }
}
string str = File.ReadAllText(strPath);
StringBuilder sb = new StringBuilder();
foreach (var item in strList)
{
sb.Append("\r\n" + DateTime.Now.ToString() + "-----" + item + "");
}
File.WriteAllText(strPath, sb.ToString() + "\r\n-----z-----\r\n" + str);
} }

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

   /// <summary>
/// 日志类
/// </summary>
/// <remarks>Creator: lixh CreateTime: 2017/3/23 11:18:09</remarks>
/// <Description></Description>
public class Log
{
//日期文件夹路径
public static string strDicPath = ""; //静态方法todo:在处理话类型之前自动调用,去检查日志文件夹是否存在
static Log()
{
//todo:通过当前http请求上下文获取的服务器相对路径下的物理路径--非静态资源--占用资源
//string strDicPath = System.Web.HttpContext.Current.Server.MapPath("~/temp/log/"); //静态类型--获取应用所在的物理路径--节省资源
//strDicPath = System.Web.HttpRuntime.AppDomainAppPath + "\\temp\\logs\\";
       //winform等非web程序可使用以下方法:
       strDicPath = System.Threading.Thread.GetDomain().BaseDirectory.Replace("\\bin\\Debug", "") + "\\temp\\logs\\";
//创建文件夹
if (!Directory.Exists(strDicPath))
{
Directory.CreateDirectory(strDicPath);
}
} /// <summary>
/// 写入日志.
/// </summary>
/// <param name="strList">The STR list.</param>
/// <remarks> </remarks>
/// <Description></Description>
public static void WriteLog(params object[] strList)
{
if (strList.Count() == ) return;
string strPath = ""; //文件路径
try
{
strPath = strDicPath + string.Format("{0:yyyy年-MM月-dd日}", DateTime.Now) + "日志记录.txt";
}
catch (Exception e)
{
strDicPath = "C:\\temp\\log\\";
strPath = strDicPath + string.Format("{0:yyyy年-MM月-dd日}", DateTime.Now) + "日志记录.txt";
} //todo:自动创建文件(但不能创建文件夹),并设置文件内容追加模式,使用using会自动释放FileSteam资源
using (FileStream stream = new FileStream(strPath, FileMode.Append))
{
lock (stream) //锁定资源,一次只允许一个线程写入
{
StreamWriter write = new StreamWriter(stream);
string content = "";
foreach (var str in strList)
{
content += "\r\n" + DateTime.Now.ToString() + "-----" + str;
}
content += "\r\n-----z-----\r\n";
write.WriteLine(content); //关闭并销毁流写入文件
write.Close();
write.Dispose();
}
}
} /// <summary>
/// 写入日志.
/// </summary>
/// <param name="strList">The STR list.</param>
/// <remarks></remarks>
/// <Description></Description>
public static void WriteLog(Action DefFunc, Func<string> ErrorFunc = null)
{
try
{
DefFunc();
}
catch (Exception ex)
{
string strPath = strDicPath + string.Format("{0:yyyy年-MM月-dd日}", DateTime.Now) + "日志记录.txt"; //todo:自动创建文件(但不能创建文件夹),并设置文件内容追加模式,使用using会自动释放FileSteam资源
using (FileStream stream = new FileStream(strPath, FileMode.Append))
{
lock (stream) //锁定资源,一次只允许一个线程写入
{
StreamWriter write = new StreamWriter(stream);
string content = "\r\n" + DateTime.Now.ToString() + "-----" + ex.Message;
content += "\r\n" + DateTime.Now.ToString() + "-----" + ex.StackTrace;
content += "\r\n-----z-----\r\n";
write.WriteLine(content); //关闭并销毁流写入文件
write.Close();
write.Dispose();
}
}
}
}
}

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

//读写锁,当资源处于写入模式时,其他线程写入需要等待本次写入结束之后才能继续写入
private static ReaderWriterLockSlim LogWriteLock = new ReaderWriterLockSlim();
/// <summary>
/// 写入日志.
/// </summary>
/// <param name="strList">The STR list.</param>
/// <remarks> </remarks>
/// <Description></Description>
public static void WriteLog(params object[] strList)
{
if (strList.Count() == ) return;
string strPath = ""; //文件路径
try
{
strPath = strDicPath + string.Format("{0:yyyy年-MM月-dd日}", DateTime.Now) + "日志记录.txt";
}
catch (Exception e)
{
strDicPath = "C:\\temp\\log\\";
strPath = strDicPath + string.Format("{0:yyyy年-MM月-dd日}", DateTime.Now) + "日志记录.txt";
} try
{
//todo:自动创建文件(但不能创建文件夹),并设置文件内容追加模式,使用using会自动释放FileSteam资源
LogWriteLock.EnterWriteLock(); using (FileStream stream = new FileStream(strPath, FileMode.Append))
{
StreamWriter write = new StreamWriter(stream);
string content = "";
foreach (var str in strList)
{
content += "\r\n" + DateTime.Now.ToString() + "-----" + str;
}
content += "\r\n-----z-----\r\n";
write.WriteLine(content); //关闭并销毁流写入文件
write.Close();
write.Dispose();
}
}
catch (Exception)
{ }
finally {
LogWriteLock.ExitWriteLock();
}
}

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. Visual Studio 2015 前端开发工作流

    Visual Studio 2015 CTP 5,全称为 Visual Studio 2015 Community Technology Preview 5,意为社区技术预览版,之前的版本为:Visu ...

  2. ABP理论学习之仓储

    返回总目录 本篇目录 IRepository接口 查询 插入 更新 删除 其他 关于异步方法 仓储实现 管理数据库连接 仓储的生命周期 仓储最佳实践 Martin Fowler对仓储的定义 位于领域层 ...

  3. Unity3D游戏开发初探—1.跨平台的游戏引擎让.NET程序员新生

    一.Unity3D平台简介 Unity是由Unity Technologies开发的一个让轻松创建诸如三维视频游戏.建筑可视化.实时三维动画等类型互动内容的多平台的综合型游戏开发工具,是一个全面整合的 ...

  4. 老司机学新平台 - Xamarin开发之我的第一个MvvmCross跨平台插件:SimpleAudioPlayer

    大家好,老司机学Xamarin系列又来啦!上一篇MvvmCross插件精选文末提到,Xamarin平台下,一直没找到一个可用的跨平台AudioPlayer插件.那就自力更生,让我们就自己来写一个吧! ...

  5. Referenced file contains errors (http://www.springframework.org/schema/context). For more information, right click on the message in the Problems

    spring 配置文件的DTD或schema出问题,一般两种情况: 1.当前网络环境不稳定,按住ctrl+"http://www.springframework.org/schema/con ...

  6. memset

    函数原型: void *memset(void *s, int ch, size_t n); 函数解释:将s中当前位置后面的n个字节 (typedef unsigned int size_t )用 c ...

  7. YY一下淘宝商品模型

    淘宝的电商产品种类非常丰富,必然得力于其商品模型的高度通用性和扩展性. 下面我将亲自操作淘宝商品的发布过程,结合网上其他博客对淘宝网商品库的分析,简单谈谈我的理解. 注:下面不特殊说明,各个表除主键外 ...

  8. Distributed4:SQL Server 分布式数据库性能测试

    我使用三台SQL Server 2012 搭建分布式数据库,将一年的1.4亿条数据大致均匀存储在这三台Server中,每台Server 存储4个月的数据,Physical Server的配置基本相同, ...

  9. 原生JS下拉加载插件分享。

    无聊写了一个JS下拉加载插件,有需要的可以下载. // 使用 // new ManDownLoad("#ul","json/load.json",functio ...

  10. 利用Bootstrap快速搭建个人响应式主页(附演示+源码)

    1.前言 我们每个程序员都渴望搭建自己的技术博客平台与他人进行交流分享,但使用别人的博客模板没有创意.做网站后台的开发人员可能了解前端,可是自己写一个不错的前端还是很费事的.幸好我们有Bootstra ...