상관 ID로 관련 로그 항목 찾기


Tier: Free, Premium, Ultimate
Offering: Self-Managed

GitLab 인스턴스는 대부분의 요청에 대한 고유한 요청 추적 ID(상관 ID로 알려짐)를 기록합니다. GitLab에서 각각의 개별 요청마다 상관 ID가 생성되며, 그런 다음 해당 요청의 각 GitLab 구성 요소 로그에 기록됩니다. 이렇게 함으로써 분산 시스템에서의 동작을 추적하기가 더 쉬워집니다. 이 ID가 없으면 해당하는 로그 항목을 찾는 것이 어려울 수 있거나 불가능할 수 있습니다.

요청의 상관 ID 식별

상관 ID는 correlation_id 키가 있는 구조화된 로그 및 GitLab이 응답해주는 모든 헤더 x-request-id에 기록됩니다. 원하는 곳에서 상관 ID를 찾을 수 있습니다.

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

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

관련 요청을 찾고 해당 상관 ID를 보려면:

  1. 네트워크 모니터링에서 지속적인 로깅을 활성화합니다. GitLab의 일부 작업은 양식을 제출한 후 신속하게 리디렉션되므로, 이는 모든 관련 활동을 기록하는 데 도움이 됩니다.
  2. 찾고 있는 요청을 격리하는 데 도움이 되도록 document 요청을 필터링할 수 있습니다.
  3. 추가 세부 정보를 보려면 흥미로운 요청을 선택합니다.
  4. 헤더 섹션으로 이동하고 응답 헤더를 찾습니다. 거기에는 GitLab에서 해당 요청을 위해 임의로 생성한 x-request-id 헤더가 있어야 합니다.

다음 예제를 참조하세요:

Firefox Network Monitor showing a request ID header

로그에서 상관 ID 가져오기

올바른 상관 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를 결합하면 찾고자 하는 항목을 찾는 데 충분합니다.

# find <gitlab log directory> -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. 세션 쿠키는 요청 헤더 섹션의 헤더 패널 아래에 표시됩니다. 쿠키 값에 마우스 오른쪽 버튼을 클릭한 다음 값 복사를 선택합니다.

요청을 위한 세션 쿠키 얻기

세션 쿠키의 값을 클립보드에 복사했습니다. 예:

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

세션 쿠키 값을 사용하여 다음과 같이 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'

  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. 성능 막대요청 세부 정보 필드에 x-request-id 값을 붙여넣은 후 Enter/Return 키를 누릅니다. 이 예시에서는 위의 응답에서 반환된 x-request-id 값을 01FGN8P881GF2E5J91JYA338Y3로 사용합니다:

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

  2. 새 요청이 성능 막대의 오른쪽에 있는 요청 선택기 드롭다운 목록에 삽입됩니다. API 요청의 메트릭을 보려면 새 요청을 선택하세요:

    요청 선택기에서 요청 ID 선택

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

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

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

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