- JQ란 무엇입니까?
- 로그 구문 분석
GitLab 로그를 jq
로 구문 분석하기
가능한 경우 Kibana 및 Splunk와 같은 로그 집계 및 검색 도구를 사용하는 것을 권장하지만, 사용할 수 없는 경우에도
GitLab 로그를 JSON 형식으로 빠르게 구문 분석할 수 있습니다
jq
를 사용하여.
fast-stats
도구를 제공합니다.JQ란 무엇입니까?
그의 매뉴얼에 명시된 바와 같이, jq
는 명령줄 JSON 프로세서입니다. 다음 예시는
GitLab 로그 파일을 구문 분석하는 데 필요한 사용 사례를 포함합니다.
로그 구문 분석
아래 나열된 예시는 각각의 로그 파일을 상대적인 리눅스 패키지 설치 경로와 기본 파일 이름으로 다룹니다. 상대적인 전체 경로는 GitLab 로그 섹션에서 확인하세요.
압축된 로그
로그 파일이 순환될 때, Unix 타임스탬프 형식으로 이름이 바뀌고 gzip
로 압축됩니다.
결과 파일 이름은 @40000000624492fa18da6f34.s
와 같이 나타납니다.
이 파일들은 더 최신 로그 파일과는 다르게 구문 분석하기 전에 다루어야 합니다:
- 파일의 압축을 해제하려면
gunzip -S .s @40000000624492fa18da6f34.s
를 사용하고 압축된 로그 파일의 이름으로 파일 이름을 교체하세요. - 파일을 직접 읽거나 파이프하려면
zcat
또는zless
를 사용하세요. - 파일 내용 검색을 원할 경우
zgrep
을 사용하세요.
일반 명령어
색상이 적용된 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.log
및 gitlab-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
파싱
요청량에 따른 상위 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
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
상위 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
이 예시는 예상치 못한 높은 수의 요청을 발생시키는 커스텀 도구 또는 스크립트를 보여줍니다.
이 상황에서 사용자 에이전트는 전문화된 서드 파티 클라이언트일 수 있으며,
curl
과 같은 일반 도구일 수도 있습니다.
또한 사용자 또는 봇에 대한 성능 통계 추출을 위해 fast-stats 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
및 브라우저가 포함됩니다.
새 작업을 확인하는 러너의 성능 영향을 줄이려면
check_interval 설정을 늘리는 것이 좋습니다.
gitlab-rails/geo.log
파싱
가장 일반적인 Geo 동기화 오류 찾기
반복적으로 일부 항목이 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
요청 양에 따른 상위 10개 프로젝트와 그들의 세 가지 가장 긴 지속 시간 출력
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 호출 조사를 위해.
프로젝트와 사용자에 따른 상위 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