您的位置:首页 > 编程语言 > C#

C# 简单的日志系统(服务端)

2018-02-27 15:58 721 查看
新的一年开始,也该开始学习一些新的东西,首先就是将去年写的C#服务器重新构思一下。

今天的目标:日志系统

需求:

1.显示日志

2.写入到本地文件

3.错误或异常日志需要通过邮件通知

4.可以自定日志类型(可有可无)

日志:

我个人理解,就是系统在运行过程中所产生的提示信息。比如,Debug程序的时候,除了进行断点调试,大多都是进行文本输出,来观察这一段程序书写是否正确。其次,就是我们经常碰到的错误或者捕获的异常信息等。通过观察日志,可以快速的帮助我们找到想要东西。

在该日志系统中,我们使用两个类:
Debug
LogInFile
LogInFile
主要是用来进行日志写入功能得。

1.显示日志

C# 输出文字的语句:

Console.WriteLine(info, param);


在现实日志上,我们只是对上面语句进行了一层封装而已。

实现:

/// <summary>
/// 信息
/// </summary>
/// <param name="info"></param>
/// <param name="param"></param><
4000
/span>
public static void LogInfo(string info, params object[] param)
{
LogInfo("", info.ToString(), param);
}
/// <summary>
/// 信息
/// </summary>
/// <param name="info"></param>
public static void LogInfo(object info)
{
LogInfo("", info.ToString(), null);
}
/// <summary>
/// 自定义信息
/// </summary>
/// <param name="genre"></param>
/// <param name="info"></param>
/// <param name="param"></param>
public static void LogInfo(string genre, string info, params object[] param)
{
SetColor(genre, ColorConfig.InfoColor, info,param);

LogInFileInfo lifi = WriteLine(genre, LogGenreEnum.Info, info, param);
if(lifi!=null)
SendEamil(genre, LogGenreEnum.Info, string.Format("{0} - Info:{1}", DateTime.Now, string.Format(info, param)), lifi.GetMessage);
}

/// <summary>
/// 错误
/// </summary>
/// <param name="info"></param>
/// <param name="param"></param>
public static void LogError(string info, params object[] param)
{
LogError("", info.ToString(), param);
}

/// <summary>
/// 错误
/// </summary>
/// <param name="info"></param>
public static void LogError(object info)
{
LogError("", info.ToString(), null);
}
/// <summary>
/// 错误
/// </summary>
/// <param name="genre"></param>
/// <param name="info"></param>
/// <param name="param"></param>
public static void LogError(string genre, string info, params object[] param)
{
SetColor(genre, ColorConfig.ErrorColor, info,param);
LogInFileInfo lifi = WriteLine(genre, LogGenreEnum.Error, info, param);
if(lifi!=null)
SendEamil(genre, LogGenreEnum.Warring, string.Format("{0} - Error:{1}", DateTime.Now, string.Format(info, param)), lifi.GetMessage);
}

/// <summary>
/// 警告
/// </summary>
/// <param name="info"></param>
/// <param name="param"></param>
public static void LogWarring(string info, params object[] param)
{
LogWarring("", info, param);
}

/// <summary>
/// 警告
/// </summary>
/// <param name="info"></param>
public static void LogWarring(object info)
{
LogWarring("", info.ToString(), null);
}
/// <summary>
/// 警告
/// </summary>
/// <param name="genre"></param>
/// <param name="info"></param>
/// <param name="param"></param>
public static void LogWarring(string genre, string info, params object[] param)
{
SetColor(genre, ColorConfig.WarringColor, info,param);
LogInFileInfo lifi = WriteLine(genre, LogGenreEnum.Warring, info, param);
//发送邮件
if (lifi != null)
SendEamil(genre, LogGenreEnum.Warring, string.Format("{0} - Warring:{1}", DateTime.Now, string.Format(info, param)), lifi.GetMessage);
}

/// <summary>
/// 异常信息
/// </summary>
/// <param name="ex"></param>
/// <param name="tag"></param>
public static void LogException(Exception ex, string tag = "")
{
LogException("", ex, tag);
}

