| stage | Systems |
|---|---|
| group | Distribution |
| info | To determine the technical writer assigned to the Stage/Group associated with this page, see https://handbook.gitlab.com/handbook/product/ux/technical-writing/#assignments |
DETAILS: Tier: Free, Premium, Ultimate Offering: Self-managed
We recommend using log aggregation and search tools like Kibana and Splunk whenever possible,
but if they are not available you can still quickly parse
GitLab logs in JSON format
(the default in GitLab 12.0 and later) using jq.
NOTE:
Specifically for summarizing error events and basic usage statistics,
the GitLab Support Team provides the specialised
fast-stats tool.
As noted in its manual, jq is a command-line JSON processor. The following examples
include use cases targeted for parsing GitLab log files.
The examples listed below address their respective log files by their relative Linux package installation paths and default filenames. Find the respective full paths in the GitLab logs sections.
jq . <FILE> -C | less -Rgrep <TERM> <FILE> | jq .jq -cR 'fromjson?' file.json | jq <COMMAND>By default jq errors out when it encounters a line that is not valid JSON.
This skips over all invalid lines and parses the rest.
cat log.json | (head -1; tail -1) | jq '.time'Use zcat if the file has been rotated and compressed:
zcat @400000006026b71d1a7af804.s | (head -1; tail -1) | jq '.time'
zcat some_json.log.25.gz | (head -1; tail -1) | jq '.time'grep -hR <correlationID> | jq -c -R 'fromjson?' | jq -C -s 'sort_by(.time)' | less -Rjq 'select(.status >= 500)' <FILE>jq -s 'sort_by(-.duration_s) | limit(10; .[])' <FILE>grep <PROJECT_NAME> <FILE> | jq .jq 'select(.duration_s > 5000)' <FILE>grep <PROJECT_NAME> <FILE> | jq 'select(.gitaly_calls > 5)'jq 'select(.gitaly_duration_s > 10000)' <FILE>jq 'select(.queue_duration_s > 10000)' <FILE>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>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.logExample output
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
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.logExample output
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
jq --raw-output 'select(.remote_ip != "127.0.0.1") | [.remote_ip, .username, .route, .ua] | @tsv' api_json.log |
sort | uniq -c | sort -n | tailExample output:
89 1.2.3.4, 127.0.0.1 some_user /api/:version/projects/:id/pipelines # plus browser details; OK
567 5.6.7.8, 127.0.0.1 /api/:version/jobs/:id/trace gitlab-runner # plus version details; OK
1234 98.76.54.31, 127.0.0.1 some_bot /api/:version/projects/:id/repository/files/:file_path/raw
This example shows a custom tool or script causing an unexpectedly high number of requests. User agents in this situation can be:
- Third party libraries like
python-requestsorcurl. - GitLab CLI clients.
You can also use fast-stats top to extract performance statistics for those users or bots.
To troubleshoot project imports or migrations, run this command:
jq 'select(.project_path == "<namespace>/<project>").error_messages' importer.logFor common issues, see troubleshooting.
jq --raw-output 'select(.remote_ip != "127.0.0.1") | [.remote_ip, .uri, .user_agent] | @tsv' current |
sort | uniq -c | sort -n | tailSimilar to the API ua example,
many unexpected user agents in this output indicate unoptimized scripts.
Expected user agents include gitlab-runner, GitLab-Shell, and browsers.
The performance impact of runners checking for new jobs can be reduced by increasing
the check_interval setting,
for example.
If the geo:status Rake task
repeatedly reports that some items never reach 100%,
the following command helps to focus on the most common errors.
jq --raw-output 'select(.severity == "ERROR") | [.project_path, .class, .message, .error] | @tsv' geo.log | sort | uniq -c | sort | tailRefer to our Geo troubleshooting page for advice about specific error messages.
Use the following examples to troubleshoot Gitaly.
jq 'select(."grpc.meta.client_name" == "gitlab-web")' currentjq 'select(."grpc.code" != null and ."grpc.code" != "OK")' currentjq 'select(."grpc.time_ms" > 30000)' currentjq --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 }'Example output
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 -ngrep "fatal: " current |
jq '."grpc.request.glProjectPath"' |
sort | uniqFor investigating Git calls via SSH, from GitLab 12.10.
Find the top 20 calls by project and user:
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.logFind the top 20 calls by project, user, and command:
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