NLog 시작
- Serilog는 사용 못한다고 치고.. NLog를 찾기로함. 여기서 안되면 포기.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33
public class logger_2 { public logger_2() { var target = new NLog.Targets.FileTarget(); target.Name = "file_1"; target.FileName = "D:\\logs\\file_1.txt"; target.Layout = "${date:format=HH\\:MM\\:ss} ${logger} ${message}"; var target_2 = new NLog.Targets.FileTarget(); target_2.Name = "file_2"; target_2.FileName = "D:\\logs\\file_2.txt"; target_2.Layout = "${date:format=HH\\:MM\\:ss} ${logger} ${message}"; var config = new NLog.Config.LoggingConfiguration(); config.AddTarget(target.Name, target); config.AddTarget(target_2.Name, target_2); var rule = new NLog.Config.LoggingRule("*", LogLevel.Info, target); var rule_2 = new NLog.Config.LoggingRule("*", LogLevel.Info, target_2); config.LoggingRules.Add(rule); config.LoggingRules.Add(rule_2); LogManager.Configuration = config; var _logger = LogManager.GetLogger(target.Name); _logger.Info("Logger1 is initialized"); LogManager.Flush(); var _logger_2 = LogManager.GetLogger(target_2.Name); _logger_2.Info("Logger2 is initialized"); } }
- 간단하게 쓰는 방법을 정리해 본건데 Serilog랑 쓰는건 비슷하기도 하고 간단해 보임.
- 근데 확실히 다른점이 보이는데 이 차이 때문에 이거 될것같음 느낌이 좋음
- NLog는 target로 Log를 어떻게, 어디에 쓸지 정의하는데 이게 console, file, db인데 (Serilog도 쌉가능) 보기에 target를 여러개 만들수 있고 그걸 AddTarget해서 쓴다는게 확연히 달라보임.
- 단, config가 global인듯해보임.
- 결론만 말하면 위 방식대로 하면 안됨. 세상에ㅁ재댤;ㅣ좋ㅁㄷㄱ
- 원하는건 file_1.txt랑 file_2.txt가 각각 만들어지고 각각 따로 message를 찍을것 같은데 log내용이 아래같음.
1 2
13:04:31 file_1 Logger1 is initialized 13:04:31 file_2 Logger2 is initialized
file_1, file_2가 만들어지고 위 message가 둘 파일에 같이 찍힘.
- 근데 또 찾은 자료 중에 이렇게 하면 대충 된다고 하는걸 찾았는데1 내가 위에 한 방법에서 특별히 뭐 더 한것같지는 않은데 그냥 아무튼 안됨. 뭘 하던 저렇게 다른 파일을 상성하고 같은로그를 같이씀…
- 근데 나랑 같은 문제로 NLog에 issue남긴걸 봤는데2 3 4 저 세 뭉탱이가 다 관련되어 보임. 정확히 같은 이유로 같은 구조로 만들길 원했고 이슈 닫은걸로보아 해결한것같음…
config 교체??
- 그럼 상황에 따라 내가 쓰고싶은 Config를 AddTarget까지 해서 만들어 놓고 관리한다. -> 내가 쓰고싶은 Log에 맞는 config를 상황에 맞춰 NLog config에 덮어쓰고 Log를 쓴다
- 느낌이 좋음
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72
public class Logger { NLog.Config.LoggingConfiguration config; NLog.Logger logger; string logPath; string logName; //StackTrace st = new StackTrace(); //StackFrame sf = new StackFrame(1, true); string id; public Logger() { this.id = Guid.NewGuid().ToString(); config = new NLog.Config.LoggingConfiguration(); NLog.Targets.FileTarget logfile = new NLog.Targets.FileTarget(); logfile.FileName = "D:\\logs\\file_1.txt"; logfile.Layout = "${longdate} ${level:uppercase=true:truncate=5} \t ${message}"; NLog.Targets.ConsoleTarget logconsole = new NLog.Targets.ConsoleTarget(); logconsole.Layout = "${longdate} ${level:uppercase=true:truncate=5} \t ${message}"; NLog.Targets.DebuggerTarget de = new NLog.Targets.DebuggerTarget(); de.Layout = "${longdate} ${level:uppercase=true:truncate=5} \t ${message}"; NLog.Targets.FileTarget logfile_2 = new NLog.Targets.FileTarget(); logfile_2.FileName = "D:\\logs\\file_2.txt"; logfile_2.Layout = "${longdate} ${level:uppercase=true:truncate=5} \t ${message}"; config.AddRule(LogLevel.Trace, LogLevel.Fatal, logfile); config.AddRule(LogLevel.Trace, LogLevel.Fatal, logfile_2); config.AddRule(LogLevel.Trace, LogLevel.Fatal, de); config.AddTarget(this.id, logfile); // Apply config NLog.LogManager.Configuration = config; logger = NLog.LogManager.GetLogger(this.id); } public Logger(string _path, string _name) { this.id = Guid.NewGuid().ToString(); NLog.Targets.FileTarget logfile = new NLog.Targets.FileTarget(); logfile.FileName = Path.Combine(_path, _name+"_${shortdate}.log"); logfile.Layout = "${longdate} ${level:uppercase=true:truncate=5} \t ${message}"; logfile.Name = this.id; NLog.Targets.ConsoleTarget logconsole = new NLog.Targets.ConsoleTarget(); logconsole.Layout = "${longdate} ${level:uppercase=true:truncate=5} \t ${message}"; config = new NLog.Config.LoggingConfiguration(); config.AddRule(LogLevel.Trace, LogLevel.Fatal, logfile); config.AddTarget(this.id, logfile); // Apply config NLog.LogManager.Configuration = config; logger = NLog.LogManager.GetLogger(this.id); } public void LogFile(string _msg) { StackTrace st = new StackTrace(); LogManager.Configuration = this.config; LogManager.ReconfigExistingLoggers(); (LogManager.GetLogger(this.id)).Trace("[{0}][{1}]\t" + _msg, st.GetFrame(1).GetMethod().ReflectedType.Name, st.GetFrame(1).GetMethod().Name); } public void LogConsole() { } }
- 테스트 하다가 바꾼게 많이서 정확하진 않은데 대충 이런 컨셉인데 위 Logger class를 넣어두는 dictionary가 하나 더 있었을거임 key는 id고 value가 Logger class.
- 무튼 이건 내가 생각하는것처럼 동작함 끝임
- 근데 아니네 매쟏러 ;ㅐㄷㄱㅎ ;ㅐㅣㄹ
- 되는것처럼 보였는데 thread여러개 두고 테스트 해보면 가끔 A.txt에 쓰여져야할 Log가 B.Log에 쓰여짐
- 이 현상은 규칙성도 안보이고 간헐적이라 … 사실 써도 가끔 한두줄이긴해서 써도 될것같았는데(고민 많이함) 전에 쓰던것도 이렇게 넘어가다 프로그램이 뻗었겠지…
Logfactory를 이용한 방법
- 여기까지 내용은 얼마 안되보이고 테스트 내용도 사실 별 어려운 내용은 아님
- 문제는
- 보통 이 문제에 대해 검색해보면 log level에 따른 분류는 많아도 그 외 의도적으로(나처럼) Log를 나누는 자료는 없었음 당장 이거하기위해 찾으면서 딱 한번 직접적으로 질문한거 딱 한번봄
- 안될꺼면 그냥 깔끔하게 안됐다면 포기했을텐데 file나누는건 성공하고 log를 모든파일에 동일하게 쓰거나(file이름만 다르지 내용은 같아짐) file가 안나눠지고 모든 내용이 한곳에 쓰인다거나, 로그가 섞여 쓰여지는등 됫듯말듯 안되니 내가좀 놓치고 있는게 아닌가 싶었음
- 여기까지 찾는데 널널하게 한달정도 삽질한듯.
- 그러다가 우연히 찾은게 하나 더 있는데 이건 어디서 찾았는지 출처가 없어짐………그사람들 복받았음좋겠다. 근데 아마 원래 쓸 수 있는 config랑 관계였나 그런거 찾다가 얻어걸린걸로 기억함…
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25
public void mtd_2() { NLog.Config.LoggingConfiguration conf_1 = new NLog.Config.LoggingConfiguration(); var target_1 = new NLog.Targets.FileTarget("targtet_1"); target_1.FileName = "D:\\log\\1.txt"; target_1.Layout = "${longdate} ${uppercase:${level}} ${message}"; conf_1.AddTarget(target_1); conf_1.AddRule(LogLevel.Info, LogLevel.Fatal, target_1); NLog.LogFactory fac_1 = new LogFactory(conf_1); NLog.Logger log_1 = fac_1.GetLogger("loger_1"); log_1.Info("log 1"); NLog.Config.LoggingConfiguration conf_2 = new NLog.Config.LoggingConfiguration(); var target_2 = new NLog.Targets.FileTarget("targtet_2"); target_2.FileName = "D:\\log\\2.txt"; target_2.Layout = "${longdate} ${uppercase:${level}} ${message}"; conf_2.AddTarget(target_2); conf_2.AddRule(LogLevel.Info, LogLevel.Fatal, target_2); NLog.LogFactory fac_2 = new LogFactory(conf_2); NLog.Logger log_2 = fac_2.GetLogger("loger_2"); log_2.Info("log 2"); }
- 이렇게 쓰는데 이 전처럼 conf를 만들고 target를 등록하는것까지 같은데 이걸 바로 NLog에 넣는게 아니라 LogFactory를 만들어 LogFactory에서 Logger를 받아오는식임 그러니까 이 전위 단계 중 LogFactory가 한단계 더 들어감
- 이거 결과는 1.txt 생성, 2.txt생성 후 각각의 파일에 내용도 따로 쓴다. 내가 찾던거임.
- 여기까지 내가 쓰고자 하는거 기본은 만들어진것같음…
last test
- 그럼 하나더 테스트.
- main
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76
class NLogMain { static void Main(string[] args) { Logger_4 log4 = new Logger_4(@"D:\logs", "log_main"); log4.info("in main, log init"); temp temp = new temp(); temp_2 temp_2 = new temp_2(); Lib lib = new Lib(); } } class temp { Logger_4 log4 = new Logger_4(@"D:\logs", "log_temp1"); public temp() { try { ThreadStart threadStart = new ThreadStart(run); Thread th = new Thread(threadStart); th.Start(); } catch (Exception ex) { } } void run() { while (true) { Thread.Sleep(500); log4.info("temp1 msg"); } } public void throwtest() { try { int i = 0; int ii = 1 / i; } catch (Exception e) { throw; } } } class temp_2 { Logger_4 log4 = new Logger_4(@"D:\logs", "log_temp2"); public temp_2() { ThreadStart threadStart = new ThreadStart(run); Thread th = new Thread(threadStart); th.Start(); } void run() { while (true) { Thread.Sleep(500); log4.info("temp2 msg"); } } }
- lib
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32
public class Lib { Logger_4 log_1 = new Logger_4(@"D:\logs", "lib_1"); Logger_4 log_2 = new Logger_4(@"D:\logs", "lib_2"); Logger_4 log_3 = new Logger_4(@"D:\logs", "log_temp2"); public Lib() { asdf(); ThreadStart threadStart = new ThreadStart(run); Thread th = new Thread(threadStart); th.Start(); } private void asdf() { log_1.info("lib1 msg"); } void run() { while (true) { Thread.Sleep(500); log_1.info("lib1 msg"); log_2.info("lib2 msg"); log_3.info("lib3 msg"); //break; } } }
- logger lib
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26
public class Logger_4 { private NLog.Logger logger; public Logger_4(string _path, string _name) { NLog.Config.LoggingConfiguration conf = new NLog.Config.LoggingConfiguration(); NLog.Targets.FileTarget target = new NLog.Targets.FileTarget(_name); target.FileName = Path.Combine(_path, _name + "_${shortdate}.log"); target.Layout = "${longdate} ${uppercase:${level}} ${message}"; conf.AddTarget(target); conf.AddRule(LogLevel.Trace, LogLevel.Fatal, target); NLog.LogFactory logfac = new LogFactory(conf); this.logger = logfac.GetLogger(_name); } public void info(string _msg) { this.logger.Info(_msg); } }
- 설명
- main은 lib, temp1, temp2를 참조함.
- main, lib, temp1, temp2 는 loglib를 참조함.
- main은 main용 로그, temp1,2는 각각 로그를 남기고 lib는 lib1, lib2, lib3 log를 각각 남기는데 lib3은 temp2와 같은곳에 남긴다.
- 이지랄 떠는게 이렇게까진 쓸것같진 않은데 이렇게 비슷하게 쓰긴 했었음
- 결과는 잘 됨. config만 갈아끼우며 사용하는식처럼 log가 섞이지도 않음 .
- 드디어 이걸로 기본 준비는 다 끝난듯하다.
- main
Comments powered by Disqus.