본문 바로가기
WIKI 기술 지식 베이스

로깅

원문 보기 위키 갱신

로깅 (Logging)

CloudNativePG가 로그를 어떻게 출력하는지, 로그 항목 구조와 로그 레벨 설정, 그리고 PGAudit 로그까지 정리해 드릴게요. 로그는 스토리지에 저장하지 않고 표준 출력으로 JSON 형식으로 내보낸다는 점이 핵심이에요.

출처: 문서

본문

CloudNativePG는 보안상의 이유로 로그를 스토리지에 저장하지 않고, PostgreSQL 로그를 포함한 모든 로그를 JSON 형식으로 표준 출력(stdout)에 직접 출력해요. 이런 설계 덕분에 stern 같은 커맨드라인 도구를 비롯한 대부분의 Kubernetes 호환 로그 관리 도구와 매끄럽게 연동돼요.

:::info[Important] 로그의 장기 보관과 관리는 오퍼레이터의 범위 밖이에요. 이는 Kubernetes 인프라 레벨에서 처리해야 해요. 자세한 내용은 Kubernetes 로깅 아키텍처 문서를 참고해 주세요. :::

각 로그 항목에는 다음 필드가 포함돼요:

  • level – 로그 레벨 (예: info, notice).
  • ts – 타임스탬프.
  • logger – 로그 유형 (예: postgres, pg_controldata).
  • msg – 로그 메시지. 메시지가 JSON 형식이면 키워드 record.
  • record – 실제 레코드. logger 유형에 따라 구조가 달라져요.
  • logging_pod – 로그가 생성된 파드의 이름.

:::info 로그 수집 시스템에서 커스텀 필드 이름이 필요하다면, 오퍼레이터 컨트롤러의 log-field-level 및 log-field-timestamp 플래그를 사용해 level과 ts 필드 이름을 바꿀 수 있어요. 이는 cloudnative-pg 오퍼레이터의 Deployment 정의를 편집해 설정할 수 있어요. :::

클러스터 로그 (Cluster Logs)

클러스터 스펙에서 logLevel 옵션을 사용해 인스턴스 파드의 로그 레벨을 설정할 수 있어요. 사용 가능한 로그 레벨은 error, warning, info(기본값), debug, trace예요.

:::info[Important] 현재 로그 레벨은 인스턴스가 시작할 때만 설정할 수 있어요. 클러스터 시작 후 클러스터 스펙에서 로그 레벨을 변경하면 기존 파드에는 적용되지 않고 새 파드에만 적용돼요. :::

오퍼레이터 로그 (Operator Logs)

오퍼레이터 파드가 만드는 로그도 인스턴스 파드와 마찬가지로 로그 레벨을 설정할 수 있어요: error, warning, info(기본값), debug, trace.

오퍼레이터의 로그 레벨은 오퍼레이터의 Deployment 정의를 편집해 --log-level 커맨드라인 인자를 원하는 값으로 설정하면 돼요.

PostgreSQL 로그 (PostgreSQL Logs)

각 PostgreSQL 로그 항목은 logger 키가 postgres로 설정된 JSON 객체예요. 로그 항목의 구조는 다음과 같아요:

{
  "level": "info",
  "ts": 1619781249.7188137,
  "logger": "postgres",
  "msg": "record",
  "record": {
    "log_time": "2021-04-30 11:14:09.718 UTC",
    "user_name": "",
    "database_name": "",
    "process_id": "25",
    "connection_from": "",
    "session_id": "608be681.19",
    "session_line_num": "1",
    "command_tag": "",
    "session_start_time": "2021-04-30 11:14:09 UTC",
    "virtual_transaction_id": "",
    "transaction_id": "0",
    "error_severity": "LOG",
    "sql_state_code": "00000",
    "message": "database system was interrupted; last known up at 2021-04-30 11:14:07 UTC",
    "detail": "",
    "hint": "",
    "internal_query": "",
    "internal_query_pos": "",
    "context": "",
    "query": "",
    "query_pos": "",
    "location": "",
    "application_name": "",
    "backend_type": "startup"
  },
  "logging_pod": "cluster-example-1",
}

:::info 내부적으로 오퍼레이터는 PostgreSQL의 CSV 로그 형식을 사용해요. 자세한 내용은 PostgreSQL CSV 로그 형식 문서를 참고해 주세요. :::

PGAudit 로그 (PGAudit Logs)

