InfoGrab Docs

`jq`로 GitLab 로그 파싱

요약

가능한 경우 Kibana 및 Splunk와 같은 로그 집계 및 검색 도구를 사용하는 것이 좋습니다. 특히 오류 이벤트 요약 및 기본 사용 통계를 위해 GitLab 지원 팀은 특화된 fast-stats 도구를 제공합니다.

가능한 경우 Kibana 및 Splunk와 같은 로그 집계 및 검색 도구를 사용하는 것이 좋습니다. 그러나 사용할 수 없는 경우에도 jq를 사용하여 JSON 형식의 GitLab 로그를 빠르게 파싱할 수 있습니다.

Note

특히 오류 이벤트 요약 및 기본 사용 통계를 위해 GitLab 지원 팀은 특화된 fast-stats 도구를 제공합니다. 이 도구는 일반적으로 jq보다 훨씬 빠르게 더 큰 로그를 처리하고 더 많은 통계 정보를 출력합니다.

JQ란?#

매뉴얼에 명시된 바와 같이 jq는 명령줄 JSON 프로세서입니다. 다음 예시에는 GitLab 로그 파일 파싱을 위한 사용 사례가 포함되어 있습니다.

로그 파싱#

아래 나열된 예시는 각각의 Linux 패키지 설치 경로 및 기본 파일명으로 해당 로그 파일을 참조합니다. 각 전체 경로는 GitLab 로그 섹션에서 찾을 수 있습니다.

압축된 로그#

로그 파일이 교체되면 Unix 타임스탬프 형식으로 이름이 변경되고 gzip으로 압축됩니다. 결과 파일 이름은 @40000000624492fa18da6f34.s처럼 보입니다. 이 파일들은 최근 로그 파일들과 다르게 처리해야 합니다:

  • 파일의 압축을 해제하려면 gunzip -S .s @40000000624492fa18da6f34.s를 사용하여 파일명을 압축된 로그 파일의 이름으로 바꿉니다.
  • 파일을 직접 읽거나 파이프하려면 zcat 또는 zless를 사용합니다.
  • 파일 내용을 검색하려면 zgrep을 사용합니다.

일반 명령#

색상화된 jq 출력을 less로 파이프#

jq .  -C | less -R

용어 검색 및 일치하는 모든 줄 예쁘게 출력#

grep   | jq .

JSON의 잘못된 줄 건너뛰기#

jq -cR 'fromjson?' file.json | jq 

기본적으로 jq는 유효한 JSON이 아닌 줄을 만나면 오류가 발생합니다. 이는 모든 잘못된 줄을 건너뛰고 나머지를 파싱합니다.

JSON 로그의 시간 범위 출력#

cat log.json | (head -1; tail -1) | jq '.time'

파일이 교체되고 압축된 경우 zcat을 사용합니다:

zcat @400000006026b71d1a7af804.s | (head -1; tail -1) | jq '.time'

zcat some_json.log.25.gz | (head -1; tail -1) | jq '.time'

여러 JSON 로그에서 상관 관계 ID에 대한 활동을 시간 순서로 가져오기#

grep -hR <correlationID> | jq -c -R 'fromjson?' | jq -C -s 'sort_by(.time)'  | less -R

gitlab-rails/production_json.loggitlab-rails/api_json.log 파싱#

5XX 상태 코드가 있는 모든 요청 찾기#

jq 'select(.status >= 500)' 

가장 느린 요청 상위 10개#

jq -s 'sort_by(-.duration_s) | limit(10; .[])' 

프로젝트 관련 모든 요청 찾기 및 예쁘게 출력#

grep   | jq .

총 기간이 5초 초과인 모든 요청 찾기#

jq 'select(.duration_s > 5000)' 

Gitaly 호출이 5번 이상인 모든 프로젝트 요청 찾기#

grep   | jq 'select(.gitaly_calls > 5)'

Gitaly 기간이 10초 초과인 모든 요청 찾기#

jq 'select(.gitaly_duration_s > 10000)' 

대기 기간이 10초 초과인 모든 요청 찾기#

