correlation ID를 사용하여 관련 로그 항목 찾기

Tier: Free, Premium, Ultimate Offering: 자체 관리

GitLab 인스턴스는 대부분의 요청에 대해 고유한 요청 추적 ID(즉 “상관 ID”라고 함)를 기록합니다. GitLab의 각각의 요청은 자체 상관 ID를 받고, 그런 다음 해당 요청에 대한 각 GitLab 구성 요소 로그에 기록됩니다. 이로써 분산 시스템에서의 동작을 추적하기가 더 쉬워집니다. 이 ID 없이는 연관 로그 항목을 매칭하는 것이 어렵거나 불가능할 수 있습니다.

요청의 상관 ID 식별하기

상관 ID는 correlation_id 키에 로그된 구조화된 로그 및 GitLab이 보낸 모든 응답 헤더인 x-request-id 헤더에 기록됩니다. 상관 ID는 두 곳 중 어느 곳에서나 찾을 수 있습니다.

브라우저에서 상관 ID 가져오기

방문 중인 사이트의 네트워크 활동을 모니터링 및 검사하려면 브라우저의 개발자 도구를 사용할 수 있습니다. 인기있는 브라우저의 네트워크 모니터링 설명서에 대한 아래 링크를 참조하세요.

적절한 요청을 찾아 상관 ID를 보려면 다음을 수행합니다.

  1. 네트워크 모니터에서 지속적 로깅을 활성화합니다. GitLab의 일부 작업은 양식을 제출한 후 빠르게 리디렉션되기 때문에 모든 관련 활동을 캡처하는 데 도움이 됩니다.
  2. 찾고 있는 요청을 격리하기 위해 document 요청을 필터링할 수 있습니다.
  3. 원하는 요청을 선택하여 자세한 내용을 확인합니다.
  4. 헤더 섹션으로 이동하여 Response Headers를 찾습니다. 거기에서 해당 요청에 대해 GitLab에서 무작위로 생성한 x-request-id 헤더를 찾을 수 있어야 합니다.

다음 예를 참조하세요.

Firefox의 네트워크 모니터가 요청 ID 헤더를 표시하는 이미지

로그에서 상관 ID 가져오기

올바른 상관 ID를 찾는 또 다른 방법은 로그를 검색하거나 모니터링하여 관심 있는 로그 항목의 correlation_id 값을 찾는 것입니다.

예를 들어 GitLab에서 작업을 재현할 때 어떤 일이 일어나거나 중단되는지 파악하고 싶다면 사용자별로 GitLab 로그를 모니터링하고 관련 요청을 볼 때까지 기다릴 수 있습니다.

curl에서 상관 ID 가져오기

만약 curl을 사용 중이라면 요청 및 응답 헤더 및 기타 디버그 정보를 표시하기 위해 verbose 옵션을 사용할 수 있습니다.

➜  ~ curl --verbose "https://gitlab.example.com/api/v4/projects"
# 다음과 같은 모습인 라인을 찾아보세요
< x-request-id: 4rAMkV3gof4

jq 사용

이 예시는 jq를 사용하여 결과를 필터링하고 주로 관심 있는 값들을 표시합니다.

sudo gitlab-ctl tail gitlab-rails/production_json.log | jq 'select(.username == "bob") | "User: \(.username), \(.method) \(.path), \(.controller)#\(.action), ID: \(.correlation_id)"'
"User: bob, GET /root/linux, ProjectsController#show, ID: U7k7fh6NpW3"
"User: bob, GET /root/linux/commits/master/signatures, Projects::CommitsController#signatures, ID: XPIHpctzEg1"
"User: bob, GET /root/linux/blob/master/README, Projects::BlobController#show, ID: LOt9hgi1TV4"

grep 사용

이 예시는 jq보다는 더 자주 설치된 greptr을 사용합니다.

sudo gitlab-ctl tail gitlab-rails/production_json.log | grep '"username":"bob"' | tr ',' '\n' | egrep 'method|path|correlation_id'
{"method":"GET"
"path":"/root/linux"
"username":"bob"
"correlation_id":"U7k7fh6NpW3"}
{"method":"GET"
"path":"/root/linux/commits/master/signatures"
"username":"bob"
"correlation_id":"XPIHpctzEg1"}
{"method":"GET"
"path":"/root/linux/blob/master/README"
"username":"bob"
"correlation_id":"LOt9hgi1TV4"}

