一个简单的.net写日志方法 - 可能的改进点

昨天有个朋友在评论的时候问我如下代码在web开发中有什么问题

public void Log(string msg)
{
System.IO.File.AppendAllText(Server.MapPath("~/log.txt"), msg);
}

这里能说的点太多了....只好新开一个文章来说,而且也只是选重点的说

 

功能

1.线程不安全

  asp.net是原生的多线程的框架,那么日志类必须是多线程安全的, 该类库内部使用了File类来附加日志,而这个部分不是线程安全的,这里有一个BUG (windows资源.例如网络 文件 在asp.net中都要注意多线程同步)

  改进方案:最最简单的办法是加lock,(其他的改进方案之后再提)

2.方法未做输入检查

  所有public的输入参数 要做输入值检查,如果是null或者是empty,那么就不要再调用File类写日志, 这样会有性能和健壮性上的提高(最常见的问题就是未将对象引用到设置对象的实例)

  解决方案:做输入值检查

3. IIS默认帐号对于 Server.MapPath("~/log.txt") 这个路径是没有写入/修改权限的 (可能在生产环境你才会发现这个问题)

  解决方案:配置IIS帐号权限,或者是配置一个有权限的目录 (推荐后者)

4.未做try catch( 是否需要try catch,要考虑实际情况)

  一般来说写日志的方法是不会抛出异常的,如果没有catch( 可以在内部 也可以在外部catch,我个人推荐外部) 会导致程序/逻辑中止

  绝对要避免日志这样的非核心逻辑 导致业务逻辑的中止

安全性

1.将日志写入网站根目录是一种高风险的行为,第一是需要额外的权限,第二是有可能存在写入程序文件(例如有些人写入aspx文件)

  解决方案:配置一个网站根目录外的日志目录

性能

1.采用异步写入的方式提高性能

  即 写入队列,定时刷新队列到数据文件; 由于写入的瓶颈一般在IO上,这样的话性能会好很多;当然,如果忽然断电,就有可能丢失数据 (小概率事件,我们考虑性能多过这一点小瑕疵)

  这也是我最喜欢的方式,但是该方式需要开发人员有较高的水平,而且方案复杂,开发时间长...唯一的好处就是性能高....写日志响应时间短

2.采用其他的写日志的方式

  例如CLFS windows2008开始支持common log file system,

  如果不是windows 2008 直接打开一个FileStream 然后保存在本地变量中会更好, 不要每写一条日志都打开文件又关闭

3.将实例方法替换为静态方法(或者至少使用call而不是callvirt来调用方法)  [具体使用具体分析]

扩展性和可维护性

1.日志路径不应该是写死的Server.MapPath("~/log.txt")  这样这个日志只能被web程序使用,而不能被windows form 或者服务器应用程序等其他应用程序使用

2.日志路径不应该写死,而是应该可配置,至少应该有一个独立的成员存储(可预期写日志的方法必然有非常多的重载)

3.日志类这种基本类库一般使用静态方法, 好歹不要每次使用都new一个 [具体使用具体分析]

4.有可能的话,第三方类库,例如log4net是一个比较好的方案

5.如果是生产环境的代码,这个命名还有注释都是完全不合格的..

6.不推荐使用完整的命名空间 (文本太多...烦 哈哈)

 

就一个写日志的方法,我们做设计的时候,总是要考虑:(优先级和项目类型有关)

1.团队能否有足够的能力完成 

2.开发时间

3.复杂程度 (导致维护成本上升)

4.程序稳定性

5.性能 

6.目前已经存在的技术体系和类库. (复用性啊什么的...)

7.其他的和一时想不起来的因素(例如大老板说要这么做......好吧 你是老板你说了算 哈哈  just kidding) 

 

可能考虑的还不够全面,毕竟时间有限...最近太忙了

如有遗漏 还请各位帮忙补充下

 

具体的代码就不提供了, 一般我们做日志都是公司级的日志, 所有的服务器会通过网络传输到日志集群服务器, 这和简单的文件日志是完全不一样的体系

简单的文件日志,我们也会用很简单方式来写入.....(在某些项目中,最简单就是最适合,)

项目类型和开发时间需要, 稍微复杂点的我们会用log4net之类的第三方日志库来做

最简单的日志也许几分钟就写好了, 最复杂的日志做了几个月才是一个架子.......

posted on   听说读写  阅读(8145)  评论(2编辑  收藏  举报

努力加载评论中...

导航

点击右上角即可分享
微信分享提示