/// <summary>
/// 输出异常
/// </summary>
/// <param name="ex"></param>
/// <param name="tag"></param>
public static void LogException(string genre, Exception ex, string tag = "")
{
string info = string.Empty;
info += string.Format("异常信息 {0} - {1} " + Environment.NewLine, tag, ex.Message);
info += string.Format("\t异常对象:{0}" + Environment.NewLine, ex.Source);
info += "\t异常堆栈:" + Environment.NewLine + "\t" + ex.StackTrace.Trim() + Environment.NewLine;
info += string.Format("\t触发方法:{0}" + Environment.NewLine + Environment.NewLine, ex.TargetSite);

SetColor(genre, ColorConfig.ExcepitonColor, info);
LogInFileInfo lifi = WriteLine(genre,LogGenreEnum.Exception, info);
if (lifi != null)
SendEamil(genre, LogGenreEnum.Exception, string.Format("{0} - Exception:{1}", DateTime.Now, ex.Message), lifi.GetMessage);
}


上面只是进行一层封装没什么好说的。

从上面可以看出,我将程序里的信息分为四类:

public enum LogGenreEnum : int
{
/// <summary>
/// 信息
/// </summary>
Info = 2,
/// <summary>
/// 错误
/// </summary>
Error = 4,
/// <summary>
/// 警告
/// </summary>
Warring = 8,
/// <summary>
/// 异常
/// </su
1e943
mmary>
Exception = 16
}


感觉这4类已经足够用了。

2.写入本地文件

我的想法是:

1.创建一个队列存储日志信息

2.开启别的线程进行文件写入,线程数量可以进行设置,默认为3条

3.每个线程每次可以写入N条日志,日志数据可以设置,默认100条

4.当CPU的使用率低于多少数值时,才进行写入,使用率可以设置,默认30%(我的想法是,在电脑空闲的时候进行写入,但是我不知道怎么才能判断电脑是否在空闲状态,所以用cpu的使用率。这里有一个问题就是我在获取CPU使用率的时候感觉很慢,不知道为什么,大家有什么办法吗?)

5.日志文件每天一个,如果文件大小大于50M则自动创建新的文件(刚想起来,还没写,不过就是判断文件大小,然后新建一个就行了)

6.线程每隔多少秒进行一次写入,时间也是可以进行配置的。

完整的LogInFile类

using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using System.IO;