CloudNativePG는 PostgreSQL 클러스터에서 PGAudit를 매끄럽고 네이티브하게 지원해요.

PGAudit를 활성화하려면 클러스터 구성의 postgresql 섹션에 필요한 pgaudit 파라미터를 추가하세요.

:::info[Important] PGAudit 라이브러리는 shared_preload_libraries에 추가되어야 해요. CloudNativePG는 PostgreSQL 구성에 pgaudit.* 파라미터가 있는지를 기반으로 이를 자동으로 관리해요. 오퍼레이터는 shared_preload_libraries에서 라이브러리 추가와 제거를 모두 처리해요. :::

또한 오퍼레이터는 클러스터 내 모든 데이터베이스에서 PGAudit 확장의 생성과 제거를 관리해요.

:::info[Important] CloudNativePG는 연결을 수락하는 클러스터 내 모든 데이터베이스에서 CREATE EXTENSION 및 DROP EXTENSION 명령을 실행해요. :::

다음 예시는 PGAudit이 활성화되고 구성된 PostgreSQL Cluster 배포를 보여줘요:

apiVersion: postgresql.cnpg.io/v1
kind: Cluster
metadata:
  name: cluster-example
spec:
  instances: 3

  postgresql:
    parameters:
      "pgaudit.log": "all, -misc"
      "pgaudit.log_catalog": "off"
      "pgaudit.log_parameter": "on"
      "pgaudit.log_relation": "on"

  storage:
    size: 1Gi

PGAudit이 생성한 감사(audit) CSV 로그 항목은 다른 모든 로그와 마찬가지로 파싱되어 JSON 형식으로 표준 출력으로 라우팅돼요:

  • .logger는 pgaudit로 설정돼요.
  • .msg는 record로 설정돼요.
  • .record는 파싱된 전체 레코드를 JSON 객체로 포함해요. 이 구조는 logging_collector 로그와 비슷하지만, PGAudit CSV 메시지를 JSON 객체로 포맷한 .record.audit가 예외적으로 추가돼요.

다음 예시는 샘플 로그 항목을 보여줘요:

{
  "level": "info",
  "ts": 1627394507.8814096,
  "logger": "pgaudit",
  "msg": "record",
  "record": {
    "log_time": "2021-07-27 14:01:47.881 UTC",
    "user_name": "postgres",
    "database_name": "postgres",
    "process_id": "203",
    "connection_from": "[local]",
    "session_id": "610011cb.cb",
    "session_line_num": "1",
    "command_tag": "SELECT",
    "session_start_time": "2021-07-27 14:01:47 UTC",
    "virtual_transaction_id": "3/336",
    "transaction_id": "0",
    "error_severity": "LOG",
    "sql_state_code": "00000",
    "backend_type": "client backend",
    "audit": {
      "audit_type": "SESSION",
      "statement_id": "1",
      "substatement_id": "1",
      "class": "READ",
      "command": "SELECT FOR KEY SHARE",
      "statement": "SELECT pg_current_wal_lsn()",
      "parameter": "<none>"
    }
  },
  "logging_pod": "cluster-example-1",
}

레코드의 각 필드에 대한 자세한 내용은 PGAudit 문서를 참고해 주세요.

기타 로그 (Other Logs)

오퍼레이터와 그 인스턴스가 만드는 모든 로그는 JSON 형식이며, logger 필드가 이를 생성한 프로세스를 나타내요. 가능한 logger 값은 다음과 같아요:

  • barman-cloud-wal-archive: barman-cloud-wal-archive의 로그
  • barman-cloud-wal-restore: barman-cloud-wal-restore의 로그
  • initdb: initdb 실행 로그
  • pg_basebackup: pg_basebackup 실행 로그
  • pg_controldata: pg_controldata 실행 로그
  • pg_ctl: 모든 pg_ctl 하위 명령 실행 로그
  • pg_rewind: pg_rewind 실행 로그
  • pgaudit: PGAudit 확장 로그
  • postgres: postgres 인스턴스 로그 (msg가 record와 구분됨)
  • wal-archive: 인스턴스 매니저의 wal-archive 하위 명령 로그
  • wal-restore: 인스턴스 매니저의 wal-restore 하위 명령 로그
  • instance-manager: PostgreSQL 인스턴스 매니저 로그

postgres가 특정 구조를 따르는 것을 제외하고, 다른 모든 logger 값들은 로그된 메시지가 이스케이프된 msg 필드를 포함해요.