초기커밋
This commit is contained in:
17
ServerBase/BusinessLog/Appender/IAppender.cs
Normal file
17
ServerBase/BusinessLog/Appender/IAppender.cs
Normal file
@@ -0,0 +1,17 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Runtime.Serialization;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
|
||||
|
||||
|
||||
namespace ServerBase;
|
||||
|
||||
public abstract class IAppender
|
||||
{
|
||||
public abstract void write(IFormatter logFormatter, BusinessLog log);
|
||||
|
||||
}//ILogAppender
|
||||
60
ServerBase/BusinessLog/Appender/NLogAppender.cs
Normal file
60
ServerBase/BusinessLog/Appender/NLogAppender.cs
Normal file
@@ -0,0 +1,60 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Runtime.Serialization;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
|
||||
using NLog;
|
||||
using NLog.Fluent;
|
||||
|
||||
|
||||
using ServerCore; using ServerBase;
|
||||
|
||||
|
||||
namespace ServerBase;
|
||||
|
||||
public class NLogAppender : IAppender
|
||||
{
|
||||
private readonly NLog.Logger m_logger = NLog.LogManager.GetLogger("BusinessLogger");
|
||||
|
||||
public NLogAppender(string xmlCofigFilePath = "")
|
||||
{
|
||||
if(true == xmlCofigFilePath.isNullOrWhiteSpace())
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
reconfigureXML(xmlCofigFilePath);
|
||||
}
|
||||
|
||||
public bool reconfigureXML(string xmlCofigFilePath)
|
||||
{
|
||||
var to_reload_configure = new NLog.Config.XmlLoggingConfiguration(xmlCofigFilePath);
|
||||
if(null == to_reload_configure)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
LogManager.Configuration = to_reload_configure;
|
||||
LogManager.ReconfigExistingLoggers();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public bool isLoadedConfigXML()
|
||||
{
|
||||
if(null == LogManager.Configuration)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public override void write(IFormatter logFormatter, BusinessLog log)
|
||||
{
|
||||
m_logger?.Info(logFormatter.toLogString(log));
|
||||
}
|
||||
}
|
||||
93
ServerBase/BusinessLog/BusinessLogger.cs
Normal file
93
ServerBase/BusinessLog/BusinessLogger.cs
Normal file
@@ -0,0 +1,93 @@
|
||||
|
||||
|
||||
using ServerCore; using ServerBase;
|
||||
|
||||
|
||||
namespace ServerBase;
|
||||
|
||||
//========================================================================================================
|
||||
// 비즈니스 로그 처리자
|
||||
//
|
||||
// 운영 담당 부서와 사업 담당 부서에서 필요로 하는 주요 속성들 정의 하여
|
||||
// 필요로 하는 데이터 포멧에 맞게 출력 한다.
|
||||
//========================================================================================================
|
||||
public static class BusinessLogger
|
||||
{
|
||||
private static IAppender? m_appender;
|
||||
private static IFormatter? m_formatter;
|
||||
private static LogTransToOutputType m_output_type = LogTransToOutputType.TransToSingleLine;
|
||||
|
||||
//==========================================================================
|
||||
// appender를 셋팅한다.
|
||||
//==========================================================================
|
||||
public static void setup(IAppender appender, IFormatter logFormatter, LogTransToOutputType outputType)
|
||||
{
|
||||
m_appender = appender;
|
||||
m_formatter = logFormatter;
|
||||
m_output_type = outputType;
|
||||
}
|
||||
|
||||
|
||||
//==========================================================================
|
||||
// 단일 로그를 수집 한다.
|
||||
//==========================================================================
|
||||
public static ServerErrorCode collectLog(IWithLogActor actor, ILogInvoker invoker)
|
||||
{
|
||||
ArgumentNullReferenceCheckHelper.throwIfNull(actor, () => $"actor is null !!!");
|
||||
ArgumentNullReferenceCheckHelper.throwIfNull(invoker, () => $"invoker is null !!!");
|
||||
|
||||
if (m_appender == null)
|
||||
{
|
||||
return ServerErrorCode.LogAppenderIsNull;
|
||||
}
|
||||
|
||||
if(m_formatter == null)
|
||||
{
|
||||
return ServerErrorCode.LogAppenderIsNull;
|
||||
}
|
||||
|
||||
if(true == invoker.hasLog())
|
||||
{
|
||||
var is_success = invoker.alloc(actor.toLogActor(), out var log);
|
||||
if (is_success.isSuccess() && log != null)
|
||||
{
|
||||
m_appender.write(m_formatter, log);
|
||||
}
|
||||
}
|
||||
|
||||
return ServerErrorCode.Success;
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
// 복합 로그를 수집 한다.
|
||||
//==========================================================================
|
||||
public static ServerErrorCode collectLogs(LogAction logAction, IWithLogActor actor, List<ILogInvoker> invokers)
|
||||
{
|
||||
if (m_appender == null)
|
||||
{
|
||||
return ServerErrorCode.LogAppenderIsNull;
|
||||
}
|
||||
|
||||
if (m_formatter == null)
|
||||
{
|
||||
return ServerErrorCode.LogFormatterIsNull;
|
||||
}
|
||||
|
||||
List<BusinessLog> logs = new List<BusinessLog>();
|
||||
var result_code = ILogInvoker.alloc(logAction.getLogActionType(), logAction.getTranId(), actor.toLogActor(), invokers, m_output_type, ref logs);
|
||||
if(result_code.isFail())
|
||||
{
|
||||
return result_code;
|
||||
}
|
||||
|
||||
foreach (var log in logs)
|
||||
{
|
||||
if (log != null && log.hasLog())
|
||||
{
|
||||
m_appender.write(m_formatter, log);
|
||||
}
|
||||
}
|
||||
|
||||
return ServerErrorCode.Success;
|
||||
}
|
||||
}
|
||||
17
ServerBase/BusinessLog/Formatter/IFormatter.cs
Normal file
17
ServerBase/BusinessLog/Formatter/IFormatter.cs
Normal file
@@ -0,0 +1,17 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.ComponentModel;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
|
||||
|
||||
|
||||
namespace ServerBase;
|
||||
|
||||
public abstract class IFormatter
|
||||
{
|
||||
public abstract string toLogString(BusinessLog log);
|
||||
|
||||
}//IFormatter
|
||||
82
ServerBase/BusinessLog/Formatter/JsonText.cs
Normal file
82
ServerBase/BusinessLog/Formatter/JsonText.cs
Normal file
@@ -0,0 +1,82 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Reflection;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
|
||||
using Newtonsoft.Json.Serialization;
|
||||
using Newtonsoft.Json;
|
||||
|
||||
|
||||
namespace ServerBase;
|
||||
|
||||
public class JsonText : IFormatter
|
||||
{
|
||||
private static readonly JsonSerializerSettings m_serialize_settings = new JsonSerializerSettings();
|
||||
private static readonly ContractResolver m_resolver = new ContractResolver();
|
||||
|
||||
public JsonText()
|
||||
{
|
||||
m_serialize_settings.ContractResolver = m_resolver;
|
||||
m_serialize_settings.Converters.Add(new Newtonsoft.Json.Converters.StringEnumConverter());
|
||||
}
|
||||
|
||||
public override string toLogString(BusinessLog log)
|
||||
{
|
||||
return JsonConvert.SerializeObject(log, m_serialize_settings);
|
||||
}
|
||||
|
||||
|
||||
//=============================================================================================
|
||||
// Json을 만들때 무시할 property를 등록한다.
|
||||
//=============================================================================================
|
||||
private class ContractResolver : Newtonsoft.Json.Serialization.DefaultContractResolver
|
||||
{
|
||||
private readonly Dictionary<Type, HashSet<string>> m_ignores;
|
||||
|
||||
public ContractResolver()
|
||||
{
|
||||
m_ignores = new Dictionary<Type, HashSet<string>>();
|
||||
}
|
||||
|
||||
public void ignoreProperty(Type type, params string[] jsonPropertyNames)
|
||||
{
|
||||
if (false == m_ignores.ContainsKey(type))
|
||||
{
|
||||
m_ignores[type] = new HashSet<string>();
|
||||
}
|
||||
|
||||
foreach (var prop in jsonPropertyNames)
|
||||
{
|
||||
m_ignores[type].Add(prop);
|
||||
}
|
||||
}
|
||||
|
||||
public bool isIgnored(Type type, string jsonPropertyName)
|
||||
{
|
||||
if (false == m_ignores.ContainsKey(type))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
return m_ignores[type].Contains(jsonPropertyName);
|
||||
}
|
||||
|
||||
protected override JsonProperty CreateProperty(MemberInfo member, MemberSerialization memberSerialization)
|
||||
{
|
||||
var property = base.CreateProperty(member, memberSerialization);
|
||||
|
||||
if (property.DeclaringType != null &&
|
||||
property.PropertyName != null &&
|
||||
isIgnored(property.DeclaringType, property.PropertyName))
|
||||
{
|
||||
property.ShouldSerialize = i => false;
|
||||
property.Ignored = true;
|
||||
}
|
||||
return property;
|
||||
}
|
||||
|
||||
}//ContractResolver
|
||||
|
||||
}//JsonText
|
||||
21
ServerBase/BusinessLog/Log/Actor/ILogActor.cs
Normal file
21
ServerBase/BusinessLog/Log/Actor/ILogActor.cs
Normal file
@@ -0,0 +1,21 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
|
||||
|
||||
namespace ServerBase;
|
||||
|
||||
|
||||
//===================================================================================
|
||||
// 로그 주체를 지칭한다
|
||||
//===================================================================================
|
||||
public abstract class ILogActor
|
||||
{
|
||||
public virtual bool fillup(IFormatter formatter)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
243
ServerBase/BusinessLog/Log/ILog.cs
Normal file
243
ServerBase/BusinessLog/Log/ILog.cs
Normal file
@@ -0,0 +1,243 @@
|
||||
using System;
|
||||
using System.Collections.Concurrent;
|
||||
using System.Collections.Generic;
|
||||
|
||||
|
||||
using Amazon.OpenSearchService.Model.Internal.MarshallTransformations;
|
||||
using Newtonsoft.Json;
|
||||
using Newtonsoft.Json.Serialization;
|
||||
|
||||
|
||||
using ServerCore; using ServerBase;
|
||||
|
||||
|
||||
using LOG_ACTION_TYPE = System.String;
|
||||
using LOG_DOMAIN_TYPE = System.String;
|
||||
|
||||
|
||||
namespace ServerBase;
|
||||
|
||||
public enum LogTransToOutputType
|
||||
{
|
||||
TransToMultyLine = 0, // Body 갯수대로 로그 출력
|
||||
TransToSingleLine = 1, // 한개의 Body로 로그 출력
|
||||
}
|
||||
|
||||
//===================================================================================
|
||||
// 로그 액션
|
||||
//===================================================================================
|
||||
|
||||
public partial class LogAction
|
||||
{
|
||||
private readonly LOG_ACTION_TYPE m_log_action_type = string.Empty;
|
||||
private Guid m_tran_id = Guid.Empty;
|
||||
|
||||
public LogAction(LOG_ACTION_TYPE logActionType)
|
||||
{
|
||||
m_log_action_type = logActionType;
|
||||
m_tran_id = Guid.NewGuid();
|
||||
}
|
||||
|
||||
public LogAction(LOG_ACTION_TYPE logActionType, Guid tranId)
|
||||
{
|
||||
m_log_action_type = logActionType;
|
||||
m_tran_id = tranId;
|
||||
}
|
||||
|
||||
}//LogAction
|
||||
|
||||
|
||||
//===================================================================================
|
||||
// 로그를 발생 시킨다
|
||||
//===================================================================================
|
||||
|
||||
public abstract partial class ILogInvoker
|
||||
{
|
||||
private LogAction? m_log_action_nullable;
|
||||
private readonly LOG_DOMAIN_TYPE m_log_domain_type = string.Empty;
|
||||
|
||||
public ILogInvoker()
|
||||
{
|
||||
}
|
||||
|
||||
public ILogInvoker(LOG_DOMAIN_TYPE logDomainType)
|
||||
{
|
||||
m_log_domain_type = logDomainType;
|
||||
}
|
||||
|
||||
public ILogInvoker(LOG_DOMAIN_TYPE logDomainType, LogAction logAction)
|
||||
{
|
||||
m_log_action_nullable = logAction;
|
||||
m_log_domain_type = logDomainType;
|
||||
}
|
||||
|
||||
public ServerErrorCode alloc(ILogActor logActor, out BusinessLog? businessLog)
|
||||
{
|
||||
ArgumentNullReferenceCheckHelper.throwIfNull(logActor, () => $"logActor is null !!!");
|
||||
|
||||
businessLog = null;
|
||||
|
||||
if (null == m_log_action_nullable)
|
||||
{
|
||||
return ServerErrorCode.LogActionIsNull;
|
||||
}
|
||||
|
||||
var header = new BusinessLog.LogHeader(m_log_action_nullable.getTranId().ToString(), logActor);
|
||||
var body = new BusinessLog.LogBody(m_log_action_nullable.getLogActionType());
|
||||
{
|
||||
fillup(ref body);
|
||||
}
|
||||
|
||||
businessLog = new BusinessLog(header, body);
|
||||
|
||||
return ServerErrorCode.Success;
|
||||
}
|
||||
|
||||
public static ServerErrorCode alloc( LOG_ACTION_TYPE logActionType, Guid tran
|
||||
, ILogActor actorLog, List<ILogInvoker> invokers
|
||||
, LogTransToOutputType outputType, ref List<BusinessLog> outLogs )
|
||||
{
|
||||
if (logActionType.isNullOrWhiteSpace())
|
||||
{
|
||||
return ServerErrorCode.LogActionTypeInvalid;
|
||||
}
|
||||
|
||||
var header = new BusinessLog.LogHeader(tran.ToString(), actorLog);
|
||||
switch (outputType)
|
||||
{
|
||||
case LogTransToOutputType.TransToMultyLine:
|
||||
{
|
||||
foreach (var each in invokers)
|
||||
{
|
||||
var body = new BusinessLog.LogBody(logActionType);
|
||||
{
|
||||
if (false == each.hasLog())
|
||||
{
|
||||
continue;
|
||||
}
|
||||
each.fillup(ref body);
|
||||
|
||||
outLogs.Add(new BusinessLog(header, body));
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
case LogTransToOutputType.TransToSingleLine:
|
||||
{
|
||||
var body = new BusinessLog.LogBody(logActionType);
|
||||
{
|
||||
foreach (var each in invokers)
|
||||
{
|
||||
if (false == each.hasLog())
|
||||
{
|
||||
continue;
|
||||
}
|
||||
each.fillup(ref body);
|
||||
}
|
||||
outLogs.Add(new BusinessLog(header, body));
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
return ServerErrorCode.Success;
|
||||
}
|
||||
|
||||
protected abstract void fillup(ref BusinessLog.LogBody body);
|
||||
|
||||
// 로그가 들어 있는지 검사한다.
|
||||
public abstract bool hasLog();
|
||||
|
||||
public virtual string toBasicString()
|
||||
{
|
||||
return $"LogInvoker:{this.getTypeName()}";
|
||||
}
|
||||
|
||||
//===================================================================================
|
||||
// 사용자 정의 로그 정보 추상 클래스 이다.
|
||||
//===================================================================================
|
||||
public abstract class IInfo
|
||||
{
|
||||
[JsonProperty(Order = -2)]
|
||||
private readonly LOG_DOMAIN_TYPE Domain = string.Empty;
|
||||
|
||||
// ILogInvoker 에 의해 생성될 경우 로그 정보 컨테이너에 적재되고
|
||||
// 로그 정보를 Json 기반으로 직렬화 한다.
|
||||
public IInfo(ILogInvoker parent)
|
||||
{
|
||||
Domain = parent.m_log_domain_type;
|
||||
}
|
||||
|
||||
// 로그 정보 전달 객체로 활용 된다 !!!
|
||||
public IInfo()
|
||||
{
|
||||
}
|
||||
}//IInfo
|
||||
}//ILogInvoker
|
||||
|
||||
|
||||
public class BusinessLog
|
||||
{
|
||||
[JsonProperty]
|
||||
private readonly LogHeader Header;
|
||||
[JsonProperty]
|
||||
private readonly LogBody Body;
|
||||
|
||||
public BusinessLog(LogHeader header, LogBody body)
|
||||
{
|
||||
Header = header;
|
||||
Body = body;
|
||||
}
|
||||
|
||||
public bool hasLog()
|
||||
{
|
||||
return Header != null && Body != null && Header.hasLog() && Body.hasLog();
|
||||
}
|
||||
|
||||
public class LogHeader
|
||||
{
|
||||
[JsonProperty]
|
||||
private readonly string TranId = string.Empty;
|
||||
[JsonProperty]
|
||||
private readonly ILogActor Actor;
|
||||
|
||||
public LogHeader(string tran_id, ILogActor actor_log)
|
||||
{
|
||||
TranId = tran_id;
|
||||
Actor = actor_log;
|
||||
}
|
||||
|
||||
public bool hasLog()
|
||||
{
|
||||
return Actor != null;
|
||||
}
|
||||
}
|
||||
|
||||
public class LogBody
|
||||
{
|
||||
[JsonProperty]
|
||||
private readonly LOG_ACTION_TYPE Action = string.Empty;
|
||||
[JsonProperty]
|
||||
private readonly List<ILogInvoker.IInfo> Infos = new List<ILogInvoker.IInfo>();
|
||||
|
||||
public LogBody(LOG_ACTION_TYPE action)
|
||||
{
|
||||
Action = action;
|
||||
}
|
||||
|
||||
public bool hasLog(bool allow_empty = false)
|
||||
{
|
||||
if (Action.isNullOrWhiteSpace())
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
return allow_empty ? true : Infos.Count != 0;
|
||||
}
|
||||
|
||||
public void append(ILogInvoker.IInfo info)
|
||||
{
|
||||
Infos.Add(info);
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user