- 什么是 JQ?
- 解析日志
{{< details >}}
- Tier: 基础版, 专业版, 旗舰版
- Offering: 私有化部署
{{< /details >}}
我们建议尽可能使用像 Kibana 和 Splunk 这样的日志聚合和搜索工具,但如果它们不可用,您仍然可以快速解析使用 jq
以 JSON 格式的极狐GitLab日志。
{{< alert type=”note” >}}
专门用于总结错误事件和基本使用统计,极狐GitLab 支持团队提供了专用的 fast-stats
工具。
{{< /alert >}}
什么是 JQ?
正如其手册中所述,jq
是一个命令行 JSON 处理器。以下示例包括针对解析极狐GitLab日志文件的用例。
解析日志
下面列出的示例通过它们在 Linux 软件包安装路径中的相对路径和默认文件名来处理各自的日志文件。在极狐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
打印请求量排名前三的控制器方法及其三个最长持续时间
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 # 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
此示例显示了一个自定义工具或脚本导致意外高数量的请求。在这种情况下,用户代理可以是专用的第三方客户端,也可以是像 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
设置,可以减少 runner 检查新作业的性能影响,例如。
解析 gitlab-rails/geo.log
找到最常见的 Geo 同步错误
如果 geo:status
Rake 任务反复报告某些项目从未达到 100%,则以下命令有助于集中注意最常见的错误。
jq --raw-output 'select(.severity == "ERROR") | [.project_path, .class, .message, .error] | @tsv' geo.log | sort | uniq -c | sort | tail
有关特定错误消息的建议,请参阅我们的Geo 故障排除页面。
解析 gitaly/current
使用以下示例排查 Gitaly 问题。
查找所有从 Web 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 调用。
查找前 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