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