z8018
3 天以前 d8dc91f9c1fece5711e38edd1b1274cb9e579015
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using WIDESEA_Core.Helper;
 
namespace WIDESEA_Core.LogHelper
{
    public class QuartzLogger
    {
        static ReaderWriterLockSlim LogWriteLock = new ReaderWriterLockSlim();
        static string folderPath = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, $"Log\\{DateTime.Now.ToString("yyyy-MM-dd")}");
 
        /// <summary>
        /// 将日志内容写入指定文件
        /// </summary>
        /// <param name="fileName">日志文件名</param>
        /// <param name="log">要记录的日志内容</param>
        /// <remarks>
        /// 该方法会确保线程安全地写入日志,若目录不存在会自动创建,
        /// 日志内容会自动添加时间戳并追加到文件末尾
        /// </remarks>
        public static void WriteLogToFile(string fileName, string log)
        {
            try
            {
                // 进入写锁
                LogWriteLock.EnterWriteLock();
 
                // 如果文件夹不存在,则创建文件夹
                if (!Directory.Exists(folderPath))
                {
                    Directory.CreateDirectory(folderPath);
                }
                // 获取日志文件路径
                string logFilePath = Path.Combine(folderPath, GetLastAccessFileName(fileName));
                // 获取当前时间
                DateTime now = DateTime.Now;
                // 构造日志内容
                string logContent = $"【{now}】{Environment.NewLine}{log}";
 
                // 将日志内容追加到日志文件中
                File.AppendAllText(logFilePath, logContent);
            }
            catch { }
            finally
            {
                // 退出写锁
                LogWriteLock.ExitWriteLock();
            }
        }
        static int size = 10 * 1024 * 1024;
        static string ext = ".log";
        /// <summary>
        /// 获取指定文件夹下符合条件的日志文件路径
        /// </summary>
        /// <param name="folderPath">要搜索的文件夹路径</param>
        /// <param name="fileName">要匹配的文件名</param>
        /// <returns>如果找到符合条件的文件则返回第一个文件的完整路径,否则返回带时间戳的新文件路径</returns>
        /// <remarks>
        /// 查找规则:文件名包含指定名称、扩展名匹配且小于指定大小的文件,按文件名降序排列
        /// </remarks>
        private static string GetLogFilePath(string folderPath, string fileName)
        {
            // 获取指定文件夹下的所有文件
            var allFiles = new DirectoryInfo(folderPath);
            // 获取符合条件的文件,按文件名降序排列
            var selectFiles = allFiles.GetFiles().Where(fi => fi.Name.ToLower().Contains(fileName.ToLower()) && fi.Extension.ToLower() == ext.ToLower() && fi.Length < size).OrderByDescending(d => d.Name).ToList();
 
            FileInfo? file = selectFiles.FirstOrDefault();
            // 如果有符合条件的文件,返回第一个文件的完整路径
            if (file != null)
            {
                return file.FullName;
            }
 
            // 如果没有符合条件的文件,返回一个新的文件路径,文件名为原文件名加上当前时间
            return Path.Combine(folderPath, $@"{fileName}_{DateTime.Now.ToString("HH-mm-ss")}.log");
        }
 
        /// <summary>
        /// 获取最后一个可用的日志文件名
        /// </summary>
        /// <param name="fileName">日志文件基础名称</param>
        /// <returns>如果存在未达到大小限制的日志文件则返回该文件名,否则返回基于当前时间的新日志文件名</returns>
        /// <remarks>
        /// 该方法会遍历所有已存在的日志文件,返回第一个文件大小未超过限制的文件名。
        /// 如果没有符合条件的文件,则生成一个以当前时间命名的新日志文件名。
        /// </remarks>
        private static string GetLastAccessFileName(string fileName)
        {
            foreach (var m in GetExistLogFileNames(fileName))
            {
                FileInfo fileInfo = new FileInfo(m);
                if (fileInfo.Length < size)
                {
                    return m;
                }
            }
 
            // 返回一个新的默认当前时间的日志名称
            return $@"{fileName}_{DateTime.Now.ToString("HH-mm-ss")}.log";
        }
 
        /// <summary>
        /// 获取指定文件名模式的所有日志文件
        /// </summary>
        /// <param name="fileName">日志文件名前缀</param>
        /// <returns>匹配文件名模式的所有日志文件路径数组</returns>
        public static string[] GetExistLogFileNames(string fileName)
        {
            string[] fileNames = Directory.GetFiles(folderPath, fileName + "*.log");
            return fileNames;
        }
    }
}