888 lines
29 KiB
C#
888 lines
29 KiB
C#
using log4net;
|
|
using log4net.Appender;
|
|
using log4net.Config;
|
|
using log4net.Repository.Hierarchy;
|
|
using System;
|
|
using System.Collections.Generic;
|
|
using System.Diagnostics;
|
|
using System.Drawing;
|
|
using System.IO;
|
|
using System.Linq;
|
|
using System.Reflection;
|
|
using System.Text;
|
|
using System.Text.RegularExpressions;
|
|
using System.Windows.Forms;
|
|
using static log4net.Appender.RollingFileAppender;
|
|
|
|
namespace JWH
|
|
{
|
|
|
|
/// <summary>
|
|
/// log4net을 활용한 로그작성 라이브러리
|
|
/// [assembly: log4net.Config.XmlConfigurator(ConfigFile = "log4net.config", Watch = true)]
|
|
/// </summary>
|
|
public class XLogger
|
|
{
|
|
|
|
#region [ Static ] ====================================================
|
|
|
|
/// <summary>
|
|
/// Logger root
|
|
/// </summary>
|
|
public static XLogger Instance { get; set; } = new XLogger();
|
|
|
|
/// <summary>
|
|
/// RollingFileAppender를 생성한다
|
|
/// </summary>
|
|
/// <param name="name">Appender.Name</param>
|
|
/// <param name="file">Appender.File</param>
|
|
/// <param name="pattern">Appender.ConversionPattern</param>
|
|
/// <returns></returns>
|
|
public static RollingFileAppender CreateRollingFileAppender(string name, string path, string pattern)
|
|
{
|
|
log4net.Appender.RollingFileAppender appender = new log4net.Appender.RollingFileAppender();
|
|
try
|
|
{
|
|
appender.Name = name;
|
|
appender.File = $"{path}{name}_";
|
|
appender.DatePattern = $"yyyyMMddHH'.log'";
|
|
//appender.MaxSizeRollBackups = 100;
|
|
appender.MaximumFileSize = "10MB";
|
|
appender.StaticLogFileName = false;
|
|
appender.AppendToFile = true;
|
|
appender.PreserveLogFileNameExtension = true;
|
|
appender.RollingStyle = log4net.Appender.RollingFileAppender.RollingMode.Date;
|
|
appender.LockingModel = new RollingFileAppender.MinimalLock();
|
|
//appender.CountDirection = XLogger.GetCountDirection(path, $"{name}_", appender.DatePattern);
|
|
log4net.Layout.PatternLayout layout = new log4net.Layout.PatternLayout() { ConversionPattern = pattern };
|
|
layout.ActivateOptions();
|
|
appender.Layout = layout;
|
|
appender.ActivateOptions();
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
XLogger.Instance.Fatal(ex);
|
|
}
|
|
|
|
return appender;
|
|
}
|
|
|
|
/// <summary>
|
|
/// log4net.GlobalContext.Properties
|
|
/// <para>You must call ConfigureAndWatch</para>
|
|
/// </summary>
|
|
/// <param name="name"></param>
|
|
/// <param name="value"></param>
|
|
public static void AddProperties(string name, string value)
|
|
{
|
|
log4net.GlobalContext.Properties[name] = value;
|
|
}
|
|
|
|
/// <summary>
|
|
/// log4net.GlobalContext.Properties
|
|
/// </summary>
|
|
/// <param name="name"></param>
|
|
/// <returns></returns>
|
|
public static string GetProperties(string name)
|
|
{
|
|
return log4net.GlobalContext.Properties[name] as string;
|
|
}
|
|
|
|
/// <summary>
|
|
/// XmlConfigurator.ConfigureAndWatch
|
|
/// </summary>
|
|
/// <param name="file"></param>
|
|
public static void ConfigureAndWatch(FileInfo file)
|
|
{
|
|
if (file?.Exists == false) return;
|
|
|
|
XmlConfigurator.ConfigureAndWatch(file);
|
|
}
|
|
|
|
#endregion
|
|
|
|
#region [ Enum ] ======================================================
|
|
|
|
/// <summary>XLogLevel</summary>
|
|
public enum eXLogLevel
|
|
{
|
|
None = 0,
|
|
Debug = 1,
|
|
Info = 2,
|
|
Warn = 3,
|
|
Error = 4,
|
|
Fatal = 5
|
|
}
|
|
|
|
#endregion
|
|
|
|
#region [ Variable ] ==================================================
|
|
|
|
/// <summary>Filter Types</summary>
|
|
private List<Type> m_FilterTypes = new List<Type>();
|
|
|
|
#endregion
|
|
|
|
#region [ Properties ] ================================================
|
|
|
|
/// <summary>Logger Name</summary>
|
|
public string Name { get; set; } = string.Empty;
|
|
|
|
/// <summary>log4net.Repository.Hierarchy.Logger</summary>
|
|
public Logger Logger { get { return this.GetLogger(); } }
|
|
|
|
/// <summary>LOG Control</summary>
|
|
public TextBoxBase Control { get; set; } = null;
|
|
|
|
/// <summary>Control.ScrollToCaret</summary>
|
|
public bool OnScrollToCaret { get; set; } = true;
|
|
|
|
/// <summary>LOG Control : 0.DateTime, 1.LogLevel, 2.LogName, 3.ClassFullName, 4.Method, 5.Message, 6.ClassName</summary>
|
|
/// <example></example>
|
|
public string ControlPatternLayout { get; set; } = "[{0}] {1} {2} {3}.{4}() {5}";
|
|
|
|
/// <summary>Last Deleted LogFile</summary>
|
|
public DateTime LastDeletedDateTime { get; set; } = DateTime.MinValue;
|
|
|
|
/// <summary>Filter Types</summary>
|
|
public List<Type> FilterTypes
|
|
{
|
|
get { return m_FilterTypes; }
|
|
}
|
|
|
|
/// <summary>RichTextBox.SelectionColor</summary>
|
|
public Color ForeColor { get; set; } = SystemColors.ControlText;
|
|
|
|
#endregion
|
|
|
|
#region [ XLogger ] ===================================================
|
|
|
|
/// <summary>
|
|
/// XLogger
|
|
/// </summary>
|
|
public XLogger()
|
|
{
|
|
}
|
|
|
|
/// <summary>
|
|
/// XLogger
|
|
/// </summary>
|
|
/// <param name="name">Logger Name defined in log4net.config</param>
|
|
public XLogger(string name)
|
|
{
|
|
this.Name = name;
|
|
}
|
|
|
|
#endregion
|
|
|
|
#region [ Method ] ====================================================
|
|
|
|
#region [ Appender ] --------------------------------------------------
|
|
|
|
/// <summary>
|
|
/// 동적으로 RollingFileAppender를 추가한다
|
|
/// </summary>
|
|
public IAppender AddRollingFileAppender(string path, string pattern)
|
|
{
|
|
FileAppender appender = null;
|
|
try
|
|
{
|
|
string name = this.Name;
|
|
appender = XLogger.CreateRollingFileAppender(name, path, pattern);
|
|
this.AddAppender(appender);
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
XLogger.Instance.Fatal(ex);
|
|
}
|
|
|
|
return appender;
|
|
}
|
|
|
|
/// <summary>
|
|
/// 동적으로 RollingFileAppender를 추가한다
|
|
/// </summary>
|
|
/// <param name="name"></param>
|
|
/// <param name="file"></param>
|
|
/// <param name="pattern"></param>
|
|
public void AddRollingFileAppender(string name, string file, string pattern)
|
|
{
|
|
try
|
|
{
|
|
log4net.Repository.Hierarchy.Logger logger = this.Logger;
|
|
RollingFileAppender appender = XLogger.CreateRollingFileAppender(name, file, pattern);
|
|
this.AddAppender(appender);
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
XLogger.Instance.Fatal(ex);
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// 다른 XLogger의 Appender를 추가한다
|
|
/// </summary>
|
|
/// <param name="srcXLogger"></param>
|
|
/// <param name="index"></param>
|
|
public void AddRollingFileAppender(XLogger srcXLogger, int index = 0)
|
|
{
|
|
try
|
|
{
|
|
log4net.Repository.Hierarchy.Logger srclogger = srcXLogger.Logger;
|
|
if (srclogger.Appenders.Count <= index) return;
|
|
|
|
IAppender srcAppender = srclogger.Appenders[index];
|
|
this.AddAppender(srcAppender);
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
XLogger.Instance.Fatal(ex);
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Appender를 추가한다
|
|
/// </summary>
|
|
/// <param name="appender"></param>
|
|
public void AddAppender(IAppender appender)
|
|
{
|
|
try
|
|
{
|
|
log4net.Repository.Hierarchy.Logger logger = this.Logger;
|
|
FileAppender fileAppender = null;
|
|
IAppender removeItem = null;
|
|
foreach (IAppender item in logger.Appenders)
|
|
{
|
|
if (item.Name == appender.Name)
|
|
{
|
|
removeItem = item;
|
|
break;
|
|
}
|
|
}
|
|
if (removeItem != null)
|
|
{
|
|
fileAppender = removeItem as FileAppender;
|
|
logger.RemoveAppender(removeItem).Close();
|
|
}
|
|
|
|
fileAppender = appender as FileAppender;
|
|
logger.AddAppender(appender);
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
XLogger.Instance.Fatal(ex);
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// 모든 Appender를 제거한다
|
|
/// </summary>
|
|
public void ClearAppender()
|
|
{
|
|
log4net.Repository.Hierarchy.Logger logger = this.Logger;
|
|
List<IAppender> lstAppender = new List<IAppender>();
|
|
|
|
foreach (IAppender item in logger.Appenders)
|
|
lstAppender.Add(item);
|
|
|
|
foreach (IAppender item in lstAppender)
|
|
logger.RemoveAppender(item).Close();
|
|
}
|
|
|
|
#endregion
|
|
|
|
#region [ MDC ] -------------------------------------------------------
|
|
|
|
/// <summary>
|
|
/// MDC Key
|
|
/// </summary>
|
|
private enum eMDCKey
|
|
{
|
|
Logger,
|
|
Name,
|
|
Class,
|
|
Method
|
|
}
|
|
|
|
/// <summary>
|
|
/// Set MDC
|
|
/// </summary>
|
|
/// <param name="mdcKey"></param>
|
|
/// <param name="value"></param>
|
|
private void SetMDC(eMDCKey mdcKey, string value)
|
|
{
|
|
try
|
|
{
|
|
MDC.Set(mdcKey.ToString().ToLower(), value);
|
|
}
|
|
catch
|
|
{
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Set MDC
|
|
/// </summary>
|
|
/// <param name="mdcKey"></param>
|
|
/// <param name="value"></param>
|
|
private void SetMDC(string mdcKey, string value)
|
|
{
|
|
try
|
|
{
|
|
MDC.Set(mdcKey.ToLower(), value);
|
|
}
|
|
catch
|
|
{
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Clear MDC
|
|
/// </summary>
|
|
private void ClearMDC()
|
|
{
|
|
foreach (string mdcKey in Enum.GetNames(typeof(eMDCKey)))
|
|
SetMDC(mdcKey, string.Empty);
|
|
}
|
|
|
|
#endregion
|
|
|
|
#region [ Filter ] ----------------------------------------------------
|
|
|
|
/// <summary>
|
|
/// Add Filter(Type)
|
|
/// </summary>
|
|
/// <param name="types"></param>
|
|
public void AddFilterType(params Type[] types)
|
|
{
|
|
m_FilterTypes.AddRange(types);
|
|
}
|
|
|
|
/// <summary>
|
|
/// Clear Filter(Type)
|
|
/// </summary>
|
|
public void ClearFilterType()
|
|
{
|
|
m_FilterTypes.Clear();
|
|
}
|
|
|
|
#endregion
|
|
|
|
#region [ Debug ] -----------------------------------------------------
|
|
|
|
/// <summary>
|
|
/// Debug
|
|
/// </summary>
|
|
/// <param name="value"></param>
|
|
/// <param name="color"></param>
|
|
public string Debug(object value = null, Color? color = null)
|
|
{
|
|
return this.WriteLine(eXLogLevel.Debug, value, color);
|
|
}
|
|
|
|
/// <summary>
|
|
/// Debug
|
|
/// </summary>
|
|
/// <param name="message"></param>
|
|
/// <param name="e"></param>
|
|
/// <param name="color"></param>
|
|
public string Debug(string message, Exception e, Color? color = null)
|
|
{
|
|
return this.WriteLine(eXLogLevel.Debug, message, e, color);
|
|
}
|
|
|
|
#endregion
|
|
|
|
#region [ Info ] ------------------------------------------------------
|
|
|
|
/// <summary>
|
|
/// Info
|
|
/// </summary>
|
|
/// <param name="value"></param>
|
|
/// <param name="color"></param>
|
|
public string Info(object value = null, Color? color = null)
|
|
{
|
|
return this.WriteLine(eXLogLevel.Info, value, color);
|
|
}
|
|
|
|
/// <summary>
|
|
/// Info
|
|
/// </summary>
|
|
/// <param name="message"></param>
|
|
/// <param name="e"></param>
|
|
/// <param name="color"></param>
|
|
public string Info(string message, Exception e, Color? color = null)
|
|
{
|
|
return this.WriteLine(eXLogLevel.Info, message, e, color);
|
|
}
|
|
|
|
#endregion
|
|
|
|
#region [ Warn ] ------------------------------------------------------
|
|
|
|
/// <summary>
|
|
/// Warn
|
|
/// </summary>
|
|
/// <param name="value"></param>
|
|
/// <param name="color"></param>
|
|
public string Warn(object value = null, Color? color = null)
|
|
{
|
|
return this.WriteLine(eXLogLevel.Warn, value, color);
|
|
}
|
|
|
|
/// <summary>
|
|
/// Warn
|
|
/// </summary>
|
|
/// <param name="message"></param>
|
|
/// <param name="e"></param>
|
|
/// <param name="color"></param>
|
|
public string Warn(string message, Exception e, Color? color = null)
|
|
{
|
|
return this.WriteLine(eXLogLevel.Warn, message, e, color);
|
|
}
|
|
|
|
#endregion
|
|
|
|
#region [ Error ] -----------------------------------------------------
|
|
|
|
/// <summary>
|
|
/// Error
|
|
/// </summary>
|
|
/// <param name="value"></param>
|
|
/// <param name="color"></param>
|
|
public string Error(object value = null, Color? color = null)
|
|
{
|
|
return this.WriteLine(eXLogLevel.Error, value, color);
|
|
}
|
|
|
|
/// <summary>
|
|
/// Error
|
|
/// </summary>
|
|
/// <param name="message"></param>
|
|
/// <param name="e"></param>
|
|
/// <param name="color"></param>
|
|
public string Error(string message, Exception e, Color? color = null)
|
|
{
|
|
return this.WriteLine(eXLogLevel.Error, message, e, color);
|
|
}
|
|
|
|
#endregion
|
|
|
|
#region [ Fatal ] -----------------------------------------------------
|
|
|
|
/// <summary>
|
|
/// Fatal
|
|
/// </summary>
|
|
/// <param name="value"></param>
|
|
public string Fatal(object value, bool showMessageBox)
|
|
{
|
|
string message = this.WriteLine(eXLogLevel.Fatal, value);
|
|
|
|
if (showMessageBox)
|
|
MessageBox.Show(message, "Fatal", MessageBoxButtons.OK, MessageBoxIcon.Error);
|
|
|
|
return message;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Fatal
|
|
/// </summary>
|
|
/// <param name="value"></param>
|
|
/// <param name="color"></param>
|
|
public string Fatal(object value = null, Color? color = null)
|
|
{
|
|
string result = this.WriteLine(eXLogLevel.Fatal, value, color);
|
|
return result;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Fatal
|
|
/// </summary>
|
|
/// <param name="message"></param>
|
|
/// <param name="e"></param>
|
|
/// <param name="color"></param>
|
|
public string Fatal(string message, Exception e, Color? color = null)
|
|
{
|
|
string result = this.WriteLine(eXLogLevel.Fatal, message, e, color);
|
|
return result;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Fatal
|
|
/// </summary>
|
|
/// <param name="value"></param>
|
|
/// <param name="showMessageBox">Show MessageBox</param>
|
|
/// <param name="color"></param>
|
|
private string xFatal(object value = null, bool showMessageBox = false, Color? color = null)
|
|
{
|
|
string result = this.WriteLine(eXLogLevel.Fatal, value, color);
|
|
if (showMessageBox)
|
|
MessageBox.Show(result, "Fatal", MessageBoxButtons.OK, MessageBoxIcon.Error);
|
|
|
|
return result;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Fatal
|
|
/// </summary>
|
|
/// <param name="message"></param>
|
|
/// <param name="e"></param>
|
|
/// <param name="showMessageBox">Show MessageBox</param>
|
|
/// <param name="color"></param>
|
|
private string xFatal(string message, Exception e, bool showMessageBox = false, Color? color = null)
|
|
{
|
|
string result = this.WriteLine(eXLogLevel.Fatal, message, e, color);
|
|
if (showMessageBox)
|
|
MessageBox.Show(result, "Fatal", MessageBoxButtons.OK, MessageBoxIcon.Error);
|
|
|
|
return result;
|
|
}
|
|
|
|
#endregion
|
|
|
|
#region [ WriteLine ] -------------------------------------------------
|
|
|
|
private StackFrame GetStackFrame(StackTrace trace)
|
|
{
|
|
try
|
|
{
|
|
foreach (StackFrame frame in trace.GetFrames())
|
|
{
|
|
MethodBase method = frame.GetMethod();
|
|
if (method.DeclaringType != typeof(XLogger))
|
|
return frame;
|
|
}
|
|
|
|
return trace.GetFrame(2);
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
Trace.WriteLine(ex.Message);
|
|
return trace.GetFrame(2);
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// 지정된 문자열 값을 log4net 혹은 표준 출력 스트림에 출력합니다
|
|
/// </summary>
|
|
/// <param name="level"></param>
|
|
/// <param name="value"></param>
|
|
public string WriteLine(eXLogLevel level, object value = null, Color? color = null)
|
|
{
|
|
try
|
|
{
|
|
StackTrace trace = new StackTrace();
|
|
//StackFrame frame = trace.GetFrame(2);
|
|
StackFrame frame = this.GetStackFrame(trace);
|
|
MethodBase method = frame.GetMethod();
|
|
Exception ex = null;
|
|
string strMessage = string.Empty;
|
|
|
|
if (value != null)
|
|
{
|
|
if (value is Exception)
|
|
{
|
|
ex = value as Exception;
|
|
//strMessage = ex.Message;
|
|
}
|
|
else
|
|
{
|
|
strMessage = value.ToString();
|
|
}
|
|
}
|
|
|
|
return WriteLine(level, strMessage, method, ex, color);
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
Trace.WriteLine(ex.Message);
|
|
return ex.Message;
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// 지정된 문자열 값을 log4net 혹은 표준 출력 스트림에 출력합니다
|
|
/// </summary>
|
|
/// <param name="level"></param>
|
|
/// <param name="message"></param>
|
|
/// <param name="e"></param>
|
|
public string WriteLine(eXLogLevel level, string message, Exception e, Color? color = null)
|
|
{
|
|
try
|
|
{
|
|
StackTrace trace = new StackTrace();
|
|
//StackFrame frame = trace.GetFrame(2);
|
|
StackFrame frame = this.GetStackFrame(trace);
|
|
MethodBase method = frame.GetMethod();
|
|
string strMessage = string.Empty;
|
|
|
|
strMessage = message;
|
|
|
|
return WriteLine(level, strMessage, method, e);
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
Trace.WriteLine(ex.Message);
|
|
return ex.Message;
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// 지정된 문자열 값을 log4net 혹은 표준 출력 스트림에 출력합니다
|
|
/// </summary>
|
|
/// <param name="level"></param>
|
|
/// <param name="message"></param>
|
|
/// <param name="method"></param>
|
|
public string WriteLine(eXLogLevel level, string message, MethodBase method, Exception e = null, Color? color = null)
|
|
{
|
|
string result = string.Empty;
|
|
try
|
|
{
|
|
string name = this.Name;
|
|
string strDTime = DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss.fff");
|
|
string strClassFullName = string.Empty;
|
|
string strClassName = string.Empty;
|
|
string strMethod = string.Empty;
|
|
string strLog = string.Empty;
|
|
string strConsole = string.Empty;
|
|
|
|
ILog log = LogManager.GetLogger(name);
|
|
ClearMDC();
|
|
|
|
if (method == null)
|
|
{
|
|
StackTrace trace = new StackTrace();
|
|
StackFrame frame = trace.GetFrame(1);
|
|
method = frame.GetMethod();
|
|
}
|
|
|
|
if (method != null && method.DeclaringType != null)
|
|
{
|
|
if (m_FilterTypes.Count > 0 && m_FilterTypes.Contains(method.DeclaringType) == false) return result;
|
|
|
|
strClassFullName = method.DeclaringType.FullName;
|
|
strClassName = method.DeclaringType.Name;
|
|
strMethod = method.Name;
|
|
}
|
|
|
|
if (message.EndsWith(Environment.NewLine))
|
|
message = message.Remove(message.Length - Environment.NewLine.Length);
|
|
strLog = message;
|
|
strConsole = string.Format(this.ControlPatternLayout, strDTime, level.ToString().ToUpper(), name, strClassFullName, strMethod, message, strClassName);
|
|
|
|
SetMDC(eMDCKey.Name, name);
|
|
SetMDC(eMDCKey.Class, strClassFullName);
|
|
SetMDC(eMDCKey.Method, strMethod);
|
|
|
|
result = $"{strConsole}" + (e != null ? string.Format("{0}{2}", Environment.NewLine, e.Message, e.ToString()) : "");
|
|
switch (level)
|
|
{
|
|
case eXLogLevel.Debug:
|
|
if (log.IsDebugEnabled) { log.Debug(strLog, e); this.WriteControl(result, color); }
|
|
break;
|
|
case eXLogLevel.Info:
|
|
if (log.IsInfoEnabled) { log.Info(strLog, e); this.WriteControl(result, color); }
|
|
break;
|
|
case eXLogLevel.Warn:
|
|
if (log.IsWarnEnabled) { log.Warn(strLog, e); this.WriteControl(result, color); }
|
|
break;
|
|
case eXLogLevel.Error:
|
|
if (log.IsErrorEnabled) { log.Error(strLog); this.WriteControl(result, color); }
|
|
break;
|
|
case eXLogLevel.Fatal:
|
|
if (log.IsFatalEnabled) { log.Fatal(strLog, e); this.WriteControl(result, color); }
|
|
break;
|
|
}
|
|
|
|
//this.DeleteRollingFiles();
|
|
|
|
return result;
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
Trace.WriteLine(ex.ToString());
|
|
return ex.ToString();
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Control.Text에 로그를 기록한다
|
|
/// </summary>
|
|
/// <param name="message"></param>
|
|
private void WriteControl(string message, Color? color = null)
|
|
{
|
|
try
|
|
{
|
|
if (this.Control == null) return;
|
|
if (color.Equals(Color.Transparent)) return;
|
|
if (this.Control.InvokeRequired)
|
|
{
|
|
this.Control.Invoke((MethodInvoker)delegate { this.WriteControl(message, color); });
|
|
return;
|
|
}
|
|
|
|
Application.DoEvents();
|
|
this.Control.SuspendLayout();
|
|
if (this.Control.MaxLength <= this.Control.TextLength + message.Length)
|
|
{
|
|
int count = 0;
|
|
while (this.Control.MaxLength * 0.9 <= this.Control.TextLength + message.Length)
|
|
{
|
|
this.Control.SelectionStart = 0;
|
|
this.Control.SelectionLength = this.Control.GetFirstCharIndexFromLine(count + 1);
|
|
this.Control.SelectedText = string.Empty;
|
|
count++;
|
|
}
|
|
}
|
|
|
|
int index = this.Control.TextLength;
|
|
this.Control.AppendText(message + Environment.NewLine);
|
|
if (this.Control.GetType() == typeof(RichTextBox))
|
|
{
|
|
RichTextBox richTextBox = (RichTextBox)this.Control;
|
|
if (color == null) color = richTextBox.ForeColor;
|
|
|
|
richTextBox.SelectionStart = index;
|
|
richTextBox.SelectionLength = message.Length;
|
|
richTextBox.SelectionColor = (Color)color;
|
|
}
|
|
|
|
if (this.OnScrollToCaret)
|
|
this.Control.ScrollToCaret();
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
Trace.WriteLine(ex.ToString());
|
|
}
|
|
finally
|
|
{
|
|
if (this.Control != null) this.Control.ResumeLayout();
|
|
}
|
|
}
|
|
|
|
#endregion
|
|
|
|
#region [ ETC ] -------------------------------------------------------
|
|
|
|
/// <summary>
|
|
/// Change LogLevel
|
|
/// </summary>
|
|
/// <param name="level"></param>
|
|
public void SetLevel(log4net.Core.Level level)
|
|
{
|
|
Logger logger = this.Logger;
|
|
logger.Repository.Threshold = logger.Repository.LevelMap["DEBUG"];
|
|
logger.Level = level;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Logger를 반환한다
|
|
/// </summary>
|
|
/// <returns></returns>
|
|
private log4net.Repository.Hierarchy.Logger GetLogger(string name = "")
|
|
{
|
|
if (string.IsNullOrEmpty(name)) name = this.Name;
|
|
ILog log = LogManager.GetLogger(name);
|
|
|
|
log4net.Repository.Hierarchy.Logger logger = log.Logger as log4net.Repository.Hierarchy.Logger;
|
|
|
|
return logger;
|
|
}
|
|
|
|
/// <summary>
|
|
/// RollingAppender 로그파일을 삭제합니다.
|
|
/// </summary>
|
|
/// <param name="interval">동작주기(분)</param>
|
|
/// <remarks>
|
|
/// RollingMode='Date'일 경우 동작하며,
|
|
/// MaxSizeRollBackups 값을 보관일로 적용하여 기간이 경과된 파일들을 삭제한다
|
|
/// </remarks>
|
|
public void DeleteRollingFiles(int interval = 30)
|
|
{
|
|
try
|
|
{
|
|
if (DateTime.Now.Subtract(this.LastDeletedDateTime).TotalMinutes < interval) return;
|
|
this.LastDeletedDateTime = DateTime.Now;
|
|
|
|
var repositories = LogManager.GetAllRepositories().FirstOrDefault();
|
|
if (repositories == null) return;
|
|
|
|
foreach (IAppender appender in repositories.GetAppenders())
|
|
{
|
|
FileAppender fileAppender = appender as FileAppender;
|
|
RollingFileAppender rollingAppender = appender as RollingFileAppender;
|
|
if (rollingAppender != null)
|
|
{
|
|
int maxSizeRollBackups = rollingAppender.MaxSizeRollBackups;
|
|
if (maxSizeRollBackups < 1) continue;
|
|
|
|
RollingMode rollingStyle = rollingAppender.RollingStyle;
|
|
if (rollingStyle != RollingMode.Date) continue;
|
|
|
|
string path = System.IO.Path.GetDirectoryName(rollingAppender.File);
|
|
DirectoryInfo directory = new DirectoryInfo(path);
|
|
|
|
//string pattern = this.GetDatePatten(rollingAppender.DatePattern);
|
|
string extension = System.IO.Path.GetExtension(rollingAppender.File);
|
|
List<FileInfo> files = directory.GetFiles($"*{extension}")
|
|
.Where(x => DateTime.Now.Subtract(x.CreationTime).TotalDays > maxSizeRollBackups)
|
|
.OrderBy(x => x.CreationTime).ToList();
|
|
foreach (FileInfo file in files)
|
|
{
|
|
Trace.WriteLine($"Delete {file.FullName}");
|
|
file.Delete();
|
|
}
|
|
}
|
|
}
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
Trace.WriteLine(ex.ToString());
|
|
}
|
|
}
|
|
|
|
private string GetDatePatten(string name)
|
|
{
|
|
StringBuilder sb = new StringBuilder();
|
|
string pattern = @"'([^']*)'";
|
|
|
|
MatchCollection matches = Regex.Matches(name, pattern);
|
|
for (int i = 0; i < matches.Count; i++)
|
|
{
|
|
sb.Append(matches[i].Groups[1].Value);
|
|
if (i + 1 < matches.Count) sb.Append("*");
|
|
}
|
|
|
|
return sb.ToString();
|
|
}
|
|
|
|
public static string GetCallStack()
|
|
{
|
|
StringBuilder sb = new StringBuilder();
|
|
try
|
|
{
|
|
StackTrace trace = new StackTrace();
|
|
for (int i = 0; i < trace.FrameCount; i++)
|
|
{
|
|
StackFrame frame = trace.GetFrame(i);
|
|
MethodBase method = frame.GetMethod();
|
|
sb.AppendLine($"{method?.DeclaringType?.Name}.{method.Name}");
|
|
}
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
Console.WriteLine(ex.ToString());
|
|
}
|
|
|
|
return sb.ToString();
|
|
}
|
|
|
|
#endregion
|
|
|
|
#endregion
|
|
|
|
}
|
|
|
|
}
|
|
|