MythTV 0.25-pre
mythlogging.cpp
Go to the documentation of this file.
00001 #include <QMutex>
00002 #include <QMutexLocker>
00003 #include <QList>
00004 #include <QQueue>
00005 #include <QThread>
00006 #include <QHash>
00007 #include <QCoreApplication>
00008 
00009 #define _LogLevelNames_
00010 #include "mythlogging.h"
00011 #include "mythverbose.h"
00012 #include "mythconfig.h"
00013 #include "mythdb.h"
00014 #include "mythcorecontext.h"
00015 #include "dbutil.h"
00016 
00017 #include <stdlib.h>
00018 #define SYSLOG_NAMES
00019 #include <syslog.h>
00020 #include <stdarg.h>
00021 #include <string.h>
00022 #include <sys/stat.h>
00023 #include <sys/types.h>
00024 #include <fcntl.h>
00025 #include <stdio.h>
00026 #include <unistd.h>
00027 #if HAVE_GETTIMEOFDAY
00028 #include <sys/time.h>
00029 #endif
00030 #include <signal.h>
00031 
00032 // Various ways to get to thread's tid
00033 #if defined(linux)
00034 #include <sys/syscall.h>
00035 #elif defined(__FreeBSD__)
00036 #include <sys/ucontext.h>
00037 #include <sys/thr.h>
00038 #elif CONFIG_DARWIN
00039 #include <mach/mach.h>
00040 #endif
00041 
00042 QMutex                  loggerListMutex;
00043 QList<LoggerBase *>     loggerList;
00044 
00045 QMutex                  logQueueMutex;
00046 QQueue<LoggingItem_t *> logQueue;
00047 
00048 QMutex                  logThreadMutex;
00049 QHash<uint64_t, char *> logThreadHash;
00050 
00051 QMutex                   logThreadTidMutex;
00052 QHash<uint64_t, int64_t> logThreadTidHash;
00053 
00054 LoggerThread            logThread;
00055 bool                    debugRegistration = false;
00056 
00057 #define TIMESTAMP_MAX 30
00058 #define MAX_STRING_LENGTH 2048
00059 
00060 LogLevel_t LogLevel = LOG_UNKNOWN;  
00064 char *getThreadName( LoggingItem_t *item );
00065 int64_t getThreadTid( LoggingItem_t *item );
00066 void setThreadTid( LoggingItem_t *item );
00067 void deleteItem( LoggingItem_t *item );
00068 void logSighup( int signum, siginfo_t *info, void *secret );
00069 
00070 LoggerBase::LoggerBase(char *string, int number)
00071 {
00072     QMutexLocker locker(&loggerListMutex);
00073     if (string)
00074     {
00075         m_handle.string = strdup(string);
00076         m_string = true;
00077     }
00078     else
00079     {
00080         m_handle.number = number;
00081         m_string = false;
00082     }
00083     loggerList.append(this);
00084 }
00085 
00086 LoggerBase::~LoggerBase()
00087 {
00088     QMutexLocker locker(&loggerListMutex);
00089 
00090     QList<LoggerBase *>::iterator it;
00091 
00092     for(it = loggerList.begin(); it != loggerList.end(); it++)
00093     {
00094         if( *it == this )
00095         {
00096             loggerList.erase(it);
00097             break;
00098         }
00099     }
00100 
00101     if (m_string)
00102         free(m_handle.string);
00103 }
00104 
00105 
00106 FileLogger::FileLogger(char *filename) : LoggerBase(filename, 0),
00107                                          m_opened(false), m_fd(-1)
00108 {
00109     if( !strcmp(filename, "-") )
00110     {
00111         m_opened = true;
00112         m_fd = 1;
00113         LogPrint( VB_IMPORTANT, LOG_INFO, "Added logging to the console" );
00114     }
00115     else
00116     {
00117         m_fd = open(filename, O_WRONLY|O_CREAT|O_APPEND, 0664);
00118         m_opened = (m_fd != -1);
00119         LogPrint( VB_IMPORTANT, LOG_INFO, "Added logging to %s", filename );
00120     }
00121 }
00122 
00123 FileLogger::~FileLogger()
00124 {
00125     if( m_opened )
00126     {
00127         if( m_fd != 1 )
00128         {
00129             LogPrint( VB_IMPORTANT, LOG_INFO, "Removed logging to %s",
00130                       m_handle.string );
00131             close( m_fd );
00132         }
00133         else
00134             LogPrint( VB_IMPORTANT, LOG_INFO,
00135                       "Removed logging to the console" );
00136     }
00137 }
00138 
00139 void FileLogger::reopen(void)
00140 {
00141     char *filename = m_handle.string;
00142 
00143     // Skip console
00144     if( !strcmp(filename, "-") )
00145         return;
00146 
00147     close(m_fd);
00148 
00149     m_fd = open(filename, O_WRONLY|O_CREAT|O_APPEND, 0664);
00150     m_opened = (m_fd != -1);
00151     LogPrint( VB_IMPORTANT, LOG_INFO, "Rolled logging on %s", filename );
00152 }
00153 
00154 bool FileLogger::logmsg(LoggingItem_t *item)
00155 {
00156     char                line[MAX_STRING_LENGTH];
00157     char                usPart[9];
00158     char                timestamp[TIMESTAMP_MAX];
00159     int                 length;
00160     char               *threadName = NULL;
00161     pid_t               pid = getpid();
00162     pid_t               tid = 0;
00163 
00164     if (!m_opened)
00165         return false;
00166 
00167     strftime( timestamp, TIMESTAMP_MAX-8, "%Y-%m-%d %H:%M:%S",
00168               (const struct tm *)&item->tm );
00169     snprintf( usPart, 9, ".%06d", (int)(item->usec) );
00170     strcat( timestamp, usPart );
00171     length = strlen( timestamp );
00172 
00173     if (m_fd == 1)
00174     {
00175         // Stdout
00176         snprintf( line, MAX_STRING_LENGTH, "%s %c  %s\n", timestamp,
00177                   LogLevelShortNames[item->level], item->message );
00178     }
00179     else
00180     {
00181         threadName = getThreadName(item);
00182         tid = getThreadTid(item);
00183 
00184         if( tid )
00185             snprintf( line, MAX_STRING_LENGTH, 
00186                       "%s %c [%d/%d] %s %s:%d (%s) - %s\n",
00187                       timestamp, LogLevelShortNames[item->level], pid, tid,
00188                       threadName, item->file, item->line, item->function,
00189                       item->message );
00190         else
00191             snprintf( line, MAX_STRING_LENGTH,
00192                       "%s %c [%d] %s %s:%d (%s) - %s\n",
00193                       timestamp, LogLevelShortNames[item->level], pid,
00194                       threadName, item->file, item->line, item->function,
00195                       item->message );
00196     }
00197 
00198     int result = write( m_fd, line, strlen(line) );
00199 
00200     {
00201         QMutexLocker locker((QMutex *)item->refmutex);
00202         item->refcount--;
00203     }
00204 
00205     if( result == -1 )
00206     {
00207         LogPrint( VB_IMPORTANT, LOG_UNKNOWN,
00208                   "Closed Log output on fd %d due to errors", m_fd );
00209         m_opened = false;
00210         if( m_fd != 1 )
00211             close( m_fd );
00212         return false;
00213     }
00214     return true;
00215 }
00216 
00217 
00218 SyslogLogger::SyslogLogger(int facility) : LoggerBase(NULL, facility),
00219                                            m_opened(false)
00220 {
00221     CODE *name;
00222 
00223     m_application = strdup((char *)QCoreApplication::applicationName()
00224                            .toLocal8Bit().constData());
00225 
00226     openlog( m_application, LOG_NDELAY | LOG_PID, facility );
00227     m_opened = true;
00228 
00229     for( name = &facilitynames[0];
00230          name->c_name && name->c_val != facility; name++ );
00231 
00232     LogPrint(VB_IMPORTANT, LOG_INFO, "Added syslogging to facility %s",
00233              name->c_name);
00234 }
00235 
00236 SyslogLogger::~SyslogLogger()
00237 {
00238     LogPrint(VB_IMPORTANT, LOG_INFO, "Removing syslogging");
00239     free(m_application);
00240     closelog();
00241 }
00242 
00243 bool SyslogLogger::logmsg(LoggingItem_t *item)
00244 {
00245     if (!m_opened)
00246         return false;
00247 
00248     syslog( item->level, "%s", item->message );
00249 
00250     {
00251         QMutexLocker locker((QMutex *)item->refmutex);
00252         item->refcount--;
00253     }
00254 
00255     return true;
00256 }
00257 
00258 
00259 DatabaseLogger::DatabaseLogger(char *table) : LoggerBase(table, 0),
00260                                               m_host(NULL), m_opened(false),
00261                                               m_loggingTableExists(false)
00262 {
00263     static const char *queryFmt =
00264         "INSERT INTO %s (host, application, pid, thread, "
00265         "msgtime, level, message) VALUES (:HOST, :APPLICATION, "
00266         ":PID, :THREAD, :MSGTIME, :LEVEL, :MESSAGE)";
00267 
00268     LogPrint(VB_IMPORTANT, LOG_INFO, "Added database logging to table %s",
00269              m_handle.string);
00270 
00271     if (gCoreContext && !gCoreContext->GetHostName().isEmpty())
00272         m_host = strdup((char *)gCoreContext->GetHostName()
00273                         .toLocal8Bit().constData());
00274 
00275     m_application = strdup((char *)QCoreApplication::applicationName()
00276                            .toLocal8Bit().constData());
00277     m_pid = getpid();
00278 
00279     m_query = (char *)malloc(strlen(queryFmt) + strlen(m_handle.string));
00280     sprintf(m_query, queryFmt, m_handle.string);
00281 
00282     m_thread = new DBLoggerThread(this);
00283     m_thread->start();
00284 
00285     m_opened = true;
00286 }
00287 
00288 DatabaseLogger::~DatabaseLogger()
00289 {
00290     LogPrint(VB_IMPORTANT, LOG_INFO, "Removing database logging");
00291 
00292     if( m_thread )
00293     {
00294         m_thread->stop();
00295         m_thread->wait();
00296         delete m_thread;
00297     }
00298 
00299     if( m_query )
00300         free(m_query);
00301     if( m_application )
00302         free(m_application);
00303     if( m_host )
00304         free(m_host);
00305 }
00306 
00307 bool DatabaseLogger::logmsg(LoggingItem_t *item)
00308 {
00309     if( m_thread )
00310         m_thread->enqueue(item);
00311     return true;
00312 }
00313 
00314 bool DatabaseLogger::logqmsg(LoggingItem_t *item)
00315 {
00316     char        timestamp[TIMESTAMP_MAX];
00317     char       *threadName = getThreadName(item);;
00318 
00319     if( !isDatabaseReady() )
00320         return false;
00321 
00322     strftime( timestamp, TIMESTAMP_MAX-8, "%Y-%m-%d %H:%M:%S",
00323               (const struct tm *)&item->tm );
00324 
00325     if( gCoreContext && !m_host )
00326         m_host = strdup((char *)gCoreContext->GetHostName()
00327                         .toLocal8Bit().constData());
00328 
00329     MSqlQuery   query(MSqlQuery::InitCon());
00330     query.prepare( m_query );
00331     query.bindValue(":HOST",        m_host);
00332     query.bindValue(":APPLICATION", m_application);
00333     query.bindValue(":PID",         m_pid);
00334     query.bindValue(":THREAD",      threadName);
00335     query.bindValue(":MSGTIME",     timestamp);
00336     query.bindValue(":LEVEL",       item->level);
00337     query.bindValue(":MESSAGE",     item->message);
00338 
00339     {
00340         QMutexLocker locker((QMutex *)item->refmutex);
00341         item->refcount--;
00342     }
00343 
00344     if (!query.exec())
00345     {
00346         MythDB::DBError("DBLogging", query);
00347         return false;
00348     }
00349 
00350     return true;
00351 }
00352 
00353 void DBLoggerThread::run(void)
00354 {
00355     threadRegister("DBLogger");
00356     LoggingItem_t *item;
00357 
00358     aborted = false;
00359 
00360     QMutexLocker qLock(&m_queueMutex);
00361 
00362     while(!aborted || !m_queue->isEmpty())
00363     {
00364         if (m_queue->isEmpty())
00365         {
00366             qLock.unlock();
00367             msleep(100);
00368             qLock.relock();
00369             continue;
00370         }
00371 
00372         item = m_queue->dequeue();
00373         if (!item)
00374             continue;
00375 
00376         qLock.unlock();
00377 
00378         if( item->message && !aborted )
00379         {
00380             m_logger->logqmsg(item);
00381         }
00382 
00383         deleteItem(item);
00384 
00385         qLock.relock();
00386     }
00387 }
00388 
00389 bool DatabaseLogger::isDatabaseReady()
00390 {
00391     bool ready = false;
00392     MythDB *db;
00393 
00394     if ( !m_loggingTableExists )
00395         m_loggingTableExists = DBUtil::TableExists(m_handle.string);
00396 
00397     if ( m_loggingTableExists && (db = GetMythDB()) && db->HaveValidDatabase() )
00398         ready = true;
00399 
00400     return ready;
00401 }
00402 
00403 char *getThreadName( LoggingItem_t *item )
00404 {
00405     static const char  *unknown = "thread_unknown";
00406     char *threadName;
00407 
00408     if( !item )
00409         return( (char *)unknown );
00410 
00411     if( !item->threadName )
00412     {
00413         QMutexLocker locker(&logThreadMutex);
00414         if( logThreadHash.contains(item->threadId) )
00415             threadName = logThreadHash[item->threadId];
00416         else
00417             threadName = (char *)unknown;
00418     }
00419     else
00420     {
00421         threadName = item->threadName;
00422     }
00423 
00424     return( threadName );
00425 }
00426 
00427 int64_t getThreadTid( LoggingItem_t *item )
00428 {
00429     pid_t tid = 0;
00430 
00431     if( !item )
00432         return( 0 );
00433 
00434     QMutexLocker locker(&logThreadTidMutex);
00435     if( logThreadTidHash.contains(item->threadId) )
00436         tid = logThreadTidHash[item->threadId];
00437 
00438     return( tid );
00439 }
00440 
00441 void setThreadTid( LoggingItem_t *item )
00442 {
00443     int64_t tid = 0;
00444 
00445     QMutexLocker locker(&logThreadTidMutex);
00446 
00447     if( ! logThreadTidHash.contains(item->threadId) )
00448     {
00449 #if defined(linux)
00450         tid = (int64_t)syscall(SYS_gettid);
00451 #elif defined(__FreeBSD__) && 0
00452         long lwpid;
00453         int dummy = thr_self( &lwpid );
00454         tid = (int64_t)lwpid;
00455 #elif CONFIG_DARWIN
00456         tid = (int64_t)mach_thread_self();
00457 #endif
00458         logThreadTidHash[item->threadId] = tid;
00459     }
00460 }
00461 
00462 
00463 LoggerThread::LoggerThread()
00464 {
00465     char *debug = getenv("VERBOSE_THREADS");
00466     if (debug != NULL)
00467     {
00468         VERBOSE(VB_IMPORTANT, "Logging thread registration/deregistration "
00469                               "enabled!");
00470         debugRegistration = true;
00471     }
00472 }
00473 
00474 LoggerThread::~LoggerThread()
00475 {
00476     QMutexLocker locker(&loggerListMutex);
00477 
00478     QList<LoggerBase *>::iterator it;
00479 
00480     for(it = loggerList.begin(); it != loggerList.end(); it++)
00481     {
00482         (*it)->deleteLater();
00483     }
00484 }
00485 
00486 void LoggerThread::run(void)
00487 {
00488     threadRegister("Logger");
00489     LoggingItem_t *item;
00490 
00491     aborted = false;
00492 
00493     QMutexLocker qLock(&logQueueMutex);
00494 
00495     while(!aborted || !logQueue.isEmpty())
00496     {
00497         if (logQueue.isEmpty())
00498         {
00499             qLock.unlock();
00500             msleep(100);
00501             qLock.relock();
00502             continue;
00503         }
00504 
00505         item = logQueue.dequeue();
00506         if (!item)
00507             continue;
00508 
00509         qLock.unlock();
00510 
00511         if (item->registering)
00512         {
00513             int64_t tid = getThreadTid(item);
00514 
00515             QMutexLocker locker(&logThreadMutex);
00516             logThreadHash[item->threadId] = strdup(item->threadName);
00517 
00518             if( debugRegistration )
00519             {
00520                 item->message   = (char *)malloc(LOGLINE_MAX+1);
00521                 if( item->message )
00522                 {
00523                     snprintf( item->message, LOGLINE_MAX,
00524                               "Thread 0x%llX (%lld) registered as \'%s\'",
00525                               (long long unsigned int)item->threadId,
00526                               (long long int)tid, 
00527                               logThreadHash[item->threadId] );
00528                 }
00529             }
00530         }
00531         else if (item->deregistering)
00532         {
00533             int64_t tid = 0;
00534 
00535             {
00536                 QMutexLocker locker(&logThreadTidMutex);
00537                 if( logThreadTidHash.contains(item->threadId) )
00538                 {
00539                     tid = logThreadTidHash[item->threadId];
00540                     logThreadTidHash.remove(item->threadId);
00541                 }
00542             }
00543 
00544             QMutexLocker locker(&logThreadMutex);
00545             if( logThreadHash.contains(item->threadId) )
00546             {
00547                 if( debugRegistration )
00548                 {
00549                     item->message   = (char *)malloc(LOGLINE_MAX+1);
00550                     if( item->message )
00551                     {
00552                         snprintf( item->message, LOGLINE_MAX,
00553                                   "Thread 0x%llX (%lld) deregistered as \'%s\'",
00554                                   (long long unsigned int)item->threadId,
00555                                   (long long int)tid, 
00556                                   logThreadHash[item->threadId] );
00557                     }
00558                 }
00559                 item->threadName = logThreadHash[item->threadId];
00560                 logThreadHash.remove(item->threadId);
00561             }
00562         }
00563 
00564         if( item->message )
00565         {
00566             QMutexLocker locker(&loggerListMutex);
00567 
00568             QList<LoggerBase *>::iterator it;
00569 
00570             item->refcount = loggerList.size();
00571             item->refmutex = new QMutex;
00572 
00573             for(it = loggerList.begin(); it != loggerList.end(); it++)
00574             {
00575                 (*it)->logmsg(item);
00576             }
00577         }
00578 
00579         deleteItem(item);
00580 
00581         qLock.relock();
00582     }
00583 }
00584 
00585 void deleteItem( LoggingItem_t *item )
00586 {
00587     if( !item )
00588         return;
00589 
00590     {
00591         QMutexLocker locker((QMutex *)item->refmutex);
00592         if( item->refcount != 0 )
00593             return;
00594 
00595         if( item->message )
00596             free(item->message);
00597 
00598         if( item->threadName )
00599             free( item->threadName );
00600     }
00601 
00602     delete (QMutex *)item->refmutex;
00603     delete item;
00604 }
00605 
00606 void LogTimeStamp( time_t *epoch, uint32_t *usec )
00607 {
00608     if( !epoch || !usec )
00609         return;
00610 
00611 #if HAVE_GETTIMEOFDAY
00612     struct timeval  tv;
00613     gettimeofday(&tv, NULL);
00614     *epoch = tv.tv_sec;
00615     *usec  = tv.tv_usec;
00616 #else
00617     /* Stupid system has no gettimeofday, use less precise QDateTime */
00618     QDateTime date = QDateTime::currentDateTime();
00619     QTime     time = date.time();
00620     *epoch = date.toTime_t();
00621     *usec = time.msec() * 1000;
00622 #endif
00623 }
00624 
00625 void LogPrintLine( uint32_t mask, LogLevel_t level, const char *file, int line,
00626                    const char *function, const char *format, ... )
00627 {
00628     va_list         arguments;
00629     char           *message;
00630     LoggingItem_t  *item;
00631     time_t          epoch;
00632     uint32_t        usec;
00633 
00634     if( !VERBOSE_LEVEL_CHECK(mask) )
00635         return;
00636 
00637     if( level > LogLevel )
00638         return;
00639 
00640     item = new LoggingItem_t;
00641     if (!item)
00642         return;
00643 
00644     memset( item, 0, sizeof(LoggingItem_t) );
00645 
00646     message = (char *)malloc(LOGLINE_MAX+1);
00647     if( !message )
00648         return;
00649 
00650     va_start(arguments, format);
00651     vsnprintf(message, LOGLINE_MAX, format, arguments);
00652     va_end(arguments);
00653 
00654     LogTimeStamp( &epoch, &usec );
00655 
00656     localtime_r(&epoch, &item->tm);
00657     item->usec     = usec;
00658 
00659     item->level    = level;
00660     item->file     = file;
00661     item->line     = line;
00662     item->function = function;
00663     item->threadId = (uint64_t)QThread::currentThreadId();
00664     item->message  = message;
00665     setThreadTid(item);
00666 
00667     QMutexLocker qLock(&logQueueMutex);
00668     logQueue.enqueue(item);
00669 }
00670 
00671 void logSighup( int signum, siginfo_t *info, void *secret )
00672 {
00673     VERBOSE(VB_GENERAL, "SIGHUP received, rolling log files.");
00674 
00675     /* SIGHUP was sent.  Close and reopen debug logfiles */
00676     QMutexLocker locker(&loggerListMutex);
00677 
00678     QList<LoggerBase *>::iterator it;
00679     for(it = loggerList.begin(); it != loggerList.end(); it++)
00680     {
00681         (*it)->reopen();
00682     }
00683 }
00684 
00685 
00686 void logStart(QString logfile, int quiet, int facility, bool dblog)
00687 {
00688     LoggerBase *logger;
00689     struct sigaction sa;
00690 
00691     if (logThread.isRunning())
00692         return;
00693 
00694     /* log to the console */
00695     if( !quiet )
00696         logger = new FileLogger((char *)"-");
00697 
00698     /* Debug logfile */
00699     if( !logfile.isEmpty() )
00700         logger = new FileLogger((char *)logfile.toLocal8Bit().constData());
00701 
00702     /* Syslog */
00703     if( facility < 0 )
00704         LogPrint(VB_IMPORTANT, LOG_CRIT,
00705                  "Syslogging facility unknown, disabling syslog output");
00706     else if( facility > 0 )
00707         logger = new SyslogLogger(facility);
00708 
00709     /* Database */
00710     if( dblog )
00711         logger = new DatabaseLogger((char *)"logging");
00712 
00713     /* Setup SIGHUP */
00714     LogPrint(VB_IMPORTANT, LOG_CRIT, "Setting up SIGHUP handler");
00715     sa.sa_sigaction = logSighup;
00716     sigemptyset( &sa.sa_mask );
00717     sa.sa_flags = SA_RESTART | SA_SIGINFO;
00718     sigaction( SIGHUP, &sa, NULL );
00719 
00720     logThread.start();
00721 }
00722 
00723 void logStop(void)
00724 {
00725     struct sigaction sa;
00726 
00727     logThread.stop();
00728     logThread.wait();
00729 
00730     /* Tear down SIGHUP */
00731     sa.sa_handler = SIG_DFL;
00732     sigemptyset( &sa.sa_mask );
00733     sa.sa_flags = SA_RESTART;
00734     sigaction( SIGHUP, &sa, NULL );
00735 
00736     QMutexLocker locker(&loggerListMutex);
00737     QList<LoggerBase *>::iterator it;
00738 
00739     for(it = loggerList.begin(); it != loggerList.end(); )
00740     {
00741         locker.unlock();
00742         delete *it;
00743         locker.relock();
00744         it = loggerList.begin();
00745     }
00746 }
00747 
00748 void threadRegister(QString name)
00749 {
00750     uint64_t id = (uint64_t)QThread::currentThreadId();
00751     LoggingItem_t  *item;
00752     time_t epoch;
00753     uint32_t usec;
00754 
00755     item = new LoggingItem_t;
00756     if (!item)
00757         return;
00758 
00759     memset( item, 0, sizeof(LoggingItem_t) );
00760     LogTimeStamp( &epoch, &usec );
00761 
00762     localtime_r(&epoch, &item->tm);
00763     item->usec = usec;
00764 
00765     item->level = (LogLevel_t)LOG_DEBUG;
00766     item->threadId = id;
00767     item->line = __LINE__;
00768     item->file = (char *)__FILE__;
00769     item->function = (char *)__FUNCTION__;
00770     item->threadName = strdup((char *)name.toLocal8Bit().constData());
00771     item->registering = true;
00772     setThreadTid(item);
00773 
00774     QMutexLocker qLock(&logQueueMutex);
00775     logQueue.enqueue(item);
00776 }
00777 
00778 void threadDeregister(void)
00779 {
00780     uint64_t id = (uint64_t)QThread::currentThreadId();
00781     LoggingItem_t  *item;
00782     time_t epoch;
00783     uint32_t usec;
00784 
00785     item = new LoggingItem_t;
00786     if (!item)
00787         return;
00788 
00789     memset( item, 0, sizeof(LoggingItem_t) );
00790     LogTimeStamp( &epoch, &usec );
00791 
00792     localtime_r(&epoch, &item->tm);
00793     item->usec = usec;
00794 
00795     item->level = (LogLevel_t)LOG_DEBUG;
00796     item->threadId = id;
00797     item->line = __LINE__;
00798     item->file = (char *)__FILE__;
00799     item->function = (char *)__FUNCTION__;
00800     item->deregistering = true;
00801 
00802     QMutexLocker qLock(&logQueueMutex);
00803     logQueue.enqueue(item);
00804 }
00805 
00806 int syslogGetFacility(QString facility)
00807 {
00808     CODE *name;
00809     int i;
00810     char *string = (char *)facility.toLocal8Bit().constData();
00811 
00812     for( i = 0, name = &facilitynames[0];
00813          name->c_name && strcmp(name->c_name, string); i++, name++ );
00814 
00815     return( name->c_val );
00816 }
00817 
00818 /*
00819  * vim:ts=4:sw=4:ai:et:si:sts=4
00820  */
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends