zoukankan      html  css  js  c++  java
  • C# 简易异步日志类 [ C# | Log | TextWriterTraceListener ]


    前言

      即使是小型项目,也需要日志的功能,这里就不讨论Log4Net之类的框架,提供一个异步的、控制台输出+日志文件输出的简易日志帮助类。

    正文

      一、帮助类文件Logger.cs

    //=========================================
    //
    // 作 者:农民伯伯
    // 邮 箱:over140@gmail.com
    // 博 客:http://over140.cnblogs.com/
    // 时 间:2009-7-16
    // 描 述:日志类,注意需要在日志记录的目录给用户写入权限!
    //
    //=========================================

    using System;
    using System.Configuration;
    using System.Collections.Generic;
    using System.Data.SqlClient;
    using System.Diagnostics;
    using System.IO;
    using System.Text;
    using System.Runtime.CompilerServices;
    using System.Web;


    namespace CentralHousesTest
    {
        
    /// <summary>
        
    /// 日志类
        
    /// </summary>
        public sealed class Logger
        {
            
    #region Member Variables

            
    /// <summary>
            
    /// 用于Trace的组织输出的类别名称
            
    /// </summary>
            private const string trace_sql = "\r\n***********************TRACE_SQL {0}*****************************\r\nTRACE_SQL";

            
    /// <summary>
            
    /// 用于Trace的组织输出的类别名称
            
    /// </summary>
            private const string trace_exception = "\r\n***********************TRACE_EXCEPTION {0}***********************";

            
    /// <summary>
            
    /// 当前日志的日期
            
    /// </summary>
            private static DateTime CurrentLogFileDate = DateTime.Now;

            
    /// <summary>
            
    /// 日志对象
            
    /// </summary>
            private static TextWriterTraceListener twtl;

            
    /// <summary>
            
    /// 日志根目录
            
    /// </summary>
            private const string log_root_directory = @"D:\log";

            
    /// <summary>
            
    /// 日志子目录
            
    /// </summary>
            private static string log_subdir;


            
    /// <summary>
            
    /// "      {0} = {1}"
            
    /// </summary>
            private const string FORMAT_TRACE_PARAM = "      {0} = {1}";

            
    /// <summary>
            
    /// 1   仅控制台输出
            
    /// 2   仅日志输出
            
    /// 3   控制台+日志输出
            
    /// </summary>
            private static readonly int flag = 2;         //可以修改成从配置文件读取

            
    #endregion

            
    #region Constructor

            
    static Logger()
            {
                System.Diagnostics.Trace.AutoFlush 
    = true;

                
    switch (flag)
                {
                    
    case 1:
                        System.Diagnostics.Trace.Listeners.Add(
    new ConsoleTraceListener());
                        
    break;
                    
    case 2:
                        System.Diagnostics.Trace.Listeners.Add(TWTL);
                        
    break;
                    
    case 3:
                        System.Diagnostics.Trace.Listeners.Add(
    new ConsoleTraceListener());
                        System.Diagnostics.Trace.Listeners.Add(TWTL);
                        
    break;
                }
            }

            
    #endregion

            
    #region Method

            
    #region trace

            
    /// <summary>
            
    /// 异步错误日志
            
    /// </summary>
            
    /// <param name="value"></param>
            public static void Trace(Exception ex)
            {
                
    new AsyncLogException(BeginTraceError).BeginInvoke(ex, nullnull);
            }

            
    /// <summary>
            
    /// 异步SQL日志
            
    /// </summary>
            
    /// <param name="cmd"></param>
            public static void Trace(SqlCommand cmd)
            {
                
    new AsyncLogSqlCommand(BeginTraceSqlCommand).BeginInvoke(cmd, nullnull);
            }

            
    /// <summary>
            
    /// 异步SQL日志
            
    /// </summary>
            
    /// <param name="sql"></param>
            
    /// <param name="parameter"></param>
            public static void Trace(string sql, params SqlParameter[] parameter)
            {
                
    new AsyncLogSql(BeginTraceSql).BeginInvoke(sql, parameter, nullnull);
            }

            
    #endregion

            
    #region delegate

            
    private delegate void AsyncLogException(Exception ex);
            
    private delegate void AsyncLogSqlCommand(SqlCommand cmd);
            
    private delegate void AsyncLogSql(string sql, params SqlParameter[] parameter);

            
    private static void BeginTraceError(Exception ex)
            {
                
    if (null != ex)
                {
                    
    //检测日志日期
                    StrategyLog();

                    
    //输出日志头
                    System.Diagnostics.Trace.WriteLine(string.Format(trace_exception, DateTime.Now));
                    
    while (null != ex)
                    {
                        System.Diagnostics.Trace.WriteLine(
    string.Format("{0} {1}\r\n{2}\r\nSource:{3}", ex.GetType().Name, ex.Message, ex.StackTrace, ex.Source));
                        ex 
    = ex.InnerException;
                    }
                }
            }

            
    private static void BeginTraceSqlCommand(SqlCommand cmd)
            {
                
    if (null != cmd)
                {
                    SqlParameter[] parameter 
    = new SqlParameter[cmd.Parameters.Count];
                    cmd.Parameters.CopyTo(parameter, 
    0);
                    BeginTraceSql(cmd.CommandText, parameter);
                }
            }

            
    private static void BeginTraceSql(string sql, params SqlParameter[] parameter)
            {
                
    if (!string.IsNullOrEmpty(sql))
                {
                    
    //检测日志日期
                    StrategyLog();

                    System.Diagnostics.Trace.WriteLine(sql, 
    string.Format(trace_sql, DateTime.Now));
                    
    if (parameter != null)
                    {
                        
    foreach (SqlParameter param in parameter)
                        {
                            System.Diagnostics.Trace.WriteLine(
    string.Format(FORMAT_TRACE_PARAM, param.ParameterName, param.Value));
                        }
                    }
                }
            }

            
    #endregion

            
    #region helper

            
    /// <summary>
            
    /// 根据日志策略生成日志
            
    /// </summary>
            private static void StrategyLog()
            {
                
    //判断日志日期
                if (DateTime.Compare(DateTime.Now.Date, CurrentLogFileDate.Date) != 0)
                {
                    DateTime currentDate 
    = DateTime.Now.Date;

                    
    //生成子目录
                    BuiderDir(currentDate);
                    
    //更新当前日志日期
                    CurrentLogFileDate = currentDate;

                    System.Diagnostics.Trace.Flush();

                    
    //更改输出
                    if (twtl != null)
                        System.Diagnostics.Trace.Listeners.Remove(twtl);

                    System.Diagnostics.Trace.Listeners.Add(TWTL);
                }
            }

            
    /// <summary>
            
    /// 根据年月生成子目录
            
    /// </summary>
            
    /// <param name="currentDate"></param>
            private static void BuiderDir(DateTime currentDate)
            {
                
    int year = currentDate.Year;
                
    int month = currentDate.Month;
                
    //年/月
                string subdir = string.Concat(year, '\\', month);
                
    string path = Path.Combine(log_root_directory, subdir);
                
    if (!Directory.Exists(path))
                {
                    Directory.CreateDirectory(path);
                }
                log_subdir 
    = subdir;
            }

            
    #endregion

            
    #endregion

            
    #region Properties

            
    /// <summary>
            
    /// 日志文件路径
            
    /// </summary>
            
    /// <returns></returns>
            private static string GetLogFullPath
            {
                
    get
                {
                    
    return string.Concat(log_root_directory, '\\'string.Concat(log_subdir, @"\log", CurrentLogFileDate.ToShortDateString(), ".txt"));
                }
            }

            
    /// <summary>
            
    /// 跟踪输出日志文件
            
    /// </summary>
            private static TextWriterTraceListener TWTL
            {
                
    get
                {
                    
    if (twtl == null)
                    {
                        
    if (string.IsNullOrEmpty(log_subdir))
                            BuiderDir(DateTime.Now);
                        
    else
                        {
                            
    string logPath = GetLogFullPath;
                            
    if (!Directory.Exists(Path.GetDirectoryName(logPath)))
                                BuiderDir(DateTime.Now);
                        }
                        twtl 
    = new TextWriterTraceListener(GetLogFullPath);
                    }
                    
    return twtl;
                }
            }

            
    #endregion

        }
    }

      二、示例

        2.1  错误记录

            static void Main(string[] args)
            {
                IList
    <string> list = null;

                
    try
                {
                    Console.WriteLine(list.Count);
                }
                
    catch (Exception ex)
                {
                    Logger.Trace(ex);
                }

                Console.ReadLine();
            }

          代码说明:错误很明显,未实例化就使用Count属性。

          日志截图:

           

        2.2  数据库记录

                using (SqlConnection con = new SqlConnection("Data Source=OVERA;Initial Catalog=Northwind;User ID=sa;Password=sa;"))
                {
                    con.Open();
                    SqlCommand sqlCmd 
    = new SqlCommand("SELECT * FROM Customers WHERE CompanyName = @CompanyName", con);
                    sqlCmd.Parameters.Add(
    new SqlParameter("@CompanyName""Alfreds Futterkiste"));

                    Logger.Trace(sqlCmd);

                    SqlDataReader sdr 
    = sqlCmd.ExecuteReader();
                    
    while (sdr.Read())
                    {
                        Console.Write(sdr.GetName(
    1));
                        Console.Write(
    " : ");
                        Console.WriteLine( sdr[
    1]); 
                    }
                    sdr.Close();
                }

                Console.ReadLine();
            }

          日志截图:

          

           需要注意这里日志策略改为了仅日志文件输出。


      三、注意事项

        3.1  进行日志文件输出的时候需要有写的权限。

        3.2  实际使用中可能还会有一个变量控制是否进行日志记录。

        3.3  错误记录一般会在Global.asax的Application_Error里面加上。

    结束语  

      对于一般的小项目这个日志类是够用的了,日志的策略还可以根据自己的需求改变一下,合适就行: )  

    本博你可能感兴趣的文章

          1.      .Net Validator验证框架 [ .Net | Validator Framework | Attribute ]

          2.      C# DLL资源文件打包(图片、JS、CSS)[WebResource]

          3.      C# 键盘监视+剪切板编程(每次复制都不一样哦!*v*)



  • 相关阅读:
    黄聪:数据库基础
    黄聪:(C#)利用反射动态调用类成员[转载]
    黄聪:SQL 2005 全文索引
    黄聪:自动化测试的7个步骤
    黄聪:队列Queue笔记
    黄聪:VMware三种网络连接方式的概念
    Nginx 模块细节详探
    munin因为plugin而亮
    Zookeeper简介
    Munin进阶使用
  • 原文地址:https://www.cnblogs.com/over140/p/1524735.html
Copyright © 2011-2022 走看看