본문 바로가기

데이터 엑세스

[FireDAC Skill Sprints] 2. FireDAC으로 DBMS 사용 내역 추적, 모니터링 하기

엠바카데로에서 FireDAC Skill Sprint 웨비나(1월 23일 ~ 3월 27일: 매주 금요일 10시)를 진행하고 있습니다.


이 글에서는 웨비나 다시보기와 함께 웨비나 일부 내용을 샘플코드와 함께 소개합니다. 하단 온라인 기술 도움말 링크를 통해 더 자세한 내용을 추가학습하시기 바랍니다.


2회차에서는 FireDAC의 추적과 모니터링에 대한 내용으로 진행합니다.

FireDAC 추적과 모니터링

FireDAC의 추적기능을 이용하면 애플리케이션과 데이터베이스 사이의 통신내용을 상세하게 보거나 기록할 수 있습니다. 

이 추적 정보에는 이벤트 발생시간, API 호출내역, DB로 전송된 SQL, 파라메터와 필드 값, 오류와 경고 등이 기록되어 여러분의 DB 애플리케이션으 문제점을 디버깅하고 해결하는데 유용하게 사용할 수 있습니다.

(주의 : 추적과 모니터링 기능은 애플리케이션의 성능에 영향을 줄 수 있습니다. 디버그 모드에서만 추적기능이 동작하도록 구성하기 바랍니다.)


추적 모니터링 컴포넌트

FireDAC에서는 추적 모니터링 기능을 아래 3종류의 컴포넌트로 제공합니다.

  • TFDMoniFlatFileClientLink : 추적 결과를 텍스트 파일로 기록합니다. 애플리케이션이 완료되면 생성된 추적기록 파일 목록이 표시됩니다.
  • TFDMoniRemoteClientLink : 추적 결과를 FDMonitor 유틸리티에 출력(원격지 가능)합니다.(추적 시작 전에 FDMonitor를 미리 실행해야 추적이 기록됩니다.)
  • TFDMoniCustomClientLik : 추적 결과를 커스텀 이벤트핸들러를 통해 출력합니다. 애플리케이션에서는 OnOut 이벤트를 이용해 직접 추적 결과를 기록해야 합니다.
추적 모니터링 컴포넌트는 아래와 같이 사용합니다.
  1. 추적 모니터링 컴포넌트(TFDMoniXXXXClientLink)를 폼(또는 데이터모듈)에 추가합니다.
  2. 추가한 컴포넌트의 Tracing 속성을 True로 설정(기록을 위한 속성 추가설정)
  3. 연결 컴포넌트(TFDConnection)의 연결속성에서 MonitorBy 항목을 선택(FlatFile, Remote, Custom) 합니다.

추적 항목 선택

추적 항목은 추적 모니터링 컴포넌트의 EventKinds 속성을 통해 선택할 수 있습니다. 각 항목은 아래와 같습니다.(참고 : Debugging and Reporting Environment Questions (FireDAC))

  • LiveCycle : 객체의 생성 / 소멸. 예를 들어, IFDPhysConnection가 생성됩니다. 
  • Error : DBMS 오류 
  • ConnConnect : 연결 열기 및 닫기 
  • ConnTransact : 시작 / 커밋 / 롤백 
  • ConnService : 특별 이벤트 
  • CmdPrepare : IFDPhysCommand.Prepare 호출 
  • CmdExecute : IFDPhysCommand.Execute 또는 Open 호출 
  • CmdDataIn : 명령 매개 변수 값 
  • CmdDataOut : 결과 집합 행 
  • AdaptUpdat :​​ 업데이트 후 처리 모든 정보 
  • Vendor : 낮은 수준 DBMS API 호출 
  • Component : 고레벨 이벤트

추적과 모니터링에 대해 더 자세한 내용은 FireDAC 기술문서 - Tracing and Monitoring(FireDAC)을 참고하기 바랍니다.

메타데이터와 DBMS 연결정보

FireDAC은 데이터베이스의 메타데이터를 조회할 수 있습니다.


메타데이터 쿼리 - TFDConnection 사용

다음과 같이 데이터베이스 오브젝트 이름 목록을 손쉽게 조회할 수 있는 메소드를 제공합니다.

  • GetCatalogNames - 카탈로그 목록 
  • GetSchemaNames - 스키마 목록 
  • GetTableNames - 테이블 및 뷰 목록 
  • GetFieldNames - 테이블 필드 목록 
  • GetKeyFieldNames - 테이블 기본 키 목록 
  • GetGeneratorNames - 발전기 / 시퀀스 목록 
  • GetPackageNames - 패키지 목록 
  • GetStoredProcNames - 저장 프로 시저 목록

사용 예제는 아래와 같습니다.(Memo1에 테이블명 목록을 출력)

FDConnection1.GetTableNames('Northwind', 'dbo', '', Memo1.Lines);

메타데이터 쿼리 - TFDMetaInfoQuery 사용

