[DelphiCon 요약] 코드사이트 로깅 실전 활용 기법
- 2021-01-20
- Posted by: Narae Kim
- Categories: 기술자료, 메인 노출
- 원본 비디오 시청: https://delphicon.embarcadero.com/talks/real-world-codesite-logging-techniques-1/
- DelphiCon 전체 보기 (현재 무료, 향후 유료 전환 예상): https://delphicon.embarcadero.com/replays/
- 데브기어의 DelphiCon 소개 페이지로 가기: https://devgear.co.kr/archives/3692
코드사이트 로깅 실전 활용 기법 (Real-world CodeSite Logging Techniques) 를 요약했습니다. (이 요약 번역은 원본 비디오와 내용이 일부 다르거나, Q&A등 일부 생략되었을 수 있습니다.)
실전에서 바로 활용할 수 있도록 코드사이트(CodeSite)의 로깅 기술 중 핵심적인 것을 뽑아서 설명합니다.
(코드사이트 무료 에디션은 델파이의 겟잇 패키지 매니저에서 무료로 받을 수 있습니다.)
- 코드사이트(CodeSite) 개요: Raize에서 만든 로깅 도구 개요
- (데모) 겟잇에서 코드 사이트 익스프레스 무료 다운로드
- CodeSite 도구들
- (데모) CodeSite 도구 메뉴 위치
- (데모) CodeSite 폴더 살펴보기
- (데모) CSDispatcher.exe를 윈도우 서비스로 설치하기 (07분07초부터)
- (데모) CSContoller.exe를 통해 디스패처를 수작업으로 시작/종료하거나 설정하기 (07분29초부터)
- (데모) 고객용 샘플앱을 통해 로깅 살펴보기 (08분26초부터)
- (데모) Method Tracer 사용하여 오류 위치를 쉽게 찾기 (11분22초부터)
- 디스패처 (CodeSite Dispatcher)
- (데모) 원격 로깅 설정 (15분46초부터)
- CodeSite.Send 메소드의 메시지 유형
- (데모) CodeSite.Send 메소드의 메시지 유형 활용하기 (19분09초부터)
- (데모) 너무 큰 데이터세트가 로깅되는 것을 방지하기 (22분58초부터)
- 스크래치패드 (CodeSite ScratchPad)
- (데모) CodeSite ScratchPad에서 메모리 누수 파악하기 (24분54초부터)
- CodeSite 로그 목적지 지정
- (데모) DestinationString 직접 작성하기 (29분40초부터)
- (데모) DestinationStringBuilder 사용하기 (34분25초부터)
- CodeSite에서 Logger 여러개 사용하기
- (데모) 하나의 앱에 CodeSite 로거 2개를 사용하기 (38분40초부터)
- CodeSite 로거 활성화를 활용한 실전 팁
- (데모) 평소에는 오류 정보만 로깅하다가 꼭 필요할 때에 전체 로깅하기 (45분05초부터)
- CodeSite의 OnSendMsg로 메시지 가로채기와 다루기
- (데모) OnSendMsg로 메시지 가로채기와 다루기 (49분19초부터)
- 세션에서 소개한 코드사이트 로깅 테크닉 요약
발표자 (Bob Swart)는 Dr. Bob으로 잘 알려진 델파이 개발자이자 컨설턴트입니다.
- Dr. Bob의블로그: drbob42.com
원본 비디오 시청: https://delphicon.embarcadero.com/talks/real-world-codesite-logging-techniques-1/
코드사이트(CodeSite) 개요: Raize의 로깅 도구 개요
- 에디션
- 코드사이트 익스프레스: 무료, 겟잇패키지매니저에서 다운로드
- 코드사이트 스튜디오: 유료, www.raize.com에서 구입
- 로그 표현 방식
- 라이브 로깅
- 파일 로깅
- 로그 저장 위치
- 로컬 로깅
- 원격 로깅 (스튜디오 에디션 Only, 배포한 앱에서 로그를 원격의 로그 저장소로 보내도록 함)
- 로깅 솔루션으로서 제공되는 기능
- 앱 사용자는 어떤 로그가 얼마나 수집되는지를 신경 쓰지 않아도 됨
- 로그 파일 분석 도구 제공됨
(데모) 겟잇에서 (무료 에디션인) 코드 사이트 익스프레스 무료 다운로드
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 폴더 살펴보기
코드사이트 폴더 (기본 위치는 Program Files (x86) > Raize > CS5
- Bin 폴더: 설치된 앱이 있는 곳으로서 CodeSite의 모든 도구들의 실행 파일이 있는 곳
- Tool 폴더: CS5_Tools.exe가 있는 곳
- CS5_Tools.exe를 사용하면, 고객의 컴퓨터에도 디스패처, 뷰어 등의 도구를 설치할 수 있다.
- 내 경우 고객의 컴퓨터에는 로컬 로깅일 경우 대체로 ‘디스패처’만 설치한다. 디스패처는 ‘윈도우 서비스’로 작동하도록 설치하여서 고객이 로그와 관련하여 크게 신경쓰지 않도록 한다. (원격 로깅의 경우에는 고객의 컴퓨터에 디스패처도 설치할 필요가 없다)
(데모) CSDispatcher.exe를 윈도우 서비스로 설치하기 (7분7초부터)
- 명령창 C:\Program Files (x86)\Raize\CS5\Bin 위치에서 CSDispatcher.exe / install 을 입력하고 엔터키를 치면, Service installed successfully 메시지 창이 표시됨
- C:\Program Files (x86)\Raize\CS5\Bin>CSDispatcher.exe / install
- 위와 같이 설치하면, 로그를 수작업으로 시작하거나 종료할 필요가 없음
(데모) CSContoller.exe를 통해 디스패처를 수작업으로 시작/종료하거나 설정하기 (7분29초부터)
- 이미 디스패처가 윈도우 서비스로 설치되었다면 제거한다.
- CSContoller.exe를 관리자 계정으로 실행 (Run as Administrator)
(데모) 고객용 샘플앱을 통해 로깅 살펴보기 (8분26초부터)
아래와 같이 로깅 코드를 넣으면, 코드사이트로 SQL 구문이 오류 정보와 함께 전달되므로, SQL 구문으로 인해 발생된 오류임음을 쉽게 파악할 수 있음
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 |
uses <strong> CodeSiteLogging; </strong> … procedure … begin FDQuery1.Close; FDQuery1.SQL.Text := ‘SELECT * FROM Customers’+ ‘WHERE Country = ‘’’+ cbCountry.Items[cbCountry.ItemIndex] + ‘’’’; <strong> try </strong> FDQuery1.Open; <strong> except on E: Exception do CodeSite.SendException(FDQuery1.SQL.Text, E) end; </strong> end; |
(데모) Method Tracer 사용하여 오류 위치를 쉽게 찾기 (11분22초부터)
- 원하는 메소드를 선택하고 Trace Method, $IFDEF 등을 지정하면 해당 위치에 로깅 코드가 들어간다.
- $IFDEF는 DEBUG가 기본 설정이지만, 원한다면 RELEASE 등을 설정할 수도 있다.
디스패처 (CodeSite Dispatcher)
프로젝트 파일에서 Application.Initialize 아래에 코드 2줄을 추가한다.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 |
program… uses CodeSiteLogging, .. begin Application.Initialize; <strong> CodeSite.Enabled := True; CodeSite.ConnectUsingTcp(192.168.1.19’); </strong> … end. |
그 결과
- 원격의 로그 서버에서 해당 로그를 볼 수 있다.
- 고객 컴퓨터는 코드에서 지정된 대로 로그를 보내기만 하므로 아무것도 설치할 필요가 없다.
- 로그 서버를 별로로 두고, 각 고객의 컴퓨터에서 보내온 로그를 각 컴퓨터 별로 관리하면, 로그 파악을 위해 고객과 연락할 필요가 없다.
CodeSite.Send 메소드의 메시지 유형
- csmYellow, csmGreen, csmOrange, csmBlue, csmRed,…
- 각 색상별로 특정 유형이 지정되도록 하면 (특히 팀 프로젝트에서) 매우 유용하다.
- 예시: 녹색(SQL문장), 노랑(결과), 파랑(SOAP 또는 REST 호출), 주황(XML 또는 JSON), 빨강(200 OK가 아닌 모든 Response) …
- csmInfo, csmWarning, csmError
- csmDataSet (CodeSiteDBTools 유닛 사용 시)
(데모) CodeSite.Send 메소드의 메시지 유형 활용하기 (19분09초부터)
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 |
uses CodeSiteLogging; <strong> CodeSiteDBTools;</strong> //csmDataSet 사용을 위함 … procedure … begin <span class="has-inline-color has-vivid-green-cyan-color"> {$IFDEF DEBUG}CodeSite.TraceMethod(Self, ‘Button1Click’);{$ENDIF} </span> FDQuery1.Close; FDQuery1.SQL.Text := ‘SELECT * FROM Customers’+ ‘WHERE Country = ‘’’+ cbCountry.Items[cbCountry.ItemIndex] + ‘’’’; try // SQL 구문에는 녹색 표시 (그림3) <strong>CodeSite.Send(scmGreen, FDQuery1.SQL.Text); </strong> FDQuery1.Open; // 결과 데이터의 갯수에는 노랑색 표시 (그림3) <strong> CodeSite.Send(scmYellow, FDQuery1.RecordCount.ToString + ‘ 개 데이터’); </strong> // 결과 데이터세트를 통채로 전달 (그림4) <strong> CodeSite.Send(csmDataSet, ‘Customers’, FDQuery1); </strong> except on E: Exception do CodeSite.SendException(FDQuery1.SQL.Text, E) end; end; |
(데모) 너무 큰 데이터세트가 로깅되는 것을 방지하기 (22분58초부터)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 |
// (변경전) <strong>CodeSite.Send(csmDataSet, ‘Customers’, FDQuery1); </strong> // (변경후, 그림5) <strong>If FDQuery1.RecordCount > 5 then CodeSite.SendWarning(‘데이터가 5개를 넘음’) else CodeSite.Send(csmDataSet, ‘Customers’, FDQuery1);</strong> |
스크래치패드 (CodeSite ScratchPad)
- (유료인) 스튜디오 에디션에 있는 기능
- 라이브 뷰어에 지정한 정보가 지정된 주기에 따라 실시간 표시되며 로그 파일로 남지는 않는다.
- 메모리 점유, 사용자 수 등 원하는 모든 문자열 정보를 실시간으로 볼 수 있다.
(데모) CodeSite ScratchPad에서 메모리 누수 파악하기 (24분54초부터)
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 |
<span class="has-inline-color has-black-color">procedure … var S: TStringList; begin S:= TStringList.Create; S.LoadFromFile(‘C:\temp\verybigfile.txt’); </span><span class="has-inline-color has-cyan-bluish-gray-color"> // Free 하지 않았으므로 한번 실행될 때 마다 16.6MB 메모리 누수가 발생한다. </span><span class="has-inline-color has-black-color"> end; </span> // [메모리 누수를 라이브 뷰어에 보내는 코드] // 먼저 Timer 콘트롤을 추가하고 Interval을 2초로 주고 Timer 메소드에 아래 코드를 쓴다. <span class="has-inline-color has-black-color">procedure TFrom42.<strong>Timer1Timer</strong>(Sender: Object); begin <strong> CodeSite.Send(csmScratchPad, TimeToStr(now) + ‘ 메모리 사용: ‘ + (CurrentProcessMemory div (1024 * 1024).ToString + ‘ MB’);</strong> </span><span class="has-inline-color has-cyan-bluish-gray-color">//CurrentProcessMemory 함수 설명은 생략 </span><span class="has-inline-color has-black-color"> end;</span> |
고객의 컴퓨터의 (메모리 등) 자원 현황을 실시간으로 파악하고 재부팅 등 필요한 결정을 할 수 있다.
CodeSite 로그 목적지 지정
- 뷰어
- Enabled 여부만 지정하면 됨
- 로그 파일
- 모든 에디션: FilePath, FileName, MaxSize, MaxParts
- 스튜디오 에디션에만: LogByDate, LogByDateFormat, Compressed
- DestinationStringBuilder: 설정을 하나의 문자열로 생성
(데모) DestinationString 직접 작성하기 (29분40초부터)
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 |
<span class="has-inline-color has-black-color">(프로젝트 파일에서) program… uses CodeSiteLogging, .. var <strong> Destination: TCodeSiteDestination; </strong> begin Application.Initialize; <strong>Destination := TCodeSiteDestination.Create(CodeSite); </strong> with Destination.LogFile do begin <strong>FilePath </strong>:= ‘c:\tmp’; // C드라이브 경로에 로그 파일이 생성 <strong>FileName </strong>:= ‘DelphiCon2020.csl’; <strong>SetLogbyDate(True)</strong>; // 일별로 로그 파일이 생성 <strong>MaxSize </strong>:= 2000; <strong>MaxParts </strong>:= 1000; <strong>Active</strong> := True; end; <strong>Destination.Viewer.Active := False; </strong></span><span class="has-inline-color has-cyan-bluish-gray-color">// 라이브뷰어는 일단 끈다. </span><span class="has-inline-color has-black-color"> <strong>CodeSite.Destination := Destination; </strong> <strong> CodeSite.Enabled := True; </strong> </span><span class="has-inline-color has-cyan-bluish-gray-color">// 로깅은 작동하도록 켠다 </span><span class="has-inline-color has-black-color"> <strong>CodeSite.ConnectUsingTcp(192.168.1.19’);</strong> //원격 장비로 셋팅되었으므로, 원격의 C드라이브에 로그 파일이 생성됨 <strong>CodeSite.Send</strong>(‘델파이콘 2020 앱이 로딩됨’); </span><span class="has-inline-color has-cyan-bluish-gray-color">//앱이 로딩되었음을 로그로 남긴다.</span><span class="has-inline-color has-black-color"> … end.</span> |
- 로그 파일이 클라이언트인 로컬 장비에 저장되는 것이아니라 원격 로그 서버에 저장되도록 하면 로그 관리가 중앙화되고 더 유용하다.
(데모) DestinationStringBuilder 사용하기 (34분25초부터)
DestinationStringBuilder를 통해 생성된 문자열을 넣으면 수작업으로 설정 코드를 넣을 필요가 없다.
HTTP로 연결할 수도 있지만, TCP 포트가 허용된다면 굳이 HTTP로 웹서버에 연결할 필요까지는 없다.
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 |
// (변경 전) with Destination.LogFile do begin FilePath := ‘c:\tmp’; // C드라이브 경로에 로그 파일이 생성 FileName := ‘DelphiCon2020.csl’; SetLogbyDate(True); // 일별로 로그 파일이 생성 MaxSize := 2000; MaxParts := 1000; Active := True; end; // (변경 후) <strong>Destination.AsString</strong> := ‘[생성된 문자열을 여기에 붙여넣는다]’; |
CodeSite에서 Logger 여러개 사용하기
- 여러 로거를 사용할 수 있다.
- 예: CodeSiteEx를 만들어서 에러와 익셉션인 경우에만 로그를 남기는 역할을 맡긴다 (데모 참조)
- 각 로거 별로 TCodeSiteDestination을 이용하여 로그 위치를 분리할 수 있다.
- Errors.csl로 남기거나,
- 라이브뷰어 (예: “알람 설정, 스크래치패드와 함께 사용)에 남기거나, 등
(데모) 하나의 앱에 CodeSite 로거 2개를 사용하기 (38분40초부터)
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 |
// [CodeSiteEX]라는 로거를 폼 변수로 하나 만들고, 이것을 Except 구문 안에서 사용하기 // 1/2 폼 코드에서 <strong>var CodeSiteEx: TCodeSiteLogger;</strong> // 폼의 변수로 로거를 선언 … <strong>Initialization </strong>// 폼의 Initialization 블록을 사용하여 로거 <strong> CodeSiteEx</strong> := TCodeSiteLogger.Create(nil); // (finalization 블록에서) 직접 Free 하기로 한다 <strong> CodeSiteEx.Destination</strong> := TCodeSiteDestination.Create(CodeSiteEx); // CodeSiteEx 소멸시, 해당 Destination 오브젝트도 소멸 CodeSiteEx.Desination.AsString := ‘…..’; // 이때 로그 파일 명은 Errors.csl 로 지정하자. <strong>finalisation </strong> CodeSiteEx.Free; end. // 2/2 try-excpt 구문 안에서 CodeSiteEx가 작동하도록 하자. <strong>try </strong> … <strong>except on E: Exception do </strong> begin <strong> CodeSiteEx.SendException</strong>(FDQuery1.SQL.Text, E); // Error.csl에 따로 또 로그를 남기자. CodeSite.SendException(FDQuery1.SQL.Text, E); // 기존에 있던 구문도 유지하여 함께 작동하도록해도 관계 없다. end; |
CodeSite 로거 활성화를 활용한 실전 팁
- (과도한 로그 수집을 피하기 위해 기본 설정인) 일반 로깅은 비활성화 하자.
- 대신, 오류 또는 익셉션만을 로깅하는 CodeSiteEx를 따로 만들고 평소에는 이것만 작동시키자
- 오류가 발견되고 재현이 어려운 상황이 될 때, 일반 로깅을 활성화하자.
- 각 단계가 로깅 (Enter/ExitMethod)될 수 있도록 일반 로거를 설정하자.
- 이때, 사용자가 직접 로그 수집을 켜고 끌 수 있도록 메뉴로 추가하자.
- 로그 수집 여부에 따라 화면 배경색을 다르게 하는 등 쉽게 파악되도록 하자.
- 기타 필요한 정보를 메시지도 일반 로거에 담아서 추가하자
(데모) 평소에는 오류 정보만 로깅하다가 꼭 필요할 때에 전체 로깅하기 (45분05초부터)
HTTP로 연결할 수도 있지만, TCP 포트가 허용된다면 굳이 HTTP로 웹서버에 연결할 필요까지는 없다.
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 |
// 켜기 메뉴 선택 시 코드 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로 메시지 가로채기와 다루기 (49분19초부터)
- (이벤트 핸들러를 만들어야 하므로) CodeSiteLogging 유닛은 인터페이스 uses절에 있어야 한다.
- 이벤트 핸들러 프로시저를 만든다.(아래 코드 참조)
- 타이머를 이용하여 스크래치패드에서 모니터리 되도록 한다.(아래 코드 참조)
- FormCreate와 FormDestroy에서 이벤트를 이벤트 핸들러에 연결한다. (아래 코드 참조)
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 |
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.<strong>Timer1Timer</strong>(Sender: Object); begin <strong> CodeSiteEx.Send(csmScratchPad, TimeToStr(now) +…. </strong> end; procedure TFrom42.<strong>FormCreate</strong>(Sender: Object); begin <strong> CodeSiteEx.OnSendMsg := Self.CodeSiteSendMsgEvent; </strong> end; procedure TFrom42.<strong>FormDestroy</strong>(Sender: Object); begin <strong> CodeSiteEx.OnSendMsg := nil; </strong> end; |
세션에서 소개한 코드사이트 로깅 테크닉 요약
- CodeSite Dispatcher
- (스튜디오 에디션 전용) 원격 로깅
- 메시지 유형들
- (스튜디오 에디션 전용) ScratchPad
- CodeSite Destination들
- 로거 여러개 사용하기
- 로거 켜기와 끄기
- (스튜디오 에디션 전용) CodeSite OnSendMsg
- 원본 비디오 시청: https://delphicon.embarcadero.com/talks/real-world-codesite-logging-techniques-1/
- DelphiCon 전체 보기 (현재 무료, 향후 유료 전환 예상): https://delphicon.embarcadero.com/replays/
- 데브기어의 DelphiCon 소개 페이지로 가기: https://devgear.co.kr/archives/3692
12.0 12.1 AI AWS C++ c++빌더 chatgpt DelphiCon ios rad서버 RAD스튜디오 UI UIUX UX uxsummit vcl 개발 개발사례 고객사례 기술레터 기술백서 데브옵스 데이터 데이터베이스 델파이 리눅스 마이그레이션 맥 머신러닝 모바일 새버전 샘플 세미나 안드로이드 웹 윈도우 인공지능 인터베이스 출시 커뮤니티에디션 코드 클라우드 파이썬 파이어몽키 현대화