文章出處

 

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


文章列表




Avast logo

Avast 防毒軟體已檢查此封電子郵件的病毒。
www.avast.com


arrow
arrow
    全站熱搜
    創作者介紹
    創作者 大師兄 的頭像
    大師兄

    IT工程師數位筆記本

    大師兄 發表在 痞客邦 留言(0) 人氣()