namespace SvEngine.Log
{
public class LogInFile
{
PerformanceCounter cpuRate = new PerformanceCounter("Processor", "% Processor Time", "_Total");
public List<LogInFileInfo> MessageStack = new List<LogInFileInfo>();

public void AddMessage(LogInFileInfo message)
{
lock (MessageStack) { MessageStack.Add(message); }
}

/// <summary>
/// 开始写入文件
/// </summary>
public void StartInFile()
{
while (true)
{
lock (MessageStack)
{
if (MessageStack.Count < 1)
{
Thread.Sleep(Debug.InFileConfig.LogInFileWriteInterval);
continue;
}

if (cpuRate.NextValue() > Debug.InFileConfig.CpuRate)
{
Thread.Sleep(Debug.InFileConfig.LogInFileWriteInterval);
continue;
}

List<LogInFileInfo> writeList = new List<LogInFileInfo>();
if (MessageStack.Count > Debug.InFileConfig.LogInFileWriteNum)
{
writeList.AddRange(MessageStack.GetRange(0, Debug.InFileConfig.LogInFileWriteNum));
MessageStack.RemoveRange(0, Debug.InFileConfig.LogInFileWriteNum);
}
else
{
writeList.AddRange(MessageStack);
MessageStack.Clear();
}
string infoMessage = string.Empty;
string errorMessage = string.Empty;
string waringMessage = string.Empty;
//写入文件
for (int i = 0; i < writeList.Count; i++)
{
LogInFileInfo curMes = writeList[i];
switch (curMes.Genre)
{
case Debug.LogGenreEnum.Info:
infoMessage += curMes.GetMessage;
break;
case Debug.LogGenreEnum.Error:
case Debug.LogGenreEnum.Exception:
errorMessage += curMes.GetMessage;
break;
case Debug.LogGenreEnum.Warring:
waringMessage += curMes.GetMessage;
break;
}
curMes.Dispose();
}

WriteText(Debug.LogGenreEnum.Info,infoMessage);
WriteText(Debug.LogGenreEnum.Error, errorMessage);
WriteText(Debug.LogGenreEnum.Warring, waringMessage);

writeList = null;
}
//等待执行
Thread.Sleep(Debug.InFileConfig.LogInFileWriteInterval);
}
}

private void WriteText(Debug.LogGenreEnum genre,string text)
{
//文件写入
string filePath = string.Format(@"{0}\{1}\", Debug.InFileConfig.LogPath, genre.ToString());
string fileName = string.Format("{0}.txt", CurDate);
if (!Directory.Exists(filePath))
Directory.CreateDirectory(filePath);
if (!File.Exists(filePath + fileName))
{
FileStream fs = File.Create(filePath + fileName);
fs.Close();
}

using (FileStream fs = new FileStream(filePath + fileName, FileMode.Append, FileAccess.Write, FileShare.Write))
{
Byte[] info = new UTF8Encoding(true).GetBytes(text);
fs.Write(info, 0, info.Length);
}
}

private string CurDate
{
get { return string.Format("{0}-{1}-{2}", DateTime.Now.Year, DateTime.Now.Month, DateTime.Now.Day); }
}

}

/// <summary>
/// 日志数据
/// </summary>
public class LogInFileInfo:IDisposable
{
/// <summary>
/// Log类型
/// </summary>
public Debug.LogGenreEnum Genre;

/// <summary>
/// 创建时间
/// </summary>
public DateTime CreateTime;
/// <summary>
/// 内容
/// </summary>
public string MessageConnect;
/// <summary>
/// 获取内容
/// </summary>
public string GetMessage
{
get { return string.Format("{0} - {1}"+ System.Environment.NewLine , CreateTime, MessageConnect); }
}

public void Dispose()
{

}
}

}


PerformanceCounter cpuRate = new PerformanceCounter("Processor", "% Processor Time", "_Total");


这条语句就是获取当前CPU的使用率,一定要注意,这个条语句最好不要放在方法中,第一次获取的值为0,如果在方法中的每一次调用,总是会获取的值为0的。

if (cpuRate.NextValue() > Debug.CpuRate)
{
Thread.Sleep(Debug.LogInFileWriteInterval);
continue;
}


这里判断了一下CPU的使用率。

case Debug.LogGenreEnum.Error:
case Debug.LogGenreEnum.Exception:
errorMessage += curMes.GetMessage;


我将Error类型的日志和异常类型的日志,放在同一个文件中。

if (!File.Exists(filePath + fileName))
{
FileStream fs = File.Create(filePath + fileName);
fs.Close();
}


这里文件创建完毕后,一定要关闭一下,否则下面会报文件被其他进程占用的异常。

在InFileConfig类中,则存放了日志写入相关的配置和方法:

/// <summary>
/// 日志写入配置
/// </summary>
public class InFileConfig
{
private LogInFile _logInFile;
private Thread[] _logInFileThread;

private bool _isInFile = false;
/// <summary>
/// 是否写入文件
/// </summary>
public bool IsInFile
{
get { return _isInFile; }
set
{
_isInFile = value;
if (_isInFile)
{
_logInFile = new LogInFile();
_logInFileThread = new Thread[_logInFileThreadNum];
StartThread();
}
else
{
CloseThread();
_logInFile = null;
}
}
}

private int _inFileGenre = (int)LogGenreEnum.Info | (int)LogGenreEnum.Error | (int)LogGenreEnum.Exception | (int)LogGenreEnum.Warring;
/// <summary>
/// 开启日志写入的类型
/// </summary>
public int InFileGenre
{
get { return _inFileGenre; }
set { _inFileGenre = value; }
}

private string _logPath = "";
/// <summary>
/// 日志存储位置
/// </summary>
public string LogPath
{
get { return _logPath.Equals("") ? Environment.CurrentDirectory + @"\Log" : _logPath; }
set { _logPath = value; }
}

private int _logInFileWriteInterval = 2000;
/// <summary>
/// 日志写入间隔时间
/// </summary>
public int LogInFileWriteInterval
{
get { return _logInFileWriteInterval; }
set { _logInFileWriteInterval = value; }
}

private int _logInFileWriteNum = 99;
/// <summary>
/// 每次日志写入量
/// </summary>
public int LogInFileWriteNum
{
get { return _logInFileWriteNum; }
set { _logInFileWriteNum = value; }
}

private int _logInFileThreadNum = 3;
/// <summary>
/// 日志写入线程数量
/// </summary>
public int LogInFileThreadNum
{
get { return _logInFileThreadNum; }
set
{
_logInFileThreadNum = value;
if (_logInFileThread != null)
CloseThread();
_logInFileThread = new Thread[_logInFileThreadNum];
}
}

private  float _cpuRate = 30;
/// <summary>
/// Cpu 使用率小于多少开始写入文件
/// </summary>
public float CpuRate
{
get { return _cpuRate; }
set { _cpuRate = value; }
}

/// <summary>
/// 添加消息
/// </summary>
/// <param name="message"></param>
public void AddMessage(LogInFileInfo message)
{
_logInFile.AddMessage(message);
}

/// <summary>
/// 开启线程
/// </summary>
private void StartThread()
{
for (int i = 0; i < _logInFileThread.Length; i++)
{
_logInFileThread[i] = new Thread(new ThreadStart(_logInFile.StartInFile));
_logInFileThread[i].IsBackground = true;
_logInFileThread[i].Start();
}
}

/// <summary>
/// 关闭线程
/// </summary>
private void CloseThread()
{
for (int i = 0; i < _logInFileThread.Length; i++)
{
if (_logInFileThread[i].IsAlive)
_logInFileThread[i].Abort();
}
_logInFileThread = null;
}

}


以上这些属性对写入日志进行相关配置。

StartThread()
CloseThread()
定义了线程开启和关闭。

InFileGenre
属性则定义了那些日志可以及进行文件写入

private int _inFileGenre = (int)LogGenreEnum.Info | (int)LogGenreEnum.Error | (int)LogGenreEnum.Exception | (int)LogGenreEnum.Warring;


默认下4中类型都可以进行写入。

日志写入大概就是这些内容。

3.邮件通知

邮件部分我也是参考其他作者的博客写的,下面放出地址:

参考地址 https://www.cnblogs.com/xiezunxu/articles/7421322.html

/// <summary>
/// 发送邮件,参考地址 https://www.cnblogs.com/xiezunxu/articles/7421322.html /// </summary>
public static void SendEmail(string title,string body)
{
if (!EmailConfig.IsEmail  //不发送邮件
|| EmailConfig.SenderEmail.Equals(string.Empty)  //发送人为空
|| EmailConfig.ReceiverEamil.Count < 1  //接收人为空
|| EmailConfig.AuthorizationCode.Equals(string.Empty)  //授权码为空
|| EmailConfig.SmtpHost.Equals(string.Empty)) return; //主机名为空

MailMessage mailMessage = new MailMessage();
mailMessage.From = new MailAddress(EmailConfig.SenderEmail);
for(int i = 0;i<EmailConfig.ReceiverEamil.Count;i++)
mailMessage.To.Add(new MailAddress(EmailConfig.ReceiverEamil[i]));
mailMessage.Subject = title;
mailMessage.Body = body;

SmtpClient client = new SmtpClient();
client.Host =EmailConfig.SmtpHost;
client.EnableSsl = true;
client.UseDefaultCredentials = false;
client.Credentials = new NetworkCredential(EmailConfig.SenderEmail, EmailConfig.AuthorizationCode);
client.Send(mailMessage);
}
}


