250501 커밋
This commit is contained in:
@@ -2,25 +2,22 @@
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
|
||||
|
||||
using Newtonsoft.Json;
|
||||
using Newtonsoft.Json.Linq;
|
||||
|
||||
|
||||
using YamlDotNet.Serialization;
|
||||
using YamlDotNet.Serialization.NamingConventions;
|
||||
|
||||
|
||||
|
||||
namespace ServerCore;
|
||||
|
||||
|
||||
public sealed class ConfigManager : Singleton<ConfigManager>
|
||||
public sealed class ConfigManager
|
||||
{
|
||||
private readonly List<(string path, string type)> m_file_sources = new();
|
||||
private readonly List<JObject> m_jobject_sources = new();
|
||||
|
||||
private readonly Dictionary<uint, (string path, string type)> m_key_to_source = new();
|
||||
private readonly Dictionary<string, JObject> m_path_to_jobject = new();
|
||||
private readonly Dictionary<string, FileSystemWatcher> m_watchers = new();
|
||||
|
||||
private bool m_is_detect_duplicates = true;
|
||||
|
||||
public ConfigManager() { }
|
||||
@@ -30,39 +27,38 @@ public sealed class ConfigManager : Singleton<ConfigManager>
|
||||
m_is_detect_duplicates = enable;
|
||||
}
|
||||
|
||||
public ConfigManager addJson(string path)
|
||||
public ConfigManager addJson(uint key, string path)
|
||||
{
|
||||
loadJson(path);
|
||||
watchFile(path, "json");
|
||||
|
||||
m_key_to_source[key] = (path, "json");
|
||||
return this;
|
||||
}
|
||||
|
||||
public ConfigManager addYaml(string path)
|
||||
public ConfigManager addYaml(uint key, string path)
|
||||
{
|
||||
loadYaml(path);
|
||||
watchFile(path, "yaml");
|
||||
|
||||
m_key_to_source[key] = (path, "yaml");
|
||||
return this;
|
||||
}
|
||||
|
||||
private void loadJson(string path)
|
||||
{
|
||||
if (false == File.Exists(path))
|
||||
{
|
||||
if (!File.Exists(path))
|
||||
throw new FileNotFoundException($"Not found Json File !!! : path:{path}");
|
||||
}
|
||||
|
||||
var json_text = File.ReadAllText(path);
|
||||
var jObject = JObject.Parse(json_text);
|
||||
m_file_sources.Add((path, "json"));
|
||||
m_jobject_sources.Add(jObject);
|
||||
m_path_to_jobject[path] = jObject;
|
||||
}
|
||||
|
||||
private void loadYaml(string path)
|
||||
{
|
||||
if (false == File.Exists(path))
|
||||
{
|
||||
if (!File.Exists(path))
|
||||
throw new FileNotFoundException($"Not found Yaml File !!! : path:{path}");
|
||||
}
|
||||
|
||||
var yamlText = File.ReadAllText(path);
|
||||
var deserializer = new DeserializerBuilder()
|
||||
@@ -76,20 +72,18 @@ public sealed class ConfigManager : Singleton<ConfigManager>
|
||||
|
||||
var json = serializer.Serialize(yamlObject);
|
||||
var jObject = JObject.Parse(json);
|
||||
m_file_sources.Add((path, "yaml"));
|
||||
m_jobject_sources.Add(jObject);
|
||||
m_path_to_jobject[path] = jObject;
|
||||
}
|
||||
|
||||
private void watchFile(string path, string type)
|
||||
{
|
||||
if (m_watchers.ContainsKey(path))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
var directory_name = Path.GetDirectoryName(path);
|
||||
NullReferenceCheckHelper.throwIfNull(directory_name, () => $"directory_name is null !!! : path:{path}, format:{type}");
|
||||
var watcher = new FileSystemWatcher(directory_name)
|
||||
|
||||
var watcher = new FileSystemWatcher(directory_name!)
|
||||
{
|
||||
Filter = Path.GetFileName(path),
|
||||
NotifyFilter = NotifyFilters.LastWrite | NotifyFilters.FileName | NotifyFilters.Size
|
||||
@@ -102,40 +96,54 @@ public sealed class ConfigManager : Singleton<ConfigManager>
|
||||
|
||||
m_watchers[path] = watcher;
|
||||
}
|
||||
|
||||
private void reloadAll()
|
||||
{
|
||||
Log.getLogger().error("Detected changes in config file !!!, Reloading...");
|
||||
|
||||
m_jobject_sources.Clear();
|
||||
foreach (var (path, type) in m_file_sources)
|
||||
m_path_to_jobject.Clear();
|
||||
|
||||
foreach (var key in m_key_to_source.Keys)
|
||||
{
|
||||
if (type == "json")
|
||||
if (false == reloadConfig(key))
|
||||
{
|
||||
loadJson(path);
|
||||
}
|
||||
else if (type == "yaml")
|
||||
{
|
||||
loadYaml(path);
|
||||
Log.getLogger().error($"Failed to reload config for key={key} during full reload");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public bool reloadConfig(uint key)
|
||||
{
|
||||
if (!m_key_to_source.TryGetValue(key, out var entry))
|
||||
return false;
|
||||
|
||||
try
|
||||
{
|
||||
if (entry.type == "json")
|
||||
loadJson(entry.path);
|
||||
else if (entry.type == "yaml")
|
||||
loadYaml(entry.path);
|
||||
|
||||
Log.getLogger().info($"Reloaded config for key={key}, path={entry.path}");
|
||||
return true;
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Log.getLogger().error($"Failed to reload config: key={key}, path={entry.path}, error={ex.Message}");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
public T bind<T>(string sectionName)
|
||||
{
|
||||
if (m_jobject_sources.Count == 0)
|
||||
{
|
||||
if (m_path_to_jobject.Count == 0)
|
||||
throw new InvalidOperationException("No config sources have been loaded !!!");
|
||||
}
|
||||
|
||||
var merged = new JObject();
|
||||
|
||||
foreach (var source in m_jobject_sources)
|
||||
foreach (var source in m_path_to_jobject.Values)
|
||||
{
|
||||
if (true == m_is_detect_duplicates)
|
||||
{
|
||||
if (m_is_detect_duplicates)
|
||||
detectDuplicateKeys(merged, source);
|
||||
}
|
||||
|
||||
merged.Merge(source, new JsonMergeSettings
|
||||
{
|
||||
@@ -144,22 +152,114 @@ public sealed class ConfigManager : Singleton<ConfigManager>
|
||||
});
|
||||
}
|
||||
|
||||
JToken? target_token = null;
|
||||
if (false == merged.TryGetValue(sectionName, out var found_target_token))
|
||||
return extractSection<T>(merged, sectionName, "merged");
|
||||
}
|
||||
|
||||
public T bindFromPath<T>(string path, string sectionName)
|
||||
{
|
||||
if (!m_path_to_jobject.TryGetValue(path, out var jObject))
|
||||
throw new ArgumentException($"Config file not loaded or not found: path={path}");
|
||||
|
||||
return extractSection<T>(jObject, sectionName, $"path={path}");
|
||||
}
|
||||
|
||||
public T bindFromKey<T>(uint key, string sectionName)
|
||||
{
|
||||
if (!m_key_to_source.TryGetValue(key, out var entry))
|
||||
throw new ArgumentException($"Key not found: key={key}");
|
||||
|
||||
if (!m_path_to_jobject.TryGetValue(entry.path, out var jObject))
|
||||
throw new Exception($"JObject not found for path associated with key={key}");
|
||||
|
||||
return extractSection<T>(jObject, sectionName, $"key={key}, path={entry.path}");
|
||||
}
|
||||
|
||||
public bool tryBindFromKey<T>(uint key, string sectionName, out T? result)
|
||||
{
|
||||
result = default;
|
||||
|
||||
try
|
||||
{
|
||||
target_token = merged;
|
||||
result = bindFromKey<T>(key, sectionName);
|
||||
return true;
|
||||
}
|
||||
else
|
||||
catch
|
||||
{
|
||||
target_token = found_target_token;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
public bool tryBindFromPath<T>(string path, string sectionName, out T? result)
|
||||
{
|
||||
result = default;
|
||||
|
||||
try
|
||||
{
|
||||
result = bindFromPath<T>(path, sectionName);
|
||||
return true;
|
||||
}
|
||||
catch
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
public JObject? getRawJsonByKey(uint key)
|
||||
{
|
||||
if (!m_key_to_source.TryGetValue(key, out var entry))
|
||||
return null;
|
||||
|
||||
return m_path_to_jobject.TryGetValue(entry.path, out var jObject)
|
||||
? jObject
|
||||
: null;
|
||||
}
|
||||
|
||||
public JObject? getRawJsonByPath(string path)
|
||||
{
|
||||
return m_path_to_jobject.TryGetValue(path, out var jObject)
|
||||
? jObject
|
||||
: null;
|
||||
}
|
||||
|
||||
public bool removeConfig(uint key)
|
||||
{
|
||||
if (!m_key_to_source.TryGetValue(key, out var entry))
|
||||
return false;
|
||||
|
||||
m_key_to_source.Remove(key);
|
||||
m_path_to_jobject.Remove(entry.path);
|
||||
|
||||
if (m_watchers.TryGetValue(entry.path, out var watcher))
|
||||
{
|
||||
watcher.EnableRaisingEvents = false;
|
||||
watcher.Dispose();
|
||||
m_watchers.Remove(entry.path);
|
||||
}
|
||||
|
||||
if (target_token == null)
|
||||
return true;
|
||||
}
|
||||
|
||||
public IEnumerable<uint> getAllKeys()
|
||||
{
|
||||
return m_key_to_source.Keys;
|
||||
}
|
||||
|
||||
public IEnumerable<string> getAllPaths()
|
||||
{
|
||||
return m_path_to_jobject.Keys;
|
||||
}
|
||||
|
||||
private T extractSection<T>(JObject jObject, string sectionName, string context)
|
||||
{
|
||||
if (!jObject.TryGetValue(sectionName, out var token))
|
||||
{
|
||||
throw new Exception($"Section could not be found !!! : sectionName:{sectionName}");
|
||||
token = jObject; // fallback
|
||||
}
|
||||
|
||||
return target_token.ToObject<T>()!;
|
||||
if (token == null)
|
||||
throw new Exception($"Section not found: sectionName={sectionName}, context={context}");
|
||||
|
||||
return token.ToObject<T>()!;
|
||||
}
|
||||
|
||||
private void detectDuplicateKeys(JObject existing, JObject incoming)
|
||||
@@ -172,4 +272,4 @@ public sealed class ConfigManager : Singleton<ConfigManager>
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
66
ServerCore/Config/ConfigManagerConfigurationProvider.cs
Normal file
66
ServerCore/Config/ConfigManagerConfigurationProvider.cs
Normal file
@@ -0,0 +1,66 @@
|
||||
using Microsoft.Extensions.Configuration;
|
||||
using Newtonsoft.Json.Linq;
|
||||
|
||||
|
||||
using ServerCore;
|
||||
|
||||
|
||||
public class ConfigManagerConfigurationProvider : ConfigurationProvider
|
||||
{
|
||||
private readonly ConfigManager m_config_manager;
|
||||
|
||||
public ConfigManagerConfigurationProvider(ConfigManager configManager)
|
||||
{
|
||||
m_config_manager = configManager;
|
||||
|
||||
Load();
|
||||
}
|
||||
|
||||
public override void Load()
|
||||
{
|
||||
var data = new Dictionary<string, string>();
|
||||
|
||||
foreach (var jObj in m_config_manager.getAllPaths())
|
||||
{
|
||||
var jtoken = m_config_manager.getRawJsonByPath(jObj);
|
||||
if (jtoken == null) continue;
|
||||
|
||||
flattenJson(jtoken, data, parentPath: null);
|
||||
}
|
||||
|
||||
Data = data!;
|
||||
}
|
||||
|
||||
private void flattenJson(JToken token, IDictionary<string, string> data, string? parentPath)
|
||||
{
|
||||
NullReferenceCheckHelper.throwIfNull(token, () => $"token is null !!!");
|
||||
|
||||
switch (token.Type)
|
||||
{
|
||||
case JTokenType.Object:
|
||||
foreach (var prop in (JObject)token)
|
||||
{
|
||||
var path = parentPath == null ? prop.Key : $"{parentPath}:{prop.Key}";
|
||||
NullReferenceCheckHelper.throwIfNull(prop.Value, () => $"prop.Value is null !!!");
|
||||
flattenJson(prop.Value, data, path);
|
||||
}
|
||||
break;
|
||||
|
||||
case JTokenType.Array:
|
||||
var index = 0;
|
||||
foreach (var item in (JArray)token)
|
||||
{
|
||||
var path = $"{parentPath}:{index++}";
|
||||
flattenJson(item, data, path);
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
if (token is JValue value && parentPath != null)
|
||||
{
|
||||
data[parentPath] = value.ToString();
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
19
ServerCore/Config/ConfigManagerConfigurationSource.cs
Normal file
19
ServerCore/Config/ConfigManagerConfigurationSource.cs
Normal file
@@ -0,0 +1,19 @@
|
||||
using Microsoft.Extensions.Configuration;
|
||||
|
||||
|
||||
namespace ServerCore;
|
||||
|
||||
public class ConfigManagerConfigurationSource : IConfigurationSource
|
||||
{
|
||||
private readonly ConfigManager m_config_manager;
|
||||
|
||||
public ConfigManagerConfigurationSource(ConfigManager configManager)
|
||||
{
|
||||
m_config_manager = configManager;
|
||||
}
|
||||
|
||||
public IConfigurationProvider Build(IConfigurationBuilder builder)
|
||||
{
|
||||
return new ConfigManagerConfigurationProvider(m_config_manager);
|
||||
}
|
||||
}
|
||||
31
ServerCore/Config/ConfigManagerHelper.cs
Normal file
31
ServerCore/Config/ConfigManagerHelper.cs
Normal file
@@ -0,0 +1,31 @@
|
||||
using Microsoft.Extensions.Configuration;
|
||||
|
||||
|
||||
using ServerCore;
|
||||
|
||||
/*=============================================================================================
|
||||
|
||||
ConfigurationBuilder 연동 지원 Helper 클래스
|
||||
|
||||
var configManager = new ConfigManager()
|
||||
.addJson(1, "appsettings.json")
|
||||
.addYaml(2, "settings.yaml");
|
||||
|
||||
var configuration = new ConfigurationBuilder()
|
||||
.addConfigManager(configManager)
|
||||
.Build();
|
||||
|
||||
var mySetting = configuration["MyApp:Setting"];
|
||||
|
||||
|
||||
author : kangms
|
||||
|
||||
=============================================================================================*/
|
||||
|
||||
public static class ConfigManagerHelper
|
||||
{
|
||||
public static IConfigurationBuilder addConfigManager(this IConfigurationBuilder builder, ConfigManager manager)
|
||||
{
|
||||
return builder.Add(new ConfigManagerConfigurationSource(manager));
|
||||
}
|
||||
}
|
||||
@@ -10,7 +10,7 @@ namespace ServerCore;
|
||||
|
||||
|
||||
//=============================================================================================
|
||||
// 조건 체크 관련 예외 지원 함수
|
||||
// 조건별 체크 관련 예외 지원 함수
|
||||
//
|
||||
// author : kangms
|
||||
//
|
||||
@@ -19,25 +19,57 @@ namespace ServerCore;
|
||||
public static class ConditionValidCheckHelper
|
||||
{
|
||||
public static void throwIfFalse( bool isCondition
|
||||
, string errMsg )
|
||||
, string errMsg
|
||||
, Func<string, Exception>? overrideException = null )
|
||||
{
|
||||
if (false == isCondition)
|
||||
if (isCondition)
|
||||
return;
|
||||
|
||||
if (overrideException != null)
|
||||
{
|
||||
throw new InvalidOperationException(errMsg);
|
||||
throw overrideException(errMsg);
|
||||
}
|
||||
|
||||
throw new InvalidOperationException(errMsg);
|
||||
}
|
||||
|
||||
public static void throwIfFalseWithCondition( Expression<Func<bool>> conditionExpression
|
||||
, Func<string>? fnLog = null )
|
||||
, Func<string>? fnLog = null
|
||||
, Func<string, Exception>? overrideException = null )
|
||||
{
|
||||
var compiled_expression = conditionExpression.Compile();
|
||||
if (false == compiled_expression())
|
||||
if (compiled_expression())
|
||||
return;
|
||||
|
||||
string condition_text = conditionExpression.Body.ToString();
|
||||
string errMsg = fnLog?.Invoke() ?? $"Failed to check condition: '{condition_text}'";
|
||||
|
||||
if (overrideException != null)
|
||||
{
|
||||
string condition_text = conditionExpression.Body.ToString();
|
||||
|
||||
var err_msg = fnLog?.Invoke() ?? $"Failed to check Condition: '{condition_text}'";
|
||||
|
||||
throw new InvalidOperationException(err_msg);
|
||||
throw overrideException(errMsg);
|
||||
}
|
||||
|
||||
throw new InvalidOperationException(errMsg);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public static class RangeCheckHelper
|
||||
{
|
||||
public static void throwIfOutOfRange( int value, int min, int max
|
||||
, Func<string>? fnLog = null
|
||||
, Func<string, Exception>? overrideException = null )
|
||||
{
|
||||
if (value >= min && value <= max)
|
||||
return;
|
||||
|
||||
string message = fnLog?.Invoke() ?? $"Value {value} is out of range [{min}, {max}]";
|
||||
|
||||
if (overrideException != null)
|
||||
{
|
||||
throw overrideException(message);
|
||||
}
|
||||
|
||||
throw new ArgumentOutOfRangeException(nameof(value), message);
|
||||
}
|
||||
}
|
||||
@@ -23,22 +23,20 @@ public static class ArgumentNullReferenceCheckHelper
|
||||
{
|
||||
public static void throwIfNull( [NotNull] object? argument
|
||||
, Func<string>? fnLog = null
|
||||
, [CallerArgumentExpression(nameof(argument))] string? paramName = null )
|
||||
, [CallerArgumentExpression(nameof(argument))] string? paramName = null
|
||||
, Func<string, Exception>? overrideException = null )
|
||||
{
|
||||
if (argument != null)
|
||||
return;
|
||||
|
||||
if (fnLog != null)
|
||||
string message = fnLog?.Invoke() ?? $"Argument '{paramName}' cannot be null !!!";
|
||||
|
||||
if (overrideException != null)
|
||||
{
|
||||
throw new ArgumentNullException(paramName, fnLog());
|
||||
throw overrideException(message);
|
||||
}
|
||||
|
||||
if (paramName != null)
|
||||
{
|
||||
throw new ArgumentNullException(paramName, $"Argument '{paramName}' cannot be null !!!");
|
||||
}
|
||||
|
||||
throw new ArgumentNullException("Cannot generate null-check error message: both 'fnLog' and 'paramName' are null !!!");
|
||||
throw new ArgumentNullException(paramName, message);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -46,21 +44,19 @@ public static class NullReferenceCheckHelper
|
||||
{
|
||||
public static void throwIfNull( [NotNull] object? argument
|
||||
, Func<string>? fnLog = null
|
||||
, [CallerArgumentExpression(nameof(argument))] string? paramName = null )
|
||||
, [CallerArgumentExpression(nameof(argument))] string? paramName = null
|
||||
, Func<string, Exception>? overrideException = null )
|
||||
{
|
||||
if (argument != null)
|
||||
return;
|
||||
|
||||
if (fnLog != null)
|
||||
string message = fnLog?.Invoke() ?? $"'{paramName}' object cannot be null !!!";
|
||||
|
||||
if (overrideException != null)
|
||||
{
|
||||
throw new NullReferenceException(fnLog());
|
||||
throw overrideException(message);
|
||||
}
|
||||
|
||||
if (paramName != null)
|
||||
{
|
||||
throw new NullReferenceException($"'{paramName}' object cannot be null !!!");
|
||||
}
|
||||
|
||||
throw new NullReferenceException("Cannot generate null-check error message: both 'fnLog' and 'paramName' are null !!!");
|
||||
throw new NullReferenceException(message);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,224 +0,0 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Runtime.CompilerServices;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
|
||||
using NLog;
|
||||
using NLog.Config;
|
||||
using NLog.Fluent;
|
||||
|
||||
|
||||
namespace ServerCore;
|
||||
|
||||
//===========================================================================================
|
||||
// 로그 처리자
|
||||
//
|
||||
// author : kangms
|
||||
//
|
||||
//===========================================================================================
|
||||
|
||||
public static class Log
|
||||
{
|
||||
public static string NLogFileName { get; set; } = "./Config/nlog.config";
|
||||
|
||||
private static string m_process_type = string.Empty;
|
||||
private static string m_ip_port = string.Empty;
|
||||
private static string m_default_logger_name_pattern = string.Empty;
|
||||
|
||||
private static bool m_is_initialized = false;
|
||||
|
||||
private static bool m_is_reconfigure = true;
|
||||
|
||||
public static void initLog( string processType, string defaultLoggerNamePattern = ""
|
||||
, EventHandler<LoggingConfigurationChangedEventArgs>? handler = null )
|
||||
{
|
||||
m_process_type = processType;
|
||||
m_default_logger_name_pattern = defaultLoggerNamePattern;
|
||||
|
||||
if(null != handler)
|
||||
{
|
||||
registerConfigurationChangedHandler(handler);
|
||||
}
|
||||
|
||||
m_is_initialized = true;
|
||||
}
|
||||
|
||||
public static void setIPnPort(string ip, UInt16 port)
|
||||
{
|
||||
m_ip_port = $"{ip}:{port}";
|
||||
}
|
||||
|
||||
public static NLog.Logger getLogger(string loggerName = "")
|
||||
{
|
||||
if (true == m_is_reconfigure)
|
||||
{
|
||||
reconfigureXML(NLogFileName);
|
||||
}
|
||||
|
||||
if (0 == loggerName.Length)
|
||||
{
|
||||
loggerName = m_default_logger_name_pattern;
|
||||
}
|
||||
|
||||
return LogManager.GetLogger(loggerName);
|
||||
}
|
||||
|
||||
private static void registerConfigurationChangedHandler(EventHandler<LoggingConfigurationChangedEventArgs> handler)
|
||||
{
|
||||
LogManager.ConfigurationChanged += handler;
|
||||
}
|
||||
|
||||
private static bool reconfigureXML(string xmlCofigFilePath)
|
||||
{
|
||||
if (true == m_is_reconfigure)
|
||||
{
|
||||
var to_reload_configure = new NLog.Config.XmlLoggingConfiguration(xmlCofigFilePath);
|
||||
if (null == to_reload_configure)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
LogManager.Configuration = to_reload_configure;
|
||||
LogManager.ReconfigExistingLoggers();
|
||||
|
||||
m_is_reconfigure = false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
public static void shutdown()
|
||||
{
|
||||
CloudWatchLog.setClosed();
|
||||
LogManager.Shutdown();
|
||||
}
|
||||
|
||||
public static void sequence(string sender, string message)
|
||||
{
|
||||
NLog.Logger sequence_logger = LogManager.GetLogger("SequenceLogger");
|
||||
|
||||
LogEventInfo logEventInfo = new LogEventInfo(LogLevel.Debug, "SequenceLogger", message);
|
||||
logEventInfo.Properties["sender"] = sender;
|
||||
sequence_logger.Debug(logEventInfo);
|
||||
}
|
||||
|
||||
public static void sequence(string sender, string receiver, string message, string errDesc = "")
|
||||
{
|
||||
NLog.Logger sequence_logger = LogManager.GetLogger("SequenceLogger");
|
||||
|
||||
LogEventInfo logEventInfo = new LogEventInfo(LogLevel.Debug, "SequenceLogger", message);
|
||||
logEventInfo.Properties["sender"] = sender;
|
||||
logEventInfo.Properties["receiver"] = receiver;
|
||||
logEventInfo.Properties["errordesc"] = (errDesc == string.Empty || errDesc.Contains("Success") == true ? $"{errDesc}" : $"ERR-{errDesc}");
|
||||
sequence_logger.Debug(logEventInfo);
|
||||
}
|
||||
|
||||
|
||||
public static string getProcessType() => m_process_type;
|
||||
|
||||
public static string getIpPort() => m_ip_port;
|
||||
|
||||
public static bool isInitialized() => m_is_initialized;
|
||||
}
|
||||
|
||||
//===========================================================================================
|
||||
// 로그 관련 확장 함수
|
||||
//
|
||||
// author : kangms
|
||||
//
|
||||
//===========================================================================================
|
||||
|
||||
public static class NLogExtend
|
||||
{
|
||||
|
||||
public static void trace( this NLog.Logger _this
|
||||
, string message
|
||||
, [CallerMemberName] string memberName = ""
|
||||
, [CallerFilePath] string sourceFilePath = ""
|
||||
, [CallerLineNumber] Int32 sourceLineNumber = 0 )
|
||||
{
|
||||
var logEventInfo = new LogEventInfo(LogLevel.Trace, null, message);
|
||||
logEventInfo.setLogEventProperties( sourceFilePath, sourceLineNumber, memberName
|
||||
, Log.getProcessType(), Log.getIpPort() );
|
||||
|
||||
_this.Trace(logEventInfo);
|
||||
}
|
||||
|
||||
public static void debug( this NLog.Logger _this
|
||||
, string message
|
||||
, [CallerMemberName] string memberName = ""
|
||||
, [CallerFilePath] string sourceFilePath = ""
|
||||
, [CallerLineNumber] Int32 sourceLineNumber = 0 )
|
||||
{
|
||||
var logEventInfo = new LogEventInfo(LogLevel.Debug, null, message);
|
||||
logEventInfo.setLogEventProperties( sourceFilePath, sourceLineNumber, memberName
|
||||
, Log.getProcessType(), Log.getIpPort() );
|
||||
|
||||
_this.Debug(logEventInfo);
|
||||
}
|
||||
|
||||
public static void info( this NLog.Logger _this
|
||||
, string message
|
||||
, [CallerMemberName] string memberName = ""
|
||||
, [CallerFilePath] string sourceFilePath = ""
|
||||
, [CallerLineNumber] Int32 sourceLineNumber = 0 )
|
||||
{
|
||||
var logEventInfo = new LogEventInfo(LogLevel.Info, null, message);
|
||||
logEventInfo.setLogEventProperties( sourceFilePath, sourceLineNumber, memberName
|
||||
, Log.getProcessType(), Log.getIpPort() );
|
||||
|
||||
_this.Info(logEventInfo);
|
||||
}
|
||||
|
||||
public static void warn( this NLog.Logger _this
|
||||
, string message
|
||||
, [CallerMemberName] string memberName = ""
|
||||
, [CallerFilePath] string sourceFilePath = ""
|
||||
, [CallerLineNumber] Int32 sourceLineNumber = 0 )
|
||||
{
|
||||
var logEventInfo = new LogEventInfo(LogLevel.Warn, null, message);
|
||||
logEventInfo.setLogEventProperties( sourceFilePath, sourceLineNumber, memberName
|
||||
, Log.getProcessType(), Log.getIpPort() );
|
||||
|
||||
_this.Warn(logEventInfo);
|
||||
}
|
||||
|
||||
public static void error( this NLog.Logger _this
|
||||
, string message
|
||||
, [CallerMemberName] string memberName = ""
|
||||
, [CallerFilePath] string sourceFilePath = ""
|
||||
, [CallerLineNumber] Int32 sourceLineNumber = 0 )
|
||||
{
|
||||
var logEventInfo = new LogEventInfo(LogLevel.Error, null, message);
|
||||
logEventInfo.setLogEventProperties( sourceFilePath, sourceLineNumber, memberName
|
||||
, Log.getProcessType(), Log.getIpPort() );
|
||||
|
||||
_this.Error(logEventInfo);
|
||||
}
|
||||
|
||||
public static void fatal( this NLog.Logger _this
|
||||
, string message
|
||||
, [CallerMemberName] string memberName = ""
|
||||
, [CallerFilePath] string sourceFilePath = ""
|
||||
, [CallerLineNumber] Int32 sourceLineNumber = 0 )
|
||||
{
|
||||
var logEventInfo = new LogEventInfo(LogLevel.Fatal, null, message);
|
||||
logEventInfo.setLogEventProperties( sourceFilePath, sourceLineNumber, memberName
|
||||
, Log.getProcessType(), Log.getIpPort() );
|
||||
|
||||
_this.Fatal(logEventInfo);
|
||||
}
|
||||
|
||||
private static void setLogEventProperties( this LogEventInfo _this
|
||||
, string sourceFilePath, Int32 sourceLineNumber, string memberName
|
||||
, string processType, string ipPort )
|
||||
{
|
||||
_this.Properties["server"] = processType;
|
||||
_this.Properties["ip/port"] = ipPort;
|
||||
_this.Properties["memberName"] = memberName;
|
||||
_this.Properties["filePath"] = sourceFilePath;
|
||||
_this.Properties["lineNumber"] = sourceLineNumber;
|
||||
}
|
||||
}
|
||||
116
ServerCore/Log/NLog.cs
Normal file
116
ServerCore/Log/NLog.cs
Normal file
@@ -0,0 +1,116 @@
|
||||
using NLog;
|
||||
using NLog.Config;
|
||||
using NLog.Fluent;
|
||||
|
||||
|
||||
namespace ServerCore;
|
||||
|
||||
//===========================================================================================
|
||||
// 로그 처리자
|
||||
//
|
||||
// author : kangms
|
||||
//
|
||||
//===========================================================================================
|
||||
|
||||
public static class Log
|
||||
{
|
||||
public static string NLogFileName { get; set; } = "./Config/nlog.config";
|
||||
|
||||
private static string m_process_type = string.Empty;
|
||||
private static string m_ip_port = string.Empty;
|
||||
private static string m_default_logger_name_pattern = string.Empty;
|
||||
|
||||
private static bool m_is_initialized = false;
|
||||
|
||||
private static bool m_is_reconfigure = true;
|
||||
|
||||
public static void initLog( string processType, string defaultLoggerNamePattern = ""
|
||||
, EventHandler<LoggingConfigurationChangedEventArgs>? handler = null )
|
||||
{
|
||||
m_process_type = processType;
|
||||
m_default_logger_name_pattern = defaultLoggerNamePattern;
|
||||
|
||||
if(null != handler)
|
||||
{
|
||||
registerConfigurationChangedHandler(handler);
|
||||
}
|
||||
|
||||
m_is_initialized = true;
|
||||
}
|
||||
|
||||
public static void setIPnPort(string ip, UInt16 port)
|
||||
{
|
||||
m_ip_port = $"{ip}:{port}";
|
||||
}
|
||||
|
||||
public static NLog.Logger getLogger(string loggerName = "")
|
||||
{
|
||||
if (true == m_is_reconfigure)
|
||||
{
|
||||
reconfigureXML(NLogFileName);
|
||||
}
|
||||
|
||||
if (0 == loggerName.Length)
|
||||
{
|
||||
loggerName = m_default_logger_name_pattern;
|
||||
}
|
||||
|
||||
return LogManager.GetLogger(loggerName);
|
||||
}
|
||||
|
||||
private static void registerConfigurationChangedHandler(EventHandler<LoggingConfigurationChangedEventArgs> handler)
|
||||
{
|
||||
LogManager.ConfigurationChanged += handler;
|
||||
}
|
||||
|
||||
private static bool reconfigureXML(string xmlCofigFilePath)
|
||||
{
|
||||
if (true == m_is_reconfigure)
|
||||
{
|
||||
var to_reload_configure = new NLog.Config.XmlLoggingConfiguration(xmlCofigFilePath);
|
||||
if (null == to_reload_configure)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
LogManager.Configuration = to_reload_configure;
|
||||
LogManager.ReconfigExistingLoggers();
|
||||
|
||||
m_is_reconfigure = false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
public static void shutdown()
|
||||
{
|
||||
CloudWatchLog.setClosed();
|
||||
LogManager.Shutdown();
|
||||
}
|
||||
|
||||
public static void sequence(string sender, string message)
|
||||
{
|
||||
NLog.Logger sequence_logger = LogManager.GetLogger("SequenceLogger");
|
||||
|
||||
LogEventInfo logEventInfo = new LogEventInfo(LogLevel.Debug, "SequenceLogger", message);
|
||||
logEventInfo.Properties["sender"] = sender;
|
||||
sequence_logger.Debug(logEventInfo);
|
||||
}
|
||||
|
||||
public static void sequence(string sender, string receiver, string message, string errDesc = "")
|
||||
{
|
||||
NLog.Logger sequence_logger = LogManager.GetLogger("SequenceLogger");
|
||||
|
||||
LogEventInfo logEventInfo = new LogEventInfo(LogLevel.Debug, "SequenceLogger", message);
|
||||
logEventInfo.Properties["sender"] = sender;
|
||||
logEventInfo.Properties["receiver"] = receiver;
|
||||
logEventInfo.Properties["errordesc"] = (errDesc == string.Empty || errDesc.Contains("Success") == true ? $"{errDesc}" : $"ERR-{errDesc}");
|
||||
sequence_logger.Debug(logEventInfo);
|
||||
}
|
||||
|
||||
|
||||
public static string getProcessType() => m_process_type;
|
||||
|
||||
public static string getIpPort() => m_ip_port;
|
||||
|
||||
public static bool isInitialized() => m_is_initialized;
|
||||
}
|
||||
112
ServerCore/Log/NLogHelper.cs
Normal file
112
ServerCore/Log/NLogHelper.cs
Normal file
@@ -0,0 +1,112 @@
|
||||
using NLog;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Runtime.CompilerServices;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
|
||||
|
||||
namespace ServerCore;
|
||||
|
||||
|
||||
//===========================================================================================
|
||||
// NLog 관련 확장 함수
|
||||
//
|
||||
// author : kangms
|
||||
//
|
||||
//===========================================================================================
|
||||
|
||||
public static class NLogHelper
|
||||
{
|
||||
public static void trace( this NLog.Logger _this
|
||||
, string message
|
||||
, [CallerMemberName] string memberName = ""
|
||||
, [CallerFilePath] string sourceFilePath = ""
|
||||
, [CallerLineNumber] Int32 sourceLineNumber = 0)
|
||||
{
|
||||
var logEventInfo = new LogEventInfo(LogLevel.Trace, null, message);
|
||||
logEventInfo.setLogEventProperties(sourceFilePath, sourceLineNumber, memberName
|
||||
, Log.getProcessType(), Log.getIpPort());
|
||||
|
||||
_this.Trace(logEventInfo);
|
||||
}
|
||||
|
||||
public static void debug( this NLog.Logger _this
|
||||
, string message
|
||||
, [CallerMemberName] string memberName = ""
|
||||
, [CallerFilePath] string sourceFilePath = ""
|
||||
, [CallerLineNumber] Int32 sourceLineNumber = 0)
|
||||
{
|
||||
var logEventInfo = new LogEventInfo(LogLevel.Debug, null, message);
|
||||
logEventInfo.setLogEventProperties(sourceFilePath, sourceLineNumber, memberName
|
||||
, Log.getProcessType(), Log.getIpPort());
|
||||
|
||||
_this.Debug(logEventInfo);
|
||||
}
|
||||
|
||||
public static void info( this NLog.Logger _this
|
||||
, string message
|
||||
, [CallerMemberName] string memberName = ""
|
||||
, [CallerFilePath] string sourceFilePath = ""
|
||||
, [CallerLineNumber] Int32 sourceLineNumber = 0)
|
||||
{
|
||||
var logEventInfo = new LogEventInfo(LogLevel.Info, null, message);
|
||||
logEventInfo.setLogEventProperties(sourceFilePath, sourceLineNumber, memberName
|
||||
, Log.getProcessType(), Log.getIpPort());
|
||||
|
||||
_this.Info(logEventInfo);
|
||||
}
|
||||
|
||||
public static void warn( this NLog.Logger _this
|
||||
, string message
|
||||
, [CallerMemberName] string memberName = ""
|
||||
, [CallerFilePath] string sourceFilePath = ""
|
||||
, [CallerLineNumber] Int32 sourceLineNumber = 0)
|
||||
{
|
||||
var logEventInfo = new LogEventInfo(LogLevel.Warn, null, message);
|
||||
logEventInfo.setLogEventProperties(sourceFilePath, sourceLineNumber, memberName
|
||||
, Log.getProcessType(), Log.getIpPort());
|
||||
|
||||
_this.Warn(logEventInfo);
|
||||
}
|
||||
|
||||
public static void error( this NLog.Logger _this
|
||||
, string message
|
||||
, [CallerMemberName] string memberName = ""
|
||||
, [CallerFilePath] string sourceFilePath = ""
|
||||
, [CallerLineNumber] Int32 sourceLineNumber = 0)
|
||||
{
|
||||
var logEventInfo = new LogEventInfo(LogLevel.Error, null, message);
|
||||
logEventInfo.setLogEventProperties(sourceFilePath, sourceLineNumber, memberName
|
||||
, Log.getProcessType(), Log.getIpPort());
|
||||
|
||||
_this.Error(logEventInfo);
|
||||
}
|
||||
|
||||
public static void fatal( this NLog.Logger _this
|
||||
, string message
|
||||
, [CallerMemberName] string memberName = ""
|
||||
, [CallerFilePath] string sourceFilePath = ""
|
||||
, [CallerLineNumber] Int32 sourceLineNumber = 0)
|
||||
{
|
||||
var logEventInfo = new LogEventInfo(LogLevel.Fatal, null, message);
|
||||
logEventInfo.setLogEventProperties(sourceFilePath, sourceLineNumber, memberName
|
||||
, Log.getProcessType(), Log.getIpPort());
|
||||
|
||||
_this.Fatal(logEventInfo);
|
||||
}
|
||||
|
||||
private static void setLogEventProperties( this LogEventInfo _this
|
||||
, string sourceFilePath, Int32 sourceLineNumber, string memberName
|
||||
, string processType, string ipPort)
|
||||
{
|
||||
_this.Properties["server"] = processType;
|
||||
_this.Properties["ip/port"] = ipPort;
|
||||
_this.Properties["memberName"] = memberName;
|
||||
_this.Properties["filePath"] = sourceFilePath;
|
||||
_this.Properties["lineNumber"] = sourceLineNumber;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -33,16 +33,30 @@
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="AsyncStateMachine" />
|
||||
<PackageReference Include="AutoMapper" />
|
||||
<PackageReference Include="AutoMapper.AspNetCore.OData.EFCore" />
|
||||
<PackageReference Include="AutoMapper.Collection" />
|
||||
<PackageReference Include="AutoMapper.Collection.EntityFrameworkCore" />
|
||||
<PackageReference Include="AutoMapper.Contrib.Autofac.DependencyInjection" />
|
||||
<PackageReference Include="AutoMapper.Data" />
|
||||
<PackageReference Include="AutoMapper.EF6" />
|
||||
<PackageReference Include="AutoMapper.Extensions.EnumMapping" />
|
||||
<PackageReference Include="AutoMapper.Extensions.ExpressionMapping" />
|
||||
<PackageReference Include="AWS.Logger.NLog" />
|
||||
<PackageReference Include="AWSSDK.Core" />
|
||||
<PackageReference Include="AWSSDK.DynamoDBv2" />
|
||||
<PackageReference Include="AWSSDK.OpenSearchService" />
|
||||
<PackageReference Include="AWSSDK.S3" />
|
||||
<PackageReference Include="AWSSDK.SecurityToken" />
|
||||
<PackageReference Include="Axion.ConcurrentHashSet" />
|
||||
<PackageReference Include="BCrypt.Net-Next" />
|
||||
<PackageReference Include="BouncyCastle.Cryptography" />
|
||||
<PackageReference Include="CommandLineParser" />
|
||||
<PackageReference Include="Google.Protobuf" />
|
||||
<PackageReference Include="JWT" />
|
||||
<PackageReference Include="Microsoft.Diagnostics.NETCore.Client" />
|
||||
<PackageReference Include="Microsoft.Extensions.Configuration" />
|
||||
<PackageReference Include="Microsoft.Extensions.Options" />
|
||||
<PackageReference Include="MongoDB.Analyzer" />
|
||||
<PackageReference Include="MongoDB.Bson" />
|
||||
<PackageReference Include="MongoDB.Driver" />
|
||||
|
||||
Reference in New Issue
Block a user