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