상관 ID로 로그 검색하기

상관 ID를 갖고 있다면 관련 로그 항목을 검색할 수 있습니다. findgrep를 결합하여 찾고자 하는 항목을 찾는 데 충분합니다.

# <gitlab 로그 디렉토리 찾기> -type f -mtime -0 exec grep '<correlation ID>' '{}' '+'
find /var/log/gitlab -type f -mtime 0 -exec grep 'LOt9hgi1TV4' '{}' '+'
/var/log/gitlab/gitlab-workhorse/current:{"correlation_id":"LOt9hgi1TV4","duration_ms":2478,"host":"gitlab.domain.tld","level":"info","method":"GET","msg":"access","proto":"HTTP/1.1","referrer":"https://gitlab.domain.tld/root/linux","remote_addr":"68.0.116.160:0","remote_ip":"[filtered]","status":200,"system":"http","time":"2019-09-17T22:17:19Z","uri":"/root/linux/blob/master/README?format=json\u0026viewer=rich","user_agent":"Mozilla/5.0 (Mac) Gecko Firefox/69.0","written_bytes":1743}
/var/log/gitlab/gitaly/current:{"correlation_id":"LOt9hgi1TV4","grpc.code":"OK","grpc.meta.auth_version":"v2","grpc.meta.client_name":"gitlab-web","grpc.method":"FindCommits","grpc.request.deadline":"2019-09-17T22:17:47Z","grpc.request.fullMethod":"/gitaly.CommitService/FindCommits","grpc.request.glProjectPath":"root/linux","grpc.request.glRepository":"project-1","grpc.request.repoPath":"@hashed/6b/86/6b86b273ff34fce19d6b804eff5a3f5747ada4eaa22f1d49c01e52ddb7875b4b.git","grpc.request.repoStorage":"default","grpc.request.topLevelGroup":"@hashed","grpc.service":"gitaly.CommitService","grpc.start_time":"2019-09-17T22:17:17Z","grpc.time_ms":2319.161,"level":"info","msg":"finished streaming call with code OK","peer.address":"@","span.kind":"server","system":"grpc","time":"2019-09-17T22:17:19Z"}
/var/log/gitlab/gitlab-rails/production_json.log:{"method":"GET","path":"/root/linux/blob/master/README","format":"json","controller":"Projects::BlobController","action":"show","status":200,"duration":2448.77,"view":0.49,"db":21.63,"time":"2019-09-17T22:17:19.800Z","params":[{"key":"viewer","value":"rich"},{"key":"namespace_id","value":"root"},{"key":"project_id","value":"linux"},{"key":"id","value":"master/README"}],"remote_ip":"[filtered]","user_id":2,"username":"bob","ua":"Mozilla/5.0 (Mac) Gecko Firefox/69.0","queue_duration":3.38,"gitaly_calls":1,"gitaly_duration":0.77,"rugged_calls":4,"rugged_duration_ms":28.74,"correlation_id":"LOt9hgi1TV4"}

분산 아키텍처에서 검색

GitLab 인프라에서 수평 확장을 수행했다면 모든 GitLab 노드를 대상으로 검색해야 합니다. Loki, ELK, Splunk 또는 기타 유형의 로그 집계 소프트웨어를 사용할 수 있습니다.

병렬로 서버 상에서 동일한 명령을 실행할 수 있는 Ansible 또는 PSSH(병렬 SSH)와 같은 도구를 사용하거나 고유한 솔루션을 만들 수 있습니다.

성능 바에서 요청 보기

성능 바를 사용하여 SQL 및 Gitaly에 대한 호출과 같은 흥미로운 데이터를 볼 수 있습니다.

데이터를 보려면 요청의 상관 ID가 사용자의 성능 바를 보는 동안 동일한 세션과 일치해야 합니다. API 요청의 경우 인증된 사용자의 세션 쿠키를 사용하여 요청을 수행해야 합니다.

