DelphiCon 의 2020 시리즈 중, Real-world CodeSite Logging Techniques Bob Swart 의 한글 요약본입니다.
실전에서 바로 활용할 수 있도록 코드사이트(CodeSite)의 로깅 기술 중 핵심만 뽑아서 설명합니다. (코드사이트 무료 에디션은 델파이의 겟잇 패키지 매니저에서 무료로 받을 수 있습니다.)
- 발표자 (Bob Swart)는 Dr. Bob으로 잘 알려진 델파이 개발자이자 컨설선트입니다.
목차
코드사이트(CodeSite) 개요: Raize사의 로깅 도구
개요
-
에디션
- 코드사이트 익스프레스: 무료, 겟잇패키지매니저에서 다운로드(데모 참조)
- 코드사이트 스튜디오: 유료, www.raize.com에서 구입
-
로그 표현 방식
- 라이브 로깅
- 파일 로깅
-
로그 저장 위치
- 로컬 로그 저장소에 저장
- 원격 로그 저장소로 보내서 저장 (스튜디오 에디션 전용, 앱의 로그를 원격의 로그 저장소로 보내도록 설정 가능)
-
로깅 솔루션 사용 시 장점
- 앱 사용자는 로그에 대해 전혀 신경쓸 필요가 없음 (앱 제공자만 어떤 로그가 얼마나 수집되는 지를 신경쓰면 됨)
- 앱 제공자는분석 도구를 활용해 손쉽게 로그 분석
[데모] 겟잇에서 (무료 에디션인) 코드 사이트 익스프레스 무료 다운로드
- 설치: Delphi > Tools > GetIt Package Manager 선택 > 겟잇 필터에서 ‘Code’라고 입력 > CodeSite Express를 선택하고 [Install] 버튼 클릭 후 기본 설정을 따라 설치
- 확인: 델파이 재시작 후 겟잇에서 Installed로 표시되는 지 확인
CodeSite 도구들
역할별 도구
-
로깅 도구
- CSDispatcher.exe: 앱에서 발생하는 로그를 가져와서 저장하는 도구 (윈도우 서비스로 작동하면 자동으로 시작/종료되므로 편함)
- CSContoller.exe: CSDispatcher를 시작/종료 하거나 설정하는 도구
-
조회 도구
- CSFileViewer.exe: 저장된 로그 파일을 조회하는 도구
- CSLiveViewer.exe: 로그가 전달되면 바로 보여주는 도구 (매우 유용함)
-
기타 도구
- CSDestStringBuilder.exe: 로그 저장소 설정을 선택하면 해당 경로 지정 문자열을 자동으로 생성
- CSFileExporter.exe: 로그 파일을 XML형식으로 내보내기
- CSFileSplitter.exe: 큰 로그 파일을 지정된 파일 크기의 작은 로그 파일들로 쪼개기
- CSMergeFiles.exe: 작은 로그 파일들을 하나로 병합하기
[데모] CodeSite의 각 도구 열어보기
델파이 메인메뉴 > Tools > CodeSite > 각 도구
(예를 들어) Delphi > Tools > CodeSite > CodeSite Method Tracer를 사용하면,
메소드 진입과 메소트 통과를 로깅하도록 하는 코드를 쉽게 추가할 수 있음
[데모] CodeSite 주요 폴더 살펴보기
- 설치 폴더 위치: Program Files (x86)이 디펄트 > Raize > CS5 아래에 이 폴더들이 있다.
- Bin 폴더: 설치된 앱이 있는 곳, CodeSite의 모든 도구들의 실행 파일이 있다.
- Tool 폴더: CS5_Tools.exe가 있다 (보다 자세한 설명 보기)
[데모] CSDispatcher.exe를 윈도우 서비스로 설치하기
- 설치: 명령줄에서 "C:\Program Files (x86)\Raize\CS5\Bin>CSDispatcher.exe / install" 입력하고 엔터 키
- 확인: 메시지 창에 Service installed successfully 라고 표시되는 지 확인
- 작동: 위와 같이 설치하면, 로깅 작업을 수작업으로 시작하거나 종료할 필요가 없다
[데모] CSContoller.exe를 통해 디스패처를 수작업으로 시작/종료하거나 설정하기
- 이미 디스패처가 윈도우 서비스로 설치되어 있는 경우, 먼저 제거부터 하고 콘트롤러를 설치 해야 한다.
- CSContoller.exe에서 마우스 오른쪽 버튼을 클릭하고 관리자 계정으로 실행
[데모] 고객용 샘플앱에 로그 기록 구현하기
오류 당시의 SQL 구문을 쉽게 파악하려면, 해당 SQL구문을 오류 정보와 함께 로깅하도록 코드에 반영하자.
uses CodeSiteLogging; … procedure … begin FDQuery1.Close; FDQuery1.SQL.Text := ‘SELECT * FROM Customers’+ ‘WHERE Country = ‘’’+ cbCountry.Items[cbCountry.ItemIndex] + ‘’’’; try FDQuery1.Open; except on E: Exception do CodeSite.SendException(FDQuery1.SQL.Text, E) end; end;
[데모] 뷰어에서 Method Tracer 사용하여 오류 위치를 쉽게 찾기
- 트레이스를 사용하자 (오류 로그 만으로는 오류 위치를 찾기 어려울 수도 있기 때문이다.)
- 델파이 메인메뉴 > Tools > CodeSite > CodeSite Method Tracer를 선택한다.
-
메소드 추척 창에서 원하는 메소드를 선택하고, Trace Method, $IFDEF 등 설정을 지정하면 선택한 메소드 안에 로깅 코드가 생성된다.
($IFDEF는 DEBUG가 기본 설정이지만, 원한다면 RELEASE 등으로 설정해도 된다.)
디스패처 (CodeSite Dispatcher)
디스패처 배포는 완전 무료이다.
CS5_Tools.exe: 디스패처, 뷰어 등의 도구를 설치할 때 사용한다 (고객의 컴퓨터에 설치할 때 주로 사용)
로컬 로깅 (앱이 작동하는 컴퓨터에 로그를 남김)을 할 경우
-
고객의 컴퓨터에 ‘디스패처’만 설치한다.
- 디스패처가 ‘윈도우 서비스’로 작동하도록 설치하면 편하다. (고객은 로그 작동을 신경쓸 필요가 없다)
- (윈도우 서비스로 작동되도록 설치하는 방법과 데모는 위에 있음)
원격 로깅 (디스패처가 작동하는 원격 컴퓨터에 로그를 남김)을 할 경우
- 고객의 컴퓨터에는 설치할 것이 아무것도 없다 (디스패처 조차도 설치할 필요가 없다).
-
앱에서 코드사이트 로깅 루틴이 실행되면, 해당 로그는 지정 된 IP 주소 (디스패처가 작동하는 원격 컴퓨터의 주소)로 전달된다.
- 로그가 원격으로 전달될 수 있도록 ConnectUsingTCP 옵션을 선택하고, 디스패처가 작동하는 원격 IP주소를 등록 해야 한다.
- 앱에 ISAPI DLL들이 포함되어 배포되며, ISAPI DLL들이 서비스로 작동한다.
- 기본 포트: TCP 3434 또는 UDP 3435 (HTTP도 가능. 하지만, TCP 포트가 허용된다면 굳이 HTTP로 웹서버에 연결할 필요까지는 없다)
[데모] 원격 로깅 설정하기
로그 서버를 별로로 두고, 모든 고객의 로그를 한곳에서 모으고, 각 고객 컴퓨터 별로 분석/관리할 수 있다.
그러면,
- 로그 파악을 위해 따로 고객과 연락할 필요가 없다.
- 고객 컴퓨터에 아무 것도 설치할 필요가 없다.
원격 로깅을 설정하려면, 프로젝트 파일에서 Application.Initialize 아래에 코드 2줄을 추가하면된다.
program… uses CodeSiteLogging, .. begin Application.Initialize; // [원격 로깅 설정] 프로그램 소스의 "Application.Initialize;" 바로 아래에 이 2줄을 추가 CodeSite.Enabled := True; CodeSite.ConnectUsingTcp(192.168.1.19’); //디스패처가 작동하는 로그 서버의 IP 주소 … end.
CodeSite.Send 메소드
메시지 유형
-
색상 지정
- csmYellow, csmGreen, csmOrange, csmBlue, csmRed,…
- 각 색상별로 특정 유형이 지정되도록 하면 (특히 팀 프로젝트에서) 매우 유용하다.
- 예시: 녹색(SQL문장), 노랑(결과), 파랑(SOAP 또는 REST 호출), 주황(XML 또는 JSON), 빨강(200 OK가 아닌 모든 Response) …
-
중요도 지정
- csmInfo, csmWarning, csmError
-
데이터셋으로 지정
- csmDataSet (CodeSiteDBTools 유닛 사용 시)
- 뷰어에서 데이터세트를 표로 볼 수 있다.
- 주의! 너무 큰 데이터세트를 로그로 받지 않도록 하자
장점: 뷰어에서 메시지 유형 별로 손쉽게 파악할 수 있다.
참고: 뷰어에서 메시지 2개를 선택하면 각 로그 간의 시간 차이가 좌측 하단에 표시되므로 수행 시간을 파악하기 좋다.
[데모] CodeSite.Send 메소드의 메시지 유형 활용하기
uses CodeSiteLogging; CodeSiteDBTools; //csmDataSet 사용을 위함 … procedure … begin {$IFDEF DEBUG}CodeSite.TraceMethod(Self, ‘Button1Click’);{$ENDIF} FDQuery1.Close; FDQuery1.SQL.Text := ‘SELECT * FROM Customers’+ ‘WHERE Country = ‘’’+ cbCountry.Items[cbCountry.ItemIndex] + ‘’’’; try // SQL 구문에는 녹색 표시 CodeSite.Send(scmGreen, FDQuery1.SQL.Text); FDQuery1.Open; // 결과 데이터의 갯수에는 노랑색 표시 CodeSite.Send(scmYellow, FDQuery1.RecordCount.ToString + ‘ 개 데이터’); // 결과 데이터세트를 통채로 전달 CodeSite.Send(csmDataSet, ‘Customers’, FDQuery1); except on E: Exception do CodeSite.SendException(FDQuery1.SQL.Text, E) end; end;
[데모] 너무 큰 데이터세트가 로깅되는 것을 방지하도록 코드 작성하기
// [변경전] CodeSite.Send(csmDataSet, ‘Customers’, FDQuery1); // [변경후] If FDQuery1.RecordCount > 5 then CodeSite.SendWarning(‘데이터가 5개를 넘음’) //데이터는 보내지 말고, 대신 메시지 유형을 '경고'로 지정하여 '느낌표'가 표시되게 하자. else CodeSite.Send(csmDataSet, ‘Customers’, FDQuery1);
스크래치패드 (CodeSite ScratchPad)
- 스튜디오 에디션 (유료) 에 있는 기능
- 라이브 뷰어에 지정한 정보가 지정된 주기에 따라 실시간 표시되며 로그 파일로 남지는 않는다.
- 메모리 점유, 사용자 수 등 원하는 모든 문자열 정보를 실시간으로 볼 수 있다.
[데모] CodeSite ScratchPad에서 메모리 사용 (및 누수) 파악하기
스크래치패드 창에서 메모리 사용량을 실시간으로 볼 수 있다.
- 고객의 컴퓨터의 (메모리 등) 자원 사용 현황을 실시간으로 파악할 수 있으므로, 재부팅 등 필요한 결정을 하는데 도움이 된다.
// [메모리 누수가 발생하는 코드] procedure … var S: TStringList; begin S:= TStringList.Create; S.LoadFromFile(‘C:\temp\verybigfile.txt’); // 파일 크기: 16.6MB // Free 하지 않았으므로 한번 실행될 때 마다 16.6MB 메모리 누수가 발생한다. end; // [메모리 사용량을 2초마다 라이브 뷰어에 보내는 코드] // 먼저 Timer 콘트롤을 추가하고 Interval을 2초로 주고 Timer 메소드에 아래 코드를 쓴다. procedure TFrom42.Timer1Timer(Sender: Object); begin CodeSite.Send(csmScratchPad, TimeToStr(now) + ‘ 메모리 사용: ‘ + (CurrentProcessMemory div (1024 * 1024).ToString + ‘ MB’); //CurrentProcessMemory 함수 설명은 생략 end;
CodeSite 로그 목적지 지정
뷰어
- Enabled 여부만 지정하면 됨
로그 파일
- 모든 에디션에 있는 속성: FilePath, FileName, MaxSize, MaxParts
- 스튜디오 에디션에만 있는 속성: LogByDate, LogByDateFormat, Compressed
DestinationStringBuilder: 설정된 내용을 목적지 지정 문자열로 생성
[데모] DestinationString을 직접 작성하기
로그 파일이 클라이언트인 로컬 장비에 저장되는 것이 아니라 원격 로그 서버에 저장되도록 하면 로그 관리가 중앙화되고 더 유용하다.
//프로그램 파일 코드 program… uses CodeSiteLogging, .. var Destination: TCodeSiteDestination; begin Application.Initialize; Destination := TCodeSiteDestination.Create(CodeSite); with Destination.LogFile do begin FilePath := ‘c:\tmp’; //C드라이브의 해당 경로에 로그 파일이 생성 FileName := ‘DelphiCon2020.csl’; SetLogbyDate(True); //일별로 로그 파일이 생성 MaxSize := 2000; MaxParts := 1000; Active := True; end; Destination.Viewer.Active := False; //라이브뷰어는 일단 끈다. CodeSite.Destination := Destination; CodeSite.Enabled := True; //로깅이 작동하도록 켠다 CodeSite.ConnectUsingTcp(192.168.1.19’); //원격 장비로 셋팅되었으므로, 원격의 로그 서버에 있는C드라이브에 로그 파일이 생성됨 CodeSite.Send(‘델파이콘 2020 앱이 로딩됨’); //앱이 로딩되었음을 로그로 남긴다. … end.
참고: 코드사이트 로그 파일을 클릭하면 파일 뷰어가 실행된다. 파일 뷰어는 스크래치패드가 없다는 점만 빼고 라이브 뷰어와 같다.
[데모] 생성된 DestinationStringBuilder 사용하기
DestinationStringBuilder를 통해 생성된 문자열에 원하는 설정을 모두 담을 수 있다. 이렇게 하면 설정 코드를 수작업으로 쓸 필요가 없다.
// [변경 전] 프로그램 파일 코드 with Destination.LogFile do begin FilePath := ‘c:\tmp’; // C드라이브 경로에 로그 파일이 생성 FileName := ‘DelphiCon2020.csl’; SetLogbyDate(True); // 일별로 로그 파일이 생성 MaxSize := 2000; MaxParts := 1000; Active := True; end; // [변경 후] 프로그램 파일 코드 Destination.AsString := ‘[생성된 문자열을 여기에 붙여넣는다]’;
CodeSite에서 Logger 여러개 사용하기
로거를 여러개 사용할 수 있다
- 예: CodeSiteEx를 만들어서 에러와 익셉션인 경우에만 로그를 남기는 역할을 맡긴다 (데모 참조)
각 로거 별로 TCodeSiteDestination을 이용하여 로그 위치를 나눌 수도 있다.
- Errors.csl로 남기거나,
- 라이브뷰어 (예: “알람 설정, 스크래치패드와 함께 사용)에 남기거나, 등
[데모] 하나의 앱에 CodeSite 로거 2개를 사용하기
// [1/2단계] Form 코드에서 "CodeSiteEX"라는 로거를 추가로 만든다. var CodeSiteEx: TCodeSiteLogger; // 폼의 변수로 로거를 선언 … Initialization // 폼의 Initialization 블록을 사용하여 "CodeSiteEx" 라는 로거 등록 CodeSiteEx := TCodeSiteLogger.Create(nil); // (finalization 블록에서) 직접 Free 하기로 한다 CodeSiteEx.Destination := TCodeSiteDestination.Create(CodeSiteEx); // CodeSiteEx 소멸시, 해당 Destination 오브젝트도 소멸 CodeSiteEx.Desination.AsString := ‘…..’; // 이 로거는 Errors.csl 파일에 기록하도록 지정하자. … finalisation CodeSiteEx.Free; end. // [2/2단계] Form 안의 코드 중 try-excpt 구문 안에서 CodeSiteEx가 작동하도록 추가 try … except on E: Exception do begin CodeSiteEx.SendException(FDQuery1.SQL.Text, E); // Error.csl에 별도로 추가 로그를 남기자. CodeSite.SendException(FDQuery1.SQL.Text, E); // 일반 로그 (기존에 있던 구문)도 유지하여 함께 작동시켜도 된다. end; …
CodeSite 로거 활성화를 활용한 실전 팁
-
일반 로깅은 평소에 비활성화 하자. (과도한 로그 수집을 피한다)
- 대신, Error 또는 Exception 만을 로깅하는 CodeSiteEx를 따로 만들고 평소에는 이것만 작동시키자.
-
일반 로깅을 오류가 발견되고 재현이 어려운 상황이 될 때에만 활성화하자.
- 일반 로거는 각 단계가 로깅 (Enter/ExitMethod)될 수 있도록 설정하자.
- 이때, 사용자가 직접 로그 수집을 켜고 끌 수 있도록 메뉴로 추가하자.
- 로그 수집 여부에 따라 화면 배경색을 다르게 하는 등 쉽게 파악되도록 하자.
- 기타 필요한 정보를 메시지도 일반 로거에 담아서 추가하자
[데모] 평소에는 오류 정보만 로깅하다가 꼭 필요할 때에 전체 로깅하기
앱에서 로그 수집을 켜거나 끌 수 있도록 하자. 앱의 메뉴에 ‘로그 수집’이라는 메뉴를 만들고 그 아래에 켜기와 끄기 메뉴를 넣는다.
// 앱에서 로그 "켜기" 메뉴 선택 시 procedure … begin CodeSite.Enabled := True; CodeSite.AddSeparator; // 분리선 추가 CodeSite.Send(‘사용자가 코드사이트 로그를 켬’); end; // 앱에서 로그 "끄기" 메뉴 선택 시 procedure … begin CodeSite.Enabled := False; end; // 프로그램 파일 소스에서 CodeSite.Enabled := False; 로 설정하여 // 평상시에는 일반 로그 수집을 하지 않도록 한다.
윈도우 메시지를 CodeSite의 OnSendMsg로 가로채기와 다루기
스튜디오 에디션(유료)에만 있음
오류 횟수 남기기 등 필요한 모든 조치 가능
TCodeSiteSendMsgEvent = procedure ( Sender: TObject; MsgData: TCodeSiteMsgData; var Handled: Boolean ) of object;
[데모] OnSendMsg로 메시지 가로채기와 다루기
- (이벤트 핸들러를 만들어야 하므로) CodeSiteLogging 유닛은 인터페이스 uses절에 있어야 한다.
- 이벤트 핸들러 프로시저를 만든다.(아래 코드 참조)
- 타이머를 이용하여 스크래치패드에서 모니터리 되도록 한다.(아래 코드 참조)
- FormCreate와 FormDestroy에서 이벤트를 이벤트 핸들러에 연결한다. (아래 코드 참조)
procesure TForm42.CodeSiteSendMsgEvent ( Sender: Object; MsgData: TCodeSiteMsgData; var Handled: Boolean); begin if MsgData.MsgType = csmException then Inc(Exceptions); //Exceptions는 폼 변수이며 Integer 타입 else if MsgData.MsgType = csmError then Inc(Errors); //Errors는 폼 변수이며 Integer 타입 Handled := False; //이벤트가 계속 전달되도록 한다 end; procedure TFrom42.Timer1Timer(Sender: Object); begin CodeSiteEx.Send(csmScratchPad, TimeToStr(now) +…. end; procedure TFrom42.FormCreate(Sender: Object); begin CodeSiteEx.OnSendMsg := Self.CodeSiteSendMsgEvent; end; procedure TFrom42.FormDestroy(Sender: Object); begin CodeSiteEx.OnSendMsg := nil; end;
코드사이트 로깅 테크닉 요약
- CodeSite Dispatcher
- (스튜디오 에디션 전용) 원격 로깅
- 메시지 유형들
- (스튜디오 에디션 전용) ScratchPad
- CodeSite Destination들
- 로거 여러개 사용하기
- 로거 켜기와 끄기
- (스튜디오 에디션 전용) CodeSite OnSendMsg
Recommended Comments
There are no comments to display.