Вывод Qt (qDebug qWarning и т. Д.) Не работает, если приложение выполняется через cronjob - PullRequest
0 голосов
/ 26 августа 2018

Я создал образец воспроизведения для этого:

#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

При выполнении приложения в интерактивной оболочке перенаправление вывода работает должным образом:

Настройка:

./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.

Enviroment vars

Вывод env в интерактивной оболочке выглядит следующим образом:

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

Вывод env при вызове через cronjob выглядит следующим образом:

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

Ответы [ 2 ]

0 голосов
/ 07 сентября 2018

Проблема в том, что qt ведет себя по-разному, в зависимости от того, думает ли он, что работает в (интерактивном?) Терминале или нет.

Цитата

Один подводный камень, о котором следует знать: назначение журнала зависит от переменной среды. Если переменная QT_LOGGING_TO_CONSOLE установлена ​​в 1, функции сообщений всегда будут регистрироваться на консоли. Если установлено значение 0, они не будут входить в консоль, а вместо этого будут входить в системный журнал, если он включен. Когда переменная окружения не установлена, функции сообщений записываются на консоль, если таковая имеется (то есть, если программа подключена к терминалу). Таким образом, чтобы гарантировать, что выходные данные нашей примерной программы перейдут в системный журнал, я установил для переменной среды значение 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 выводит изменения в поведении логирования во время выполнения.
0 голосов
/ 27 августа 2018

cronjob перенаправляет вывод и ошибается на адрес электронной почты.

добавьте >> /tmp/myscript.log 2>&1 в вашу запись в crontab.

см. ответ

...