jq를 사용하여 GitLab 로그 구문 분석

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

가능한 경우 Kibana 및 Splunk와 같은 로그 집계 및 검색 도구를 사용하는 것이 좋지만 사용할 수 없는 경우에도 GitLab 로그를 JSON 형식(12.0 버전 이상의 GitLab 기본 형식)으로 빠르게 구문 분석할 수 있습니다.jq를 사용하여.

note
특히 오류 이벤트 및 기본 사용 통계를 요약하기 위해 GitLab 지원팀은 전용 fast-stats 도구를 제공합니다.

JQ란?

메뉴얼에 설명된대로 jq는 명령줄 JSON 프로세서입니다. 다음 예제에는 GitLab 로그 파일을 구문 분석하기 위해 대상으로 하는 사용 사례가 포함되어 있습니다.

로그 구문 분석

아래 나열된 예제들은 해당하는 로그 파일을 해당하는 상대적인 Linux 패키지 설치 경로와 기본 파일 이름으로 처리합니다. GitLab 로그 섹션에서 해당 전체 경로를 찾을 수 있습니다.

일반적인 명령어

colorized jq 출력을 less로 파이핑

jq . <FILE> -C | less -R

용어 검색 및 모든 일치하는 줄들을 정돈해서 출력

grep <TERM> <FILE> | jq .

JSON이 잘못된 줄들 건너뛰기

jq -cR 'fromjson?' file.json | jq <COMMAND>

기본적으로 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)' <FILE>

상위 10개 가장 느린 요청

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

프로젝트와 관련된 모든 요청 찾아서 정리해서 출력

grep <PROJECT_NAME> <FILE> | jq .

총 기간이 5초보다 큰 모든 요청 찾기

jq 'select(.duration_s > 5000)' <FILE>

5개 이상의 Gitaly 호출이 있는 모든 프로젝트 요청 찾기

grep <PROJECT_NAME> <FILE> | jq 'select(.gitaly_calls > 5)'

Gitaly 기간이 10초보다 큰 모든 요청 찾기

jq 'select(.gitaly_duration_s > 10000)' <FILE>

대기 기간이 10초보다 큰 모든 요청 찾기

jq 'select(.queue_duration_s > 10000)' <FILE>

Gitaly 호출 개수별 상위 10개 요청 출력

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

특정한 시간 범위 출력

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

gitlab-rails/production_json.log 구문 분석

요청 볼륨에 따른 상위 세 개의 컨트롤러 메서드 출력 및 각각의 가장 긴 기간

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

gitlab-rails/api_json.log 구문 분석

상위 세 개의 루트와 요청 횟수, 그리고 가장 긴 지속 기간 세 개를 출력합니다.

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

상위 API 사용자 에이전트를 출력합니다.

jq --raw-output 'select(.remote_ip != "127.0.0.1") | [.remote_ip, .username, .route, .ua] | @tsv' api_json.log |
  sort | uniq -c | sort -n | tail

출력 예시:

  89 1.2.3.4, 127.0.0.1  some_user  /api/:version/projects/:id/pipelines  # 브라우저 세부 정보 포함; OK
 567 5.6.7.8, 127.0.0.1      /api/:version/jobs/:id/trace gitlab-runner   # 버전 세부 정보 포함; OK
1234 98.76.54.31, 127.0.0.1  some_bot  /api/:version/projects/:id/repository/files/:file_path/raw

이 예시는 사용자 정의 도구 또는 스크립트가 예상치 못하게 많은 요청을 유발하는 것을 보여줍니다. 이 상황에서의 사용자 에이전트는 다음과 같을 수 있습니다:

또한, 해당 사용자나 봇들의 성능 통계를 추출하기 위해 빠른 통계 top을 사용할 수 있습니다.

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") | [.remote_ip, .uri, .user_agent] | @tsv' current |
  sort | uniq -c | sort -n | tail

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

새로운 작업을 확인하는 러너의 성능 영향은, 예를 들어, 체크 간격 설정을 증가시킴으로써 감소시킬 수 있습니다.

gitlab-rails/geo.log 구문 분석

가장 일반적인 Geo 동기화 오류를 찾습니다.

만약 the geo:status Rake task가 일부 항목이 반복적으로 100%에 도달하지 못했다고 보고하는 경우, 다음 명령은 가장 일반적인 오류에 집중할 수 있도록 돕습니다.

jq --raw-output 'select(.severity == "ERROR") | [.project_path, .class, .message, .error] | @tsv' geo.log | sort | uniq -c | sort | tail

특정 오류 메시지에 대한 자세한 조언은 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

요청 볼륨 상위 열 개 프로젝트 및 가장 긴 세 가지 기간 인쇄

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'
  ...

사용자 및 프로젝트 활동 종류 개요

jq --raw-output '[.username, ."grpc.method", ."grpc.request.glProjectPath"] | @tsv' current | sort | uniq -c | sort -n

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

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

gitlab-shell/gitlab-shell.log 구문 분석

SSH를 통한 Git 호출 조사를 위해, GitLab 12.10부터.

프로젝트 및 사용자별 상위 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