编辑
2025-03-03
工作知识
0
请注意,本文编写于 62 天前,最后修改于 62 天前,其中某些信息可能已经过时。

目录

一:常用日志方式
二:找到应用的日志
三:Qt的日志
1,判断源码文件是否打开QDebug
2, 判断代码编译是否有宏QT_DEBUG
3, 判断日志到文件还是标准输出
4, 日志过滤
5,已有工程的qDebug日志
四:全局日志

通常需要一些技巧抓取应用日志,下面列举一下方法抓取一些通用的日志来判断系统问题

一:常用日志方式

显示管理器lightdm tail -f /var/log/lightdm/lightdm.log 显示服务器Xorg tail -f /var/log/Xorg.0.log 窗口管理器ukui-kwin tail -f /home/kylin/.log/ukui_kwin_0.log 系统全局的日志 tail -f /var/log/syslog 系统session启动日志 tail -f /home/kylin/.config/ukui-session/ukui-session-xsmp.log 系统自启动图形的错误日志 tail -f /home/kylin/.xsession-errors 系统启动默认设置的日志 taif -f /home/kylin/.log/usd/MON.log (以日期命名) 应用的系统调用日志 strace -p `pidof XXX` 应用的标准输出日志(未重定向) tail -f /proc/`pidof XXX`/fd/2 查看系统统计的日志 journalctl -r

二:找到应用的日志

对于一些应用程序,我们不清楚他在哪里输出了日志,可以使用如下方法来找到应用的日志文件

strace -p `pidof XXX` 2>&1 | grep "openat\|faccessat"

解释一下:这里从系统调用出发,找到进程正在打开和正在准备进入的文件。如果是openat,则日志文件一定存在,如果是faccessat,则日志文件因为权限问题无法写入。

如果应用程序没有日志输出到文件,那么日志只会默认在fd2上,也就是标准输出,如下可以看到日志

tail -f /proc/`pidof XXX`/fd/2

三:Qt的日志

对于Qt的日志,均通过QDebug来实现,但是QDebug并不是都能正常输出,通常我们需要结合《二》,并添加Qt的配置来正常打开qDebug输出。方法如下:

1,判断源码文件是否打开QDebug

确定源文件是否有 #include ,如果没有,qDebug不会输出

2, 判断代码编译是否有宏QT_DEBUG

如果编译过程中,出现宏QT_NO_DEBUG,则代码qDebug并不会输出。则需要修改源码pro文件或cmakefile或makefile等,设置编译为debug,或者手动添加QT_DEBUG宏,例如:

CONFIG(debug ,debug|release){ DEFINES -= QT_NO_DEBUG_OUTPUT }else{ DEFINES += QT_NO_DEBUG_OUTPUT }

这里设置去掉宏QT_NO_DEBUG_OUTPUT,当然直接打开QT_DEBUG宏也可以

3, 判断日志到文件还是标准输出

确定代码是否使用 qInstallMessageHandler。如使用,日志默认到文件,如未使用,日志默认到标准输出

确定方法如上述第二章节

4, 日志过滤

一些Qt使用了QLoggingCategory来管理日志,对应的qt日志api的日志并不会显示,这时候需要配置环境变量来打开日志。如下

export QT_LOGGING_RULES="*.debug=true;qt.*.debug=false"

当然,可以按照自己的规则来过滤,主要参考代码。例如ukui-kwin可以如下:

export QT_LOGGING_RULES="kwin_libinput*=true;"

这样可以看到kwin相关libinput的日志

5,已有工程的qDebug日志

/usr/share/glib-2.0/schemas/org.ukui.log4qt.gschema.xml

修改为false 和 DEBUG 和 DEBUG,daily

image.png

image.png

修改后,重编译glib schemas即可

glib-compile-schemas /usr/share/glib-2.0/schemas/

四:全局日志

因为Qt的日志太过复杂,我们通常在release版本上调试代码,但是反复修改配置太累,为了让调试日志更加容易,可以使用syslog,它简单好用,用完随即可删。主要使用步骤如下:

先在代码中引入syslog头文件

#include <syslog,h>

如果为了日志单独使用一个文件,可以如下,否则默认日志文件在/var/log/syslog

void openlog (char*ident, int option, int facility);

设置日志等级

#define LOG_EMERG 0 /* system is unusable */ #define LOG_ALERT 1 /* action must be taken immediately */ #define LOG_CRIT 2 /* critical conditions */ #define LOG_ERR 3 /* error conditions */ #define LOG_WARNING 4 /* warning conditions */ #define LOG_NOTICE 5 /* normal but significant condition */ #define LOG_INFO 6 /* informational */ #define LOG_DEBUG 7 /* debug-level messages */

打印

syslog(LOG_DEBUG, "[%s] xxxx failed", __func__);

tail -f /var/log/syslog