问题描述
想要找到以特定方式失败的所有作业,有几种方法是可行的:
– 一种方法是找到GitLab存储其日志文件的位置,并使用类似Grep的工具进行搜索。他在这里提出了这个问题。
– 另一种方法是使用GitLab的原生搜索功能来搜索日志。是否存在这样的功能?
解决方案
请注意以下操作注意版本差异及修改前做好备份。
方案1
目前,GitLab的用户界面中还没有这个功能,但是作业日志在内部作为作业构件上传。你可以通过一些工作来搜索它们。作业日志的后端存储在/etc/gitlab/gitlab.rb
中进行配置。
如果启用了artifacts_object_store_enabled
并且正在使用对象存储,那么构件将存储在artifacts_object_store_remote_directory
的值下,文件名为job.log
。假设该值为artifacts
,并且你正在使用类似minio
的工具,你可以使用以下命令在所有作业中搜索特定的失败:
mc find minio/artifacts --name 'job.log' --exec 'sh -c "mc cat {} | grep Client\.Timeout | xargs -r echo {time} {}; exit 0"' | tee /tmp/client_timeout.log
在我的经验中,这种方法太慢了,因为mc find
没有索引,它只是在查找任何名为job.log
的存储桶。
方案2
更快的方法是依赖于数据库。GitLab提供了一个名为gitlab-psql
的PostgreSQL客户端包装器,允许你连接到底层的PostgreSQL数据存储。连接到gitlab-psql
后,可以查询所有file.log
并从结果中获取到存储桶的相对路径。你可以通过创建一个命令批处理文件来轻松地使用s5cmd
工具来处理日志:
\a\o /tmp/pull_logs.s5cmd
SELECT FORMAT('cp s3://artifacts/%s /tmp/job_%s.log', to_bucket_path(ci_job_artifacts), id)
FROM ci_job_artifacts
WHERE file = 'job.log'
AND expire_at IS NULL
AND file_store = 2;
这将生成一个文件,你可以使用类似s5cmd
的工具运行,从GitLab对象存储中下载所有日志。你可以通过设置~/.aws/credentials
并运行以下命令来运行它(以minio为例):
s5cmd --endpoint-url https://minio.acme.net run /tmp/pull_logs.s5cmd
方案3
如果你正在使用NFS进行构件存储,那么你可以直接在挂载点上使用ripgrep进行搜索。
以上是在GitLab中搜索作业日志的几种方法。根据你的具体情况选择适合你的方法。