{{< 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,将文件名替换为您压缩的日志文件的名称。
  • 要直接读取或传输文件,请使用 zcatzless
  • 要搜索文件内容,请使用 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.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  # 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-runnerGitLab-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