using System;
|
using System.Collections.Generic;
|
using System.Linq;
|
using System.Text;
|
using System.Threading.Tasks;
|
using System.IO;
|
using System.Threading;
|
using System.Reflection;
|
|
namespace HxCommonLib.Log
|
{
|
internal class LogConstant
|
{
|
public static LogHelper logger = LogHelper.GetLogHelper();
|
}
|
|
/// <summary>
|
/// 日志文件操作类
|
/// </summary>
|
public class LogHelper
|
{
|
private static readonly LogHelper Instance = new LogHelper();
|
|
//读写锁,当资源处于写入模式时,其他线程写入需要等待本次写入结束之后才能继续写入
|
/// <summary>d
|
/// Print函数写文件锁
|
/// </summary>
|
static ReaderWriterLockSlim LogWriteLock = new ReaderWriterLockSlim();
|
/// <summary>
|
/// DebugPrint函数写文件锁
|
/// </summary>
|
static ReaderWriterLockSlim DebugLogWriteLock = new ReaderWriterLockSlim();
|
/// <summary>
|
/// AlarmPrint函数写文件锁
|
/// </summary>
|
static ReaderWriterLockSlim AlarmLogWriteLock = new ReaderWriterLockSlim();
|
|
/// <summary>
|
/// 日志操作类的实例
|
/// </summary>
|
/// <returns></returns>
|
public static LogHelper GetLogHelper()
|
{
|
return Instance;
|
}
|
|
/// <summary>
|
/// 取得当前源码的哪一行
|
/// </summary>
|
/// <returns></returns>
|
public static int GetCurLineNum()
|
{
|
System.Diagnostics.StackTrace st = new System.Diagnostics.StackTrace(1, true);
|
return st.GetFrame(0).GetFileLineNumber();
|
}
|
|
/// <summary>
|
/// 取当前源码的源文件名
|
/// </summary>
|
/// <returns></returns>
|
public static string GetCurSourceFileName()
|
{
|
System.Diagnostics.StackTrace st = new System.Diagnostics.StackTrace(1, true);
|
|
return st.GetFrame(0).GetFileName();
|
|
}
|
|
#region 公共属性
|
|
/// <summary>
|
/// 是否打印调试日志
|
/// </summary>
|
public bool IsPrintDebugLog = false;
|
|
/// <summary>
|
/// 获取当前dll环境的执行路径
|
/// </summary>
|
public string StrStartupPath
|
{
|
get { return Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location); }
|
}
|
|
/// <summary>
|
/// 多线程日志文件名,对应Print函数
|
/// </summary>
|
public string FileName
|
{
|
get
|
{
|
return StrStartupPath + @"\Logs\"+ DateTime.Now.ToString("yyyyMMdd") + @"\NetworkLog" + DateTime.Now.ToString("yyyyMMdd") + ".log";
|
}
|
}
|
|
/// <summary>
|
/// 多线程调试日志文件名,对应DebugPrint函数
|
/// </summary>
|
public string FileNameDebugLog
|
{
|
get
|
{
|
return StrStartupPath + @"\Logs\"+ DateTime.Now.ToString("yyyyMMdd") + @"\NetworkLog" + DateTime.Now.ToString("yyyyMMdd") + ".log";
|
}
|
}
|
|
/// <summary>
|
/// 多线程日志文件名,对应AlarmLog函数
|
/// </summary>
|
public string FileNameAlarmLog
|
{
|
get
|
{
|
return StrStartupPath + @"\Logs\network" + @"\SyncAlarmLog" + DateTime.Now.ToString("yyyyMMdd") + ".log";
|
}
|
}
|
|
/// <summary>
|
/// 获取调用打印日志的函数名和行号
|
/// </summary>
|
public string DebugInfo
|
{
|
get
|
{
|
System.Diagnostics.StackFrame sf = new System.Diagnostics.StackTrace(true).GetFrame(2); //0最内层函数,依次向外
|
return "[" + sf.GetMethod().Name + ":" + sf.GetFileLineNumber() + "]";
|
}
|
}
|
|
#endregion
|
|
#region 写日志
|
|
|
|
/// <summary>
|
/// 写日志,支持多线程有加锁
|
/// </summary>
|
/// <param name="strMsg"></param>
|
public void Print(string strMsg)
|
{
|
try
|
{
|
//设置读写锁为写入模式独占资源,其他写入请求需要等待本次写入结束之后才能继续写入
|
//注意:长时间持有读线程锁或写线程锁会使其他线程发生饥饿 (starve)。 为了得到最好的性能,需要考虑重新构造应用程序以将写访问的持续时间减少到最小。
|
//从性能方面考虑,请求进入写入模式应该紧跟文件操作之前,在此处进入写入模式仅是为了降低代码复杂度
|
//因进入与退出写入模式应在同一个try finally语句块内,所以在请求进入写入模式之前不能触发异常,否则释放次数大于请求次数将会触发异常
|
LogWriteLock.EnterWriteLock();
|
|
//1. 判断目录是否存在
|
var fileLocation = StrStartupPath + @"\Logs\" + DateTime.Now.ToString("yyyyMMdd");
|
if (!Directory.Exists(fileLocation))
|
{
|
Directory.CreateDirectory(fileLocation);
|
}
|
|
//2. 日志写入
|
using (StreamWriter myWriter = new StreamWriter(FileName, true))
|
{
|
try
|
{
|
myWriter.WriteLine("[" + DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss.fff") + "] " + DebugInfo + strMsg + ".");
|
//myWriter.WriteLine("");
|
}
|
finally
|
{
|
myWriter.Close();
|
}
|
}
|
}
|
catch (Exception ex)
|
{
|
Console.WriteLine(ex.Message);
|
}
|
finally
|
{
|
//退出写入模式,释放资源占用
|
//注意:一次请求对应一次释放
|
//若释放次数大于请求次数将会触发异常[写入锁定未经保持即被释放]
|
//若请求处理完成后未释放将会触发异常[此模式不下允许以递归方式获取写入锁定]
|
LogWriteLock.ExitWriteLock();
|
}
|
}
|
|
/// <summary>
|
/// 调试写日志,支持多线程有加锁
|
/// </summary>
|
/// <param name="strMsg"></param>
|
public void DebugPrint(string strMsg)
|
{
|
if (this.IsPrintDebugLog) //是否打印日志
|
{
|
try
|
{
|
//设置读写锁为写入模式独占资源,其他写入请求需要等待本次写入结束之后才能继续写入
|
//注意:长时间持有读线程锁或写线程锁会使其他线程发生饥饿 (starve)。 为了得到最好的性能,需要考虑重新构造应用程序以将写访问的持续时间减少到最小。
|
//从性能方面考虑,请求进入写入模式应该紧跟文件操作之前,在此处进入写入模式仅是为了降低代码复杂度
|
//因进入与退出写入模式应在同一个try finally语句块内,所以在请求进入写入模式之前不能触发异常,否则释放次数大于请求次数将会触发异常
|
DebugLogWriteLock.EnterWriteLock();
|
|
//1. 判断目录是否存在
|
var fileLocation = StrStartupPath + @"\Logs\network";
|
if (!Directory.Exists(fileLocation))
|
{
|
Directory.CreateDirectory(fileLocation);
|
}
|
|
//2. 日志写入
|
using (StreamWriter myWriter = new StreamWriter(FileNameDebugLog, true))
|
{
|
try
|
{
|
myWriter.WriteLine("[" + DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss.fff") + "] " + DebugInfo + strMsg + ".");
|
//myWriter.WriteLine("");
|
}
|
finally
|
{
|
myWriter.Close();
|
}
|
}
|
}
|
catch (Exception ex)
|
{
|
Console.WriteLine(ex.Message);
|
}
|
finally
|
{
|
//退出写入模式,释放资源占用
|
//注意:一次请求对应一次释放
|
//若释放次数大于请求次数将会触发异常[写入锁定未经保持即被释放]
|
//若请求处理完成后未释放将会触发异常[此模式不下允许以递归方式获取写入锁定]
|
DebugLogWriteLock.ExitWriteLock();
|
}
|
}
|
}
|
|
/// <summary>
|
/// 写日志.log 支持多线程有加锁
|
/// </summary>
|
/// <param name="strMsg"></param>
|
public void AlarmPrint(string strMsg)
|
{
|
try
|
{
|
//设置读写锁为写入模式独占资源,其他写入请求需要等待本次写入结束之后才能继续写入
|
//注意:长时间持有读线程锁或写线程锁会使其他线程发生饥饿 (starve)。 为了得到最好的性能,需要考虑重新构造应用程序以将写访问的持续时间减少到最小。
|
//从性能方面考虑,请求进入写入模式应该紧跟文件操作之前,在此处进入写入模式仅是为了降低代码复杂度
|
//因进入与退出写入模式应在同一个try finally语句块内,所以在请求进入写入模式之前不能触发异常,否则释放次数大于请求次数将会触发异常
|
AlarmLogWriteLock.EnterWriteLock();
|
//1. 判断目录是否存在
|
var fileLocation = StrStartupPath + @"\Logs\network";
|
if (!Directory.Exists(fileLocation))
|
{
|
Directory.CreateDirectory(fileLocation);
|
}
|
|
//2. 日志写入
|
using (StreamWriter myWriter = new StreamWriter(FileNameAlarmLog, true))
|
{
|
try
|
{
|
myWriter.WriteLine("[" + DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss.fff") + "] " + DebugInfo + strMsg + ".");
|
//myWriter.WriteLine("");
|
}
|
finally
|
{
|
myWriter.Close();
|
}
|
}
|
}
|
catch (Exception ex)
|
{
|
Console.WriteLine(ex.Message);
|
}
|
finally
|
{
|
//退出写入模式,释放资源占用
|
//注意:一次请求对应一次释放
|
//若释放次数大于请求次数将会触发异常[写入锁定未经保持即被释放]
|
//若请求处理完成后未释放将会触发异常[此模式不下允许以递归方式获取写入锁定]
|
AlarmLogWriteLock.ExitWriteLock();
|
}
|
}
|
|
#endregion
|
|
|
#region 文件/文件夹排序
|
/// <summary>
|
/// C#按文件名排序(顺序)
|
/// </summary>
|
/// <param name="arrFi">待排序数组</param>
|
public void SortAsFileNameXY(ref FileInfo[] arrFi)
|
{
|
Array.Sort(arrFi, delegate(FileInfo x, FileInfo y) { return x.Name.CompareTo(y.Name); });
|
}
|
|
/// <summary>
|
/// C#按文件名排序(倒序)
|
/// </summary>
|
/// <param name="arrFi">待排序数组</param>
|
public void SortAsFileNameYX(ref FileInfo[] arrFi)
|
{
|
Array.Sort(arrFi, delegate(FileInfo x, FileInfo y) { return y.Name.CompareTo(x.Name); });
|
}
|
|
/// <summary>
|
/// C#按创建时间排序(顺序)
|
/// </summary>
|
/// <param name="arrFi">待排序数组</param>
|
public void SortAsFileCreationTimeXY(ref FileInfo[] arrFi)
|
{
|
Array.Sort(arrFi, delegate(FileInfo x, FileInfo y) { return x.CreationTime.CompareTo(y.CreationTime); });
|
}
|
|
/// <summary>
|
/// C#按创建时间排序(倒序)
|
/// </summary>
|
/// <param name="arrFi">待排序数组</param>
|
public void SortAsFileCreationTimeYX(ref FileInfo[] arrFi)
|
{
|
Array.Sort(arrFi, delegate(FileInfo x, FileInfo y) { return y.CreationTime.CompareTo(x.CreationTime); });
|
}
|
|
/// <summary>
|
/// C#按文件夹名称排序(顺序)
|
/// </summary>
|
/// <param name="dirs">待排序文件夹数组</param>
|
public void SortAsFolderNameXY(ref DirectoryInfo[] dirs)
|
{
|
Array.Sort(dirs, delegate(DirectoryInfo x, DirectoryInfo y) { return x.Name.CompareTo(y.Name); });
|
}
|
|
/// <summary>
|
/// C#按文件夹名称排序(倒序)
|
/// </summary>
|
/// <param name="dirs">待排序文件夹数组</param>
|
public void SortAsFolderNameYX(ref DirectoryInfo[] dirs)
|
{
|
Array.Sort(dirs, delegate(DirectoryInfo x, DirectoryInfo y) { return y.Name.CompareTo(x.Name); });
|
}
|
|
/// <summary>
|
/// C#按文件夹夹创建时间排序(顺序)
|
/// </summary>
|
/// <param name="dirs">待排序文件夹数组</param>
|
public void SortAsFolderCreationTimeXY(ref DirectoryInfo[] dirs)
|
{
|
Array.Sort(dirs, delegate(DirectoryInfo x, DirectoryInfo y) { return x.CreationTime.CompareTo(y.CreationTime); });
|
}
|
|
|
/// <summary>
|
/// C#按文件夹创建时间排序(倒序)
|
/// </summary>
|
/// <param name="dirs">待排序文件夹数组</param>
|
public void SortAsFolderCreationTimeYX(ref DirectoryInfo[] dirs)
|
{
|
Array.Sort(dirs, delegate(DirectoryInfo x, DirectoryInfo y) { return y.CreationTime.CompareTo(x.CreationTime); });
|
}
|
#endregion
|
|
}
|
}
|