jq 'select(.queue_duration_s > 10000)' 

Gitaly 호출 수 기준 상위 10개 요청#

jq -s 'map(select(.gitaly_calls != null)) | sort_by(-.gitaly_calls) | limit(10; .[])' 

특정 시간 범위 출력#

jq 'select(.time >= "2023-01-10T00:00:00Z" and .time <= "2023-01-10T12:00:00Z")' 

gitlab-rails/production_json.log 파싱#

요청 볼륨 기준 상위 3개 컨트롤러 메서드 및 가장 긴 기간 3개 출력#

jq -s -r 'group_by(.controller+.action) | sort_by(-length) | limit(3; .[]) | sort_by(-.duration_s) | "CT: \(length)\tMETHOD: \(.[0].controller)#\(.[0].action)\tDURS: \(.[0].duration_s),  \(.[1].duration_s),  \(.[2].duration_s)"' production_json.log

출력 예시

CT: 2721   METHOD: SessionsController#new  DURS: 844.06,  713.81,  704.66
CT: 2435   METHOD: MetricsController#index DURS: 299.29,  284.01,  158.57
CT: 1328   METHOD: Projects::NotesController#index DURS: 403.99,  386.29,  384.39

대안으로 fast-stats를 사용합니다:

fast-stats --verbose --limit=3 production_json.log

gitlab-rails/api_json.log 파싱#

요청 수와 가장 긴 기간 3개가 있는 상위 3개 라우트 출력#

jq -s -r 'group_by(.route) | sort_by(-length) | limit(3; .[]) | sort_by(-.duration_s) | "CT: \(length)\tROUTE: \(.[0].route)\tDURS: \(.[0].duration_s),  \(.[1].duration_s),  \(.[2].duration_s)"' api_json.log

출력 예시

CT: 2472 ROUTE: /api/:version/internal/allowed   DURS: 56402.65,  38411.43,  19500.41
CT: 297  ROUTE: /api/:version/projects/:id/repository/tags       DURS: 731.39,  685.57,  480.86
CT: 190  ROUTE: /api/:version/projects/:id/repository/commits    DURS: 1079.02,  979.68,  958.21

대안으로 fast-stats를 사용합니다:

fast-stats --verbose --limit=3 api_json.log

상위 API 사용자 에이전트 출력#

jq --raw-output '
  select(.remote_ip != "127.0.0.1") | [
    (.time | split(".")[0] | strptime("%Y-%m-%dT%H:%M:%S") | strftime("…%m-%dT%H…")),
    ."meta.caller_id", .username, .ua
  ] | @tsv' api_json.log | sort | uniq -c \
  | grep --invert-match --extended-regexp '^\s+\d{1,3}\b'

출력 예시:

 1234 …01-12T01…  GET /api/:version/projects/:id/pipelines  some_user  # 브라우저 세부 정보 포함; 정상
54321 …01-12T01…  POST /api/:version/projects/:id/repository/files/:file_path/raw  some_bot
 5678 …01-12T01…  PATCH /api/:version/jobs/:id/trace gitlab-runner     # 버전 세부 정보 포함; 정상

이 예시는 커스텀 도구 또는 스크립트가 예상치 못하게 높은 요청 빈도 (>15 RPS)를 유발하는 것을 보여줍니다. 이 상황의 사용자 에이전트는 특화된 타사 클라이언트이거나 curl과 같은 일반 도구일 수 있습니다.

시간별 집계는 다음에 도움이 됩니다:

jq와 함께 fast-stats top을 사용하여 해당 사용자 및 봇의 성능 영향을 검토합니다:

fast-stats top --display=percentage --sort-by=cpu-s api_json.log

높은 요청 빈도 자체가 자동으로 문제가 되는 것은 아니지만 리소스의 많은 비율을 사용하는 것은 문제입니다.

gitlab-rails/importer.log 파싱#

프로젝트 임포트 또는 마이그레이션 문제 해결을 위해 다음 명령을 실행합니다:

jq 'select(.project_path == "<namespace>/<project>").error_messages' importer.log

