/// <summary> /// 初始化应用程序异常 /// </summary> /// <param name="message">错误消息</param> /// <param name="code">错误码</param> /// <param name="level">日志级别</param> /// <param name="exception">异常</param> public Warning(string message, string code, EnumLogLevel level, Exception exception) : base(message ?? "", exception) { Code = code; Level = level; _message = GetMessage(); }
public static string WriteLog(this string str, EnumLogLevel type = EnumLogLevel.Info) { var logLevel = ConfigurationManager.AppSettings["LogLevel"]; var level = string.IsNullOrWhiteSpace(logLevel) ? EnumLogLevel.Info.ToString() : logLevel; if ((int)type < (int)Enum.Parse(typeof(EnumLogLevel), level)) { return(string.Empty); } lock (Object) { LogType = type; var st = new StackTrace(new StackFrame(1, true)); StackFrame sf = st.GetFrame(0); var dic = new Dictionary <string, string> { { "发生时间", DateTime.Now.ToString("yyyy/MM/dd HH:mm:ss:ffff dddd") }, { "日志级别", LogType.ToString() }, { "日志消息", str }, { "当前方法", sf.GetMethod().Name }, { "发生位置", st.ToString() } }; Que.Enqueue(dic); } return(str); }
public void Log(EnumLogLevel logLevel, string message, Exception ex = null) { switch (logLevel) { case EnumLogLevel.Debug: LogDebug(message); break; case EnumLogLevel.Info: LogInfo(message); break; case EnumLogLevel.Warning: LogWarning(message); break; case EnumLogLevel.Error: LogError(ex, message); break; case EnumLogLevel.Trace: LogTrace(message); break; } }
/// <summary> /// 添加日志 /// </summary> /// <param name="level"></param> /// <param name="logContent"></param> public static void AddLogRecord(EnumLogLevel level = EnumLogLevel.Log, string logContent = null) { LogFilePath.CheckOrCreateFile(); string header = string.Empty; switch (level) { case EnumLogLevel.Log: header = string.Format("{0} {1}:\t", DateTime.Now.ToString("yyyy-MM-dd HH-mm-ss"), level.ToString()); break; case EnumLogLevel.Warnning: header = string.Format("{0} {1}:\t", DateTime.Now.ToString("yyyy-MM-dd HH-mm-ss"), level.ToString()); break; case EnumLogLevel.ResError: header = string.Format("{0} {1}:\t", DateTime.Now.ToString("yyyy-MM-dd HH-mm-ss"), level.ToString()); break; case EnumLogLevel.NetError: header = string.Format("{0} {1}:\t", DateTime.Now.ToString("yyyy-MM-dd HH-mm-ss"), level.ToString()); break; case EnumLogLevel.Final: header = string.Format("{0} {1}:\t", DateTime.Now.ToString("yyyy-MM-dd HH-mm-ss"), level.ToString()); break; } string content = string.Format("{0}{1}\r\n\r\n", header, logContent); LogFilePath.WriteAppend(content); }
/// <summary> /// 输出指定<see cref="LogLevel" />级别的日志 /// </summary> public void WriteFormatAsync(EnumLogLevel logLevel, string format, params object[] args) { switch (logLevel) { case EnumLogLevel.Debug: DebugFormatAsync(format, args); break; case EnumLogLevel.Info: InfoFormatAsync(format, args); break; case EnumLogLevel.Warn: WarnFormatAsync(format, args); break; case EnumLogLevel.Error: ErrorFormatAsync(format, args); break; case EnumLogLevel.Fatal: FatalFormatAsync(format, args); break; } }
public static void CreateLog(string message, string context, Exception exception, EnumLogLevel level) { using (NDC.Push(context)) { switch (level) { case EnumLogLevel.DEBUG: if (exception != null) Logger.log.Debug(message, exception); else Logger.log.Debug(message); break; case EnumLogLevel.ERROR: if (exception != null) Logger.log.Error(message, exception); else Logger.log.Fatal(message); break; case EnumLogLevel.FATAL: if (exception != null) Logger.log.Fatal(message, exception); else Logger.log.Fatal(message); break; case EnumLogLevel.INFO: if (exception != null) Logger.log.Info(message, exception); else Logger.log.Info(message); break; } } }
/// <summary> /// 输出指定<see cref="LogLevel" />级别的日志 /// </summary> public void WriteAsync(EnumLogLevel logLevel, object message, Exception exception = null) { switch (logLevel) { case EnumLogLevel.Debug: DebugAsync(GetPosition() + message, exception); break; case EnumLogLevel.Info: InfoAsync(GetPosition() + message, exception); break; case EnumLogLevel.Warn: WarnAsync(GetPosition() + message, exception); break; case EnumLogLevel.Error: ErrorAsync(GetPosition() + message, exception); break; case EnumLogLevel.Fatal: FatalAsync(GetPosition() + message, exception); break; } }
public async void AddLogAsync(EnumLogType logType, EnumLogLevel logLevel, string objectType, string objectId, string remark = "", Exception ex = null, string userCode = "", string address = "", string apps = "DME") { await Task.Run(() => { DmeLog log = new DmeLog { LogType = EnumUtil.GetEnumName <EnumLogType>((int)logType), LogLevel = EnumUtil.GetEnumName <EnumLogLevel>((int)logLevel), ObjectType = objectType, ObjectId = objectId, UserCode = userCode, Address = address, Apps = apps, Remark = remark, CreateTime = DateUtil.CurrentTimeMillis }; if (String.IsNullOrEmpty(remark) && ex != null) { // 把异常信息赋予remark if (ex is BusinessException) { log.Remark = $"Code:{((BusinessException)ex).Code}, Message:{ex.Message}"; } else { log.Remark = ex.StackTrace + "\\r\\n" + ex.Message; } } base.Repository.GetDbContext().Insertable <DmeLog>(log).ExecuteCommandAsync(); }); }
private static void Forward(string AssemblyClassName, EnumLogLevel level, string format, params object[] args) { string[] _assemblyinfo = AssemblyClassName.Split(new char[] { ',' }); try { Assembly logassembly = null; try { logassembly = Assembly.GetAssembly(Type.GetType(_assemblyinfo[1])); } catch { } if (logassembly == null) { string asspath = Path.Combine(Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location), _assemblyinfo[0]); logassembly = Assembly.LoadFrom(asspath); } Type LogClassType = logassembly.GetType(_assemblyinfo[1]); MethodInfo mi = LogClassType.GetMethod(level.ToString()); List <object> newargs = new List <object>(); newargs.Add(format); newargs.Add(args); mi.Invoke(null, newargs.ToArray()); } catch (Exception ex) { throw ex; } }
public void WriteLog(EnumLogLevel level, string mesajEroare, string infoSuplimentare = null) { System.Diagnostics.Debug.WriteLine($"{level}: {mesajEroare}"); if (!string.IsNullOrWhiteSpace(mesajEroare)) { System.Diagnostics.Debug.WriteLine(mesajEroare); } }
public LoggerClass(string strLogPath, EnumLogLevel LogLevel, bool IsTraceLineNum) { this.LogLevel = LogLevel; this.IsTraceLineNum = IsTraceLineNum; this.StrLogPath = strLogPath; this.ObjLock = new object(); CreateLogPath(); GenerateLogName(); }
public static void Initialize(bool logToFile, bool logToConsole, bool logToDatabase, EnumLogLevel maxlogLevel) { _maxlogLevel = maxlogLevel; _logToDatabase = logToDatabase; _logToFile = logToFile; _logToConsole = logToConsole; _initialized = true; }
public Commands(bool showHelp, List <FolderMap> folders, bool requestConfirm, bool skipCopyErrors, bool pauseWhenDone, bool doReadCheckFirst, EnumLogLevel logLevel) { ShowHelp = showHelp; RequestConfirm = requestConfirm; SkipCopyErrors = skipCopyErrors; PauseWhenDone = pauseWhenDone; ReadCheckFirst = doReadCheckFirst; LogLevel = logLevel; Folders = folders; }
public void InitializeIntelliTest( bool logToFile, bool logToConsole, bool logToDatabase, EnumLogLevel maxlogLevel ) { JobLogger.Initialize(logToFile, logToConsole, logToDatabase, maxlogLevel); // TODO: add assertions to method JobLoggerIntelliTest.InitializeIntelliTest(Boolean, Boolean, Boolean, EnumLogLevel) }
public static void LogMessage(string message, EnumLogLevel logLevel) { if (!_initialized) { throw new Exception("Not initialized"); } if (message == null || message.Length == 0) { throw new ArgumentException("Message null or empty"); // didn't inform about what was wrong } if (!_logToConsole && !_logToFile && !_logToDatabase) { throw new Exception("Invalid configuration"); } // Disable logging when maximum level of loggin is setted "Off" if (_maxlogLevel == EnumLogLevel.Off) { throw new Exception("Logging disabled"); } // Ensure at the begining of the function, that the level of loging desired of the message is below the maximum level of logging. if (logLevel <= _maxlogLevel && logLevel != EnumLogLevel.Off) { // Didn't throw exceptions try { message.Trim(); // We do not need to validate here, since we can not set logLevel with a false or null value //if ((!_logError && !_logMessage && !_logWarning) || (!message && !warning && !error)) //{ // throw new Exception("Error or Warning or Message must be specified"); //} if (_logToDatabase) { LogToDataBase(message, (int)logLevel); } if (_logToFile) { LogToFile(message); } if (_logToConsole) { LogToConsole(message, logLevel); } } catch (Exception e) { throw e; } } }
public Logger(string strLogPath, EnumLogLevel LogLevel, bool IsTraceLineNum, int maxFileQty) { this.LogLevel = LogLevel; this.IsTraceLineNum = IsTraceLineNum; this.StrLogPath = strLogPath; this.ObjLock = new object(); this.MaxFileQty = maxFileQty; FileQueue = new Queue <string>(); CreateLogPath(); GenFileQueue(); }
public static Commands ParseArgs(string[] args) { bool showHelp = false; string source = ""; bool updatedOnly = false; bool requestConfirm = true; bool subFoldersAlso = false; bool skipCopyErrors = false; bool pauseWhenDone = false; string[] exclusiveExt = new string[1]; bool readCheckFirst = false; string target = string.Empty; EnumLogLevel logLevel = EnumLogLevel.None; // If not arguments supplied or help is requested set showHelp to true and stop processing. if (args == null || args.Length < 2 || args.Contains("/?")) { showHelp = true; } else { // Check other parms // 0 should be source Logger.Info("args(0)=" + args[0]); source = PathFormatter.FormatPath(args[0]); Logger.Debug("source=" + source); // 1 should be targed target = FormatTarget(args[1]); updatedOnly = args.Contains("/d", new CommandStringComparer()); requestConfirm = !args.Contains("/y", new CommandStringComparer()); subFoldersAlso = args.Contains("/s", new CommandStringComparer()); skipCopyErrors = args.Contains("/x", new CommandStringComparer()); pauseWhenDone = args.Contains("/p", new CommandStringComparer()); readCheckFirst = args.Contains("/r", new CommandStringComparer()); logLevel = GetLogLevel(args); Logger.Info("Loglevel = " + logLevel.ToString()); foreach (string aCmd in args) { if (aCmd.ToLower().StartsWith("/exclusiveext:")) { exclusiveExt = aCmd.Split(':')[0].Split('+'); break; } } } FolderMap folderMap = new FolderMap(source, target, updatedOnly, subFoldersAlso, exclusiveExt); List <FolderMap> folderMaps = new List <FolderMap>() { folderMap }; return(new Commands(showHelp, folderMaps, requestConfirm, skipCopyErrors, pauseWhenDone, readCheckFirst, logLevel)); }
private void WriteLog(EnumLogLevel enumLogLevel, object message) { if ((int)enumLogLevel >= (int)EnumLogLevel) { switch (enumLogLevel) { case EnumLogLevel.ALL: if (TraceIsEnable) { Write(enumLogLevel, message); } break; case EnumLogLevel.Debug: if (DebugLogIsEnable) { Write(enumLogLevel, message); } break; case EnumLogLevel.Info: if (InfoIsEnable) { Write(enumLogLevel, message); } break; case EnumLogLevel.Warn: if (WarnIsEnable) { Write(enumLogLevel, message); } break; case EnumLogLevel.Error: if (ErrorIsEnable) { Write(enumLogLevel, message); } break; case EnumLogLevel.Fatal: if (FatalIsEnable) { Write(enumLogLevel, message); } break; default: throw new ArgumentOutOfRangeException("enumLogLevel"); } } }
private static Dictionary <EnumLogLevel, string> LogLevels() { var levels = Enum.GetValues(typeof(EnumLogLevel)); Dictionary <EnumLogLevel, string> values = new Dictionary <EnumLogLevel, string>(); foreach (int level in levels) { EnumLogLevel value = (EnumLogLevel)level; values.Add(value, value.ToString()); } return(values); }
private void Write(EnumLogLevel enumLogLevel, object message) { lock (_lock) { try { File.AppendAllText(_LogPath, DateTime.Now.ToString() + ":" + enumLogLevel.ToString() + ":\r\n" + message + "\r\n", System.Text.Encoding.Default); } catch { } } }
public static void Bytes(byte[] bytes) { EnumLogLevel curLevel = (EnumLogLevel)Enum.Parse(typeof(EnumLogLevel), Properties.Settings.Default.LogLevel, true); EnumLogType logType = (EnumLogType)Enum.Parse(typeof(EnumLogType), Properties.Settings.Default.LogType, true); #region LOG TO CONSOLE if (logType >= EnumLogType.Console) { Console.WriteLine(Encoding.ASCII.GetString(bytes)); } #endregion #region LOG TO FILE if (logType >= EnumLogType.File) { lock (lockfile) { if (fs == null) { try { fs = new FileStream(logfile, FileMode.Create, FileAccess.Write, FileShare.Read); } catch (Exception ex) { throw new Exception("Cannot open Repository, try running as Administrator or change location of Log", ex); } } if (fs != null) { try { StreamWriter sw = new StreamWriter(fs); sw.WriteLine(Encoding.ASCII.GetString(bytes)); sw.Flush(); } catch { // do nothing } finally { // do nothing } } } } #endregion }
/// <summary> /// 记录系统运行日志 /// </summary> /// <param name="type">类型</param> /// <param name="level">日志级别</param> /// <param name="message">日志信息</param> public static void Write(Type type, EnumLogLevel level, string message) { log4net.ILog log = log4net.LogManager.GetLogger(type); message = string.Format("{0}, Message:{1}", LogPosition(), message); switch (level) { case EnumLogLevel.Fatal: if (log.IsFatalEnabled) { log.Fatal(message); } break; case EnumLogLevel.Error: if (log.IsErrorEnabled) { log.Error(message); } break; case EnumLogLevel.Warn: if (log.IsWarnEnabled) { log.Warn(message); } break; case EnumLogLevel.Debug: if (log.IsDebugEnabled) { log.Debug(message); } break; case EnumLogLevel.Info: if (log.IsInfoEnabled) { log.Info(message); } break; } log = null; }
public void TestLogLevel(string value, EnumLogLevel expected) { string[] args; if (value != "") { args = new string[3]; args[0] = "dummy"; args[1] = "somepath"; args[2] = value; } else { args = new string[2]; args[0] = "dummy"; args[1] = "somepath"; } Assert.Equal(expected, CommandLineArgumentParser.ParseArgs(args).LogLevel); }
public void WriteLog(EnumLogLevel level, string mesajEroare, string infoSuplimentare = null) { DateTime nowDate = DateTime.Now; string fileName = $"err{nowDate.Year}{nowDate.Month.ToString().PadLeft(2, '0')}{nowDate.Day.ToString().PadLeft(2, '0')}.txt"; string fullPath = Path.Combine(this.PathToDir, fileName); using (StreamWriter sw = File.AppendText(fullPath)) { StringBuilder errorLogEntry = new StringBuilder(); errorLogEntry.AppendLine($"{level}: {mesajEroare}"); if (!string.IsNullOrWhiteSpace(infoSuplimentare)) { errorLogEntry.AppendLine(infoSuplimentare); } sw.WriteLine(errorLogEntry.ToString()); } }
private static void LogToConsole(string message, EnumLogLevel logLevel) { _sb.Clear(); switch (logLevel) { case EnumLogLevel.Error: Console.ForegroundColor = ConsoleColor.Red; break; case EnumLogLevel.Warning: Console.ForegroundColor = ConsoleColor.Yellow; break; case EnumLogLevel.Message: Console.ForegroundColor = ConsoleColor.White; break; } Console.WriteLine(_sb.AppendFormat("{0} {1}", DateTime.Now.ToString("dd/MM/yyyy-H:mm:ss:"), message).AppendLine().ToString()); }
private static void DoLog(EnumLogLevel level, string value) { if (!IsEnabled(level)) { return; } foreach (ILogger logger in _loggers) { switch (level) { case EnumLogLevel.Trace: logger.Trace(value); break; case EnumLogLevel.Error: logger.Error(value); break; case EnumLogLevel.Info: logger.Info(value); break; case EnumLogLevel.Debug: logger.Debug(value); break; case EnumLogLevel.Warning: logger.Warning(value); break; case EnumLogLevel.Critical: logger.Critical(value); break; } } }
public static void WriteLog(EnumLogLevel logLevel, string methedName, string actionName, string controllerName, string message, Exception exception) { var request = HttpContext.Current.Request; string user; try { user = ApplicationContext.Current.UserName; } catch { user = "******"; } var logMessage = new LogMessage(0, user, 0 , string.Format("{3}, 控制器:{0},动作:{1},Message:{2}" , controllerName, actionName, message, methedName) , request.UserHostAddress, request.Browser.Platform , request.Browser.Browser + request.Browser.Version); switch (logLevel) { case EnumLogLevel.Fatal: { log.Fatal(logMessage, exception); break; } case EnumLogLevel.Error: { log.Error(logMessage, exception); break; } case EnumLogLevel.Warning: { log.Warn(logMessage); break; } case EnumLogLevel.Info: { log.Info(logMessage); break; } case EnumLogLevel.Debug: { log.Debug(logMessage); break; } default: { log.Fatal(new LogMessage(0, user, 0 , string.Format("{0},logLevel error", methedName) , request.UserHostAddress, request.Browser.Platform , request.Browser.Browser + request.Browser.Version), exception); break; } } }
public static void CreateLog(string message, EnumLogLevel level) { Logger.CreateLog(message, string.Empty, null, level); }
private static void Write(EnumLogLevel level, string format, params object[] args) { string forwardstatus = null; string resetloglevel = null; string resetlogtype = null; if (Properties.Settings.Default.LogForwarding.Length > 0 && !Properties.Settings.Default.LogForwarding.ToLower().StartsWith("no") && !Properties.Settings.Default.LogForwarding.ToLower().StartsWith("off")) { try { Forward(Properties.Settings.Default.LogForwarding, level, format, args); return; } catch { forwardstatus = "FWD: "; } } if (logpath == null || logfile == null) { logpath = GetLogPath(); logfile = Path.Combine(logpath, Properties.Settings.Default.LogFile); } #region CONFIGURE TYPE AND LEVEL if (!isconfigured) { if (Properties.Settings.Default.LogLevel.Length > 0) { try { curLevel = (EnumLogLevel)Enum.Parse(typeof(EnumLogLevel), Properties.Settings.Default.LogLevel, true); } catch { curLevel = defaultLogLevel; resetloglevel = "--- Failure in determining configured log level, reset to: Audit, Error, Warning"; } } if (Properties.Settings.Default.LogType.Length > 0) { try { logType = (EnumLogType)Enum.Parse(typeof(EnumLogType), Properties.Settings.Default.LogType, true); } catch { logType = defaultLogType; resetlogtype = "--- Failure in determining configure log type, reset to: Audit, Console, File"; } } if ((curLevel & EnumLogLevel.Audit) != EnumLogLevel.Audit) { curLevel |= EnumLogLevel.Audit; } if ((logType & EnumLogType.Audit) != EnumLogType.Audit) { logType |= EnumLogType.Audit; } isconfigured = true; } #endregion string data = string.Format(format, args); string message = null; if (level == EnumLogLevel.Audit) { message = string.Format("{0}:{1}.{2}.{3}.{4}.{5}.{6},{7}:[{8}] {9}", level, DateTime.Now.Year, DateTime.Now.Month, DateTime.Now.Day, DateTime.Now.Hour, DateTime.Now.Minute, DateTime.Now.Second, DateTime.Now.Millisecond, System.Security.Principal.WindowsIdentity.GetCurrent().Name, data ); } else { if (Properties.Settings.Default.LogFormat.ToLower().Equals("plain")) { message = data; } else { message = string.Format("{0}:{1}.{2}.{3}.{4}.{5}.{6},{7}: {8}", level, DateTime.Now.Year, DateTime.Now.Month, DateTime.Now.Day, DateTime.Now.Hour, DateTime.Now.Minute, DateTime.Now.Second, DateTime.Now.Millisecond, data ); } } if (forwardstatus != null) { message = forwardstatus + message; } if (curLevel >= level && curLevel != EnumLogLevel.Off && logType != EnumLogType.Off) { #region LOG TO CONSOLE if ((logType & EnumLogType.Console) == EnumLogType.Console) { if (resetloglevel != null) { Console.WriteLine(resetloglevel); } if (resetlogtype != null) { Console.WriteLine(resetlogtype); } Console.WriteLine(message); } #endregion #region LOG TO FILE if ((logType & EnumLogType.File) == EnumLogType.File) { lock (lockfile) { if (fs == null) { try { fs = new FileStream(logfile, FileMode.Append, FileAccess.Write, FileShare.ReadWrite); } catch (Exception ex) { throw new Exception("Cannot open log file, try running as Administrator or change location of Log", ex); } } if (fs != null) { try { StreamWriter sw = new StreamWriter(fs); if (resetloglevel != null) { sw.WriteLine(resetloglevel); } if (resetlogtype != null) { sw.WriteLine(resetlogtype); } sw.WriteLine(message); sw.Flush(); sw.Close(); } catch { // do nothing } finally { if (fs != null) fs.Close(); fs = null; } } } } #endregion #region LOG TO EVENT if ((logType & EnumLogType.Event) == EnumLogType.Event) { lock (lockevent) { if (!EventLog.SourceExists(Properties.Settings.Default.LogSource)) { EventLog.CreateEventSource(Properties.Settings.Default.LogSource, "Application"); } EventLogEntryType logtype = EventLogEntryType.Information; switch(level) { case EnumLogLevel.Audit: { logtype = EventLogEntryType.SuccessAudit; break; } case EnumLogLevel.Debug: { break; } case EnumLogLevel.Error: { logtype = EventLogEntryType.Error; break; } case EnumLogLevel.Info: { logtype = EventLogEntryType.Information; break; } case EnumLogLevel.Warning: { break; } case EnumLogLevel.Trace: { break; } case EnumLogLevel.Off: { break; } default: { break; } } EventLog.WriteEntry(Properties.Settings.Default.LogSource, message, logtype); } } #endregion #region LOG TO EXCEPTION if ((logType & EnumLogType.Exception) == EnumLogType.Exception) { lock (lockexcept) { throw new Exception(message); } } #endregion #region LOG IN DebugView if ((curLevel & EnumLogLevel.Debug) == EnumLogLevel.Debug) { if (resetloglevel != null) { System.Diagnostics.Debug.WriteLine(resetloglevel); } if (resetlogtype != null) { System.Diagnostics.Debug.WriteLine(resetlogtype); } System.Diagnostics.Debug.WriteLine(message); } #endregion #region LOG IN TraceView if ((curLevel & EnumLogLevel.Trace) == EnumLogLevel.Trace) { if (resetloglevel != null) { System.Diagnostics.Debug.WriteLine(resetloglevel); } if (resetlogtype != null) { System.Diagnostics.Debug.WriteLine(resetlogtype); } System.Diagnostics.Trace.WriteLine(message); } #endregion } resetloglevel = null; resetlogtype = null; }
private static void Forward(string AssemblyClassName, EnumLogLevel level, string format, params object[] args) { string[] _assemblyinfo = AssemblyClassName.Split(new char[] { ',' }); try { Assembly logassembly = null; try { logassembly = Assembly.GetAssembly(Type.GetType(_assemblyinfo[1])); } catch { } if (logassembly == null) { string asspath = Path.Combine(Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location), _assemblyinfo[0]); logassembly = Assembly.LoadFrom(asspath); } Type LogClassType = logassembly.GetType(_assemblyinfo[1]); MethodInfo mi = LogClassType.GetMethod(level.ToString()); List<object> newargs = new List<object>(); newargs.Add(format); newargs.Add(args); mi.Invoke(null, newargs.ToArray()); } catch (Exception ex) { throw ex; } }
public LogLevel(EnumLogLevel level) { Level = level; }
public static bool IsEnabled(EnumLogLevel level) { return(level <= Level); }
public ScreenLogEventArgs(EnumLogLevel level, string value) { Level = level; Value = value; }
public static void Log(EnumLogLevel level, string value) { DoLog(level, value); }