예를 들어, 다음 API 엔드포인트에 대해 실행된 데이터베이스 쿼리를 보려는 경우:

https://gitlab.com/api/v4/groups/2564205/projects?with_security_reports=true&page=1&per_page=1

먼저 개발자 도구 패널을 활성화합니다. 자세한 내용은 브라우저에서 상관 ID 가져오기를 참조하십시오.

개발자 도구를 활성화한 후에 다음과 같이 세션 쿠키를 가져옵니다:

  1. 로그인한 상태로 https://gitlab.com을 방문합니다.
  2. 개발자 도구 패널에서 Fetch/XHR 요청 필터를 선택합니다(이 단계는 Google Chrome 개발자 도구에서 설명되었으며 엄격히 필요한 것은 아니며 올바른 요청을 찾는 데 도움이 됩니다).
  3. 왼쪽에 있는 results?request_id=<some-request-id> 요청을 선택합니다.
  4. 세션 쿠키는 Request Headers 섹션의 Headers 패널 아래에 표시됩니다. 쿠키 값을 마우스 오른쪽 단추로 클릭하고 값 복사를 선택합니다.

요청용 세션 쿠키 가져오기

클립보드에 세션 쿠키 값이 복사되었습니다. 예를 들어:

experimentation_subject_id=<subject-id>; _gitlab_session=<session-id>; event_filter=all; visitor_id=<visitor-id>; perf_bar_enabled=true; sidebar_collapsed=true; diff_view=inline; sast_entry_point_dismissed=true; auto_devops_settings_dismissed=true; cf_clearance=<cf-clearance>; collapsed_gutter=false; frequently_used_emojis=clap,thumbsup,rofl,tada,eyes,bow

세션 쿠키 값으로 curl 요청의 사용자 지정 헤더에 붙여넣어 API 요청을 만듭니다:

$ curl --include "https://gitlab.com/api/v4/groups/2564205/projects?with_security_reports=true&page=1&per_page=1" \
--header 'cookie: experimentation_subject_id=<subject-id>; _gitlab_session=<session-id>; event_filter=all; visitor_id=<visitor-id>; perf_bar_enabled=true; sidebar_collapsed=true; diff_view=inline; sast_entry_point_dismissed=true; auto_devops_settings_dismissed=true; cf_clearance=<cf-clearance>; collapsed_gutter=false; frequently_used_emojis=clap,thumbsup,rofl,tada,eyes,bow'

  date: Tue, 28 Sep 2021 03:55:33 GMT
  content-type: application/json
  ...
  x-request-id: 01FGN8P881GF2E5J91JYA338Y3
  ...
  [
    {
      "id":27497069,
      "description":"Starboard를 기반으로 하는 라이브 K8S 컨테이너에 사용된 이미지에 대한 분석기"
    },
    "container_registry_image_prefix":"registry.gitlab.com/gitlab-org/security-products/analyzers/cluster-image-scanning",
    "..."
  ]

응답에는 API 엔드포인트의 데이터와 x-request-id 헤더에서 반환된 correlation_id 값이 포함되어 있습니다. 이에 대한 설명은 요청의 상관 ID 식별 섹션에 설명되어 있습니다.

그런 다음 이 요청에 대한 데이터베이스 세부 정보를 볼 수 있습니다:

  1. 성능 바request details 필드에 x-request-id 값을 붙여넣고 Enter/Return을 누릅니다. 이 예시에서는 위 응답에서 반환된 x-request-id01FGN8P881GF2E5J91JYA338Y3을 사용합니다.

    요청 ID를 진행률 막대에 붙여넣기

  2. 새로운 요청이 성능 바의 오른쪽에 있는 Request Selector 드롭다운 목록에 추가됩니다. 새로운 요청을 선택하여 API 요청의 메트릭을 볼 수 있습니다:

    드롭다운 메뉴에서 요청 ID 선택

  3. 진행률 막대에서 pg 링크를 선택하여 API 요청에 의해 실행된 데이터베이스 쿼리를 볼 수 있습니다:

    pg 데이터베이스 세부 정보 보기

    데이터베이스 쿼리 대화 상자가 표시됩니다:

    데이터베이스 쿼리 대화 상자