일반적인 문제는 문제 해결을 참조하세요.

gitlab-workhorse/current 파싱#

상위 Workhorse 사용자 에이전트 출력#

jq --raw-output '
  select(.remote_ip != "127.0.0.1") | [
    (.time | split(".")[0] | strptime("%Y-%m-%dT%H:%M:%S") | strftime("…%m-%dT%H…")),
    .remote_ip, .uri, .user_agent
  ] | @tsv' current |
  sort | uniq -c

API ua 예시와 유사하게 이 출력에서 예상치 못한 사용자 에이전트가 많으면 최적화되지 않은 스크립트를 나타냅니다. 예상되는 사용자 에이전트에는 gitlab-runner, GitLab-Shell 및 브라우저가 포함됩니다.

예를 들어 check_interval 설정을 늘려 러너가 새 작업을 확인하는 성능 영향을 줄일 수 있습니다.

gitlab-rails/geo.log 파싱#

가장 일반적인 Geo 동기화 오류 찾기#

gitlab:geo:status Rake 태스크가 일부 항목이 100%에 도달하지 않는다고 반복적으로 보고하는 경우 다음 명령이 가장 일반적인 오류에 집중하는 데 도움이 됩니다.

jq --raw-output 'select(.severity == "ERROR") | [
  (.time | split(".")[0] | strptime("%Y-%m-%dT%H:%M:%S") | strftime("…%m-%dT%H:%M…")),
  .class, .id, .message, .error
  ] | @tsv' geo.log \
  | sort | uniq -c

특정 오류 메시지에 대한 조언은 Geo 문제 해결 페이지를 참조하세요.

gitaly/current 파싱#

다음 예시를 사용하여 Gitaly 문제를 해결합니다.

웹 UI에서 전송된 모든 Gitaly 요청 찾기#

jq 'select(."grpc.meta.client_name" == "gitlab-web")' current

실패한 모든 Gitaly 요청 찾기#

jq 'select(."grpc.code" != null and ."grpc.code" != "OK")' current

30초보다 오래 걸린 모든 요청 찾기#

jq 'select(."grpc.time_ms" > 30000)' current

요청 볼륨 기준 상위 10개 프로젝트 및 가장 긴 기간 3개 출력#

jq --raw-output --slurp '
  map(
    select(
      ."grpc.request.glProjectPath" != null
      and ."grpc.request.glProjectPath" != ""
      and ."grpc.time_ms" != null
    )
  )
  | group_by(."grpc.request.glProjectPath")
  | sort_by(-length)
  | limit(10; .[])
  | sort_by(-."grpc.time_ms")
  | [
      length,
      .[0]."grpc.time_ms",
      .[1]."grpc.time_ms",
      .[2]."grpc.time_ms",
      .[0]."grpc.request.glProjectPath"
    ]
  | @sh' current |
  awk 'BEGIN { printf "%7s %10s %10s %10s\t%s\n", "CT", "MAX DURS", "", "", "PROJECT" }
  { printf "%7u %7u ms, %7u ms, %7u ms\t%s\n", $1, $2, $3, $4, $5 }'

출력 예시

   CT    MAX DURS                              PROJECT
  206    4898 ms,    1101 ms,    1032 ms      'groupD/project4'
  109    1420 ms,     962 ms,     875 ms      'groupEF/project56'
  663     106 ms,      96 ms,      94 ms      'groupABC/project123'
  ...

대안으로 fast-stats를 사용합니다:

fast-stats top --sort-by=duration current

사용자 및 프로젝트 활동 유형 개요#

jq --raw-output '[
    (.time | split(".")[0] | strptime("%Y-%m-%dT%H:%M:%S") | strftime("…%m-%dT%H…")),
    .username, ."grpc.method", ."grpc.request.glProjectPath"
  ] | @tsv' current | sort | uniq -c \
  | grep --invert-match --extended-regexp '^\s+\d{1,3}\b'

출력 예시:

 5678 …01-12T01…     ReferenceTransactionHook  # Praefect 작업; 정상
