[mythtv] [Patch] Logging to database PLUS automatic mythfilldatabase

Matt White whitem at arts.usask.ca
Wed Feb 25 20:27:41 EST 2004


OK - here's the latest version of my db logging patch.  The changes are:

* uses the same numbering as unix syslog() priorities (make sure you
   update to the newest mythlog - see below for URL).

* on Isaac's suggestion, I've incorporated the 'mythflushlog.pl' script
   functionality into mythbackend.  Go into Settings->General, and on the
   third page, you will be able to enable/disable database logging, and
   also enable/disable the log cleaning functionality and set the
   frequency of the cleaning.

* While I was doing that, I figured I'd add a generic "Housekeeping"
   thread.  Currently, the housekeeping thread has two tasks - cleaning
   the log table, and running mythfilldatabase.  Configuration is done
   in Settings->General.  For running mythfilldatabase, configuration
   includes:
     * enable/disable automatic execution
     * frequency of execution (# days)
     * limits on when to run it (ie. only between certain hours)
     * path and arguments for mythfilldatabase
     * path for logfile for mythfilldatabase output

I figured as long as I was doing a housekeeping thread, mythfilldatabase
was a big one.  It's got some advantages - easier to configure, no
worries about QTDIR being set (it has to be set to run mythbackend, so
it'll be inherited).

I've also added a table to store the timestamps of the last run of each
of the housekeeping items.  Both this table and the logging table have
been added to dbcheck.cpp.

Everything I've added is turned off by default.  Other defaults are:

   Log Cleaning frequency: 14 days
   Mythfilldatabase frequency: 1 day
   Mythfilldatabase hour restriction: between 2 AM and 5 AM
   Mythfilldatabase path: /usr/local/bin/mythfilldatabase
   Mythfilldatabase args: none
   Mythfilldatabase logfile: /var/log/mythfilldatabase.log

As mentioned above, the mythlog module has been updated as well to make
the priorities correct.  It can be downloaded from:

http://borris.usask.ca/mythtv/mythlog-0.2.tar.gz

Attached are two patches.  The big one is what I've described above.
The second is a patch to the mainmenu.xml and main_settings.xml
to add the MythLog module to the menus.

-- 
Matt White                          whitem at arts.usask.ca
Arts and Science Computer Labs      University of Saskatchewan

It sure is Monday... Ain't it a sin
I've gotta work my way thru the week again.
	- Mark Chesnutt..."Sure Is Monday"
-------------- next part --------------
Index: contrib/mythmaillog.pl
===================================================================
RCS file: contrib/mythmaillog.pl
diff -N contrib/mythmaillog.pl
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ contrib/mythmaillog.pl	26 Feb 2004 01:18:27 -0000
@@ -0,0 +1,133 @@
+#!/usr/bin/perl
+##
+## Script to email database log entries.
+##
+## 21 Feb 04	1.0	Initial version
+##
+## written by Matt White (whitem at arts.usask.ca)
+## 
+## Remember to edit the settings below to your taste
+##
+
+use DBI;
+
+## 
+## User Configurable Settings
+##
+
+# The email address to send the logs to
+# ** REMEMBER TO ESCAPE THE @ SYMBOL!! **
+$mailto = "someone\@somewhere.changeme";
+
+# The "from" address used in the sent mail
+# ** REMEMBER TO ESCAPE THE @ SYMBOL!! **
+$mailfrom = "someoneelse\@somewhere.changeme";
+
+# Location of your sendmail binary
+$sendmail = "/usr/sbin/sendmail";
+
+# What do you want to get?
+# 1 = Mail out all unacknowledged log entries
+# 2 = Mail out all entries since last email was sent
+$mailwhat = 1;
+
+# Do you want to automatically acknowledge entries that
+# were sent out?  Yes=1, No=0
+$autoack = 1;
+
+# Database connection details for Myth DB
+$dbhost = "localhost";
+$dbname = "mythconverg";
+$dbuser = "mythtv";
+$dbpass = "mythtv";
+
+##
+## End of User-configurable settings
+##
+
+my @priorities = ("Emergency","Alert","Critical","Error","Warning","Notice",
+                  "Info","Debug");
+my $dbh = 
+DBI->connect("dbi:mysql:database=$dbname:host=$dbhost","$dbuser","$dbpass") or
+		 die "Cannot connect to database ($!)\n";
+if ($mailwhat == 2) {
+    $q = "select data from settings where value = 'LogLastEmail'";
+    $sth = $dbh->prepare($q);
+    $numrows = $sth->execute or die "Could not execute ($q)\n";
+    if ($numrows!=0) {
+        @row=$sth->fetchrow_array;
+        $lastemail = 0 + $row[0];
+    } else {
+        $lastemail = 0;
+    }
+    ($sec,$min,$hour,$mday,$mon,$year,$wday,$yday,$isdst) = 
+        localtime($lastemail);
+    $lastdate = sprintf("%4d-%02d-%02dT%02d:%02d:%02d",$year+1900,$mon+1,
+        $mday,$hour,$min,$sec);
+
+    $where = "(logdate > '$lastdate')";
+} else {
+    $where = "(acknowledged = 0)";
+}
+
+$now = time();
+$email = "";
+$q = "select logid,module,priority,acknowledged,logdate,host," .
+     "message,details from mythlog where $where order by logdate";
+$sth = $dbh->prepare($q);
+$numrows = $sth->execute or die "Could not execute ($q)\n";
+while (@row = $sth->fetchrow_array) {
+    $logid = $row[0];
+    $module = $row[1];
+    $priority = $row[2];
+    $ack = $row[3];
+    $logdate = $row[4];
+    $host = $row[5];
+    $message = $row[6];
+    $details = $row[7];
+    if ($mailwhat == 2) {
+        if ($ack == 1) {
+            $printack = "Acknowledged: Yes";
+        } else {
+            $printack = "Acknowledged: No";
+        }
+    } else {
+        $printack = "";
+    }
+
+    $email .= sprintf("%-20s %-15s %s\n",$logdate,$host,$message);
+    $email .= sprintf("    Module: %-20s Priority: %-12s %s\n\n",$module,$priority,
+                      $printack);
+}
+
+if ($numrows == 0) {
+    exit(0);
+}
+
+if ($autoack == 1) {
+    $q = "update mythlog set acknowledged = 1 where $where";
+    $sth = $dbh->prepare($q);
+    $sth->execute or die "Could not execute ($q)\n";
+}
+
+if ($mailwhat == 2) {
+    if ($lastemail == 0) {
+        $q = "insert into settings (value,data) values ('LogLastEmail','$now')";
+    } else {
+        $q = "update settings set data='$now' where value='LogLastEmail'";
+    }
+    $sth = $dbh->prepare($q);
+    $sth->execute or die "Could not execute ($q)\n";
+}
+
+($sec,$min,$hour,$mday,$mon,$year,$wday,$yday,$isdst) = 
+        localtime($now);
+$subject = sprintf("Myth Event Report for %4d-%02d-%02d",$year+1900,$mon+1,$mday);
+open MAIL,"| $sendmail -t";
+print MAIL "From: $mailfrom\n";
+print MAIL "To: $mailto\n";
+print MAIL "Subject: $subject\n\n";
+print MAIL $email;
+close MAIL;
+
+exit(0);
Index: libs/libmyth/mythcontext.cpp
===================================================================
RCS file: /var/lib/mythcvs/mythtv/libs/libmyth/mythcontext.cpp,v
retrieving revision 1.110
diff -u -w -r1.110 mythcontext.cpp
--- libs/libmyth/mythcontext.cpp	5 Feb 2004 22:50:36 -0000	1.110
+++ libs/libmyth/mythcontext.cpp	26 Feb 2004 01:18:33 -0000
@@ -845,6 +845,33 @@
     return retval.toInt();
 }
 
+void MythContext::LogEntry(const QString &module, int priority,
+                     const QString &message, const QString &details)
+{
+    if (gContext->GetNumSetting("LogEnabled", 0) == 1)
+    {
+        d->dbLock.lock();
+    
+        if (d->m_db->isOpen())
+        {
+            KickDatabase(d->m_db);
+    
+            QString querystr = QString("INSERT INTO mythlog ( module, priority, "
+                                       "logdate, host, message, details) "
+                                       "values ( '%1', %2, now(), '%3', "
+                                       "'%4','%5' );") . arg(module) .
+                                       arg(priority) . arg(d->m_localhostname) .
+                                       arg(message) . arg(details);
+    
+            QSqlQuery result = d->m_db->exec(querystr);
+            if (!result.isActive())
+                MythContext::DBError("LogEntry", querystr);
+        }
+    
+        d->dbLock.unlock();
+    }
+}
+
 QString MythContext::GetSettingOnHost(const QString &key, const QString &host,
                                       const QString &defaultval)
 {
Index: libs/libmyth/mythcontext.h
===================================================================
RCS file: /var/lib/mythcvs/mythtv/libs/libmyth/mythcontext.h,v
retrieving revision 1.128
diff -u -w -r1.128 mythcontext.h
--- libs/libmyth/mythcontext.h	17 Feb 2004 01:13:19 -0000	1.128
+++ libs/libmyth/mythcontext.h	26 Feb 2004 01:18:33 -0000
@@ -42,6 +42,17 @@
     VB_ALL       = 0xffff
 };
 
+enum LogPriorities {
+    LP_EMERG     = 0,
+    LP_ALERT     = 1,
+    LP_CRITICAL  = 2,
+    LP_ERROR     = 3,
+    LP_WARNING   = 4,
+    LP_NOTICE    = 5,
+    LP_INFO      = 6,
+    LP_DEBUG     = 7
+};
+
 #define VERBOSE(mask,args...) \
 do { \
 if ((print_verbose_messages & mask) != 0) \
@@ -129,6 +140,9 @@
     QString GetSetting(const QString &key, const QString &defaultval = "");
     int GetNumSetting(const QString &key, int defaultval = 0);
 
+    void LogEntry(const QString &module, int priority,
+                  const QString &message, const QString &details);
+
     QString GetSettingOnHost(const QString &key, const QString &host,
                              const QString &defaultval = "");
     int GetNumSettingOnHost(const QString &key, const QString &host,
Index: libs/libmythtv/dbcheck.cpp
===================================================================
RCS file: /var/lib/mythcvs/mythtv/libs/libmythtv/dbcheck.cpp,v
retrieving revision 1.35
diff -u -w -r1.35 dbcheck.cpp
--- libs/libmythtv/dbcheck.cpp	12 Feb 2004 05:58:02 -0000	1.35
+++ libs/libmythtv/dbcheck.cpp	26 Feb 2004 01:18:41 -0000
@@ -8,7 +8,7 @@
 
 #include "mythcontext.h"
 
-const QString currentDatabaseVersion = "1033";
+const QString currentDatabaseVersion = "1034";
 
 void UpdateDBVersionNumber(const QString &newnumber)
 {
@@ -638,7 +638,29 @@
 };
         performActualUpdate(updates, "1033", dbver);
     }
+    if (dbver == "1033")
+    {
+        const QString updates[] = {
+"CREATE TABLE mythlog ("
+"  logid int(10) unsigned PRIMARY KEY NOT NULL auto_increment,"
+"  module char(32) NOT NULL,"
+"  priority int(11) NOT NULL,"
+"  acknowledged bool default 0,"
+"  logdate datetime,"
+"  host varchar(128),"
+"  message varchar(255) NOT NULL,"
+"  details text"
+");",
+"CREATE TABLE housekeeping ("
+"  tag varchar(64) PRIMARY KEY NOT NULL,"
+"  lastrun datetime"
+");",
+""
 };
+        performActualUpdate(updates, "1034", dbver);
+    }
+
+}
 
 void InitializeDatabase(void)
 {
Index: programs/mythbackend/housekeeper.cpp
===================================================================
RCS file: programs/mythbackend/housekeeper.cpp
diff -N programs/mythbackend/housekeeper.cpp
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ programs/mythbackend/housekeeper.cpp	26 Feb 2004 01:18:41 -0000
@@ -0,0 +1,206 @@
+#include <unistd.h>
+#include <sys/types.h>
+#include <sys/wait.h>
+#include <signal.h>
+#include <unistd.h>
+#include <qsqldatabase.h>
+#include <qsqlquery.h>
+#include <qstring.h>
+#include <qdatetime.h>
+#include <qstringlist.h>
+
+#include <iostream>
+using namespace std;
+
+#include "housekeeper.h"
+
+#include "libmyth/mythcontext.h"
+
+bool HouseKeeper_filldb_running = false;
+
+void reapChild(int sig)
+{
+    (void) wait(0);
+    HouseKeeper_filldb_running = false;
+}
+
+HouseKeeper::HouseKeeper(bool runthread, bool master, QSqlDatabase *ldb)
+{
+    db = ldb;
+    isMaster = master;
+
+    threadrunning = runthread;
+    filldbRunning = false;
+
+    if (runthread)
+    {
+        pthread_t hkthread;
+        pthread_create(&hkthread, NULL, doHouseKeepingThread, this);
+        gContext->addListener(this);
+    }
+}
+
+HouseKeeper::~HouseKeeper()
+{
+    if (threadrunning)
+        gContext->removeListener(this);
+}
+
+bool HouseKeeper::wantToRun(QString dbTag, int period, int minhour,
+                            int maxhour)
+{
+    bool runOK = false;
+    unsigned int oneday = 60 * 60 * 24;
+
+    QDateTime now = QDateTime::currentDateTime();
+    QDateTime lastrun;
+    lastrun.setTime_t(0);
+    if (db->isOpen())
+    {
+        gContext->KickDatabase(db);
+        QString query = QString("SELECT lastrun FROM housekeeping WHERE "
+                                "tag = \"%1\";") .arg(dbTag);
+        QSqlQuery result = db->exec(query);
+        if (result.isActive() && result.numRowsAffected() > 0)
+        {
+            result.next();
+            lastrun = result.value(0).toDateTime();
+        }
+    }
+
+    if ((now.toTime_t() - lastrun.toTime_t()) > period * oneday)
+    {
+        int hour = now.toString(QString("h")).toInt();
+        if ((hour>=minhour) && (hour<=maxhour))
+            runOK = true;       
+    }
+    return(runOK);
+}
+
+void HouseKeeper::updateLastrun(QString dbTag)
+{
+    if (db->isOpen())
+    {
+        gContext->KickDatabase(db);
+        QString query = QString("DELETE FROM housekeeping WHERE "
+                                "tag = \"%1\";") .arg(dbTag);
+        QSqlQuery result = db->exec(query);
+        query = QString("INSERT INTO housekeeping (tag,lastrun) "
+                        "values (\"%1\",now())") .arg(dbTag);
+        result = db->exec(query);
+    }
+}
+
+void HouseKeeper::RunHouseKeeping(void)
+{
+    int period,maxhr,minhr;
+    // wait a little for main server to come up and things to settle down
+    sleep(10);
+
+    while (1)
+    {
+        // These tasks are only done from the master backend
+        if (isMaster)
+        {
+            // Clean out old database entries
+            if ((bool) gContext->GetNumSetting("LogEnabled", 0) &&
+               (bool) gContext->GetNumSetting("LogCleanEnabled", 0))
+            {
+                period = gContext->GetNumSetting("LogCleanPeriod",1);
+                if (wantToRun(QString("LogClean"),period,0,24))
+                {
+                    QString msg = QString("Running LogClean");
+                    VERBOSE(VB_GENERAL, msg);
+                    flushLogs();
+                    updateLastrun(QString("LogClean"));
+                }
+            }
+
+            // Run mythfilldatabase to grab the TV listings
+            if ((bool) gContext->GetNumSetting("MythFillEnabled", 0))
+            {
+                if (HouseKeeper_filldb_running)
+                {
+                    QString msg = QString("mythfilldatabase still running, skipping checks");
+                    VERBOSE(VB_GENERAL, msg);
+                } else {
+                    period = gContext->GetNumSetting("MythFillPeriod",1);
+                    minhr = gContext->GetNumSetting("MythFillMinHour",-1);
+                    if (minhr == -1)
+                    {
+                        minhr = 0;
+                        maxhr = 24;
+                    } else {
+                        maxhr = gContext->GetNumSetting("MythFillMaxHour",24);
+                    }
+                    if (wantToRun(QString("MythFillDB"),period,minhr,maxhr))
+                    {
+                        QString msg = QString("Running mythfilldatabase");
+                        VERBOSE(VB_GENERAL, msg);
+                        runFillDatabase();
+                        updateLastrun(QString("MythFillDB"));
+                    }
+                }
+            }
+        }
+    
+        sleep(1800);
+    }
+} 
+
+void HouseKeeper::flushLogs()
+{
+    int numdays = gContext->GetNumSetting("LogCleanDays",14);
+    int maxdays = gContext->GetNumSetting("LogCleanMax",30);
+
+    QDateTime days = QDateTime::currentDateTime();
+    days.addDays(0-numdays);
+    QDateTime max = QDateTime::currentDateTime();
+    max.addDays(0-maxdays);
+
+    if (db->isOpen())
+    {
+        gContext->KickDatabase(db);
+        QString dstring = days.toString(QString("yyyy-MM-dd hh:mm:ss"));
+        QString query = QString("DELETE FROM mythlog WHERE "
+                                "acknowledged=1 and logdate<\"%1\";")
+                                .arg(dstring);
+        QSqlQuery result = db->exec(query);
+
+        dstring = max.toString(QString("yyyy-MM-dd hh:mm:ss"));
+        query = QString("DELETE FROM mythlog WHERE logdate<\"%1\";")
+                                .arg(dstring);
+        result = db->exec(query);
+    }
+}
+
+void HouseKeeper::runFillDatabase()
+{
+    QString command;
+
+    QString mfpath = gContext->GetSetting("MythFillDatabasePath","/usr/local/bin/mythfilldatabase");
+    QString mfarg = gContext->GetSetting("MythFillDatabaseArgs","");
+    QString mflog = gContext->GetSetting("MythFillDatabaseLog","/var/log/mythfilldatabase.log");
+
+    if (mflog == "")
+        command = QString("%1 %2") .arg(mfpath) .arg(mfarg);
+    else
+        command = QString("%1 %2 >>%3 2>&1") .arg(mfpath) 
+                                  .arg(mfarg) .arg(mflog);
+    
+    signal(SIGCHLD,&reapChild);
+    HouseKeeper_filldb_running = true;
+    if (fork() == 0)
+    {
+        system(command.ascii());
+        exit(0);
+    }
+}
+
+void *HouseKeeper::doHouseKeepingThread(void *param)
+{
+    HouseKeeper *hkeeper = (HouseKeeper *)param;
+    hkeeper->RunHouseKeeping();
+ 
+    return NULL;
+}
Index: programs/mythbackend/housekeeper.h
===================================================================
RCS file: programs/mythbackend/housekeeper.h
diff -N programs/mythbackend/housekeeper.h
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ programs/mythbackend/housekeeper.h	26 Feb 2004 01:18:41 -0000
@@ -0,0 +1,38 @@
+#ifndef HOUSEKEEPER_H_
+#define HOUSEKEEPER_H_
+
+class QSqlDatabase;
+
+#include <qmutex.h>
+#include <qobject.h>
+#include <qfile.h>
+#include <qtextstream.h>
+#include <qprocess.h>
+
+using namespace std;
+
+class HouseKeeper : public QObject
+{
+    Q_OBJECT
+  public:
+    HouseKeeper(bool runthread, bool master, QSqlDatabase *ldb);
+   ~HouseKeeper();
+
+  protected:
+    void RunHouseKeeping(void);
+    static void *doHouseKeepingThread(void *param);
+
+
+  private:
+    QSqlDatabase *db;
+
+    bool wantToRun(QString dbTag, int period, int minhour, int maxhour);
+    void updateLastrun(QString dbTag);
+    void flushLogs();
+    void runFillDatabase();
+    bool threadrunning;
+    bool filldbRunning;
+    bool isMaster;
+};
+
+#endif
Index: programs/mythbackend/main.cpp
===================================================================
RCS file: /var/lib/mythcvs/mythtv/programs/mythbackend/main.cpp,v
retrieving revision 1.58
diff -u -w -r1.58 main.cpp
--- programs/mythbackend/main.cpp	10 Feb 2004 03:34:25 -0000	1.58
+++ programs/mythbackend/main.cpp	26 Feb 2004 01:18:41 -0000
@@ -14,6 +14,7 @@
 
 #include "tv.h"
 #include "autoexpire.h"
+#include "housekeeper.h"
 #include "scheduler.h"
 #include "transcoder.h"
 #include "mainserver.h"
@@ -26,6 +27,7 @@
 
 QMap<int, EncoderLink *> tvList;
 AutoExpire *expirer = NULL;
+HouseKeeper *housekeeping = NULL;
 Scheduler *sched = NULL;
 Transcoder *trans = NULL;
 QString pidfile;
@@ -51,6 +53,11 @@
                 cerr << "One of your capturecard entries does not have a "
                      << "hostname.\n  Please run setup and confirm all of the "
                      << "capture cards.\n";
+                gContext->LogEntry("mythbackend",LP_CRITICAL,
+                      "Problem with capture cards",
+                      "One of your capturecard entries does not have a "
+                      "hostname.\n  Please run setup and confirm all of the "
+                      "capture cards.\n");
                 exit(-1);
             }
 
@@ -85,6 +92,8 @@
     {
         cerr << "ERROR: no capture cards are defined in the database.\n";
         cerr << "Perhaps you should read the installation instructions?\n";
+        gContext->LogEntry("mythbackend",LP_CRITICAL,
+                "No capture cards are defined","Please run the setup program.");
         return false;
     }
 
@@ -360,6 +369,13 @@
         return -1;
     }
 
