The Logs are not showing in Application Window.
-
@jsulm Hi, This is the updated one:
And still not able to read file:#include <QApplication> #include <QDebug> #include <QFile> #include <QPlainTextEdit> #include <QProcess> #include <QTextStream> #include <QTimer> int main(int argc, char *argv[]) { QApplication a(argc, argv); QPlainTextEdit *textEdit = new QPlainTextEdit; textEdit->setReadOnly(true); textEdit->show(); QProcess *process = new QProcess; process->start("tail", QStringList() << "-n" << "10" << "sample.log"); QObject::connect(process, &QProcess::readyReadStandardOutput, [textEdit, process] { textEdit->setPlainText(QString(process->readAllStandardOutput())); }); QObject::connect(process, &QProcess::errorOccurred, [](QProcess::ProcessError error) { qWarning() << "Error occurred:" << error; }); QObject::connect(process, &QProcess::finished, [process](int exitCode, QProcess::ExitStatus exitStatus) { if (exitStatus == QProcess::CrashExit) { qWarning() << "Process crashed with code" << exitCode; } else { qDebug() << "Process finished with code" << exitCode; } process->start("tail", QStringList() << "-n" << "10" << "sample.log"); }); return a.exec(); }I have put the copy of file in built folder, source folder and everywhere but still its not able to read.
Also after putting absolute path of the file, still not worked!@Aviral-0 said in The Logs are not showing in Application Window.:
I have put the copy of file in built folder, source folder and everywhere but still its not able to read
Why don't you simply use an absolute path for testing?
Was errorOccurred signal emitted? -
@Aviral-0 said in The Logs are not showing in Application Window.:
I have put the copy of file in built folder, source folder and everywhere but still its not able to read
Why don't you simply use an absolute path for testing?
Was errorOccurred signal emitted? -
@Aviral-0 Could be that tail prints out an error on stderr. To check that connect a slot to https://doc.qt.io/qt-6/qprocess.html#readyReadStandardError and print out what https://doc.qt.io/qt-6/qprocess.html#readAllStandardError returns there.
-
@Aviral-0
We have said this before, but one more time. You are not doing yourself any favors by doing this viaQProcess&tailcommand. @jsulm wrote in https://forum.qt.io/topic/142476/how-to-display-recent-logs-and-can-be-filter-according-to-the-checkboxes/12@Aviral-0 You can open the file, seek to file end and then connect a slot to https://doc.qt.io/qt-6/qfilesystemwatcher.html#fileChanged signal. In the slot you simply read to the end of the file and add the data you read to your log widget.
Or just use a
QTimerinstead ofQFileSystemWatcher, which may well be whattail -fdoes. Up to you, just saying.Actually, I now see that for this question you are only using
tail -nnottail -f. Which makes it even easier to do this by reading the file in your process. -
@Aviral-0
We have said this before, but one more time. You are not doing yourself any favors by doing this viaQProcess&tailcommand. @jsulm wrote in https://forum.qt.io/topic/142476/how-to-display-recent-logs-and-can-be-filter-according-to-the-checkboxes/12@Aviral-0 You can open the file, seek to file end and then connect a slot to https://doc.qt.io/qt-6/qfilesystemwatcher.html#fileChanged signal. In the slot you simply read to the end of the file and add the data you read to your log widget.
Or just use a
QTimerinstead ofQFileSystemWatcher, which may well be whattail -fdoes. Up to you, just saying.Actually, I now see that for this question you are only using
tail -nnottail -f. Which makes it even easier to do this by reading the file in your process. -
@JonB I was using QTimer, but @jsulm suggested my not to https://forum.qt.io/post/746836
Also I replaced tail -n with tail -f and its not working. I am really confused what is not working.@Aviral-0 said in The Logs are not showing in Application Window.:
I was using QTimer, but @jsulm suggested my not to https://forum.qt.io/post/746836
Sorry, but this is just wrong!
I suggested not to use QTimer to detect when the process finishes.
@JonB is talking about something completelly different (not using QProcess). Please read more carefully! -
@JonB I was using QTimer, but @jsulm suggested my not to https://forum.qt.io/post/746836
Also I replaced tail -n with tail -f and its not working. I am really confused what is not working.@Aviral-0
No he did not. He said you don't need aQTimerforThere is also no need for a timer to detect termination of a process, there is https://doc.qt.io/qt-6/qprocess.html#finished for that.
That is detecting a program finishes, not for picking up the tail of some output.
Also I replaced tail -n with tail -f and its not working. I am really confused what is not working
Why are you attempting to run an external process to print out the last lines in some log file when you could do it yourself in your app by reading the file? I have said before: you can do it via
QProcess/tailif you really want to, but since you are having problems with that maybe it would be simpler not to do it that way. -
@Aviral-0
No he did not. He said you don't need aQTimerforThere is also no need for a timer to detect termination of a process, there is https://doc.qt.io/qt-6/qprocess.html#finished for that.
That is detecting a program finishes, not for picking up the tail of some output.
Also I replaced tail -n with tail -f and its not working. I am really confused what is not working
Why are you attempting to run an external process to print out the last lines in some log file when you could do it yourself in your app by reading the file? I have said before: you can do it via
QProcess/tailif you really want to, but since you are having problems with that maybe it would be simpler not to do it that way. -
@Aviral-0 said in The Logs are not showing in Application Window.:
But Can anyone please write in simple technical terms of what functions
Please first clarify what exactly you are asking.
Do you want code to read a file? -
-
@Aviral-0 said in The Logs are not showing in Application Window.:
But Can anyone please write in simple technical terms of what functions
Please first clarify what exactly you are asking.
Do you want code to read a file?@jsulm Yes, I want a application which displays Recent 10 Lines of Logs from a Log File. And it should be updating dynamically, any change in log file appears in real time in application window.
Secondly, User be able to pause the Log updates and Be able to select or copy any log lines.
Third, a checkbox filter to filter the application with log types: like If I click on INFO then it should display only INFO logs, similarly for DEBUG and WARN.
The Base version code is this which runs and displays last 10 Logs but is not dynamically updating new logs from file:
#include <QApplication> #include <QProcess> #include <QTextEdit> #include <QVBoxLayout> #include <QWidget> int main(int argc, char *argv[]) { QApplication app(argc, argv); QWidget window; QVBoxLayout layout(&window); QTextEdit textEdit; layout.addWidget(&textEdit); window.show(); QProcess process; process.start("tail", QStringList() << "-n" << "10" << "/home/arpitk/QT Projects/logtail1/sample.log"); process.waitForFinished(); QByteArray output = process.readAllStandardOutput(); textEdit.setPlainText(output); return app.exec(); } -
@jsulm Yes, I want a application which displays Recent 10 Lines of Logs from a Log File. And it should be updating dynamically, any change in log file appears in real time in application window.
Secondly, User be able to pause the Log updates and Be able to select or copy any log lines.
Third, a checkbox filter to filter the application with log types: like If I click on INFO then it should display only INFO logs, similarly for DEBUG and WARN.
The Base version code is this which runs and displays last 10 Logs but is not dynamically updating new logs from file:
#include <QApplication> #include <QProcess> #include <QTextEdit> #include <QVBoxLayout> #include <QWidget> int main(int argc, char *argv[]) { QApplication app(argc, argv); QWidget window; QVBoxLayout layout(&window); QTextEdit textEdit; layout.addWidget(&textEdit); window.show(); QProcess process; process.start("tail", QStringList() << "-n" << "10" << "/home/arpitk/QT Projects/logtail1/sample.log"); process.waitForFinished(); QByteArray output = process.readAllStandardOutput(); textEdit.setPlainText(output); return app.exec(); }@JonB @jsulm This is the updated code of what I am trying to do:
It is showing error with toggleAction()Error is : No Member named ToggleAction() in QCheckBox
Please Suggest me to replace it with?
#include <QApplication> #include <QCheckBox> #include <QMenuBar> #include <QProcess> #include <QTextEdit> #include <QVBoxLayout> #include <QWidget> #include <QTimer> #include <QMessageBox> #include <QAccessibleActionInterface> class LogDisplay : public QWidget { Q_OBJECT public: LogDisplay() { textEdit.setReadOnly(true); layout.addWidget(&textEdit); setLayout(&layout); QMenuBar *menuBar = new QMenuBar(this); QMenu *filterMenu = menuBar->addMenu("Filter"); infoCheckBox = new QCheckBox("INFO", this); infoCheckBox->setChecked(true); filterMenu->addAction(infoCheckBox->toggleAction()); **/Here is the error** connect(infoCheckBox, &QCheckBox::stateChanged, this, &LogDisplay::refresh); debugCheckBox = new QCheckBox("DEBUG", this); debugCheckBox->setChecked(true); filterMenu->addAction(debugCheckBox->toggleAction()); connect(debugCheckBox, &QCheckBox::stateChanged, this, &LogDisplay::refresh); warningCheckBox = new QCheckBox("WARNING", this); warningCheckBox->setChecked(true); filterMenu->addAction(warningCheckBox->toggleAction()); connect(warningCheckBox, &QCheckBox::stateChanged, this, &LogDisplay::refresh); refresh(); QTimer *timer = new QTimer(this); connect(timer, &QTimer::timeout, this, &LogDisplay::refresh); timer->start(5000); } void refresh() { QStringList args; args << "-n" << "10" << "/path/to/logfile.txt"; if (!infoCheckBox->isChecked() || !debugCheckBox->isChecked() || !warningCheckBox->isChecked()) { args << "|" << "grep"; if (infoCheckBox->isChecked()) args << "-E" << "INFO"; if (debugCheckBox->isChecked()) args << "-E" << "DEBUG"; if (warningCheckBox->isChecked()) args << "-E" << "WARNING"; } process.start("sh", QStringList() << "-c" << args.join(" ")); process.waitForFinished(); if (process.exitCode() != 0) { QMessageBox::critical(this, "Error", process.readAllStandardError()); return; } QByteArray output = process.readAllStandardOutput(); textEdit.setPlainText(output); } private: QVBoxLayout layout; QTextEdit textEdit; QProcess process; QCheckBox *infoCheckBox; QCheckBox *debugCheckBox; QCheckBox *warningCheckBox; }; int main(int argc, char *argv[]) { QApplication app(argc, argv); LogDisplay window; window.show(); return app.exec(); } -
@JonB @jsulm This is the updated code of what I am trying to do:
It is showing error with toggleAction()Error is : No Member named ToggleAction() in QCheckBox
Please Suggest me to replace it with?
#include <QApplication> #include <QCheckBox> #include <QMenuBar> #include <QProcess> #include <QTextEdit> #include <QVBoxLayout> #include <QWidget> #include <QTimer> #include <QMessageBox> #include <QAccessibleActionInterface> class LogDisplay : public QWidget { Q_OBJECT public: LogDisplay() { textEdit.setReadOnly(true); layout.addWidget(&textEdit); setLayout(&layout); QMenuBar *menuBar = new QMenuBar(this); QMenu *filterMenu = menuBar->addMenu("Filter"); infoCheckBox = new QCheckBox("INFO", this); infoCheckBox->setChecked(true); filterMenu->addAction(infoCheckBox->toggleAction()); **/Here is the error** connect(infoCheckBox, &QCheckBox::stateChanged, this, &LogDisplay::refresh); debugCheckBox = new QCheckBox("DEBUG", this); debugCheckBox->setChecked(true); filterMenu->addAction(debugCheckBox->toggleAction()); connect(debugCheckBox, &QCheckBox::stateChanged, this, &LogDisplay::refresh); warningCheckBox = new QCheckBox("WARNING", this); warningCheckBox->setChecked(true); filterMenu->addAction(warningCheckBox->toggleAction()); connect(warningCheckBox, &QCheckBox::stateChanged, this, &LogDisplay::refresh); refresh(); QTimer *timer = new QTimer(this); connect(timer, &QTimer::timeout, this, &LogDisplay::refresh); timer->start(5000); } void refresh() { QStringList args; args << "-n" << "10" << "/path/to/logfile.txt"; if (!infoCheckBox->isChecked() || !debugCheckBox->isChecked() || !warningCheckBox->isChecked()) { args << "|" << "grep"; if (infoCheckBox->isChecked()) args << "-E" << "INFO"; if (debugCheckBox->isChecked()) args << "-E" << "DEBUG"; if (warningCheckBox->isChecked()) args << "-E" << "WARNING"; } process.start("sh", QStringList() << "-c" << args.join(" ")); process.waitForFinished(); if (process.exitCode() != 0) { QMessageBox::critical(this, "Error", process.readAllStandardError()); return; } QByteArray output = process.readAllStandardOutput(); textEdit.setPlainText(output); } private: QVBoxLayout layout; QTextEdit textEdit; QProcess process; QCheckBox *infoCheckBox; QCheckBox *debugCheckBox; QCheckBox *warningCheckBox; }; int main(int argc, char *argv[]) { QApplication app(argc, argv); LogDisplay window; window.show(); return app.exec(); }@Aviral-0 said in The Logs are not showing in Application Window.:
filterMenu->addAction(infoCheckBox->toggleAction());
This can't work.
Please check https://doc.qt.io/qt-6/qaction.html to see how to add actions to a menu.
To make an action a checkable action use https://doc.qt.io/qt-6/qaction.html#checkable-prop -
@jsulm Yes, I want a application which displays Recent 10 Lines of Logs from a Log File. And it should be updating dynamically, any change in log file appears in real time in application window.
Secondly, User be able to pause the Log updates and Be able to select or copy any log lines.
Third, a checkbox filter to filter the application with log types: like If I click on INFO then it should display only INFO logs, similarly for DEBUG and WARN.
The Base version code is this which runs and displays last 10 Logs but is not dynamically updating new logs from file:
#include <QApplication> #include <QProcess> #include <QTextEdit> #include <QVBoxLayout> #include <QWidget> int main(int argc, char *argv[]) { QApplication app(argc, argv); QWidget window; QVBoxLayout layout(&window); QTextEdit textEdit; layout.addWidget(&textEdit); window.show(); QProcess process; process.start("tail", QStringList() << "-n" << "10" << "/home/arpitk/QT Projects/logtail1/sample.log"); process.waitForFinished(); QByteArray output = process.readAllStandardOutput(); textEdit.setPlainText(output); return app.exec(); }@Aviral-0 said in The Logs are not showing in Application Window.:
The Base version code is this which runs and displays last 10 Logs but is not dynamically updating new logs from file:
Since you use
tailwithout the-foption.As stated by @jsulm a better way is
@Aviral-0 You can open the file, seek to file end and then connect a slot to https://doc.qt.io/qt-6/qfilesystemwatcher.html#fileChanged signal. In the slot you simply read to the end of the file and add the data you read to your log widget.
or just a
QTimerinstead ofQFileSystemWatcher. Last time of saying this, up to you which way you go.