54321 …01-12T01…  some_bot   GetBlobs    namespace/subgroup/project
 1234 …01-12T01…  some_user  FindCommit  namespace/subgroup/project

이 예시는 커스텀 도구 또는 스크립트가 Gitaly에서 예상치 못하게 높은 요청 빈도 (>15 RPS)를 유발하는 것을 보여줍니다. 시간별 집계는 다음에 도움이 됩니다:

jq와 함께 fast-stats top을 사용하여 해당 사용자 및 봇의 성능 영향을 검토합니다:

fast-stats top --display=percentage --sort-by=cpu-s current

높은 요청 빈도 자체가 자동으로 문제가 되는 것은 아니지만 리소스의 많은 비율을 사용하는 것은 문제입니다.

치명적인 Git 문제의 영향을 받는 모든 프로젝트 찾기#

grep "fatal: " current |
  jq '."grpc.request.glProjectPath"' |
  sort | uniq

gitlab-shell/gitlab-shell.log 파싱#

SSH를 통한 Git 호출 조사를 위해.

프로젝트 및 사용자별 상위 20개 호출 찾기:

jq --raw-output --slurp '
  map(
    select(
      .username != null and
      .gl_project_path !=null
    )
  )
  | group_by(.username+.gl_project_path)
  | sort_by(-length)
  | limit(20; .[])
  | "count: \(length)\tuser: \(.[0].username)\tproject: \(.[0].gl_project_path)" ' \
  gitlab-shell.log

프로젝트, 사용자 및 명령별 상위 20개 호출 찾기:

jq --raw-output --slurp '
  map(
    select(
      .command  != null and
      .username != null and
      .gl_project_path !=null
    )
  )
  | group_by(.username+.gl_project_path+.command)
  | sort_by(-length)
  | limit(20; .[])
  | "count: \(length)\tcommand: \(.[0].command)\tuser: \(.[0].username)\tproject: \(.[0].gl_project_path)" ' \
  gitlab-shell.log

`jq`로 GitLab 로그 파싱

Tier: Free, Premium, Ultimate
Offering: GitLab Self-Managed
원문 보기
요약

가능한 경우 Kibana 및 Splunk와 같은 로그 집계 및 검색 도구를 사용하는 것이 좋습니다. 특히 오류 이벤트 요약 및 기본 사용 통계를 위해 GitLab 지원 팀은 특화된 fast-stats 도구를 제공합니다.

가능한 경우 Kibana 및 Splunk와 같은 로그 집계 및 검색 도구를 사용하는 것이 좋습니다. 그러나 사용할 수 없는 경우에도 jq를 사용하여 JSON 형식의 GitLab 로그를 빠르게 파싱할 수 있습니다.

Note

특히 오류 이벤트 요약 및 기본 사용 통계를 위해 GitLab 지원 팀은 특화된 fast-stats 도구를 제공합니다. 이 도구는 일반적으로 jq보다 훨씬 빠르게 더 큰 로그를 처리하고 더 많은 통계 정보를 출력합니다.

JQ란?#

매뉴얼에 명시된 바와 같이 jq는 명령줄 JSON 프로세서입니다. 다음 예시에는 GitLab 로그 파일 파싱을 위한 사용 사례가 포함되어 있습니다.

로그 파싱#

아래 나열된 예시는 각각의 Linux 패키지 설치 경로 및 기본 파일명으로 해당 로그 파일을 참조합니다. 각 전체 경로는 GitLab 로그 섹션에서 찾을 수 있습니다.

압축된 로그#

로그 파일이 교체되면 Unix 타임스탬프 형식으로 이름이 변경되고 gzip으로 압축됩니다. 결과 파일 이름은 @40000000624492fa18da6f34.s처럼 보입니다. 이 파일들은 최근 로그 파일들과 다르게 처리해야 합니다:

  • 파일의 압축을 해제하려면 gunzip -S .s @40000000624492fa18da6f34.s를 사용하여 파일명을 압축된 로그 파일의 이름으로 바꿉니다.
  • 파일을 직접 읽거나 파이프하려면 zcat 또는 zless를 사용합니다.
  • 파일 내용을 검색하려면 zgrep을 사용합니다.