+    QSqlDatabase *hkthread = QSqlDatabase::addDatabase("QMYSQL3", "HKDB");
+    if (!hkthread)
+    {
+        cerr << "Couldn't connect to database\n";
+        return -1;
+    }
+
     QSqlDatabase *transthread = QSqlDatabase::addDatabase("QMYSQL3", "TRANSDB");
     if (!transthread)
     {
@@ -376,6 +392,7 @@
 
     if (!gContext->OpenDatabase(db) || !gContext->OpenDatabase(subthread) ||
         !gContext->OpenDatabase(expthread) ||
+        !gContext->OpenDatabase(hkthread) ||
         !gContext->OpenDatabase(transthread) ||
         !gContext->OpenDatabase(msdb))
     {
@@ -436,6 +453,9 @@
     if (masterip == myip)
     {
         cerr << "Starting up as the master server.\n";
+        gContext->LogEntry("mythbackend",LP_INFO,
+                           "MythBackend started as master server","");
+
         ismaster = true;
 
         if (nosched)
@@ -445,6 +465,8 @@
     else
     {
         cerr << "Running as a slave backend.\n";
+        gContext->LogEntry("mythbackend",LP_INFO,
+                           "MythBackend started as a slave backend","");
     }
  
     bool runsched = setupTVs(ismaster);
@@ -458,6 +480,10 @@
     QSqlDatabase *expdb = QSqlDatabase::database("EXPDB");
     expirer = new AutoExpire(true, ismaster, expdb);
 
+    printf("here.\n");
+    QSqlDatabase *hkdb = QSqlDatabase::database("HKDB");
+    housekeeping = new HouseKeeper(true, ismaster, hkdb);
+
     QSqlDatabase *trandb = QSqlDatabase::database("TRANSDB");
     trans = new Transcoder(&tvList, trandb);
 
@@ -503,6 +529,8 @@
     a.exec();
 
     // delete trans;
+    gContext->LogEntry("mythbackend",LP_INFO,
+                       "MythBackend exiting","");
 
     cleanup();
 
Index: programs/mythbackend/mythbackend.pro
===================================================================
RCS file: /var/lib/mythcvs/mythtv/programs/mythbackend/mythbackend.pro,v
retrieving revision 1.12
diff -u -w -r1.12 mythbackend.pro
--- programs/mythbackend/mythbackend.pro	1 Jan 2004 03:38:45 -0000	1.12
+++ programs/mythbackend/mythbackend.pro	26 Feb 2004 01:18:41 -0000
@@ -19,8 +19,8 @@
 
 # Input
 HEADERS += autoexpire.h encoderlink.h filetransfer.h httpstatus.h mainserver.h
-HEADERS += playbacksock.h scheduler.h server.h transcoder.h
+HEADERS += playbacksock.h scheduler.h server.h transcoder.h housekeeper.h
 
 SOURCES += autoexpire.cpp encoderlink.cpp filetransfer.cpp httpstatus.cpp
 SOURCES += main.cpp mainserver.cpp playbacksock.cpp scheduler.cpp server.cpp
-SOURCES += transcoder.cpp
+SOURCES += transcoder.cpp housekeeper.cpp
Index: programs/mythfilldatabase/filldata.cpp
===================================================================
RCS file: /var/lib/mythcvs/mythtv/programs/mythfilldatabase/filldata.cpp,v
retrieving revision 1.92
diff -u -w -r1.92 filldata.cpp
--- programs/mythfilldatabase/filldata.cpp	24 Feb 2004 09:26:03 -0000	1.92
+++ programs/mythfilldatabase/filldata.cpp	26 Feb 2004 01:18:51 -0000
@@ -2131,6 +2131,7 @@
         return -1;
     }
 
+    gContext->LogEntry("mythfilldatabase",LP_INFO,"Listings Download Started","");
     if (from_xawfile)
     {
         readXawtvChannels(fromxawfile_id, fromxawfile_name);
@@ -2168,6 +2169,7 @@
              {
                   cerr << "There are no channel sources defined, did you run the "
                        << "setup program?\n";
+                  gContext->LogEntry("mythfilldatabase",LP_CRITICAL,"No channel sources defined","Could not find any defined channel sources - did you run the setup program?");
                   exit(-1);
              }
         }
@@ -2182,6 +2184,7 @@
         if (!ret)
         {
              cerr << "Failed to fetch some program info\n";
+             gContext->LogEntry("mythfilldatabase",LP_WARNING,"Failed to fetch some program info","");
              exit(1);
         }
     }
@@ -2196,6 +2199,7 @@
 
     ScheduledRecording::signalChange(db);
 
+    gContext->LogEntry("mythfilldatabase",LP_INFO,"Listings Download Finished","");
     delete gContext;
 
     return 0;
Index: programs/mythfrontend/globalsettings.cpp
===================================================================
RCS file: /var/lib/mythcvs/mythtv/programs/mythfrontend/globalsettings.cpp,v
retrieving revision 1.142
diff -u -w -r1.142 globalsettings.cpp
--- programs/mythfrontend/globalsettings.cpp	24 Feb 2004 07:50:36 -0000	1.142
+++ programs/mythfrontend/globalsettings.cpp	26 Feb 2004 01:18:58 -0000
@@ -966,6 +966,175 @@
     };
 };
 
