1.第一次写博客如有错误欢迎纠正。邮箱:Jiangwenyuan0217@163.com;
2.此博客可能对初学者有些帮助,对哪些骨灰级的程序员来说都是分分钟的事了,所以就不用在这里费时间了。
环境说明:
1.vs2010,sqlserver2008r2其实添加日志来说对一个程序的开发工具和数据库要求并不高。
我讲的日志有两种,一种是系统操作日志(添加到sqlserver数据库),另一种是程序未经处理异常日志(添加到用户配置的文件目录下)。
一、系统操作日志。
首先 创建数据库 ,日志表,存储过程
--创建数据库; IF EXISTS(SELECT 'a' FROM sys.databases WHERE name='BoKeYuan') BEGIN DROP DATABASE BoKeYuan END go CREATE DATABASE BoKeYuan on ( name ='BoKeYuan_data', filename='e:\data\BoKeYuan.mdf' ) log on ( name='BoKeYuan_log', filename='e:\data\BoKeYuan.ldf' ) use BoKeYuan ---创建日志表; IF EXISTS(SELECT 'a' FROM sys.objects WHERE name='Bas_SysLog' AND type='U') BEGIN DROP TABLE Bas_SysLog END go CREATE TABLE [dbo].[Bas_SysLog]( [ID] [bigint] IDENTITY(1,1) NOT NULL,--id要用bigint因为日志表数据会超大; [FMID] [int] NULL,--功能页面id [FMName] [varchar](100) NULL,--功能名称 [PageName] [varchar](100) NULL,--页面名;路径 [OpTime] [datetime] DEFAULT GETDATE() NOT NULL,--时间 [UserID] [int] NULL, --用户id [OpUser] [varchar](50) NOT NULL,--操作用户名; [OpType] [varchar](20) NULL,--操作结果枚举; [OpScp] [varchar](20) NULL,--操作描述枚举 [OpCtt] [varchar](max) NULL--操作内容可记录错误; ) GO --创建查询日志的存储过程 IF EXISTS(SELECT 'a' FROM sys.objects WHERE name='Base_GetSysLog' AND type='P') BEGIN DROP PROCEDURE Base_GetSysLog END GO CREATE PROCEDURE Base_GetSysLog @FMID INT, @FMName VARCHAR(200), @PageName VARCHAR(200), @UserID INT, @OpUser VARCHAR(20), @OpType VARCHAR(20), @OpScp VARCHAR(20), @OpCtt VARCHAR(max) AS INSERT INTO Bas_SysLog(FMID,FMName,PageName,UserID,OpUser,OpType,OpScp,OpCtt) VALUES(@FMID,@FMName,@PageName,@UserID,@OpUser,@OpType,@OpScp,@OpCtt) go
然后创建一个webForm页面
像其中拖入两个控件如下;
<div> <asp:Button ID="addLog" runat="server" Text="添加系统日志" onclick="addLog_Click" /> </div> <asp:GridView ID="GridView1" runat="server"> </asp:GridView>
转到后台cs文件中写如下代码.
using System.Data; using System.Data.SqlClient; /// <summary> /// 记录操作结果 /// </summary> public enum ELogResult { 成功, 失败, 未知, } /// <summary> /// 记录日志操作类型 /// </summary> public enum ELogType { 登录, 注销, 添加, 修改, 删除, 查询, 导出, 导入, } protected void addLog_Click(object sender, EventArgs e) { string conString = "Data Source=.;database=BoKeYuan;user id=sa;password=sqldba;"; SqlConnection sqlcon = new SqlConnection(conString); SqlCommand sqlcom = sqlcon.CreateCommand(); sqlcom.CommandType = CommandType.StoredProcedure; SqlParameter[] sps ={ new SqlParameter("@FMID",1), new SqlParameter("@FMName","测试添加日志功能"), new SqlParameter("@PageName","AddSysLog.aspx"), new SqlParameter("@UserID",2), new SqlParameter("@OpUser","圣叹"), new SqlParameter("@OpType",ELogResult.成功.ToString()), new SqlParameter("@OpScp",ELogType.添加.ToString()), new SqlParameter("@OpCtt","添加一条日志成功了") }; sqlcom.Parameters.AddRange(sps); sqlcom.CommandText = "Base_GetSysLog"; try { sqlcon.Open(); sqlcom.ExecuteNonQuery(); } catch (Exception error) { if (sqlcon.State == ConnectionState.Open) { sqlcon.Close(); } } finally { if (sqlcon.State == ConnectionState.Open) { sqlcon.Close(); } sqlcon.Dispose(); } BindSysLog(); } private void BindSysLog() { string conString = "Data Source=.;database=BoKeYuan;user id=sa;password=sqldba;"; SqlConnection sqlcon = new SqlConnection(conString); SqlCommand sqlcom = sqlcon.CreateCommand(); sqlcom.CommandType = CommandType.Text; sqlcom.CommandText = "select * from Bas_SysLog"; SqlDataAdapter sqladapter = new SqlDataAdapter(sqlcom); DataSet ds = null; try { ds = new DataSet(); sqlcon.Open(); sqladapter.Fill(ds); } catch (Exception e) { if (sqlcon.State == ConnectionState.Open) { sqlcon.Close(); } } finally { if (sqlcon.State == ConnectionState.Open) { sqlcon.Close(); } sqlcon.Dispose(); } if (ds != null) { GridView1.DataSource = ds; GridView1.DataBind(); } ds.Dispose(); }
一般我们会将添加日志的方法放在网站页面的父类BasePage中方便用户直接在页面中调用,而且还可以直接获取用户的UserID,Name,FMID,FMNAME等参数
更简单易用,达到方便添加日志的目的。当然示例中直接写了ADO.Net的数据库操作这也是不合理的,应该封装到DBUtility下的SqlHelper类文件中方便统一管理,
但是此处不是重点所以我就写在了一起。
二、添加未处理异常日志,文件系统
网站在设计时一般会设置未处理异常的日志添加功能,记录可能发生数据库网络连接中断或数据库表死锁或程序出现未处理异常时的日志。
首先在网站配置文件中添加一个日志记录文件的根文件目录的配置节如下:
<appSettings> <!--系统文档路径 请将本系统的所有目录都放在此目录的子目录下,并记录在此处。 1.SysLog:保存系统运行和系统停止及系统错误日志文件夹;位置Common类库CTryCatch类; --> <add key="DocPath" value="D:\Doc\FilePath\"/> </appSettings>
我把记录日志的cs代码放到新类库Common的CSysLog类中如下:
namespace Common { public class CSysLog { /// <summary> /// 添加系统日志的方法(开启,关闭,未处理异常等。) /// 以文本文件形式保存在文件目录的“SysLog”文件下; /// </summary> /// <param name="fileName">添加日志的文件类型【启动或关闭系统:StartOrEnd;错误日志:Error;其他:Other】等等</param> /// <param name="dataLog">日志内容</param> public void AddLog(string fileName, string dataLog) { string logPath = System.Configuration.ConfigurationManager.AppSettings["DocPath"]; string tempPath = logPath + @"SysLog\"; if (!Directory.Exists(tempPath))//创建文件夹; { Directory.CreateDirectory(tempPath); } if (fileName.Equals("StartOrEnd"))//如果是启动 { tempPath = tempPath + @"StartOrEnd\"; if (!Directory.Exists(tempPath))//创建文件夹; { Directory.CreateDirectory(tempPath); } } else if (fileName.Equals("Error"))//如果是错误日志 { tempPath = tempPath + @"Error\"; if (!Directory.Exists(tempPath))//创建文件夹; { Directory.CreateDirectory(tempPath); } tempPath = tempPath + DateTime.Now.ToString("yyyy_MM") + @"\"; if (!Directory.Exists(tempPath))//创建文件夹; { Directory.CreateDirectory(tempPath); } } else//如果是其他的就创建;文件夹; { tempPath = tempPath + fileName + @"\"; if (!Directory.Exists(tempPath))//创建文件夹; { Directory.CreateDirectory(tempPath); } } string filePath = tempPath + fileName + DateTime.Now.ToString("_yyyy-MM-dd") + @".txt";//文件完全路径; FileStream fs = new FileStream(filePath, FileMode.Append); StreamWriter writer = new StreamWriter(fs); writer.WriteLine(dataLog); writer.Close(); fs.Close(); } } }
然后就需要添加日志记录了,在网站中新建一个全局应用程序文件Global。
其中代码如下:
void Application_Start(object sender, EventArgs e) { //在应用程序启动时运行的代码 Common.CSysLog csl = new Common.CSysLog(); string log = "应用程序在【" + DateTime.Now.ToString() + "】启动!\r\n"; csl.AddLog("StartOrEnd", log); } void Application_End(object sender, EventArgs e) { //在应用程序关闭时运行的代码 Common.CSysLog csl = new Common.CSysLog(); string log = "应用程序在【" + DateTime.Now.ToString() + "】停止!\r\n"; csl.AddLog("StartOrEnd", log); } void Application_Error(object sender, EventArgs e) { //在出现未处理的错误时运行的代码 Common.CSysLog csl = new Common.CSysLog(); Exception ex = Server.GetLastError().GetBaseException(); System.Text.StringBuilder builder = new StringBuilder(); builder.Append("=======================================错误信息===============================================\r\n"); builder.AppendFormat("错误消息:{0}\r\n", ex.Message); builder.AppendFormat("错误页面:{0}\r\n", Request.Url); builder.AppendFormat("错误时间:{0}\r\n", DateTime.Now.ToString()); builder.AppendFormat("堆栈跟踪:{0}\r\n", ex.StackTrace); builder.Append("--------------------------其他信息------------------------------\r\n"); builder.AppendFormat("错误程序:{0}\r\n", ex.Source); builder.AppendFormat("目标地点:{0}\r\n", ex.TargetSite); builder.AppendFormat("主机IP:{0}\r\n", Request.UserHostAddress); builder.AppendFormat("主机名称:{0}\r\n", Request.UserHostName); builder.AppendFormat("请求类型:{0}\r\n", Request.HttpMethod); builder.AppendFormat("参数列表:{0}\r\n", Request.QueryString); builder.AppendFormat("提交表单:{0}\r\n", Request.Form.ToString()); csl.AddLog("Error", builder.ToString()); }
这样在系统出现未处理异常时则会在你配置的文件目录中出现一条错误记录,根据记录内容就可直接找到错误了,
在系统首次运行和停止时都会在日志中添加日志方便查看系统关闭和启动的时间,
记录如下
在此把一些小东西分享给大家写的不好请大家谅解。欢迎交流。2014-01-17