일반 명령#

색상화된 jq 출력을 less로 파이프#

jq .  -C | less -R

용어 검색 및 일치하는 모든 줄 예쁘게 출력#

grep   | jq .

JSON의 잘못된 줄 건너뛰기#

jq -cR 'fromjson?' file.json | jq 

기본적으로 jq는 유효한 JSON이 아닌 줄을 만나면 오류가 발생합니다. 이는 모든 잘못된 줄을 건너뛰고 나머지를 파싱합니다.

JSON 로그의 시간 범위 출력#

cat log.json | (head -1; tail -1) | jq '.time'

파일이 교체되고 압축된 경우 zcat을 사용합니다:

zcat @400000006026b71d1a7af804.s | (head -1; tail -1) | jq '.time'

zcat some_json.log.25.gz | (head -1; tail -1) | jq '.time'

여러 JSON 로그에서 상관 관계 ID에 대한 활동을 시간 순서로 가져오기#

grep -hR <correlationID> | jq -c -R 'fromjson?' | jq -C -s 'sort_by(.time)'  | less -R

gitlab-rails/production_json.loggitlab-rails/api_json.log 파싱#

5XX 상태 코드가 있는 모든 요청 찾기#

jq 'select(.status >= 500)' 

가장 느린 요청 상위 10개#

jq -s 'sort_by(-.duration_s) | limit(10; .[])' 

프로젝트 관련 모든 요청 찾기 및 예쁘게 출력#

grep   | jq .

총 기간이 5초 초과인 모든 요청 찾기#

jq 'select(.duration_s > 5000)' 

Gitaly 호출이 5번 이상인 모든 프로젝트 요청 찾기#

grep   | jq 'select(.gitaly_calls > 5)'

Gitaly 기간이 10초 초과인 모든 요청 찾기#

jq 'select(.gitaly_duration_s > 10000)' 

대기 기간이 10초 초과인 모든 요청 찾기#

jq 'select(.queue_duration_s > 10000)' 

Gitaly 호출 수 기준 상위 10개 요청#

jq -s 'map(select(.gitaly_calls != null)) | sort_by(-.gitaly_calls) | limit(10; .[])' 

특정 시간 범위 출력#

jq 'select(.time >= "2023-01-10T00:00:00Z" and .time <= "2023-01-10T12:00:00Z")' 

gitlab-rails/production_json.log 파싱#

요청 볼륨 기준 상위 3개 컨트롤러 메서드 및 가장 긴 기간 3개 출력#

jq -s -r 'group_by(.controller+.action) | sort_by(-length) | limit(3; .[]) | sort_by(-.duration_s) | "CT: \(length)\tMETHOD: \(.[0].controller)#\(.[0].action)\tDURS: \(.[0].duration_s),  \(.[1].duration_s),  \(.[2].duration_s)"' production_json.log

출력 예시

CT: 2721   METHOD: SessionsController#new  DURS: 844.06,  713.81,  704.66
CT: 2435   METHOD: MetricsController#index DURS: 299.29,  284.01,  158.57
CT: 1328   METHOD: Projects::NotesController#index DURS: 403.99,  386.29,  384.39

대안으로 fast-stats를 사용합니다:

fast-stats --verbose --limit=3 production_json.log

gitlab-rails/api_json.log 파싱#

요청 수와 가장 긴 기간 3개가 있는 상위 3개 라우트 출력#

jq -s -r 'group_by(.route) | sort_by(-length) | limit(3; .[]) | sort_by(-.duration_s) | "CT: \(length)\tROUTE: \(.[0].route)\tDURS: \(.[0].duration_s),  \(.[1].duration_s),  \(.[2].duration_s)"' api_json.log

출력 예시