+class LogEnabled: public CheckBoxSetting, public GlobalSetting {
+public:
+    LogEnabled():
+        GlobalSetting("LogEnabled") {
+        setLabel(QObject::tr("DB Logging Enabled"));
+        setValue(false);
+        setHelpText(QObject::tr("If checked, the Myth modules will send event details "
+                    "to the database, where they can be viewed with MythLog or emailed "
+                    "out periodically."));
+    };
+};
+
+class LogCleanEnabled: public CheckBoxSetting, public GlobalSetting {
+public:
+    LogCleanEnabled():
+        GlobalSetting("LogCleanEnabled") {
+        setLabel(QObject::tr("Automatic Log Cleaning Enabled"));
+        setValue(false);
+        setHelpText(QObject::tr("This enables the periodic cleanup of the events stored "
+                    "in the Myth database (see 'DB Logging Enabled' on the previous "
+                    "page)."));
+    };
+};
+
+class LogCleanPeriod: public SpinBoxSetting, public GlobalSetting {
+public:
+    LogCleanPeriod():
+        SpinBoxSetting(0,60,1),
+        GlobalSetting("LogCleanPeriod") {
+        setLabel(QObject::tr("Log Cleanup Frequency (Days)"));
+        setValue(14);
+        setHelpText(QObject::tr("The number of days between log cleanup runs"));
+    };
+};
+
+class MythFillEnabled: public CheckBoxSetting, public GlobalSetting {
+public:
+    MythFillEnabled():
+        GlobalSetting("MythFillEnabled") {
+        setLabel(QObject::tr("Automatically run mythfilldatabase"));
+        setValue(false);
+        setHelpText(QObject::tr("This enables the automatic execution of "
+                                "mythfilldatabase."));
+    };
+};
+
+class MythFillPeriod: public SpinBoxSetting, public GlobalSetting {
+public:
+    MythFillPeriod():
+        SpinBoxSetting(0,30,1),
+        GlobalSetting("MythFillPeriod") {
+        setLabel(QObject::tr("mythfilldatabase Run Frequency (Days)"));
+        setValue(1);
+        setHelpText(QObject::tr("The number of days between mythfilldatabase runs"));
+    };
+};
+
+class MythFillMinHour: public SpinBoxSetting, public GlobalSetting {
+public:
+    MythFillMinHour():
+        SpinBoxSetting(0,24,1),
+        GlobalSetting("MythFillMinHour") {
+        setLabel(QObject::tr("mythfilldatabase Execution Start"));
+        setValue(2);
+        setHelpText(QObject::tr("This setting and the following one define a "
+                    "time period when the mythfilldatabase process is allowed to "
+                    "run.  Ex. setting Min to 11 and Max to 13 would mean that "
+                    "the process would only run between 11 AM and 1 PM."));
+    };
+};
+
+class MythFillMaxHour: public SpinBoxSetting, public GlobalSetting {
+public:
+    MythFillMaxHour():
+        SpinBoxSetting(0,24,1),
+        GlobalSetting("MythFillMaxHour") {
+        setLabel(QObject::tr("mythfilldatabase Execution End"));
+        setValue(5);
+        setHelpText(QObject::tr("This setting and the preceding one define a "
+                    "time period when the mythfilldatabase process is allowed to "
+                    "run.  Ex. setting Min to 11 and Max to 13 would mean that "
+                    "the process would only run between 11 AM and 1 PM."));
+    };
+};
+
+class MythFillDatabasePath: public LineEditSetting, public GlobalSetting {
+public:
+    MythFillDatabasePath():
+        GlobalSetting("MythFillDatabasePath") {
+        setLabel(QObject::tr("mythfilldatabase Path"));
+        setValue("/usr/local/bin/mythfilldatabase");
+        setHelpText(QObject::tr("Path (including executable) of the "
+                                "mythfilldatabase program."));
+    };
+};
+
+class MythFillDatabaseArgs: public LineEditSetting, public GlobalSetting {
+public:
+    MythFillDatabaseArgs():
+        GlobalSetting("MythFillDatabaseArgs") {
+        setLabel(QObject::tr("mythfilldatabase Arguments"));
+        setValue("");
+        setHelpText(QObject::tr("Any arguments you want passed to the "
+                                "mythfilldatabase program."));
+    };
+};
+
+class MythFillDatabaseLog: public LineEditSetting, public GlobalSetting {
+public:
+    MythFillDatabaseLog():
+        GlobalSetting("MythFillDatabaseLog") {
+        setLabel(QObject::tr("mythfilldatabase Log Path"));
+        setValue("/var/log/mythfilldatabase.log");
+        setHelpText(QObject::tr("Path to use for logging output from "
+                                "mythfilldatabase program.  Leave blank "
+				"to disable logging."));
+    };
+};
+
+class MythLogSettings: public VerticalConfigurationGroup,
+                      public TriggeredConfigurationGroup {
+public:
+     MythLogSettings():
+         VerticalConfigurationGroup(false),
+         TriggeredConfigurationGroup(false) {
+         setLabel(QObject::tr("Myth Database Logging"));
+//         setUseLabel(false);
+
+         Setting* logEnabled = new LogEnabled();
+         addChild(logEnabled);
+         setTrigger(logEnabled);
+
+         ConfigurationGroup* settings = new VerticalConfigurationGroup(false);
+         settings->addChild(new LogCleanEnabled());
+         settings->addChild(new LogCleanPeriod());
+         addTarget("1", settings);
+         
+         // show nothing if logEnabled is off
+         addTarget("0", new VerticalConfigurationGroup(true));
+     };
+};
+
+class MythFillSettings: public VerticalConfigurationGroup,
+                      public TriggeredConfigurationGroup {
+public:
+     MythFillSettings():
+         VerticalConfigurationGroup(false),
+         TriggeredConfigurationGroup(false) {
+         setLabel(QObject::tr("Mythfilldatabase"));
+         setUseLabel(false);
+
+         Setting* fillEnabled = new MythFillEnabled();
+         addChild(fillEnabled);
+         setTrigger(fillEnabled);
+
+         ConfigurationGroup* settings = new VerticalConfigurationGroup(false);
+         settings->addChild(new MythFillDatabasePath());
+         settings->addChild(new MythFillDatabaseArgs());
+         settings->addChild(new MythFillDatabaseLog());
+         settings->addChild(new MythFillPeriod());
+         settings->addChild(new MythFillMinHour());
+         settings->addChild(new MythFillMaxHour());
+         addTarget("1", settings);
+         
+         // show nothing if fillEnabled is off
+         addTarget("0", new VerticalConfigurationGroup(true));
+     };
+};
+
 class XineramaScreen: public SpinBoxSetting, public GlobalSetting {
 public:
     XineramaScreen():
@@ -1680,6 +1849,12 @@
     general->addChild(new EnableMediaMon());
     general->addChild(new EnableXbox());
     addChild(general);
+
+    MythLogSettings *mythlog = new MythLogSettings();
+    addChild(mythlog);
+
+    MythFillSettings *mythfill = new MythFillSettings();
+    addChild(mythfill);
 }
 
 PlaybackSettings::PlaybackSettings()