上面这个方法就是邮件发送的主要方法。

4.自定义级别:

使用比较简单的方式:

private static Dictionary<string, CustomGenre> _customGenre = new Dictionary<string, CustomGenre>();
/// <summary>
/// 自定义类型
/// </summary>
/// <param name="genre"></param>
public static void CustomGenre(Dictionary<string, CustomGenre> genre)
{
_customGenre = genre;
}


把自定义类型传进来,在调用其他输出方法是,设置参数
string genre
即可,会先去匹配_customGenre 中是否有该类型。

/// <summary>
/// 颜色配置
/// </summary>
public class ColorConfig
{

/// <summary>
/// 字体颜色
/// </summary>
public ConsoleColor FontColor
{
get { return Console.ForegroundColor; }
set
{
Console.ForegroundColor = value;
}
}

/// <summary>
/// 默认颜色
/// </summary>
public ConsoleColor DefaultColor = ConsoleColor.White;
/// <summary>
/// 信息颜色
/// </summary>
public ConsoleColor InfoColor = ConsoleColor.White;
/// <summary>
/// 错误颜色
/// </summary>
public ConsoleColor ErrorColor = ConsoleColor.Red;
/// <summary>
/// 警告颜色
/// </summary>
public ConsoleColor WarringColor = ConsoleColor.Yellow;
/// <summary>
/// 异常颜色
/// </summary>
public ConsoleColor ExcepitonColor = ConsoleColor.Cyan;
}


