1 #ifndef NETCACHE__SRV_DIAG__HPP 2 #define NETCACHE__SRV_DIAG__HPP 3 /* $Id: srv_diag.hpp 548279 2017-10-12 13:53:21Z gouriano $ 4 * =========================================================================== 5 * 6 * PUBLIC DOMAIN NOTICE 7 * National Center for Biotechnology Information 8 * 9 * This software/database is a "United States Government Work" under the 10 * terms of the United States Copyright Act. It was written as part of 11 * the author's official duties as a United States Government employee and 12 * thus cannot be copyrighted. This software/database is freely available 13 * to the public for use. The National Library of Medicine and the U.S. 14 * Government have not placed any restriction on its use or reproduction. 15 * 16 * Although all reasonable efforts have been taken to ensure the accuracy 17 * and reliability of the software and data, the NLM and the U.S. 18 * Government do not and cannot warrant the performance or results that 19 * may be obtained by using this software or data. The NLM and the U.S. 20 * Government disclaim all warranties, express or implied, including 21 * warranties of performance, merchantability or fitness for any particular 22 * purpose. 23 * 24 * Please cite the author in any work or product based on this material. 25 * 26 * =========================================================================== 27 * 28 * Authors: Pavel Ivanov 29 * 30 * File Description: 31 */ 32 33 34 35 BEGIN_NCBI_SCOPE 36 37 38 class CTempString; 39 class CRequestContext; 40 struct SSrvThread; 41 struct SLogData; 42 43 44 #define _VERIFY(x) if (x) {} else SRV_FATAL("assertion failed: " << #x) 45 46 #ifdef _ASSERT 47 # undef _ASSERT 48 #endif 49 #ifdef _DEBUG 50 # define _ASSERT(x) _VERIFY(x) 51 #else 52 # define _ASSERT(x) do {} while (0) 53 #endif 54 55 #ifdef assert 56 # undef assert 57 #endif 58 #define assert(x) _ASSERT(x) 59 60 61 /// Class used in all diagnostic logging. 62 /// This class effectively replaces things like CNcbiDiag and CDiagContext. 63 /// Any started messages should finish by call to Flush() or by destruction 64 /// of the object. One shouldn't start any new messages before he finishes 65 /// started one. After call to Flush() the same object can be reused to start 66 /// a new message. All messages will have request number from request context 67 /// assigned to currently executing task, except those methods that get 68 /// pointer to CRequestContext as input parameter (these methods should be 69 /// used very rarely). 70 /// CSrvDiagMsg objects cannot persist upon return to TaskServer code and 71 /// cannot be used in several threads simultaneously. 72 class CSrvDiagMsg 73 { 74 public: 75 CSrvDiagMsg(void); 76 ~CSrvDiagMsg(void); 77 78 /// Severity levels for logging 79 enum ESeverity { 80 Trace, 81 Info, 82 Warning, 83 Error, 84 Critical, 85 SoftFatal, 86 Fatal 87 }; 88 89 /// Checks if given severity level is visible, i.e. will make its way to 90 /// log file if someone will print anything on this level. 91 static bool IsSeverityVisible(ESeverity sev); 92 93 /// Starts log message which will include severity, filename, line number 94 /// and function name. 95 const CSrvDiagMsg& StartSrvLog(ESeverity sev, 96 const char* file, 97 int line, 98 const char* func) const; 99 /// Starts informational message which doesn't need to have filename, line 100 /// number or function name. 101 const CSrvDiagMsg& StartInfo(void) const; 102 const CSrvDiagMsg& StartInfo(CRequestContext* ctx) const; 103 /// Starts "request-start" message. Use PrintParam() methods to include 104 /// parameters into the message. 105 CSrvDiagMsg& StartRequest(void); 106 CSrvDiagMsg& StartRequest(CRequestContext* ctx); 107 /// Starts "extra" message. Use PrintParam() methods to include 108 /// parameters into the message. 109 CSrvDiagMsg& PrintExtra(void); 110 CSrvDiagMsg& PrintExtra(CRequestContext* ctx); 111 /// Prints "request-stop" message. This is the only method that doesn't 112 /// start message, it prints the whole message which doesn't need to be 113 /// manually finished. 114 void StopRequest(void); 115 void StopRequest(CRequestContext* ctx); 116 /// Finishes current message and prepare to start new one. 117 void Flush(void); 118 /// Starts the "old style" log message. Method shouldn't be used by 119 /// anybody except ERR_POST() macro used in legacy code. 120 const CSrvDiagMsg& StartOldStyle(const char* file, int line, const char* func); 121 122 /// Adds parameter to "request-start" or "extra" message. 123 CSrvDiagMsg& PrintParam(CTempString name, CTempString value); 124 CSrvDiagMsg& PrintParam(CTempString name, Int4 value); 125 CSrvDiagMsg& PrintParam(CTempString name, Uint4 value); 126 CSrvDiagMsg& PrintParam(CTempString name, Int8 value); 127 CSrvDiagMsg& PrintParam(CTempString name, Uint8 value); 128 CSrvDiagMsg& PrintParam(CTempString name, double value); 129 130 /// Converts input value to string and adds to started log message. 131 const CSrvDiagMsg& operator<< (CTempString str) const; 132 const CSrvDiagMsg& operator<< (const string& str) const; 133 const CSrvDiagMsg& operator<< (const char* str) const; 134 const CSrvDiagMsg& operator<< (Int4 num) const; 135 const CSrvDiagMsg& operator<< (Uint4 num) const; 136 const CSrvDiagMsg& operator<< (Int8 num) const; 137 const CSrvDiagMsg& operator<< (Uint8 num) const; 138 #ifdef NCBI_OS_MSWIN operator <<(DWORD num) const139 const CSrvDiagMsg& operator<< (DWORD num) const { 140 return operator<< ((Uint8)num); 141 } 142 #endif 143 const CSrvDiagMsg& operator<< (double num) const; 144 const CSrvDiagMsg& operator<< (const void* ptr) const; 145 const CSrvDiagMsg& operator<< (const exception& ex) const; 146 147 // Consider this section private as it's public for internal use only 148 // to minimize implementation-specific clutter in headers. 149 public: 150 /// Current thread created this object. 151 SSrvThread* m_Thr; 152 /// Log data from current thread. 153 SLogData* m_Data; 154 /// Flag showing if "old style" message was started. 155 bool m_OldStyle; 156 }; 157 158 159 /// Macro to be used for printing log messages. 160 /// Macro usage is as follows: 161 /// SRV_LOG(Error, message << some_param << " more message"); 162 #define SRV_LOG(sev, msg) \ 163 do { \ 164 if (CSrvDiagMsg::IsSeverityVisible(CSrvDiagMsg::sev)) { \ 165 CSrvDiagMsg().StartSrvLog(CSrvDiagMsg::sev, \ 166 __FILE__, __LINE__, \ 167 NCBI_CURRENT_FUNCTION) \ 168 << msg; \ 169 } \ 170 } \ 171 while (0) \ 172 /**/ 173 #define SRV_FATAL(msg) \ 174 do { \ 175 SRV_LOG(Fatal, "Fatal error: " << msg); \ 176 abort(); \ 177 } while (0) \ 178 179 /// Macro to be used for printing informational messages. 180 /// Macro usage is as follows: 181 /// INFO(message << some_param << " more message"); 182 #define INFO(msg) CSrvDiagMsg().StartInfo() << msg 183 184 185 END_NCBI_SCOPE 186 187 #endif /* NETCACHE__SRV_DIAG__HPP */ 188