一个日志操作类 LogOperator

/// <summary>
    /// 日志操作,实现写日志、备份与回删日志
    /// 
    /// 使用实例:
    /// LogOperator logOperator=new LogOperator();
    /// logOperator.WriteOperationLog(category,msg);
    /// 
    /// 可以对日志文件大小、日志文件夹大小、日志文件名、日志保存路径进行设置
    /// 自动备份、自动回删日志文件
    /// 支持无阻塞的异步方式写操作日志(logOperator.WriteOperationLogAsync(int level,category,msg))
    /// 
    /// Charley
    /// 2013/8/21
    /// </summary>
    public class LogOperator
    {
        private const int LOG_FILE_SIZE = 100;      //log file size 100(KB)
        private const int LOG_DIR_SIZE = 10;        //log directory size 10(M)
        private const string LOG_FILE_NAME = "log";
        private const string LOG_PATH = "log";
        private const string LOG_NAME = "XJLogOperator";

        private delegate void WriteLogDelegate(LogMode level, string category, string msg);    //利用委托异步写操作日志
        private WriteLogDelegate mWriteLogDelegate;

        #region Properties

        private int mLogFileMaxSize;
        /// <summary>
        /// 单个日志文件的大小,单位KB
        /// </summary>
        public int LogFileMaxSize
        {
            set { mLogFileMaxSize = value; }
        }

        private int mLogDirMaxSize;
        /// <summary>
        /// 日志文件夹总大小,单位MB
        /// </summary>
        public int LogDirMaxSize
        {
            set { mLogDirMaxSize = value; }
        }

        private string mLogFileName;
        /// <summary>
        /// 日志文件名
        /// </summary>
        public string LogFileName
        {
            get { return mLogFileName; }
            set { mLogFileName = value; }
        }

        private string mLogPath;
        /// <summary>
        /// 日志路径(相对路径或绝对路径)
        /// </summary>
        public string LogPath
        {
            get { return mLogPath; }
            set
            {
                if (!Path.IsPathRooted(value))
                {
                    mLogPath = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, value);
                }
                else
                {
                    mLogPath = value;
                }
            }
        }

        private string mErrorMsg;
        /// <summary>
        /// 操作错误消息
        /// </summary>
        public string ErrorMsg
        {
            get { return mErrorMsg; }
        }

        private string mLogName;
        /// <summary>
        /// 日志名称
        /// </summary>
        public string LogName
        {
            set { mLogName = value; }
        }

        private LogMode mLogMode;
        /// <summary>
        /// 日志级别
        /// </summary>
        public LogMode LogMode
        {
            get { return mLogMode; }
            set { mLogMode = value; }
        }

        #endregion

        /// <summary>
        /// 使用默认值创建日志实例
        /// </summary>
        public LogOperator()
        {
            mWriteLogDelegate = new WriteLogDelegate(WriteOperationLogWithoutReturn);
            mLogMode = LogMode.General;
            mLogName = LOG_NAME;
            mLogFileMaxSize = LOG_FILE_SIZE;
            mLogDirMaxSize = LOG_DIR_SIZE;
            mLogFileName = LOG_FILE_NAME;
            mLogPath = LOG_PATH;
            if (!Path.IsPathRooted(mLogPath))
            {
                mLogPath = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, mLogPath);
            }
        }

        /// <summary>
        /// 指定日志名称
        /// </summary>
        /// <param name="log_name"></param>
        public LogOperator(string log_name)
            : this()
        {
            mLogName = log_name;
        }

        /// <summary>
        /// 指定日志文件大小及日志文件夹总大小
        /// </summary>
        /// <param name="file_size"></param>
        /// <param name="dir_size"></param>
        public LogOperator(int file_size, int dir_size)
            : this()
        {
            mLogFileMaxSize = file_size;
            mLogDirMaxSize = dir_size;
        }

        /// <summary>
        /// 指定日志文件名及路径
        /// </summary>
        /// <param name="file_name"></param>
        /// <param name="file_path"></param>
        public LogOperator(string file_name, string file_path)
            : this()
        {
            mLogFileName = file_name;
            mLogPath = file_path;
        }

        /// <summary>
        /// 指定日志文件大小、日志文件夹总大小和日志文件名、日志路径
        /// </summary>
        /// <param name="file_size"></param>
        /// <param name="dir_size"></param>
        /// <param name="file_name"></param>
        /// <param name="file_path"></param>
        public LogOperator(int file_size, int dir_size, string file_name, string file_path)
            : this(file_size, dir_size)
        {
            mLogFileName = file_name;
            mLogPath = file_path;
        }

        /// <summary>
        /// 指定日志名称、日志文件大小、日志文件夹总大小和日志文件名、日志路径
        /// </summary>
        /// <param name="log_name"></param>
        /// <param name="file_size"></param>
        /// <param name="dir_size"></param>
        /// <param name="file_name"></param>
        /// <param name="file_path"></param>
        public LogOperator(string log_name, int file_size, int dir_size, string file_name, string file_path)
            : this(log_name)
        {
            mLogFileMaxSize = file_size;
            mLogDirMaxSize = dir_size;
            mLogFileName = file_name;
            mLogPath = file_path;
        }

        /// <summary>
        /// 写操作日志
        /// </summary>
        /// <param name="mode">日志级别</param>
        /// <param name="category">类别</param>
        /// <param name="msg">消息</param>
        /// <returns></returns>
        public bool WriteOperationLog(LogMode mode, string category, string msg)
        {
            try
            {
                if ((mode & mLogMode) == 0) { return true; }

                string dir = string.Empty;
                string path = string.Empty;

                if (string.IsNullOrEmpty(mLogPath) || string.IsNullOrEmpty(mLogFileName))
                {
                    mErrorMsg = "Log file name or log file path is empty.";
                    return false;
                }
                if (Path.IsPathRooted(mLogPath))
                {
                    dir = mLogPath;
                }
                else
                {
                    dir = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, mLogPath);
                }
                if (!Directory.Exists(dir))
                {
                    Directory.CreateDirectory(dir);
                    addDirPower(dir, "Everyone", "FullControl");
                }
                DateTime now = DateTime.Now;
                path = Path.Combine(dir, string.Format("{0}{1}.txt", mLogFileName, now.ToString("yyyMMdd")));
                FileStream f;
                f = new FileStream(path, FileMode.Append);
                StreamWriter r = new StreamWriter(f);
                if (category.Length <= 8)
                {
                    category = category + "\t";
                }
                string formatstr = string.Format("{0}\t{1}\t{2}\t{3}", (LogMode)mode, DateTime.Now.ToString("HH:mm:ss"), category, msg);
                r.WriteLine(formatstr);
                r.Flush();
                r.Close();
                if (!BackupLog(path)
                    || !DeleteLog())
                {
                    return false;
                }
                return true;
            }
            catch (Exception ex)
            {
                mErrorMsg = ex.ToString();
                return false;
            }
        }

        /// <summary>
        /// 记录Debug日志
        /// </summary>
        /// <param name="category">类别</param>
        /// <param name="msg">消息</param>
        /// <returns></returns>
        public bool LogDebug(string category, string msg)
        {
            return WriteOperationLog(LogMode.Debug, category, msg);
        }

        /// <summary>
        /// 记录Info日志
        /// </summary>
        /// <param name="category">类别</param>
        /// <param name="msg">消息</param>
        /// <returns></returns>
        public bool LogInfo(string category, string msg)
        {
            return WriteOperationLog(LogMode.Info, category, msg);
        }

        /// <summary>
        /// 记录Warn日志
        /// </summary>
        /// <param name="category">类别</param>
        /// <param name="msg">消息</param>
        /// <returns></returns>
        public bool LogWarn(string category, string msg)
        {
            return WriteOperationLog(LogMode.Warn, category, msg);
        }

        /// <summary>
        /// 记录Error日志
        /// </summary>
        /// <param name="category">类别</param>
        /// <param name="msg">消息</param>
        /// <returns></returns>
        public bool LogError(string category, string msg)
        {
            return WriteOperationLog(LogMode.Error, category, msg);
        }

        /// <summary>
        /// 记录Fatal日志
        /// </summary>
        /// <param name="category">类别</param>
        /// <param name="msg">消息</param>
        /// <returns></returns>
        public bool LogFatal(string category, string msg)
        {
            return WriteOperationLog(LogMode.Fatal, category, msg);
        }

        /// <summary>
        /// 以无阻塞的异步方式写操作日志
        /// </summary>
        /// <param name="mode">日志级别</param>
        /// <param name="category"></param>
        /// <param name="msg"></param>
        public void WriteOperationAsync(LogMode mode, string category, string msg)
        {
            mWriteLogDelegate.BeginInvoke(mode, category, msg, null, null);
        }

        private void WriteOperationLogWithoutReturn(LogMode mode, string category, string msg)
        {
            WriteOperationLog(mode, category, msg);
        }

        /// <summary>
        /// 备份日志文件
        /// </summary>
        /// <returns></returns>
        private bool BackupLog(string filePath)
        {
            try
            {
                if (!System.IO.File.Exists(filePath))
                {
                    mErrorMsg = string.Format("File not exist.\t{0}", filePath);
                    return false;
                }
                System.IO.FileInfo file = new FileInfo(filePath);
                long size = file.Length;
                string path = string.Empty;
                if (size > mLogFileMaxSize * 1024)
                {
                    int i = 1;
                    do
                    {
                        path = filePath.Substring(0, filePath.Length - 4) + i.ToString("000") + ".txt";
                        i++;
                    }
                    while (System.IO.File.Exists(path));
                    file.CopyTo(path);
                    file.Delete();
                    WriteOperationLog(LogMode.Warn, "BackupLog", string.Format("Backup log {0} successful.", path));
                }
                return true;
            }
            catch (Exception ex)
            {
                mErrorMsg = string.Format("Backup log fail.\t{0}", ex.Message);
                WriteOperationLog(LogMode.Warn, "BackupLog", string.Format("Backup log fail.\t{0}", ex.Message));
                return false;
            }
        }

        /// <summary>
        /// 回删日志文件
        /// </summary>
        /// <returns></returns>
        private bool DeleteLog()
        {
            try
            {
                string dir = string.Empty;
                if (Path.IsPathRooted(mLogPath))
                {
                    dir = mLogPath;
                }
                else
                {
                    dir = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, mLogPath);
                }
                System.IO.DirectoryInfo logdir = new DirectoryInfo(dir);
                if (getDirSize(logdir.FullName) <= mLogDirMaxSize * 1024 * 1024)
                {
                    return true;
                }

                while (getDirSize(logdir.FullName) > mLogDirMaxSize * 1024 * 1024 / 2)
                {
                    List<FileInfo> files = logdir.GetFiles().OrderBy(f => f.LastWriteTime).ToList();
                    if (files.Count > 0)
                    {
                        if (!deleteFile(files[0]))
                        {
                            WriteOperationLog(LogMode.Warn, "DeleteLogFile", string.Format("Delete log  file {0} fail.", files[0].FullName));
                        }
                    }
                }
            }
            catch (Exception ex)
            {
                mErrorMsg = string.Format("Delete log fail.\t{0}", ex.Message);
                WriteOperationLog(LogMode.Warn, "DeleteLogFile", string.Format("Delete log file fail!\t{0}", ex.Message));
                return false;
            }
            return true;
        }

        private long getDirSize(string path)
        {
            long size = 0;
            try
            {
                DirectoryInfo dir = new DirectoryInfo(path);
                for (var i = 0; i < dir.GetFiles().Count(); i++)
                {
                    size = size + dir.GetFiles()[i].Length;
                }
            }
            catch (Exception ex)
            {
                WriteOperationLog(LogMode.Warn, "GetDirSize", string.Format("Get directory size fail.\t{0}", ex.Message));
                size = -1;
            }
            return size;
        }

        private bool deleteFile(FileInfo file)
        {
            try
            {
                File.Delete(file.FullName);
                return true;
            }
            catch (Exception ex)
            {
                WriteOperationLog(LogMode.Warn, "DeleteFile", string.Format("Delete file fail.\t{0}", ex.Message));
                return false;
            }
        }

        private void addDirPower(string dirName, string username, string power)
        {
            DirectoryInfo dirInfo = new DirectoryInfo(dirName);
            if ((dirInfo.Attributes & FileAttributes.ReadOnly) != 0)
            {
                dirInfo.Attributes = FileAttributes.Normal;
            }
            //取得访问控制列表   
            DirectorySecurity dirSecurity = dirInfo.GetAccessControl();
            switch (power)
            {
                case "FullControl":
                    dirSecurity.AddAccessRule(new FileSystemAccessRule(username, FileSystemRights.FullControl, InheritanceFlags.ContainerInherit, PropagationFlags.InheritOnly, AccessControlType.Allow));
                    break;
                case "ReadOnly":
                    dirSecurity.AddAccessRule(new FileSystemAccessRule(username, FileSystemRights.Read, AccessControlType.Allow));
                    break;
                case "Write":
                    dirSecurity.AddAccessRule(new FileSystemAccessRule(username, FileSystemRights.Write, AccessControlType.Allow));
                    break;
                case "Modify":
                    dirSecurity.AddAccessRule(new FileSystemAccessRule(username, FileSystemRights.Modify, AccessControlType.Allow));
                    break;
            }
            dirInfo.SetAccessControl(dirSecurity);
        }
    }

    /// <summary>
    /// 日志级别,可任意组合
    /// </summary>
    [Flags]
    public enum LogMode
    {
        /// <summary>
        /// 调试
        /// </summary>
        Debug = 0x01,
        /// <summary>
        /// 信息
        /// </summary>
        Info = 0x02,
        /// <summary>
        /// 警告
        /// </summary>
        Warn = 0x04,
        /// <summary>
        /// 错误
        /// </summary>
        Error = 0x08,
        /// <summary>
        /// 致命
        /// </summary>
        Fatal = 0x16,
        /// <summary>
        /// 所有消息
        /// </summary>
        All = Debug | Info | Warn | Error | Fatal,
        /// <summary>
        /// 一般(默认)
        /// </summary>
        General = Info | Warn | Error | Fatal
    }


 

发布了41 篇原创文章 · 获赞 9 · 访问量 11万+

猜你喜欢

转载自blog.csdn.net/jian200801/article/details/12005819