TFDMetaInfoQuery 컴포넌트는 메타데이터를 조회할 수 있는 데이터셋 컴포넌트입니다.

연결 설정 후 MetaInfoKind 속성만 연결하면 데이터셋을 열수 있습니다.(추가 옵션으로 CatalogName, SchemaName, BaseObjectName, ObjectName 속성을 설정합니다.)

추적과 모니터링, 메타데이터 샘플 프로그램 소개

이 샘플 프로그램에서는 아래 기능을 확인합니다.

  • 추적 & 모니터링 기능을 확인합니다.

  • DBMS 연결정보를 메모에 출력합니다.

  • 메타데이터

    • 테이블 목록, 필드목록, 제너레이터 목록, 스토어드프로시저 목록 조회

    • TFDConnection의 메소드와 TFDMetaInfoQuery를 이용합니다.

[샘플코드 받기 - 데브기어 github 페이지]


추적과 모니터링 기능

  • 폼(또는 데이터 모듈)에 추적 모니터링 컴포넌트 추가
  • FDConnection1의 연결속성 중 MonitorBy 항목을 추가한 추적 모니터링 컴포넌트 종류(Remote, FlatFile, Custom)로 선택
  • 테스트 주의사항
    • 원격 모니터링(Remote)- 애플리케이션 실행 전 FDMonitor 유틸리티(Tools > FireDAC Monitor)를 먼저 실행할 것
    • 파일 모니터링(FlatFile) - 애플리케이션 종료 후 실행파일과 같은 경로의 Trace.txt 파일에 로그가 기록됨
procedure TForm2.Button1Click(Sender: TObject);
begin
  // 원격 모니터링
  DM.FDMoniRemoteClientLink1.Tracing := False;
  DM.FDConnection1.Params.MonitorBy := TFDMonitorBy.mbRemote;
  DM.FDMoniRemoteClientLink1.Tracing := True;

  DM.FDTable1.Close;
  DM.FDTable1.Open;
end;

procedure TForm2.Button2Click(Sender: TObject);
begin
  // 파일 모니터링
  DM.FDMoniFlatFileClientLink1.Tracing := False;
  DM.FDConnection1.Params.MonitorBy := TFDMonitorBy.mbFlatFile;
  DM.FDMoniFlatFileClientLink1.FileName := TPath.Combine(TPath.GetLibraryPath, 'trace.txt');
  DM.FDMoniFlatFileClientLink1.Tracing := True;

  DM.FDTable1.Close;
  DM.FDTable1.Open;
end;

연결 정보 레포팅
DBMS 연결에 관한 정보를 레포팅합니다. 접속정보, FireDAC 정보, 클라이언트 모듈 정보, 세션 정보를 확인할 수 있습니다.
DM.FDConnection1.GetInfoReport(Memo1.Lines);

FireDAC 메타데이터 제공
연결된 DBMS의 테이블 목록, 테이블의 필드목록, 제너레이터목록, 스토어드프로시저 목록을 화면에 출력합니다.
// TFDConnection 메타데이터 메소드 이용
procedure TForm2.Button4Click(Sender: TObject);
var
  MetaType: string;
begin
  MetaType := (Sender as TButton).Caption;
  if MetaType = 'GetTableNames' then
    DM.FDConnection1.GetTableNames('', '', '', Memo2.Lines)
  else if MetaType = 'GetFieldNames' then
    DM.FDConnection1.GetFieldNames('', '', 'EMPLOYEE', '', Memo2.Lines)
  else if MetaType = 'GetGeneratorNames' then
    DM.FDConnection1.GetGeneratorNames('', '', '', Memo2.Lines)
  else if MetaType = 'GetStoredProcName' then
    DM.FDConnection1.GetStoredProcNames('', '', '', '', Memo2.Lines)
  ;
end;

// TFDMetaInfoQuery 컴포넌트 이용
procedure TForm2.Button5Click(Sender: TObject);
var
  MetaType: string;
begin
  DM.FDMetaInfoQuery1.Close;

  MetaType := (Sender as TButton).Caption;
  if MetaType = 'GetTableNames' then
    DM.FDMetaInfoQuery1.MetaInfoKind := TFDPhysMetaInfoKind.mkTables
  else if MetaType = 'GetFieldNames' then
  begin
    DM.FDMetaInfoQuery1.MetaInfoKind := TFDPhysMetaInfoKind.mkTableFields;
    DM.FDMetaInfoQuery1.ObjectName := 'EMPLOYEE';
  end
  else if MetaType = 'GetGeneratorNames' then
    DM.FDMetaInfoQuery1.MetaInfoKind := TFDPhysMetaInfoKind.mkGenerators
  else if MetaType = 'GetStoredProcName' then
    DM.FDMetaInfoQuery1.MetaInfoKind := TFDPhysMetaInfoKind.mkProcs
  ;

  DM.FDMetaInfoQuery1.Open;
end;

관련링크