NGMsoftware

NGMsoftware
로그인 회원가입
  • 매뉴얼
  • 학습
  • 매뉴얼

    학습


    C# C# .NET 매크로 프로그램 만들기. (출력창 내용을 로그로 기록하기 with log4net)

    페이지 정보

    본문

    안녕하세요. 엔지엠소프트웨어입니다. 어느정도 개발이 완료(?) 되었기 때문에 디테일한 부분들을 처리해야 할거 같은데요. 에디터로 매크로 프로그램을 개발할 때 가장 중요한 부분이 로그 분석입니다. 엔지엠 매크로 에디터는 기본적으로 하단의 출력창에 로그 및 에러 내용을 표시합니다. 이전 버전에서는 로그 파일 내용이 출력창과 동일해서 로그를 분석하는데 어려움이 많았습니다.

     

    출력창은 로그 내용을 보기 좋게 줄바꿈이 되는데요. 엄청나게 많이 쌓인 로그를 분석하려면 하나의 액션이 한줄에 모두 표시되는게 좋습니다. 일반적으로 서버 프로그램을 만들 때 로그를 한줄로 처리합니다. 그래야 개발자가 울트라에디트나 에디트플러스를 이용해서 트레이스하기가 좋기 때문입니다. 메모장보다 월등히 기능이 좋다보니 대부분 이런 텍스트 편집 도구를 사용합니다. 둘다 유료라서 라이센스가 필요합니다.

     

    우선, 출력창을 제어할 수 있는 메뉴가 필요한데요. 아래와 같이 리본 메뉴에 추가했습니다.

    F2SUpIr.jpeg

     

     

    아이콘을 붙이지 않아서 투박한 느낌이 있지만, 디자인적인 요소는 그렇게 중요한게 아니라서 지금은 이대로 개발에 집중하는게 좋겠네요. 설정 정보를 보관하기 위해서 파일 읽고 쓰기를 만들어야 합니다. config 폴더에 output.cfg 파일을 생성했습니다.

    epyyZp0.jpeg

     

     

    파일과 1:1로 대응되도록 모델을 하나 만들께요. 이 모델은 출력창의 설정 정보와 클라이언트의 출력 정보들을 모두 관리하는 모델입니다.

    namespace Ai.Model.Client
    {
        [Serializable]
        public class OutputModel
        {
            public Color ForeColor { get; set; } = Color.Black;
    
            public Color BackColor { get; set; } = Color.White;
    
            public bool ShowTime { get; set; }
    
            public bool AutoScrollToEndLine { get; set; } = true;
    
            public bool AutoSaveChecked { get; set; }
    
            public string? AutoSaveFolder { get; set; } = Path.Combine(System.Windows.Forms.Application.StartupPath, Ai.Definition.LogDirectory);
    
            public int AutoDeleteLines { get; set; } = 1000;
    
            public bool AutoDeleteChecked { get; set; }
    
            public bool ShowDefault {  get; set; }
    
            public bool ShowMouse { get; set;}
    
            public bool ShowKeyboard { get; set; }
    
            public bool ShowDateTime { get; set; }
    
            public bool ShowCondition { get; set; }
    
            public bool ShowFunction { get; set; }
    
            public bool ShowDebug { get; set; }
    
            public bool ShowWarning { get; set; }
    
            public bool ShowError { get; set; }
    
            public bool Used {  get; set; }
        }
    }

     

    에디터의 출력창(Output Control)에서 매핑할 모델을 동기화해야 합니다.

    internal partial class Output : UserControl

     

    클라이언트에서 모델을 가져올 수 있도록 속성을 만듭니다.

    public Ai.Model.Client.OutputModel Config { get { return _config; } }

     

    출력창에 로그를 기록하는 방법은 이미 만들었기 때문에 파일로 저장하는 로직을 만들면 됩니다. 사실 엔지엠 6에서도 동일하게 적용하려고 했으나, 몇가지 이슈로 인해 log4net을 도입하지 못했습니다. 이번에 새로운 버전에서는 이미 검증된 로그 라이브러리를 사용하는게 좋겠다는 판단입니다. 그래서, log4net을 사용하기로 했습니다. 회사에서 서버 프로그램을 만들 때 log4j를 사용했는데요. 기능이 동일하기 때문에 적용하는데 큰 어려움은 없었습니다.

     

    nuget에서 log4net을 설치 해줍니다.

    adQmwp8.jpeg

     

     

    프로젝트에 log4net.config 파일을 하나 추가하세요. 이 파일을 조작하면 사용자도 원하는데로 로그를 작성할 수 있습니다.

    2E0E1Oy.jpeg

     

     

    log4net.config 파일의 내용은 아래와 같습니다.

    <?xml version="1.0" encoding="utf-8"?>
    <configuration>
    	<log4net>
    		<appender name="RollingFile" type="log4net.Appender.RollingFileAppender">
    			<threshold value="All" />
    			<encoding value="utf-8" />
    			<lockingModel type="log4net.Appender.FileAppender+MinimalLock" />
    			<appendToFile value="false" />
    			<rollingStyle value="Date" />
    			<staticLogFileName value="false" />
    			<preserveLogFileNameExtension value="true" />
    			<maxSizeRollBackups value="100" />
    			<maximumFileSize value="10MB" />
    			<file type="log4net.Util.PatternString" value="logs\\" />
    			<datePattern value="'trace'\\yyyyMMdd\\yyyyMMdd_HH'_trace.log'"/>
    			<layout type="log4net.Layout.PatternLayout">
    				<conversionPattern value="[%date{HH:mm:ss.fff}] [%level] [%thread] [%logger] %message%newline"/>
    			</layout>
    		</appender>
    		<appender name="RollingFileError" type="log4net.Appender.RollingFileAppender">
    			<threshold value="Error" />
    			<encoding value="utf-8" />
    			<lockingModel type="log4net.Appender.FileAppender+MinimalLock" />
    			<appendToFile value="false" />
    			<rollingStyle value="Date" />
    			<staticLogFileName value="false" />
    			<preserveLogFileNameExtension value="true" />
    			<maxSizeRollBackups value="100" />
    			<maximumFileSize value="10MB" />
    			<file type="log4net.Util.PatternString" value="logs\\" />
    			<datePattern value="error\\yyyyMMdd\\yyyyMMdd_HH'_error.log'"/>
    			<layout type="log4net.Layout.PatternLayout">
    				<conversionPattern value="[%date{HH:mm:ss.fff}] [%level] [%thread] [%logger] %message%newline"/>
    			</layout>
    		</appender>
    		<root>
    			<appender-ref ref="RollingFile" />
    			<appender-ref ref="RollingFileError" />
    		</root>
    	</log4net>
    </configuration>

     

    제 경우는 일반적인 trace 용도의 로그와 error만 따로 볼 수 있도록 어펜더를 2개 사용하기로 했습니다. log4net에 대한 자세한 설명은 아래 링크를 참고하세요.

    [ Apache log4net ]

     

    프로젝트 csproj 파일에 아래 아이템 그룹을 추가하세요.

    <ItemGroup>
      <Content Include="log4net.config">
        <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
      </Content>
    </ItemGroup>

     

    log4net.config 파일의 속성을 아래와 같이 설정해줍니다. 나중에 배포할때도 동일하게 출력 디렉토리에 만들어질 수 있도록 해줘야 합니다.

    ZuXDQ6s.jpeg

     

     

    클라이언트의 기본폼을 열어보세요.

    public partial class MainView : KryptonForm, Ai.Interface.IEditor, Ai.Interface.IClient

     

    클래스 아래에 로그 인스턴스를 생성해줍니다.

    private readonly log4net.ILog _log = log4net.LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType);

     

    이제 _log 인스턴스를 통해서 로그를 기록할 수 있습니다. 아래와 같이 테스트를 해볼까요?

    if (Output.ShowDefault)
    {
        Output.InfoWriteLine($"{option.OutputTitle}{System.Environment.NewLine}");
    
        if (Output.IsAutoSave)
            _log.Info($"{option.OutputTitle}{System.Environment.NewLine}");
    }

     

    클라이언트에서 기본 정보를 표시하도록 하고, 자동 저장에도 체크하세요. 그리고, 실행하면 출력창과 로그 폴더의 파일에도 로그를 기록합니다.

    N4aHziK.jpeg

     

     

    로그 폴더로 이동해서 trace 파일을 열어보세요. 동일한 내용이 입력되어 있습니다. 빈 내용이 2개나 추가되었네요. 로그 처리 부분을 다시 확인해봐야겠습니다.

    oV2GBlL.jpeg

     

     

    log4net의 appender는 여러개를 만들 수 있습니다. 이 글에서는 2개를 만들었고, 하나는 All 하나는 Error로 설정했습니다. 엔지엠 매크로의 로그는 Warning, Error 레벨이 존재합니다. log4net은 Fatal까지 있는데요. Fatal은 시스템 에러로 예상하지 못한 문제라서 별도로 처리하는게 좋을거 같네요.

     

    개발자에게 후원하기

    MGtdv7r.png

     

    추천, 구독, 홍보 꼭~ 부탁드립니다.

    여러분의 후원이 빠른 귀농을 가능하게 해줍니다~ 답답한 도시를 벗어나 귀농하고 싶은 개발자~

    감사합니다~

    • 네이버 공유하기
    • 페이스북 공유하기
    • 트위터 공유하기
    • 카카오스토리 공유하기
    추천0 비추천0

    댓글목록

    등록된 댓글이 없습니다.