CT: 2472 ROUTE: /api/:version/internal/allowed   DURS: 56402.65,  38411.43,  19500.41
CT: 297  ROUTE: /api/:version/projects/:id/repository/tags       DURS: 731.39,  685.57,  480.86
CT: 190  ROUTE: /api/:version/projects/:id/repository/commits    DURS: 1079.02,  979.68,  958.21

대안으로 fast-stats를 사용합니다:

fast-stats --verbose --limit=3 api_json.log

상위 API 사용자 에이전트 출력#

jq --raw-output '
  select(.remote_ip != "127.0.0.1") | [
    (.time | split(".")[0] | strptime("%Y-%m-%dT%H:%M:%S") | strftime("…%m-%dT%H…")),
    ."meta.caller_id", .username, .ua
  ] | @tsv' api_json.log | sort | uniq -c \
  | grep --invert-match --extended-regexp '^\s+\d{1,3}\b'

출력 예시:

 1234 …01-12T01…  GET /api/:version/projects/:id/pipelines  some_user  # 브라우저 세부 정보 포함; 정상
54321 …01-12T01…  POST /api/:version/projects/:id/repository/files/:file_path/raw  some_bot
 5678 …01-12T01…  PATCH /api/:version/jobs/:id/trace gitlab-runner     # 버전 세부 정보 포함; 정상

이 예시는 커스텀 도구 또는 스크립트가 예상치 못하게 높은 요청 빈도 (>15 RPS)를 유발하는 것을 보여줍니다. 이 상황의 사용자 에이전트는 특화된 타사 클라이언트이거나 curl과 같은 일반 도구일 수 있습니다.

시간별 집계는 다음에 도움이 됩니다:

jq와 함께 fast-stats top을 사용하여 해당 사용자 및 봇의 성능 영향을 검토합니다:

fast-stats top --display=percentage --sort-by=cpu-s api_json.log

높은 요청 빈도 자체가 자동으로 문제가 되는 것은 아니지만 리소스의 많은 비율을 사용하는 것은 문제입니다.

gitlab-rails/importer.log 파싱#

프로젝트 임포트 또는 마이그레이션 문제 해결을 위해 다음 명령을 실행합니다:

jq 'select(.project_path == "<namespace>/<project>").error_messages' importer.log

일반적인 문제는 문제 해결을 참조하세요.

gitlab-workhorse/current 파싱#

상위 Workhorse 사용자 에이전트 출력#

jq --raw-output '
  select(.remote_ip != "127.0.0.1") | [
    (.time | split(".")[0] | strptime("%Y-%m-%dT%H:%M:%S") | strftime("…%m-%dT%H…")),
    .remote_ip, .uri, .user_agent
  ] | @tsv' current |
  sort | uniq -c

API ua 예시와 유사하게 이 출력에서 예상치 못한 사용자 에이전트가 많으면 최적화되지 않은 스크립트를 나타냅니다. 예상되는 사용자 에이전트에는 gitlab-runner, GitLab-Shell 및 브라우저가 포함됩니다.

예를 들어 check_interval 설정을 늘려 러너가 새 작업을 확인하는 성능 영향을 줄일 수 있습니다.

gitlab-rails/geo.log 파싱#

가장 일반적인 Geo 동기화 오류 찾기#

gitlab:geo:status Rake 태스크가 일부 항목이 100%에 도달하지 않는다고 반복적으로 보고하는 경우 다음 명령이 가장 일반적인 오류에 집중하는 데 도움이 됩니다.

jq --raw-output 'select(.severity == "ERROR") | [
  (.time | split(".")[0] | strptime("%Y-%m-%dT%H:%M:%S") | strftime("…%m-%dT%H:%M…")),
  .class, .id, .message, .error
  ] | @tsv' geo.log \
  | sort | uniq -c

특정 오류 메시지에 대한 조언은 Geo 문제 해결 페이지를 참조하세요.

gitaly/current 파싱#

다음 예시를 사용하여 Gitaly 문제를 해결합니다.

웹 UI에서 전송된 모든 Gitaly 요청 찾기#

jq 'select(."grpc.meta.client_name" == "gitlab-web")' current

실패한 모든 Gitaly 요청 찾기#