ColorConfig
这个类型进行了一些颜色属性的配置。

测试:

class Program
{
static void Main(string[] args)
{
Console.WriteLine(Environment.CurrentDirectory + @"\Log");
Debug.InFileConfig.IsInFile = true;
Debug.IsDebug = true;

Debug.EmailConfig.SenderEmail = "***@qq.com";
Debug.EmailConfig.ReceiverEamil.Add("***@qq.com");
Debug.EmailConfig.SmtpHost = "smtp.qq.com";
//此处在你邮箱中获取
Debug.EmailConfig.AuthorizationCode = "******";

Debug.EmailConfig.IsEmail = true;

try
{
throw new Exception("这是一个测试异常");
}
catch (Exception ex)
{
Debug.LogException(ex);
}

for (int i = 0; i < 10; i++)
{
Thread t = new Thread(new ParameterizedThreadStart(Input));
t.Start(i);
}

Console.ReadKey();
}

static void Input(object data)
{
int idnex = (int)data;
for (int i = 0; i < 100; i++)
{
Debug.LogError("{0} - {1} 日志测试", idnex, i);
}
}

}




成功收到邮件:



日志写入成功:



注意CPU的使用率大于设置的使用率是不会进行写入的,等到条件达成后才会进行写入。

完整的Debug类:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Net.Mail;
using System.Text;
using System.Threading;
using static SvEngine.Log.Debug;

