| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611 |
- //======================================================================
- //
- // Copyright (C) 2013 仙剑
- // All rights reserved
- // guid1: 4323ea5b-c739-4c99-add9-8739f89d0ab9
- // CLR Version: 2.0.50727.5420
- // Name: LogOperator
- // Computer: CHARLEY-PC
- // Organization: VoiceCyber
- // Namespace: VCLogWebSDK
- // File Name: LogOperator
- //
- // created by Charley at 2013/6/9 12:01:11
- // http://www.baidu.com/p/仙剑200801
- //
- //======================================================================
- using System;
- using System.Linq;
- using System.Text;
- using System.Security.AccessControl;
- using System.IO;
- using System.Threading;
- namespace Core.StlMes.Client.PlnSaleOrd
- {
- /// <summary>
- /// 日志操作,实现写日志、备份与回删日志
- ///
- /// 使用实例:
- /// LogOperator logOperator=new LogOperator();
- /// logOperator.WriteOperationLog(mode,category,msg);
- ///
- /// 可以对日志文件大小、日志文件夹大小、日志文件名、日志保存路径进行设置
- /// 自动备份、自动回删日志文件
- /// 支持无阻塞的异步方式写操作日志(logOperator.WriteOperationLogAsync(int level,category,msg))
- ///
- /// Charley
- /// 2013/11/5
- /// </summary>
- public class LogOperator
- {
- private const int LOG_FILE_SIZE = 1000; //log file size 1000(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 const int LOG_SAVE_DAYS = 31;
- private delegate void WriteLogDelegate(LogMode level, string category, string msg); //利用委托异步写操作日志
- private WriteLogDelegate mWriteLogDelegate;
- private StreamWriter mLogWriter;
- private object mLogWriterLocker;
- private DateTime mLastDate;
- private Thread mThreadDelete;
- private bool m_bStart = false;
- #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;
- private string m_LogPathDate;//包含日期的路径
- /// <summary>
- /// 日志路径(相对路径或绝对路径)
- /// </summary>
- public string LogPath
- {
- get { return mLogPath; }
- set
- {
- mLogPath = string.IsNullOrEmpty(value) ? LOG_PATH : value;
- if (!Path.IsPathRooted(mLogPath))
- {
- m_LogPathDate = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, string.Format("{0}{1}", mLogPath, "\\" + DateTime.Now.ToString("yyyyMMdd")));
- }
- if (mLogWriter != null)
- {
- try
- {
- mLogWriter.Dispose();
- //mLogWriter.Close();
- mLogWriter = null;
- }
- catch { }
- string path = Path.Combine(m_LogPathDate, m_LogPathDate);
- mLogWriter = new StreamWriter(path, true, Encoding.Default);
- }
- }
- }
- 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; }
- }
- public int mLogSaveDays;
- /// <summary>
- /// 日志保留天数
- /// </summary>
- // public int LogSaveDays
- // {
- // get { return mLogSaveDays; }
- // set { mLogSaveDays = value; }
- // }
- #endregion
- /// <summary>
- /// 使用默认值创建日志实例
- /// </summary>
- public LogOperator()
- {
- mWriteLogDelegate = WriteOperationLogWithoutReturn;
- mLogWriterLocker = new object();
- mLogMode = LogMode.General;
- mLogName = LOG_NAME;
- mLogFileMaxSize = LOG_FILE_SIZE;
- mLogDirMaxSize = LOG_DIR_SIZE;
- mLogFileName = LOG_FILE_NAME;
- mLogPath = LOG_PATH;
- mLastDate = DateTime.Now;
- mLogSaveDays = -1;
- if (!Path.IsPathRooted(mLogPath))
- {
- m_LogPathDate = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, string.Format("{0}{1}", mLogPath, "\\" + DateTime.Now.ToString("yyyyMMdd")));
- }
- }
- /// <summary>
- /// 指定日志名称
- /// </summary>
- /// <param name="logName"></param>
- public LogOperator(string logName)
- : this()
- {
- mLogName = logName;
- }
- /// <summary>
- /// 启动日志写入器
- /// </summary>
- /// <returns></returns>
- public bool Start()
- {
- if (string.IsNullOrEmpty(mLogPath) || string.IsNullOrEmpty(mLogFileName))
- {
- mErrorMsg = "Log file name or log file path is empty.";
- return false;
- }
- try
- {
- DateTime now = DateTime.Now;
- mLastDate = now;
- m_LogPathDate = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, string.Format("{0}{1}", mLogPath, "\\" + DateTime.Now.ToString("yyyyMMdd")));
- string dir = Path.IsPathRooted(mLogPath) ? mLogPath : Path.Combine(AppDomain.CurrentDomain.BaseDirectory, string.Format("{0}{1}", mLogPath, "\\" + DateTime.Now.ToString("yyyyMMdd")));
- if (!Directory.Exists(dir))
- {
- Directory.CreateDirectory(dir);
- addDirPower(dir, "Everyone", "FullControl");
- }
- string path = Path.Combine(dir, string.Format("{0}{1}.txt", mLogFileName, now.ToString("yyyMMdd")));
- lock (mLogWriterLocker)
- {
- if (mLogWriter != null)
- {
- try
- {
- mLogWriter.Dispose();
- mLogWriter.Close();
- mLogWriter = null;
- }
- catch { }
- }
- mLogWriter = new StreamWriter(path, true, Encoding.Default);
- }
- mLogWriter.WriteLine("{0}\tLog Started.{1}", LogMode.Info, mLastDate.ToString("yyyy/MM/dd"));
- mLogWriter.Flush();
- if (!m_bStart)
- {
- StartDeleteLogThread();
- m_bStart = true;
- }
- return true;
- }
- catch (Exception ex)
- {
- mErrorMsg = ex.Message;
- return false;
- }
- }
- /// <summary>
- /// 停止并关闭日志写入器
- /// </summary>
- public void Stop()
- {
- StopDeleteThread();
- if (mLogWriter != null)
- {
- try
- {
- mLogWriter.Dispose();
- mLogWriter.Close();
- mLogWriter = null;
- }
- catch { }
- }
- }
- /// <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; }
- DateTime now = DateTime.Now;
- if (mLastDate.Date != now.Date)
- {
- if (!Start())
- {
- return false;
- }
- }
- if (mLogWriter == null)
- {
- Start();
- }
- if (category.Length <= 8)
- {
- category = category + "\t";
- }
- string formatstr = string.Format("{0}\t{1}\t{2}\t{3}", mode, DateTime.Now.ToString("HH:mm:ss.fff"), category, msg);
- lock (mLogWriterLocker)
- {
- if (mLogWriter != null)
- {
- mLogWriter.WriteLine(formatstr);
- mLogWriter.Flush();
- }
- }
- if (!BackupLog())
- {
- return false;
- }
- return true;
- }
- catch (Exception ex)
- {
- mErrorMsg = ex.ToString();
- return false;
- }
- }
- /// <summary>
- /// 写操作日志
- /// </summary>
- /// <param name="mode"></param>
- /// <param name="msg"></param>
- /// <returns></returns>
- public bool WriteOperationLog(LogMode mode, string msg)
- {
- return WriteOperationLog(mode, mLogName, 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);
- }
- /// <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);
- }
- #region BackupLog
- /// <summary>
- /// 备份日志文件
- /// </summary>
- /// <returns></returns>
- private bool BackupLog()
- {
- string filePath = Path.Combine(m_LogPathDate, string.Format("{0}{1}.txt", mLogFileName, mLastDate.ToString("yyyyMMdd")));
- if (!File.Exists(filePath))
- {
- mErrorMsg = string.Format("File not exist.\t{0}", filePath);
- return false;
- }
- lock (mLogWriterLocker)
- {
- var file = new FileInfo(filePath);
- long size = file.Length;
- if (size > mLogFileMaxSize * 1024)
- {
- string path = string.Empty;
- path = Path.Combine(m_LogPathDate, string.Format("{0}{1}.txt", mLogFileName, DateTime.Now.ToString("yyyyMMddhhmmssfff")));
- mLogWriter.Dispose();
- mLogWriter.Close();
- try
- {
- file.MoveTo(path);
- }
- catch { }
- mLogWriter = new StreamWriter(filePath, true, Encoding.Default);
- WriteOperationLog(LogMode.Info, "BackupLog", string.Format("Backup log {0} successful.", path));
- }
- }
- return true;
- }
- #endregion
- #region Other
- private void WriteOperationLogWithoutReturn(LogMode mode, string category, string msg)
- {
- WriteOperationLog(mode, category, msg);
- }
- 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);
- }
- #endregion
- #region DeleteLog
- private void StartDeleteLogThread()
- {
- if (mThreadDelete != null)
- {
- try
- {
- mThreadDelete.Abort();
- mThreadDelete = null;
- }
- catch
- {
- }
- }
- try
- {
- mThreadDelete = new Thread(DeleteLogWorker);
- mThreadDelete.Start();
- }
- catch
- {
- //WriteOperationLog(LogMode.Error, "StartDeleteThread",string.Format("Start delete thread fail.\t{0}", ex.Message));
- }
- }
- private void StopDeleteThread()
- {
- if (mThreadDelete != null)
- {
- try
- {
- mThreadDelete.Abort();
- mThreadDelete = null;
- }
- catch { }
- }
- }
- public void SleepSeconds(int nSecond)
- {
- for (int i = 0; i < nSecond; i++)
- {
- Thread.Sleep(1000);
- }
- }
- private void DeleteLogWorker()
- {
- while (true)
- {
- SleepSeconds(5);
- if (mLogSaveDays < 0)
- {
- continue;
- }
- DeleteLog();
- SleepSeconds(3600);
- }
- }
- /// <summary>
- /// 回删日志文件
- /// </summary>
- /// <returns></returns>
- private void DeleteLog()
- {
- string dir = Path.IsPathRooted(mLogPath) ? mLogPath : Path.Combine(AppDomain.CurrentDomain.BaseDirectory, mLogPath);
- DirectoryInfo logdir = new DirectoryInfo(dir);
- var ListFiles = logdir.GetDirectories("*").OrderByDescending(f => f.LastWriteTime).ToList();
- DateTime now = DateTime.Now;
-
- for (int i = ListFiles.Count - 1; i >= 0; i--)
- {
- if ((now - ListFiles[i].LastWriteTime).TotalDays > mLogSaveDays)
- {
- try
- {
- WriteOperationLog(LogMode.Warn, "DeleteLogFile", string.Format("Delete log file {0}", ListFiles[i].Name));
- ListFiles[i].Delete(true);
- }
- catch (Exception ex)
- {
- WriteOperationLog(LogMode.Warn, "DeleteLogFile", string.Format("Delete log file fail!\t{0}", ex.Message));
- }
- }
- }
- }
- #endregion
- }
- /// <summary>
- /// 日志级别,可任意组合
- /// </summary>
- [Flags]
- public enum LogMode
- {
- /// <summary>
- /// 调试
- /// </summary>
- Debug = 1,
- /// <summary>
- /// 信息(默认)
- /// </summary>
- Info = 2,
- /// <summary>
- /// 警告
- /// </summary>
- Warn = 4,
- /// <summary>
- /// 错误
- /// </summary>
- Error = 8,
- /// <summary>
- /// 致命
- /// </summary>
- Fatal = 16,
- /// <summary>
- /// 所有消息
- /// </summary>
- All = Debug | Info | Warn | Error | Fatal,
- /// <summary>
- /// 一般
- /// </summary>
- General = Info | Warn | Error | Fatal,
- /// <summary>
- /// 自定义info 消息
- /// </summary>
- Infomsg = Info | Warn | Error,
- /// <summary>
- /// 自定义debug 消息
- /// </summary>
- Debugmsg = Debug | Warn | Error,
- /// <summary>
- /// 自定义默认 消息
- /// </summary>
- Defaultmsg = Warn | Error
- }
- }
|