using System;
using System.Security.Cryptography;
using System.Text;
using System.Threading.Tasks;
using CommonUtil.Config;
using CommonUtil.Json;
using CommonUtil.RabbitMQ;
using NLog;
using NLog.Config;
using NLog.Layouts;
using NLog.Targets;
namespace CommonUtil.Log
{
///
/// 日志工具类。基于NLog https://github.com/NLog/NLog
///
public class LogUtil
{
private readonly static Logger _logger = LogManager.GetCurrentClassLogger();
private const string DEBUG = "debug";
private const string ERROR = "error";
private const string FATAL = "fatal";
private const string TRACE = "trace";
private const string INFO = "info";
private const string EMAIL_TARGET = "emailTarget";
private const string CONSOLE_TARGET = "consoleTarget";
private const string DEBUG_FILE_TARGET = "debugFileTarget";
private const string ERROR_FILE_TARGET = "errorFileTarget";
private const string INFO_FILE_TARGET = "infoFileTarget";
private const string FATAL_FILE_TARGET = "fatalFileTarget";
private const string TRACE_FILE_TARGET = "traceFileTarget";
// private const string robotSecret = "SECe281ae32807c0665db4e478e85c5f2d7e1ba7c7c05556fabf992b716a513aeb3";
//private const string robotWebhook = "https://oapi.dingtalk.com/robot/send?access_token=77a969114188f052f0269b0a81c07e99d2beb9790132be9dcded72a5fc9349d1";
//100M
private const long LOG_SIZE = 104857600;
///
/// 构造函数
///
static LogUtil()
{
var logIsEmailNameConfig = ConfigUtil.Configuration["LogEmailName"];
var isStandard = ConfigUtil.Configuration["isStandard"];
var logIsEmailName = logIsEmailNameConfig.IsNullOrEmpty() ? "多卖异常报警" : logIsEmailNameConfig.ToStringEx();
var logIsEmailConfig = ConfigUtil.Configuration["LogIsEmail"];
bool isLogIsEmail = logIsEmailConfig.IsNullOrEmpty() ? false : logIsEmailConfig.ToBool();
var logIsEmailToConfig = ConfigUtil.Configuration["LogEmailTo"];
string[] emailTo = logIsEmailToConfig.IsNullOrEmpty() ? new string[] { } : logIsEmailToConfig.Split(',');
string fileName = "${basedir}/logs/${shortdate}-${fileName}.log";
//string layout = "[${longdate}]^_^[${uppercase:${level}}]^_^${message}^_^${exception:format=tostring}${newline}";
string runTime = isStandard.IsNullOrEmpty() ? "production" : isStandard == "1" ? "staging" : "production";
var layout = new JsonLayout
{
Attributes =
{
new JsonAttribute
{
EscapeForwardSlash = false,
EscapeUnicode = false,
// 这是应用的别名,如 crm,jinggeng,ecrm,必须小写
Layout = "fullchannel",
Name = "appName",
},
new JsonAttribute
{
EscapeForwardSlash = false,
EscapeUnicode = false,
// 这是应用的运行环境,如 staging:测试/预发环境;production:线上环境
Layout = runTime,
Name = "environment",
},
new JsonAttribute
{
EscapeForwardSlash = false,
EscapeUnicode = false,
Layout = "${logger}",
Name = "logger",
},
new JsonAttribute
{
EscapeForwardSlash = false,
EscapeUnicode = false,
Layout = "${longdate}",
Name = "time",
},
new JsonAttribute
{
EscapeForwardSlash = false,
EscapeUnicode = false,
Layout = "${level:upperCase=true}",
Name = "level",
},
new JsonAttribute
{
EscapeForwardSlash = false,
EscapeUnicode = false,
Layout = "${message}",
Name = "message",
},
new JsonAttribute
{
EscapeForwardSlash = false,
EscapeUnicode = false,
Layout = "${exception:format=tostring}",
Name = "exception",
}
}
};
var config = new LoggingConfiguration();
var consoleTarget = new ColoredConsoleTarget(CONSOLE_TARGET)
{
Layout = layout,
};
config.AddTarget(consoleTarget);
var traceFileTarget = new FileTarget(TRACE_FILE_TARGET)
{
FileName = fileName,
Layout = layout,
ArchiveAboveSize = LOG_SIZE,
};
config.AddTarget(traceFileTarget);
var debugFileTarget = new FileTarget(DEBUG_FILE_TARGET)
{
FileName = fileName,
Layout = layout,
ArchiveAboveSize = LOG_SIZE,
};
config.AddTarget(debugFileTarget);
var errorFileTarget = new FileTarget(ERROR_FILE_TARGET)
{
FileName = fileName,
Layout = layout,
ArchiveAboveSize = LOG_SIZE,
};
config.AddTarget(errorFileTarget);
var infoFileTarget = new FileTarget(INFO_FILE_TARGET)
{
FileName = fileName,
Layout = layout,
ArchiveAboveSize = LOG_SIZE,
};
config.AddTarget(infoFileTarget);
//NetworkTarget networkTarget = new NetworkTarget(NETWORK_TARGET)
//{
// Address = "tcp://localhost:5044",
// Layout = layout
//};
NetworkTarget networkTarget = new NetworkTarget("networkTarget")
{
KeepConnection = false,
MaxConnections = 10,
OnOverflow = NetworkTargetOverflowAction.Split,
Address = "tcp://47.92.111.210:8001",
NewLine = true,
Layout = layout
};
config.AddTarget(networkTarget);
var fatalFileTarget = new FileTarget(FATAL_FILE_TARGET)
{
FileName = fileName,
Layout = layout,
ArchiveAboveSize = LOG_SIZE,
};
config.AddTarget(fatalFileTarget);
if (isLogIsEmail)
{
var emailTarget = new MailTarget(EMAIL_TARGET)
{
Name = logIsEmailName,
//邮件主题
Subject = logIsEmailName,
//发件人
From = "warning@taocrm.com",
//收件人
To = string.Join(",", emailTo),
Header = "-----------HEAD-----------",
Body = layout,
Footer = "-----------FOOT-----------",
AddNewLines = true,
SmtpServer = "smtp.ym.163.com",
SmtpPort = 25,
SmtpAuthentication = SmtpAuthenticationMode.Basic,
SmtpUserName = "warning@taocrm.com",
SmtpPassword = "7C4dmE3exj",
};
config.AddTarget(emailTarget);
// 配置日志级别输出对象到邮件
#if !DEBUG
//config.AddRuleForOneLevel(LogLevel.Fatal, emailTarget);
//config.AddRuleForOneLevel(LogLevel.Error, emailTarget);
#endif
}
// 配置日志级别输出对象到文件
config.AddRuleForOneLevel(LogLevel.Debug, debugFileTarget);
config.AddRuleForOneLevel(LogLevel.Info, infoFileTarget);
config.AddRuleForOneLevel(LogLevel.Error, errorFileTarget);
config.AddRuleForOneLevel(LogLevel.Fatal, fatalFileTarget);
// 配置日志级别输出对象到控制台
//config.AddRuleForAllLevels(consoleTarget);
//config.AddRuleForAllLevels(networkTarget);
#if !DEBUG
// 配置日志不允许报出异常,以免影响主程序运行
LogManager.ThrowExceptions = false;
// 配置日志不允许报出异常,以免影响主程序运行
LogManager.ThrowConfigExceptions = false;
#endif
LogManager.Configuration = config;
}
///
/// 记录调试信息
///
public static void Debug(string msg)
{
Debug(msg, DEBUG);
}
///
/// 记录调试信息
///
public static void Debug(string msg, string fileName)
{
DoLog(DEBUG_FILE_TARGET, LogLevel.Debug, msg, fileName, null);
}
/////
///// 记录调试信息
/////
//public static void Debug(T value)
//{
// _logger.Debug(value);
//}
///
/// 记录异常信息
///
public static void Error(string msg)
{
Error(msg, ERROR);
}
///
/// 记录异常信息
///
public static void Error(string msg, string fileName)
{
Error(msg, fileName, null);
}
///
/// 记录异常信息
///
public static void Error(Exception exception)
{
Error(exception, null);
}
///
/// 记录异常信息
///
public static void Error(Exception exception, string msg)
{
Error(msg, ERROR, exception);
}
///
/// 记录异常信息
///
public static void Error(string msg, string fileName, Exception exception)
{
DoLog(ERROR_FILE_TARGET, LogLevel.Error, msg, fileName, exception);
string robotMsg = $"# {fileName} \n > 告警时间:{DateTime.Now.ToString("yyyy/MM/dd HH:mm:ss")} \n* " + (!msg.IsNullOrEmpty() ? msg : "") + "," + (!exception.IsNull() ? exception.ToString() : "");
// OapiRobotSend(fileName, robotMsg);
}
/////
///// 记录异常信息
/////
//public static void Error(T value)
//{
// _logger.Error(value);
//}
///
/// 记录可用信息
///
public static void Info(string msg)
{
Info(msg, INFO);
}
///
/// 记录可用信息
///
public static void Info(string msg, string fileName)
{
DoLog(INFO_FILE_TARGET, LogLevel.Info, msg, fileName, null);
}
/////
///// 记录可用信息
/////
//public static void Info(T value)
//{
// _logger.Info(value);
//}
///
/// 记录跟踪信息
///
public static void Trace(string msg)
{
Trace(msg, TRACE);
}
///
/// 记录跟踪信息
///
public static void Trace(string msg, string fileName)
{
DoLog(TRACE_FILE_TARGET, LogLevel.Trace, msg, fileName, null);
}
///
/// 记录操作日志
///
///
public static void Trace(TraceLogModel log)
{
Task.Run(() =>
{
//WebUtil webUtil = new WebUtil();
//var txtParams = new Dictionary{
// {"messageBody",log.ObjectToJson() },
// {"eventKey","duomai.log.log.senduserbehavior" }
//};
//webUtil.DoPostWithJson("http://114.55.4.22:8010/SendMessage/SendEventMessage", txtParams, null);
MessageModel model = new MessageModel(log.UserId, "duomai.log.log.senduserbehavior", log.ObjectToJson(), MessageTypeEnum.common, "duomai.log.log.senduserbehavior");
MQClient.SendMessage(model);
});
DoLog(TRACE_FILE_TARGET, LogLevel.Trace, log.ObjectToJson(), "操作日志", null);
}
///
/// 记录操作日志
///
///
///
///
///
///
///
///
///
///
///
///
public static void Trace(string app, string userId, string userName, string module, string desc, string type, string memo, string ip, string subUserId = "", string subUserName = "", bool isSuccess = true)
{
TraceLogModel log = new TraceLogModel
{
App = app,
UserId = userId,
UserName = userName,
Module = module,
Desc = desc,
Type = type,
Memo = memo,
Ip = ip,
IsSuccess = isSuccess,
SubUserId = subUserId,
SubUserName = subUserName,
Time = DateTime.Now
};
Trace(log);
}
/////
///// 记录跟踪信息
/////
//public static void Trace(string msg, params object[] args)
//{
// _logger.Trace(msg, args);
//}
/////
///// 记录跟踪信息
/////
//public static void Trace(T value)
//{
// _logger.Trace(value);
//}
///
/// 记录跟踪信息
///
public static void Fatal(string msg)
{
Fatal(msg, FATAL);
}
///
/// 记录宕机信息
///
public static void Fatal(string msg, string fileName)
{
DoLog(FATAL_FILE_TARGET, LogLevel.Fatal, msg, fileName, null);
}
/////
///// 记录宕机信息
/////
//public static void Fatal(T value)
//{
// _logger.Fatal(value);
//}
///
/// 执行记录日志
///
/// 指定模板
/// 日志级别
/// 日志内容
/// 文件名
/// 异常信息,可填
private static void DoLog(string targetName, LogLevel logLevel, string msg, string fileName, Exception exception)
{
if (!string.IsNullOrEmpty(targetName))
{
if (string.IsNullOrEmpty(fileName))
{
fileName = "${level}";
}
FileTarget target = LogManager.Configuration.FindTargetByName(targetName);
target.FileName = "${basedir}/logs/${shortdate}-" + fileName + ".log";
}
_logger.Log(logLevel, exception, msg);
}
}
}