namespace SvEngine.Log
{
public class Debug
{
public enum LogGenreEnum : int
{
/// <summary>
/// 信息
/// </summary>
Info = 2,
/// <summary>
/// 错误
/// </summary>
Error = 4,
/// <summary>
/// 警告
/// </summary>
Warring = 8,
/// <summary>
/// 异常
/// </summary>
Exception = 16
}

private static EmailConfig _emailConfig = new EmailConfig();
/// <summary>
/// 邮件配置
/// </summary>
public static EmailConfig EmailConfig
{
get {
return _emailConfig;
}
}

private static InFileConfig _inFileConfig = new InFileConfig();
/// <summary>
/// 写入日志配置
/// </summary>
public static InFileConfig InFileConfig {
get {
return _inFileConfig;
}
}

private static ColorConfig _colorConfig = new ColorConfig();
/// <summary>
/// 颜色配置
/// </summary>
public static ColorConfig ColorConfig
{
get { return _colorConfig; }
}

private static bool _isDebug = true;
/// <summary>
/// 是否显示
/// </summary>
public static bool IsDebug
{
get { return _isDebug; }
set { _isDebug = value; }
}

private static bool _isEnable = true;
/// <summary>
/// 是否开启
/// </summary>
public static bool IsEnable
{
get
{
return _isEnable;
}
set { _isEnable = value; }
}

private static Dictionary<string, CustomGenre> _customGenre = new Dictionary<string, CustomGenre>();
/// <summary>
/// 自定义类型
/// </summary>
/// <param name="genre"></param>
public static void CustomGenre(Dictionary<string, CustomGenre> genre)
{
_customGenre = genre;
}

/// <summary>
/// 信息
/// </summary>
/// <param name="info"></param>
/// <param name="param"></param>
public static void LogInfo(string info, params object[] param)
{
LogInfo("", info.ToString(), param);
}
/// <summary>
/// 信息
/// </summary>
/// <param name="info"></param>
public static void LogInfo(object info)
{
LogInfo("", info.ToString(), null);
}
/// <summary>
/// 自定义信息
/// </summary>
/// <param name="genre"></param>
/// <param name="info"></param>
/// <param name="param"></param>
public static void LogInfo(string genre, string info, params object[] param)
{
SetColor(genre, ColorConfig.InfoColor, info,param);

LogInFileInfo lifi = WriteLine(genre, LogGenreEnum.Info, info, param);
if(lifi!=null)
SendEamil(genre, LogGenreEnum.Info, string.Format("{0} - Info:{1}", DateTime.Now, string.Format(info, param)), lifi.GetMessage);
}

/// <summary>
/// 错误
/// </summary>
/// <param name="info"></param>
/// <param name="param"></param>
public static void LogError(string info, params object[] param)
{
LogError("", info.ToString(), param);
}

/// <summary>
/// 错误
/// </summary>
/// <param name="info"></param>
public static void LogError(object info)
{
LogError("", info.ToString(), null);
}
/// <summary>
/// 错误
/// </summary>
/// <param name="genre"></param>
/// <param name="info"></param>
/// <param name="param"></param>
public static void LogError(string genre, string info, params object[] param)
{
SetColor(genre, ColorConfig.ErrorColor, info,param);
LogInFileInfo lifi = WriteLine(genre, LogGenreEnum.Error, info, param);
if(lifi!=null)
SendEamil(genre, LogGenreEnum.Warring, string.Format("{0} - Error:{1}", DateTime.Now, string.Format(info, param)), lifi.GetMessage);
}

/// <summary>
/// 警告
/// </summary>
/// <param name="info"></param>
/// <param name="param"></param>
public static void LogWarring(string info, params object[] param)
{
LogWarring("", info, param);
}

/// <summary>
/// 警告
/// </summary>
/// <param name="info"></param>
public static void LogWarring(object info)
{
LogWarring("", info.ToString(), null);
}
/// <summary>
/// 警告
/// </summary>
/// <param name="genre"></param>
/// <param name="info"></param>
/// <param name="param"></param>
public static void LogWarring(string genre, string info, params object[] param)
{
SetColor(genre, ColorConfig.WarringColor, info,param);
LogInFileInfo lifi = WriteLine(genre, LogGenreEnum.Warring, info, param);
//发送邮件
if (lifi != null)
SendEamil(genre, LogGenreEnum.Warring, string.Format("{0} - Warring:{1}", DateTime.Now, string.Format(info, param)), lifi.GetMessage);
}

/// <summary>
/// 异常信息
/// </summary>
/// <param name="ex"></param>
/// <param name="tag"></param>
public static void LogException(Exception ex, string tag = "")
{
LogException("", ex, tag);
}

/// <summary>
/// 输出异常
/// </summary>
/// <param name="ex"></param>
/// <param name="tag"></param>
public static void LogException(string genre, Exception ex, string tag = "")
{
string info = string.Empty;
info += string.Format("异常信息 {0} - {1} " + Environment.NewLine, tag, ex.Message);
info += string.Format("\t异常对象:{0}" + Environment.NewLine, ex.Source);
info += "\t异常堆栈:" + Environment.NewLine + "\t" + ex.StackTrace.Trim() + Environment.NewLine;
info += string.Format("\t触发方法:{0}" + Environment.NewLine + Environment.NewLine, ex.TargetSite);

SetColor(genre, ColorConfig.ExcepitonColor, info);
LogInFileInfo lifi = WriteLine(genre,LogGenreEnum.Exception, info);
if (lifi != null)
SendEamil(genre, LogGenreEnum.Exception, string.Format("{0} - Exception:{1}", DateTime.Now, ex.Message), lifi.GetMessage);
}

/// <summary>
/// 设置颜色
/// </summary>
/// <param name="genre"></param>
/// <param name="defaultColor"></param>
/// <param name="info"></param>
/// <param name="param"></param>
private static void SetColor(string genre,ConsoleColor defaultColor, string info, params object[] param)
{
if (_customGenre.ContainsKey(genre))

Console.ForegroundColor = _customGenre[genre].ConsoleColor;
else
Console.ForegroundColor = defaultColor;

DebugWrite(info,param);

}

/// <summary>
/// 显示日志
/// </summary>
/// <param name="info"></param>
/// <param name="param"></param>
private static void DebugWrite(string info, params object[] param)
{
if (IsEnable && IsDebug)
Console.WriteLine(info, param);
Console.ForegroundColor = ColorConfig.DefaultColor;
}

/// <summary>
/// 日志写入
/// </summary>
/// <param name="Genre"></param>
/// <param name="genre"></param>
/// <param name="info"></param>
/// <param name="param"></param>
/// <returns></returns>
private static LogInFileInfo WriteLine(string Genre, LogGenreEnum genre, string info, params object[] param)
{
if (IsEnable&& InFileConfig.IsInFile)
{
if (_customGenre.ContainsKey(Genre) && !_customGenre[Genre].IsInFile)
return null;

if (Genre.Equals("")&&(InFileConfig.InFileGenre & (int)genre) <= 0)
return null;

LogInFileInfo fileInfo = new LogInFileInfo();
fileInfo.CreateTime = DateTime.Now;
fileInfo.MessageConnect = string.Format(info, param);
if (!_customGenre.ContainsKey(Genre))
{

//写入文件操作
fileInfo.Genre = genre;
//添加消息
InFileConfig.AddMessage(fileInfo);
return fileInfo;
}
CustomGenre cg = _customGenre[Genre];
fileInfo.Genre = cg.GenreEnum;
InFileConfig.AddMessage(fileInfo);
return fileInfo;
}
return null;
}

/// <summary>
/// 发送邮件
/// </summary>
/// <param name="Genre"></param>
/// <param name="genre"></param>
/// <param name="tile"></param>
/// <param name="body"></param>
private static void SendEamil(string Genre, LogGenreEnum genre, string tile,string body)
{
//自定义小于1 使用默认
if (_customGenre.Count > 0)
{
if (_customGenre.ContainsKey(Genre) && _customGenre[Genre].IsEmail)
SendEmail(tile,body);
}
else //使用自定义
{
if ((EmailConfig.EmailGenre & (int)genre) > 0)
{
SendEmail(tile,body);
}
}
}

/// <summary>
/// 发送邮件,参考地址 https://www.cnblogs.com/xiezunxu/articles/7421322.html /// </summary>
public static void SendEmail(string title,string body)
{
if (!EmailConfig.IsEmail  //不发送邮件
|| EmailConfig.SenderEmail.Equals(string.Empty)  //发送人为空
|| EmailConfig.ReceiverEamil.Count < 1  //接收人为空
|| EmailConfig.AuthorizationCode.Equals(string.Empty)  //授权码为空
|| EmailConfig.SmtpHost.Equals(string.Empty)) return; //主机名为空

MailMessage mailMessage = new MailMessage();
mailMessage.From = new MailAddress(EmailConfig.SenderEmail);
for(int i = 0;i<EmailConfig.ReceiverEamil.Count;i++)
mailMessage.To.Add(new MailAddress(EmailConfig.ReceiverEamil[i]));
mailMessage.Subject = title;
mailMessage.Body = body;

SmtpClient client = new SmtpClient();
client.Host =EmailConfig.SmtpHost;
client.EnableSsl = true;
client.UseDefaultCredentials = false;
client.Credentials = new NetworkCredential(EmailConfig.SenderEmail, EmailConfig.AuthorizationCode);
client.Send(mailMessage);
}
}

/// <summary>
/// 自定义级别
/// </summary>
public class CustomGenre
{
public string GenreName;
public ConsoleColor ConsoleColor;
public bool IsEmail = false;
public bool IsInFile = false;
public LogGenreEnum GenreEnum = LogGenreEnum.Info;
}

/// <summary>
/// 邮箱配置
/// </summary>
public class EmailConfig
{
private  bool _isEmail = false;
/// <summary>
/// 是否发送邮件提示
/// </summary>
public bool IsEmail
{
get { return _isEmail; }
set { _isEmail = value; }
}

private  int _emailGenre = (int)LogGenreEnum.Error | (int)LogGenreEnum.Exception;
/// <summary>
/// 发送邮件类型
/// </summary>
public int EmailGenre
{
get { return _emailGenre; }
set
{
_emailGenre = value;
}
}

/// <summary>
/// 发送者
/// </summary>
public string SenderEmail = string.Empty;
/// <summary>
/// 接收方
/// </summary>
public List<string> ReceiverEamil = new List<string>();
/// <summary>
/// qq 为  "smtp.qq.com" 126 为 "smtp.126.com"
/// </summary>
public string SmtpHost = string.Empty;
/// <summary>
/// 授权码,需要在邮箱中获取
/// </summary>
public string AuthorizationCode = string.Empty;
}

/// <summary>
/// 日志写入配置
/// </summary>
public class InFileConfig
{
private LogInFile _logInFile;
private Thread[] _logInFileThread;

private bool _isInFile = false;
/// <summary>
/// 是否写入文件
/// </summary>
public bool IsInFile
{
get { return _isInFile; }
set
{
_isInFile = value;
if (_isInFile)
{
_logInFile = new LogInFile();
_logInFileThread = new Thread[_logInFileThreadNum];
StartThread();
}
else
{
CloseThread();
_logInFile = null;
}
}
}

private int _inFileGenre = (int)LogGenreEnum.Info | (int)LogGenreEnum.Error | (int)LogGenreEnum.Exception | (int)LogGenreEnum.Warring;
/// <summary>
/// 开启日志写入的类型
/// </summary>
public int InFileGenre
{
get { return _inFileGenre; }
set { _inFileGenre = value; }
}

private string _logPath = "";
/// <summary>
/// 日志存储位置
/// </summary>
public string LogPath
{
get { return _logPath.Equals("") ? Environment.CurrentDirectory + @"\Log" : _logPath; }
set { _logPath = value; }
}

private int _logInFileWriteInterval = 2000;
/// <summary>
/// 日志写入间隔时间
/// </summary>
public int LogInFileWriteInterval
{
get { return _logInFileWriteInterval; }
set { _logInFileWriteInterval = value; }
}

private int _logInFileWriteNum = 99;
/// <summary>
/// 每次日志写入量
/// </summary>
public int LogInFileWriteNum
{
get { return _logInFileWriteNum; }
set { _logInFileWriteNum = value; }
}

private int _logInFileThreadNum = 3;
/// <summary>
/// 日志写入线程数量
/// </summary>
public int LogInFileThreadNum
{
get { return _logInFileThreadNum; }
set
{
_logInFileThreadNum = value;
if (_logInFileThread != null)
CloseThread();
_logInFileThread = new Thread[_logInFileThreadNum];
}
}

private  float _cpuRate = 30;
/// <summary>
/// Cpu 使用率小于多少开始写入文件
/// </summary>
public float CpuRate
{
get { return _cpuRate; }
set { _cpuRate = value; }
}

/// <summary>
/// 添加消息
/// </summary>
/// <param name="message"></param>
public void AddMessage(LogInFileInfo message)
{
_logInFile.AddMessage(message);
}

/// <summary>
/// 开启线程
/// </summary>
private void StartThread()
{
for (int i = 0; i < _logInFileThread.Length; i++)
{
_logInFileThread[i] = new Thread(new ThreadStart(_logInFile.StartInFile));
_logInFileThread[i].IsBackground = true;
_logInFileThread[i].Start();
}
}

/// <summary>
/// 关闭线程
/// </summary>
private void CloseThread()
{
for (int i = 0; i < _logInFileThread.Length; i++)
{
if (_logInFileThread[i].IsAlive)
_logInFileThread[i].Abort();
}
_logInFileThread = null;
}

}

/// <summary>
/// 颜色配置
/// </summary>
public class ColorConfig
{

/// <summary>
/// 字体颜色
/// </summary>
public ConsoleColor FontColor
{
get { return Console.ForegroundColor; }
set
{
Console.ForegroundColor = value;
}
}

/// <summary>
/// 默认颜色
/// </summary>
public ConsoleColor DefaultColor = ConsoleColor.White;
/// <summary>
/// 信息颜色
/// </summary>
public ConsoleColor InfoColor = ConsoleColor.White;
/// <summary>
/// 错误颜色
/// </summary>
public ConsoleColor ErrorColor = ConsoleColor.Red;
/// <summary>
/// 警告颜色
/// </summary>
public ConsoleColor WarringColor = ConsoleColor.Yellow;
/// <summary>
/// 异常颜色
/// </summary>
public ConsoleColor ExcepitonColor = ConsoleColor.Cyan;
}

}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: