实例
通过电子邮件自动报告崩溃故障
此示例处理libreport的配置,以发送完整的崩溃报告,包括 backtrace 通过来自自治系统的电子邮件服务。我们通常在自动测试环境中遇到这样的系统。让我们配置ABRT向发送通知电子邮件 devel@lists.project.org .
libreport的默认配置已经支持向本地系统上的root用户发送通知电子邮件。此功能存储在 /etc/libreport/events.d/mailx_event.conf
包含以下定义的文件 notify
和 notify-dup
活动:
EVENT=notify
# do not rely on the default config nor on the config file
Mailx_Subject="[abrt] a crash has been detected" \
Mailx_EmailFrom="ABRT Daemon <DoNotReply>" \
Mailx_EmailTo="root@localhost" \
reporter-mailx --notify-only
EVENT=notify-dup
# do not rely on the default config nor on the config file
Mailx_Subject="[abrt] a crash has been detected again" \
Mailx_EmailFrom="ABRT Daemon <DoNotReply>" \
Mailx_EmailTo="root@localhost" \
reporter-mailx --notify-only
备注
subject、sender和recipient通过环境变量传递,因为 reporter-mailx 在其命令行参数中不支持这些选项,并且将其放入其配置文件将破坏常规报告工作流。
检测到的问题类型可根据可用性分为两组 backtrace 在被发现的时候。第一组由Python、kerneloops、Ruby和Java问题类型组成,其中 backtrace 在检测时可用。第二组包括CCpp(过程崩溃,C/Cpp),其中 backtrace 必须从转储文件中提取。
的默认配置 notify
事件几乎可用于在检测时具有回溯的问题类型。我们可以通过一些调整重用默认配置。我们需要更新收件人的地址并删除 --notify-only
字符串来自 reporter-mailx 的命令行参数 reporters-mailx 从问题数据的最小子集合成消息,以避免在本地系统上浪费太多磁盘空间,在本地系统中,所有排除的数据都很容易访问。我们还需要将libreport配置为不将其用于CCpp问题,因为我们将提供自己的事件定义。
默认值 notify-dup
事件几乎可用于所有问题类型,因为它是针对单个问题的连续事件运行的 (notify
事件在第一次出现时运行,应创建所有必需的数据)。我们只需要更新收件人的地址,因为 --notify-only
这个论点对我来说很有意义 notify-dup
事件。
既然我们要用 repoter-mailx 在一些地方,我们不想重复我们自己,我们首先将静态电子邮件首选项(发件人和收件人)移动到 /etc/libreport/plugins/mailx.conf
:
Subject = [abrt] a crash has been detected
EmailFrom = ABRT Daemon <DoNotReply>
EmailTo = devel@lists.project.org
更新后的默认配置行如下所示:
EVENT=notify analyzer!=CCpp
# full notify e-mail
Mailx_Subject="[abrt] a crash has been detected" \
reporter-mailx
EVENT=notify-dup
# full notify-dup e-mail
Mailx_Subject="[abrt] a crash has been detected again" \
reporter-mailx --notify-only
"analyzer!=CCpp"
告诉libreport仅当 analyzer 文件不等于 "CCpp"
字符串。
我们已经完成了默认配置,现在我们要定义 notify
CCpp事件。为了能够生成完整的GDB回溯,我们需要所有相关的调试数据。在类似Fedora的系统上,ABRT可以通过从中提取构建id来提供所需的调试数据 coredump 文件和解包rpm包,提供从提取的构建id生成的路径。
CCpp notify 事件行如下:
EVENT=notify analyzer=CCpp
# CCpp notify event sending e-mail with full gdb backtrace
# extract build ids from coredump file and save them in 'build_ids' file
abrt-action-analyze-core --core=coredump -o build_ids >>event_log 2>&1 &&
# download and unpack rpm package for each id in 'build_ids' file
abrt-action-install-debuginfo -y >>event_log 2>&1 &&
# call gdb to generate backtrace with local variables, call arguments
# disassembly, etc. and save it in 'backtrace' file
abrt-action-generate-backtrace >>event_log 2>&1 &&
# generate 'duphash', 'crash_function' and 'backtrace_rating'
abrt-action-analyze-backtrace >>event_log 2>&1
#
# send e-mail
Mailx_Subject="[abrt] a crash has been detected" \
reporter-mailx
除了其他问题数据外,通知电子邮件还将包含 event_log (用于ABRT调试), backtrace_rating (基于分辨率和未分辨率帧比率的回溯质量度量值)和 duphash ABRT使用哪种方法来识别所有受支持的错误跟踪系统和所有机器(例如ABRT) "abrt_hash:$(cat duphash)"
字符串到Bugzilla错误报告的白板字段。)
提示1:
您可以添加 reporter-bugzilla -h $(cat duphash) >>bugzilla_bug_id
命令包含当前处理的崩溃的现有Bugzilla错误报告ID。这只适用于软呢帽。
提示2:
您可以使电子邮件的主题更具信息性。下面的脚本不是防弹的,但为C/Cpp问题生成了非常好的电子邮件主题:
Mailx_Subject="[abrt] $(cat package || cat executable): $(cat crash_function && echo "():") $(cat reason || (cat executable && echo " crashed"))"
从systemd coredumctl获取核心文件
默认情况下,ABRT通过注册的内核转储助手检测本地程序(C,C++)崩溃。 /proc/sys/kernel/core_pattern
. 不幸的是,一次只能有一个core模式助手,因此ABRT core dump助手不能与之共存 systemd-coredumctl .
但是,可以关闭ABRT core dumper helper并关闭ABRT systemd-coredumpctl watcher可以用来通知ABRT本机程序的崩溃。
你所要做的就是禁用 abrt-ccpp.service 它取代了 core_pattern 通过配置 sysctl 与ABRT核心模式助手。如果服务正在运行,则 core_pattern 应该从 |/usr/libexec/abrt-hook-ccpp
.
systemctl stop abrt-ccpp.service
systemctl disable abrt-ccpp.service
一旦你停止并禁用 abrt-ccpp.service , the core_pattern 变量应以开头 |/usr/lib/systemd/systemd-coredump
. 如果没有,请检查文件 /usr/lib/sysctl.d/50-coredump.conf
存在并确保没有其他文件设置 kernel.core_pattern
(见 man 5 sysctl.d
)
最后两件事你需要做的是启用和启动 abrt-journal-core.service .
systemctl enable abrt-journal-core.service
systemctl start abrt-journal-core.service
当前版本的 abrt-journal-core.service 需要复制数据,ABRT需要能够在bug跟踪工具中打开报告并离开 systemd-coredumpctl 数据未被触及。这意味着您不能使用ABRT日志核心服务来清理 systemd-coredumpctl 最终你会得到两份核心文件,一份在 systemd-coredumpctl 的子目录中 /var/spool/abrt/
.
为特定包的崩溃收集额外的日志文件
ABRT试图为维护人员提供尽可能多的信息。问题详细信息的好来源可以是日志文件。因此,一旦检测到崩溃的进程,ABRT就会遍历系统日志,并将看起来与崩溃进程相关的行复制到一个名为 var_log_messages
在问题目录中。可以在ABRT/libreport打开的bug报告中找到该文件。
但是,由于各种原因,应用程序可能不会选择登录到系统日志。在这种情况下,ABRT可以配置为将日志文件复制到问题数据目录,libreport会自动将它们附加到bug报告中。
假设我们有一个叫做 foo
我们要复制在用户数据库中创建的日志文件 /var/run/
目录。应用程序运行多个并发进程,每个进程将调试消息写入自己的日志文件(由进程的PID表示)。
要获取这些日志文件,我们需要创建一个新的libreport事件配置文件,并指示ABRT在foo的可执行文件出现崩溃后运行它。默认情况下,ABRT运行 post-create
, notify
和 notify-dup
新问题检测事件。我们不能使用 post-create
因为那时崩溃的可执行文件包可能还不知道。 notify-dup
不适合,因为执行事件是为了重新出现问题,因此应该已经捕获日志文件。因此,我们必须定义新的 notify
事件。
EVENT=notify pkg_name=foo
# Copy log files of crashed process to foo.log
cp /var/run/$(cat uid)/foo.$(cat pid).log foo.log
这个 pkg_name=foo
字符串告诉ABRT运行上面的行,查找 foo
包裹。您可以根据需要添加任意多的条件。第一行下面的行由 /bin/sh 当前工作目录包含ABRT捕获的所有问题数据。
代码必须放在 /etc/libreport/events.d/
目录。包裹通常遵循 ${{package name}}_event.conf
这些文件的规则。
忽略旧版本ABRT中钩子级别的特定二进制文件
在ABRT版本2.1.11-36的RHEL7.3、版本2.0.8-37的RHEL6.8和ABRT版本2.8.1的Fedora中引入了忽略钩子级特定二进制文件的崩溃。期权 IgnoredPaths
在conf文件中 /etc/abrt/plugins/CCpp.conf
.
即使在旧版本的ABRT中也可以忽略钩子级的崩溃吗?
是的,是的。你可以自己写 core_pattern 过滤/忽略二进制文件并作为abrt hook ccpp的包装器工作的脚本,abrt hook ccpp不能进行过滤。有关更多细节,请参阅内核文档 [1].
如何执行此操作的示例:
创建 core_pattern 脚本(例如 /etc/my_abrt_ccpp_hook.sh
)包括以下内容:
#!/bin/bash
# kernel.core_pattern = |/usr/libexec/abrt-hook-ccpp %s %c %p %u %g %t %e
# $1 $2 $3 $4 $5 $6 $7
# You want to filter %e - executable filename (without path prefix), so parameter $7
# Is it the particular binary you want to ignore?
if [[ $7 == "EXECUTABLE_YOU_WANT_TO_IGNORE" ]]
then
# Do what you want
else
# In other cases use ABRT's hook in standard way
cat /dev/stdin |/usr/libexec/abrt-hook-ccpp $1 $2 $3 $4 $5 $6 $7
fi
设置新的 kernel.core_pattern 使用 sysctl (基本上是改变 /usr/libexec/abrt-hook-ccpp
到 /etc/my_abrt_ccpp_hook.sh
):
# sysctl kernel.core_pattern
kernel.core_pattern = |/usr/libexec/abrt-hook-ccpp %s %c %p %u %g %t %e
# sysctl kernel.core_pattern="|/etc/my_abrt_ccpp_hook.sh %s %c %p %u %g %t %e"
kernel.core_pattern = |/etc/my_abrt_ccpp_hook.sh %s %c %p %u %g %t %e
是否可以忽略来自具有特定UID的程序的崩溃?
是的,是这样的。您可以在中修改文件 /etc/libreport/events.d/ 并将您自己的bash代码片段添加到其中。在事件中 post-create (例如,请参阅 /etc/libreport/events.d/python3_event.conf 对于Python 3崩溃或 /etc/libreport/events.d/ccpp_event.conf 对于C和C++崩溃),您可以访问 /proc/PID/status 崩溃的进程的文件。
C和C++程序中UID小于1000时过滤崩溃示例:~
打开 /etc/libreport/events.d/ccpp_event.conf 并将此代码段添加到 EVENT=post-create 部分:
# Parse Uid from proc_pid_status
uid=`grep '^Uid:' proc_pid_status | sed 's/^Uid:[[:space:]]*\([0-9]*\).*/\1/'`
if [ 1000 -lt "$uid" ]; then
# If Uid is less then 1000 abrt will remove the problem directory
exit 1
fi