jq 'select(."grpc.code" != null and ."grpc.code" != "OK")' current

30초보다 오래 걸린 모든 요청 찾기#

jq 'select(."grpc.time_ms" > 30000)' current

요청 볼륨 기준 상위 10개 프로젝트 및 가장 긴 기간 3개 출력#

jq --raw-output --slurp '
  map(
    select(
      ."grpc.request.glProjectPath" != null
      and ."grpc.request.glProjectPath" != ""
      and ."grpc.time_ms" != null
    )
  )
  | group_by(."grpc.request.glProjectPath")
  | sort_by(-length)
  | limit(10; .[])
  | sort_by(-."grpc.time_ms")
  | [
      length,
      .[0]."grpc.time_ms",
      .[1]."grpc.time_ms",
      .[2]."grpc.time_ms",
      .[0]."grpc.request.glProjectPath"
    ]
  | @sh' current |
  awk 'BEGIN { printf "%7s %10s %10s %10s\t%s\n", "CT", "MAX DURS", "", "", "PROJECT" }
  { printf "%7u %7u ms, %7u ms, %7u ms\t%s\n", $1, $2, $3, $4, $5 }'

출력 예시

   CT    MAX DURS                              PROJECT
  206    4898 ms,    1101 ms,    1032 ms      'groupD/project4'
  109    1420 ms,     962 ms,     875 ms      'groupEF/project56'
  663     106 ms,      96 ms,      94 ms      'groupABC/project123'
  ...

대안으로 fast-stats를 사용합니다:

fast-stats top --sort-by=duration current

사용자 및 프로젝트 활동 유형 개요#

jq --raw-output '[
    (.time | split(".")[0] | strptime("%Y-%m-%dT%H:%M:%S") | strftime("…%m-%dT%H…")),
    .username, ."grpc.method", ."grpc.request.glProjectPath"
  ] | @tsv' current | sort | uniq -c \
  | grep --invert-match --extended-regexp '^\s+\d{1,3}\b'

출력 예시:

 5678 …01-12T01…     ReferenceTransactionHook  # Praefect 작업; 정상
54321 …01-12T01…  some_bot   GetBlobs    namespace/subgroup/project
 1234 …01-12T01…  some_user  FindCommit  namespace/subgroup/project

이 예시는 커스텀 도구 또는 스크립트가 Gitaly에서 예상치 못하게 높은 요청 빈도 (>15 RPS)를 유발하는 것을 보여줍니다. 시간별 집계는 다음에 도움이 됩니다:

jq와 함께 fast-stats top을 사용하여 해당 사용자 및 봇의 성능 영향을 검토합니다:

fast-stats top --display=percentage --sort-by=cpu-s current

높은 요청 빈도 자체가 자동으로 문제가 되는 것은 아니지만 리소스의 많은 비율을 사용하는 것은 문제입니다.

치명적인 Git 문제의 영향을 받는 모든 프로젝트 찾기#

grep "fatal: " current |
  jq '."grpc.request.glProjectPath"' |
  sort | uniq

gitlab-shell/gitlab-shell.log 파싱#

SSH를 통한 Git 호출 조사를 위해.

프로젝트 및 사용자별 상위 20개 호출 찾기:

jq --raw-output --slurp '
  map(
    select(
      .username != null and
      .gl_project_path !=null
    )
  )
  | group_by(.username+.gl_project_path)
  | sort_by(-length)
  | limit(20; .[])
  | "count: \(length)\tuser: \(.[0].username)\tproject: \(.[0].gl_project_path)" ' \
  gitlab-shell.log

프로젝트, 사용자 및 명령별 상위 20개 호출 찾기:

jq --raw-output --slurp '
  map(
    select(
      .command  != null and
      .username != null and
      .gl_project_path !=null
    )
  )
  | group_by(.username+.gl_project_path+.command)
  | sort_by(-length)
  | limit(20; .[])
  | "count: \(length)\tcommand: \(.[0].command)\tuser: \(.[0].username)\tproject: \(.[0].gl_project_path)" ' \
  gitlab-shell.log