[mythtv] New patch: Event log in database

Matt White whitem at arts.usask.ca
Tue Feb 24 01:14:34 EST 2004


Joseph A. Caputo wrote:
> You can fool CVS into thinking you added a file locally by adding an 
> entry to the CVS/Entries file in the appropriate directory, like so:
> 
> (file mythtv/contrib/CVS/Entries):
> /mythmaillog.pl/0/Initial mythmaillog//

Excellent!  I tried faking an entry, but I didn't get the format
right, apparently.

Attached is the complete patch, including both new scripts for /contrib.

-- 
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/mythflushlog.pl
===================================================================
RCS file: contrib/mythflushlog.pl
diff -N contrib/mythflushlog.pl
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ contrib/mythflushlog.pl	24 Feb 2004 06:11:26 -0000
@@ -0,0 +1,63 @@
+#!/usr/bin/perl
+##
+## Script to purge old acknowledged log entries
+## from the database
+##
+## 16 Jan 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
+##
+
+# How many days of events do you want to keep (in days?)
+# The script will delete all acknowledged events older
+# than this
+$howmanydays = 14;
+
+# Absolute outer bound of how long to keep an event.
+# The script will delete any events older than this, 
+# even if it has not been acknowledged.
+$maxage = 30;
+
+# Database connection details for Myth DB
+$dbhost = "localhost";
+$dbname = "mythconverg";
+$dbuser = "mythtv";
+$dbpass = "mythtv";
+
+##
+## End of User-configurable settings
+##
+
+my $dbh = 
+DBI->connect("dbi:mysql:database=$dbname:host=$dbhost","$dbuser","$dbpass") or
+		 die "Cannot connect to database ($!)\n";
+
+$oneday = 60*60*25;
+$now = time();
+$ack = $now - ($oneday * $howmanydays);
+$max = $now - ($oneday * $maxage);
+
+($sec,$min,$hour,$mday,$mon,$year,$wday,$yday,$isdst) = 
+        localtime($ack);
+$ackdate = sprintf("%4d-%02d-%02d",$year+1900,$mon+1,$mday);
+($sec,$min,$hour,$mday,$mon,$year,$wday,$yday,$isdst) = 
+        localtime($max);
+$maxdate = sprintf("%4d-%02d-%02d",$year+1900,$mon+1,$mday);
+
+$q = "delete from mythlog where logdate<'$ackdate' and acknowledged=1";
+$sth = $dbh->prepare($q);
+$sth->execute or die "Could not execute ($q)\n";
+
+$q = "delete from mythlog where logdate<'$maxdate'";
+$sth = $dbh->prepare($q);
+$sth->execute or die "Could not execute ($q)\n";
+
+exit(0);
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	24 Feb 2004 06:11: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	24 Feb 2004 06:11:32 -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	24 Feb 2004 06:11: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	24 Feb 2004 06:11:39 -0000
@@ -8,7 +8,7 @@
 
 #include "mythcontext.h"
 
-const QString currentDatabaseVersion = "1033";
+const QString currentDatabaseVersion = "1034";
 
 void UpdateDBVersionNumber(const QString &newnumber)
 {
@@ -638,7 +638,25 @@
 };
         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"
+");",
+""
 };
+        performActualUpdate(updates, "1034", dbver);
+    }
+
+}
 
 void InitializeDatabase(void)
 {
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	24 Feb 2004 06:11:39 -0000
@@ -51,6 +51,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 +90,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;
     }
 
@@ -436,6 +443,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 +455,8 @@
     else
     {
         cerr << "Running as a slave backend.\n";
+        gContext->LogEntry("mythbackend",LP_INFO,
+                           "MythBackend started as a slave backend","");
     }
  
     bool runsched = setupTVs(ismaster);
@@ -503,6 +515,8 @@
     a.exec();
 
     // delete trans;
+    gContext->LogEntry("mythbackend",LP_INFO,
+                       "MythBackend exiting","");
 
     cleanup();
 
Index: programs/mythfilldatabase/filldata.cpp
===================================================================
RCS file: /var/lib/mythcvs/mythtv/programs/mythfilldatabase/filldata.cpp,v
retrieving revision 1.90
diff -u -w -r1.90 filldata.cpp
--- programs/mythfilldatabase/filldata.cpp	13 Feb 2004 05:59:34 -0000	1.90
+++ programs/mythfilldatabase/filldata.cpp	24 Feb 2004 06:11:45 -0000
@@ -2051,6 +2051,7 @@
         return -1;
     }
 
+    gContext->LogEntry("mythfilldatabase",LP_INFO,"Listings Download Started","");
     if (from_xawfile)
     {
         readXawtvChannels(fromxawfile_id, fromxawfile_name);
@@ -2088,6 +2089,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);
              }
         }
@@ -2102,6 +2104,7 @@
         if (!ret)
         {
              cerr << "Failed to fetch some program info\n";
+             gContext->LogEntry("mythfilldatabase",LP_WARNING,"Failed to fetch some program info","");
              exit(1);
         }
     }
@@ -2116,6 +2119,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.139
diff -u -w -r1.139 globalsettings.cpp
--- programs/mythfrontend/globalsettings.cpp	16 Feb 2004 06:43:43 -0000	1.139
+++ programs/mythfrontend/globalsettings.cpp	24 Feb 2004 06:11:51 -0000
@@ -966,6 +966,18 @@
     };
 };
 
+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 XineramaScreen: public SpinBoxSetting, public GlobalSetting {
 public:
     XineramaScreen():
@@ -1664,6 +1676,7 @@
     general->addChild(new HaltCommand());
     general->addChild(new SetupPinCodeRequired());
     general->addChild(new SetupPinCode());
+    general->addChild(new LogEnabled());
     general->addChild(new EnableMediaMon());
     general->addChild(new EnableXbox());
     addChild(general);


More information about the mythtv-dev mailing list