-------------- next part --------------
Index: main_settings.xml
===================================================================
RCS file: /var/lib/mythcvs/mythtv/programs/mythfrontend/main_settings.xml,v
retrieving revision 1.24
diff -u -w -r1.24 main_settings.xml
--- main_settings.xml	13 Feb 2004 06:01:42 -0000	1.24
+++ main_settings.xml	26 Feb 2004 01:24:55 -0000
@@ -149,6 +149,13 @@
    </button>
 
    <button>
+     <type>LOG</type>
+     <text>Event Viewer Settings</text>
+     <action>CONFIGPLUGIN mythlog</action>
+     <depends>mythlog</depends>
+   </button>
+
+   <button>
      <type>WEBPAGE</type>
      <text>Web Settings</text>
      <text lang="DE">WWW Einstellungen</text>
Index: mainmenu.xml
===================================================================
RCS file: /var/lib/mythcvs/mythtv/programs/mythfrontend/mainmenu.xml,v
retrieving revision 1.35
diff -u -w -r1.35 mainmenu.xml
--- mainmenu.xml	13 Feb 2004 06:01:42 -0000	1.35
+++ mainmenu.xml	26 Feb 2004 01:24:55 -0000
@@ -117,6 +117,13 @@
    </button>
 
    <button>
+     <type>LOG</type>
+     <text>Event Viewer</text>
+     <action>PLUGIN mythlog</action>
+     <depends>mythlog</depends>
+   </button>
+
+   <button>
       <type>WEBPAGE</type>
       <text>Web</text>
       <text lang="DE">WWW</text>


More information about the mythtv-dev mailing list