1 /*============================================================================== 2 * 3 * PUBLIC DOMAIN NOTICE 4 * National Center for Biotechnology Information 5 * 6 * This software/database is a "United States Government Work" under the 7 * terms of the United States Copyright Act. It was written as part of 8 * the author's official duties as a United States Government employee and 9 * thus cannot be copyrighted. This software/database is freely available 10 * to the public for use. The National Library of Medicine and the U.S. 11 * Government have not placed any restriction on its use or reproduction. 12 * 13 * Although all reasonable efforts have been taken to ensure the accuracy 14 * and reliability of the software and data, the NLM and the U.S. 15 * Government do not and cannot warrant the performance or results that 16 * may be obtained by using this software or data. The NLM and the U.S. 17 * Government disclaim all warranties, express or implied, including 18 * warranties of performance, merchantability or fitness for any particular 19 * purpose. 20 * 21 * Please cite the author in any work or product based on this material. 22 * 23 * Author: Kurt Rodarmer 24 * 25 * =========================================================================== 26 * 27 */ 28 29 #include "logging.hpp" 30 31 #include <unistd.h> 32 #include <stdlib.h> 33 #include <stdio.h> 34 #include <string.h> 35 #include <time.h> 36 #include <errno.h> 37 #include <assert.h> 38 39 namespace ncbi 40 { 41 /*------------------------------------------------------------------- 42 * Logger 43 * base class for log message processing engine 44 */ 45 const size_t BSIZE = 256; 46 init(const char * ident)47 void Logger :: init ( const char * ident ) 48 { 49 // use a local buffer 50 char hostname [ BSIZE ]; 51 52 // hostname 53 int status = gethostname ( hostname, sizeof hostname ); 54 if ( status != 0 ) 55 { 56 switch ( errno ) 57 { 58 case ENAMETOOLONG: 59 strncpy ( hostname, "<HOSTNAME-TOO-LONG>", sizeof hostname ); 60 break; 61 default: 62 strncpy ( hostname, "<GETHOSTNAME-FAILED>", sizeof hostname ); 63 } 64 status = 0; 65 } 66 67 // process name 68 const char * procname = ""; 69 if ( ident != 0 ) 70 { 71 // find leaf name 72 procname = strrchr ( ident, '/' ); 73 if ( procname ++ == 0 ) 74 procname = ident; 75 } 76 77 // initialize implementation 78 init ( hostname, procname, getpid () ); 79 } 80 setLogLevel(int priority)81 int Logger :: setLogLevel ( int priority ) 82 { 83 int prior = level; 84 level = LOG_PRI ( priority ); 85 return prior; 86 } 87 msg(int priority,const timespec & ts,const void * data,size_t bytes)88 void Logger :: msg ( int priority, const timespec & ts, const void * data, size_t bytes ) 89 { 90 if ( LOG_PRI ( priority ) <= level ) 91 handleMsg ( priority, ts, data, bytes ); 92 } 93 Logger()94 Logger :: Logger () 95 #if _DEBUGGING 96 : level ( LOG_DEBUG ) 97 #else 98 : level ( LOG_INFO ) 99 #endif 100 { 101 } 102 ~Logger()103 Logger :: ~ Logger () 104 { 105 level = 0; 106 } 107 108 109 /*------------------------------------------------------------------- 110 * StreamLogger 111 * a Logger that writes to a stream 112 * such as a file or socket or to a logging daemon 113 */ 114 resetLogFileDescriptor(int _log_fd)115 void StreamLogger :: resetLogFileDescriptor ( int _log_fd ) 116 { 117 log_fd = _log_fd; 118 } 119 StreamLogger()120 StreamLogger :: StreamLogger () 121 : log_fd ( 2 ) 122 { 123 } 124 StreamLogger(int _log_fd)125 StreamLogger :: StreamLogger ( int _log_fd ) 126 : log_fd ( _log_fd ) 127 { 128 } 129 ~StreamLogger()130 StreamLogger :: ~ StreamLogger () 131 { 132 log_fd = -1; 133 } 134 135 136 /*------------------------------------------------------------------- 137 * LoggerScope 138 * an object that fits into C++ stack cleanup 139 * that can be used to use a Logger while it is in scope 140 * and restore the previous logger once it goes out of scope. 141 * 142 * the most obvious use case is when switching from LocalLogger 143 * to DBLogger, all of which may fail in interesting ways. 144 */ 145 LoggerScope(Logger & _logger)146 LoggerScope :: LoggerScope ( Logger & _logger ) 147 : logger ( log . logger ) 148 { 149 log . use ( _logger ); 150 } 151 ~LoggerScope()152 LoggerScope :: ~ LoggerScope () 153 { 154 if ( logger != 0 ) 155 { 156 log . use ( * logger ); 157 logger = 0; 158 } 159 } 160 } 161