c#自定义日志记录
前言:自定义写入日志,需要注意多线程下文件读取写入时异常问题处理:下面列举了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#自定义日志记录的更多相关文章
- Windows server2012 IIs 8 自定义日志记录
问题: 通过CDN加速的网站,记录日志时无法追踪源IP,日志的IP都为CDN节点ip. 分析: 1.在解析记录header时,CDN实际会把源IP以其它header的形式回传,如网宿为[Cdn-Src ...
- shell脚本中自定义日志记录到文件
自定义日志函数和前期变量 # adirname - return absolute dirname of given file adirname() { odir=`pwd`; cd `dirname ...
- 基于.NetCore3.1系列 —— 日志记录之自定义日志组件
一.前言 回顾:日志记录之日志核心要素揭秘 在上一篇中,我们通过学习了解在.net core 中内置的日志记录中的几大核心要素,在日志工厂记录器(ILoggerFactory)中实现将日志记录提供器( ...
- IIS 7完全攻略之日志记录配置(摘自网络)
IIS 7完全攻略之日志记录配置 作者:泉之源 [IT168 专稿]除了 Windows 提供的日志记录功能外,IIS 7.0 还可以提供其他日志记录功能.例如,可以选择日志文件格式并指定要记录的请求 ...
- ASP.NET MVC自定义Module记录管道事件执行顺序
1. 在Visual Studio 新建项目,模板为空,下面结构选择MVC. 2. 在项目中新建一个类MyModule,实现IHttpModule接口 namespace SimpleApp.Infr ...
- 如何自行给指定的SAP OData服务添加自定义日志记录功能
有的时候,SAP标准的OData实现或者相关的工具没有提供我们想记录的日志功能,此时可以利用SAP系统强大的扩展特性,进行自定义日志功能的二次开发. 以SAP CRM Fiori应用"My ...
- 基于.NetCore3.1系列 —— 日志记录之初识Serilog
一.前言 对内置日志系统的整体实现进行了介绍之后,可以通过使用内置记录器来实现日志的输出路径.而在实际项目开发中,使用第三方日志框架(如: Log4Net.NLog.Loggr.Serilog.Sen ...
- 如何定制.NET6.0的日志记录
在本章中,也就是整个系列的第一部分将介绍如何定制日志记录.默认日志记录仅写入控制台或调试窗口,这在大多数情况下都很好,但有时需要写入到文件或数据库,或者,您可能希望扩展日志记录的其他信息.在这些情况下 ...
- ASP.NET全局错误处理和异常日志记录以及IIS配置自定义错误页面
应用场景和使用目的 很多时候,我们在访问页面的时候,由于程序异常.系统崩溃会导致出现黄页.在通常的情况下,黄页对于我们来说,帮助是极大的,因为它可以帮助我们知道问题根源,甚至是哪一行代码出现了错误.但 ...
随机推荐
- 动态Web API层
返回总目录 本篇目录 构建动态Web API控制器 ForAll 方法 重写ForAll 方法 Http动词 动态Javascript代理 Ajax参数 单一服务脚本 Angular支持 Durand ...
- ENode框架Conference案例分析系列之 - Quick Start
前言 前一篇文章介绍了Conference案例的架构设计,本篇文章开始介绍Conference案例的代码实现.由于代码比较多,一开始就全部介绍所有细节,估计很多人接受不了,也理解不了.所以,我先进行一 ...
- 一个新人如何学习在大型系统中添加新功能和Debug
文章背景: 今年七月份正式入职,公司主营ERP软件,楼主所在的组主要负责二次开发,使用的语言是Java. 什么叫二次开发呢?ERP软件的客户都是企业.而这些企业之间的情况都有所不同,一套标准版本的企业 ...
- OpenGL学习资料汇总
我学OpenGL的3D编程也有1.2个年头了,走了很多弯路,也算有点收获.现在整理出一些好用的资料如下. NeHe OpenGL教程中文版 地址(http://www.yakergong.net/ne ...
- Qt And MFC UI Layout
界面布局 起初,计算机的交互是通过输入的代码进行的, 慢慢的有了图形之后, 就开始了图形界面的交互. 目前来说还有语音交互, 视频交互等多媒体的交互. 不管哪一种交互, 最终在计算机的角度都是信号的输 ...
- 关闭form上chrome的autofill
Chrome的autofill会自动找到form中的type=password的元素,然后把这个元素前面的元素当做是用户名,它不在乎这个元素叫什么名字.这样又是注册又是登录,你会发现它自作聪明的aut ...
- 在MacOS 10.12上安装Tomcat8.5
在MacOS 10.12上安装Tomcat8.5 原文链接:https://wolfpaulus.com/journal/mac/tomcat8/ Context 已安装Java,使用java -ve ...
- VS无法设置断点的解决方案
第一种情况的处理 第二种情况的处理
- Entity Framework Code First添加修改及删除单独实体
对于一个单独实体的通常操作有3种:添加新的实体.修改实体以及删除实体. 1.添加新的实体 Entity Framework Code First添加新的实体通过调用DbSet.Add()方法来实现. ...
- ExtJs4之Grid详细
ExtJs博客前奏 由于这段时间事情比较杂乱,博客就主要以项目中例子来说明编写. ExtJs4中的Grid非常强大,有展示,选中,搜索,排序,编辑,拖拽等基本功能,这篇博客我就这几个功能做写累述. 1 ...