【问题标题】:Qt output (qDebug qWarning etc) does not work if application is executed via cronjob如果应用程序通过 cronjob 执行,Qt 输出(qDebug qWarning 等)将不起作用
【发布时间】:2019-02-01 07:02:51
【问题描述】:

我为此创建了一个复制样本:

#include <iostream>
#include <QtCore/QLoggingCategory>
#include <QtCore/QDebug>
#include <QtCore/QtCore>
using namespace std;
int main () {
  int i;
  QLoggingCategory::setFilterRules("*.debug=true\n");
  QLoggingCategory LogO(NULL);
  if (LogO.isDebugEnabled()) {
        cout << "QDebug enabled\n";
  } else {
        cout << "QDebug disabled!\n";
  }
  cout << "Start!\n";
  qDebug() << "qStart!";
  cerr << "print to stderr.\n";
  qWarning() << "qWarning";
  return 0;
}

构建步骤:

g++ -c -fPIC -I/usr/include/qt5 main.cpp -o main.o
g++ -fPIC main.o -L /usr/lib64 -lQt5Core -o testapp

在交互式 shell 中执行应用程序时,输出重定向按预期工作:

设置:

./testapp > out 2> err

输出:

>>cat out:
QDebug enabled
Start!

>>cat err:
qStart!
print to stderr.
qWarning

但是,如果应用程序作为 cronjob 执行,则它不起作用,缺少 qDebug() 和 qWarning() 的输出:

设置:

* * * * * username /home/username/temp/build/testapp 1> /home/username/temp/log/out 2> /home/username/temp/log/err

输出:

>>cat /home/username/temp/log/out
QDebug enabled
Start!

>>cat home/username/temp/log/err
print to stderr.

环境变量

env在交互式shell中的输出如下:

LS_COLORS=*long string*
SSH_CONNECTION=*censored*
LANG=en_US.UTF-8
HISTCONTROL=ignoredups
HOSTNAME=*censored*
XDG_SESSION_ID=492
USER=username
SELINUX_ROLE_REQUESTED=
PWD=/home/username/temp/build
HOME=/home/username
SSH_CLIENT=*censored*
SELINUX_LEVEL_REQUESTED=
SSH_TTY=/dev/pts/0
MAIL=/var/spool/mail/username
TERM=xterm
SHELL=/bin/bash
SELINUX_USE_CURRENT_RANGE=
SHLVL=1
LOGNAME=username
DBUS_SESSION_BUS_ADDRESS=unix:path=/run/user/1000/bus
XDG_RUNTIME_DIR=/run/user/1000
PATH=/usr/lib64/ccache:/usr/local/bin:/usr/bin:/usr/local/sbin:/usr/sbin:/home/username/.local/bin:/home/username/bin
HISTSIZE=1000
LESSOPEN=||/usr/bin/lesspipe.sh %s
_=/usr/bin/env
OLDPWD=/home/username/temp/build/logs

通过cronjob调用env的输出如下:

LS_COLORS=*long string*
LANG=en_US.UTF-8
HISTCONTROL=ignoredups
HOSTNAME=*censored*
XDG_SESSION_ID=995
USER=username
PWD=/home/username
HOME=/home/username
MAIL=/var/spool/mail/username
TERM=xterm
SHELL=/bin/bash
SHLVL=1
LOGNAME=username
DBUS_SESSION_BUS_ADDRESS=unix:path=/run/user/1000/bus
XDG_RUNTIME_DIR=/run/user/1000
PATH=/usr/lib64/ccache:/usr/local/bin:/usr/bin:/usr/local/sbin:/usr/sbin:/home/username/.local/bin:/home/username/bin
LESSOPEN=||/usr/bin/lesspipe.sh %s
_=/usr/bin/env

【问题讨论】:

    标签: qt cron qdebug


    【解决方案1】:

    问题在于 qt 的行为会有所不同,具体取决于它是否认为自己在(交互式?)终端中运行。

    Quote:

    需要注意的一个陷阱:日志记录的目的地取决于环境变量。如果变量 QT_LOGGING_TO_CONSOLE 设置为 1,则消息函数将始终记录到控制台。如果设置为 0,它们将不会登录到控制台,而是会登录到 syslog(如果启用)。如果未设置环境变量,则消息函数会记录到控制台(如果存在)(即,如果程序连接到终端)。因此,为了确保我们的示例程序的输出进入 syslog,我在程序中将环境变量设置为 0。

    因此,qDebug、QWarning等在cron执行时的输出不是通过stderr输出,而是直接交给journald

    TL;DR: 快速修复:将 QT_LOGGING_TO_CONSOLE=1 添加到 /etc/crontab

    .

    .

    PS:注意是否需要使用 QDebug 调试问题:

    1. 注意这一点:https://bugzilla.redhat.com/show_bug.cgi?id=1227295
    2. 你可以添加QT_LOGGING_DEBUG=1作为环境变量来制作 qt 在执行期间输出日志记录行为的变化。

    【讨论】:

      【解决方案2】:

      cronjob 将输出和错误重定向到电子邮件地址。

      在您的 crontab 条目中添加 &gt;&gt; /tmp/myscript.log 2&gt;&amp;1

      看到这个answer

      【讨论】:

      • 我会试一试,但是,为什么只有 qDebug 消息会受此影响,而不是 cerr?
      猜你喜欢
      • 2011-06-24
      • 2012-07-30
      • 2012-11-06
      • 1970-01-01
      • 2014-12-05
      • 2011-03-29
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多