一、几个问题:
1、日志干嘛用?
2、日志怎么输出?
3、用啥组件或工具?
4、日志怎么设计?(正文 - 前面废话不想看可以直接看最后内容)
二、系统日志干嘛用?
就是记录用户操作的行为,方便安全审计等等啊。
所以,日志有
1、登录访问
2、操作日志(增删改)
3、异常日志
4、开发日志
(我写离题了,应该是开发日志的使用)
三、日志怎么输出?
1、利用IIS输出
启用日志和设置日志的路径:
(备注:IIS默认是开启日志和写到系统盘的指定目录下,曾经遇到不注意这个细节,日志把C盘写满,导致服务器应用程序无法使用的情况。所以IIS日志建议(1)设置固定大小;(2)指向其他盘符。)
2、写入数据库
访问日志和操作日志等
可以设计成:
(1)写入同一数据库
(2)写入专属日志数据库
3、文本输出
4、Debug.WriteLine输出
5、写入Windows的Log里面
6、Email和短信等第三方输出
四、用啥组件或工具?
log4net是著名的一个组建,我不会用,不展开。
我用SlowX.Log4Net(自己写的一个组件)
五、日志怎么设计
这里主要讲开发日志(列表形式)
1、日志分成四类
A.SQL日志
B.SQL异常日志
C.文本日志
D.文本异常日志
2、日志输出有两个口径
A.文本输出
B.Debug.WriteLine输出
3、日志输出方式设置:
A.全部输出
B.本地输出
C.关闭(不输出)
D.本地不输出
默认设置形式:
(1)Debug.WriteLine是关闭,开发模式下开启
(2)文本日志分两种情况,开发模式和运行模式
A.开发模式:全部输出
B.运行模式:SQL异常日志和文本异常日志全部输出;SQL日志和文本日志设置为本地输出或不输出。
4、日志的文本存储格式:
网站根目录下(根目录可以指定) \\日志目录\\201606\\20160621\\
(1)2016062115_ExceptionSQL.log:2016年06月21日15时的SQL异常日志
(2)2016062115_SQL.log:2016年06月21日15时的SQL日志
(3)2016062115_Text.log:2016年06月21日15时的文本日志
(4)2016062115_Exception.log:2016年06月21日15时的异常日志
见人见智,日志存放目录可以考虑放在网站根目录下面的指定目录,也可以放在外部目录。
(1)网站根目录下:网站打包和整体管理比较容易一点,也可以通过ftp或者浏览器等直接访问查看日志。(不然得自己配套写一个工具看日志)
(2)外部目录:可以防止别人通过盗链形式,爬取到你的日志内容。特别是SQL日志,让别人知道你的表结构。
5、日志输出的格式和内容
(见下面的文字)
[1、日志内容 - 2016-06-21 15:59:10] ==>:
[异常]ExecuteDataSet ==> server=win-jqms2k-bjzw02.xincache.cn;database=host5984619; uid=host5984619;
select
t.ID, t.UserId, t.TheName,
t.EmUserStatusValue, t.YWFW, t.DWXZ,
t.CLSJ, t.ZZDJ, t.Address,
t.Zip, t.Fax, t.FDDBR,
t.ZW, t.OfficeTel, t.Mobile,
t.Email, t.LXR, t.LXRZW,
t.LXROfficeTel, t.LXRMobile, t.LXREmail,
t.LXRQQ, t.DWJJ, t.SQBG,
t.QYFRYYZZSMJ, t.ZZZSSMJ, t.QYYJZMCLSMJ,
t.IsCurrent, t.AuditText, t.AuditUserId,
t.AuditUserName, t.AuditTime, t.CreateTime,
t.UpdateTime, t.EmLastUserStatusValue, t.LockTime
from UTB_GZGREEN_MEMBER_INFO t
where t.ID = 83 and (EmUserStatusValue=3 or (EmUserStatusValue=5 and EmLastUserStatusValue=3) )
@tp1 = 83
select
t.ID, t.UserId, t.TheName,
t.EmUserStatusValue, t.YWFW, t.DWXZ,
t.CLSJ, t.ZZDJ, t.Address,
t.Zip, t.Fax, t.FDDBR,
t.ZW, t.OfficeTel, t.Mobile,
t.Email, t.LXR, t.LXRZW,
t.LXROfficeTel, t.LXRMobile, t.LXREmail,
t.LXRQQ, t.DWJJ, t.SQBG,
t.QYFRYYZZSMJ, t.ZZZSSMJ, t.QYYJZMCLSMJ,
t.IsCurrent, t.AuditText, t.AuditUserId,
t.AuditUserName, t.AuditTime, t.CreateTime,
t.UpdateTime, t.EmLastUserStatusValue, t.LockTime
from UTB_GZGREEN_MEMBER_INFO t
where t.ID = @tp1 and (EmUserStatusValue=3 or (EmUserStatusValue=5 and EmLastUserStatusValue=3) )
@tp1 83 Int64 Input SqlParameter
[执行时间]:00:00:00.0156250,开始时间:2016-6-21 15:59:09 ~ 结束时间:2016-6-21 15:59:09
在向服务器发送请求时发生传输级错误。 (provider: TCP 提供程序, error: 0 - 远程主机强迫关闭了一个现有的连接。)
.Net SqlClient Data Provider
在 System.Data.SqlClient.SqlConnection.OnError(SqlException exception, Boolean breakConnection)
在 System.Data.SqlClient.SqlInternalConnection.OnError(SqlException exception, Boolean breakConnection)
在 System.Data.SqlClient.TdsParser.ThrowExceptionAndWarning(TdsParserStateObject stateObj)
在 System.Data.SqlClient.TdsParserStateObject.WriteSni()
在 System.Data.SqlClient.TdsParserStateObject.WritePacket(Byte flushMode)
在 System.Data.SqlClient.TdsParserStateObject.ExecuteFlush()
在 System.Data.SqlClient.TdsParser.TdsExecuteRPC(_SqlRPC[] rpcArray, Int32 timeout, Boolean inSchema, SqlNotificationRequest notificationRequest, TdsParserStateObject stateObj, Boolean isCommandProc)
在 System.Data.SqlClient.SqlCommand.RunExecuteReaderTds(CommandBehavior cmdBehavior, RunBehavior runBehavior, Boolean returnStream, Boolean async)
在 System.Data.SqlClient.SqlCommand.RunExecuteReader(CommandBehavior cmdBehavior, RunBehavior runBehavior, Boolean returnStream, String method, DbAsyncResult result)
在 System.Data.SqlClient.SqlCommand.RunExecuteReader(CommandBehavior cmdBehavior, RunBehavior runBehavior, Boolean returnStream, String method)
在 System.Data.SqlClient.SqlCommand.ExecuteReader(CommandBehavior behavior, String method)
在 System.Data.SqlClient.SqlCommand.ExecuteDbDataReader(CommandBehavior behavior)
在 System.Data.Common.DbCommand.System.Data.IDbCommand.ExecuteReader(CommandBehavior behavior)
在 System.Data.Common.DbDataAdapter.FillInternal(DataSet dataset, DataTable[] datatables, Int32 startRecord, Int32 maxRecords, String srcTable, IDbCommand command, CommandBehavior behavior)
在 System.Data.Common.DbDataAdapter.Fill(DataSet dataSet, Int32 startRecord, Int32 maxRecords, String srcTable, IDbCommand command, CommandBehavior behavior)
在 System.Data.Common.DbDataAdapter.Fill(DataSet dataSet, String srcTable)
在 SlowX.DAL.Helpers.SqlHelper.ExecuteDataSetByList(IDbConnection connection, CommandType commandType, String SQL, List`1 commandParameters, String srcTable)
[URL]:http://www.gzgreen.com/memberinfo.aspx?id=83
[IP]:68.180.229.157
[客户端信息]:
操作系统:Unknown
浏览器:Mozilla
浏览器版本:0.0
客户端IP:68.180.229.157
cookies支持:True
VBScript:False
JavaScript:True
ActiveX:False
JavaApplets:False
语言:
框架支持:True
DOM:0.0
客户端Framework:0.0
[用户信息]:尚未登录
上面是SQL异常日志的输出内容有:
(1)时间:
(2)日志执行类型:上面例子是执行ExecuteDataSet发生异常
(3)数据库连接串:
A.有些系统会操作很多数据库,有很多数据库连接串,需要打印出来
B.数据库连接串不能打印密码,否者存在不安全风险,黑客盗链下载了日志后可以知道数据库连接串
(4)SQL语句内容:分成两段
A.转义了SQL参数的SQL语句,可以直接拷贝SQL语句到SQL查询面板运行和测试;
B.原始调用的SQL语句
(5)SQL的执行时间,返回记录数等(主要看SQL的运行性能)
(6)异常日志内容:打印异常的堆栈信息,方便定位发生错误的函数或方法
(7)发生异常的页面地址
(8)用户的IP(看哪个来源,有可能是黑客SQL测试注入造成的异常)
(9)客户端信息:打印客户端的信息。
之前开发遇到过一个问题,本地运行都ok,但客户使用老是报错,莫名其妙,频繁折腾于电话沟通。日志打印出来发现客户用的是IE6浏览器,对一个JavaScript脚本不支持,所以,显示客户端信息很有必要。
(10)用户信息:记录用哪个用户帐号登录和操作
6、暗黑小科技
第三方提醒:Email提醒或短信提醒。
(1)您写的系统保证100%没BUG?
(2)您会每天盯着日志看么?
(3)你会专门7×24小时派人专门运维和管理系统么?
往往都不会,所以。
系统要想无人值守,就需要::::::::
系统异常日志,做一个关键词过滤,一旦异常就通过Email或短信的方式提醒,可考虑,很必要。
SlowX.Log4Net
回头在介绍和分享。