NCBI C++ ToolKit
ncbidiag.hpp
Go to the documentation of this file.

Go to the SVN repository for this file.

1 #ifndef CORELIB___NCBIDIAG__HPP
2 #define CORELIB___NCBIDIAG__HPP
3 
4 /* $Id: ncbidiag.hpp 99381 2023-03-20 13:48:01Z ivanov $
5  * ===========================================================================
6  *
7  * PUBLIC DOMAIN NOTICE
8  * National Center for Biotechnology Information
9  *
10  * This software/database is a "United States Government Work" under the
11  * terms of the United States Copyright Act. It was written as part of
12  * the author's official duties as a United States Government employee and
13  * thus cannot be copyrighted. This software/database is freely available
14  * to the public for use. The National Library of Medicine and the U.S.
15  * Government have not placed any restriction on its use or reproduction.
16  *
17  * Although all reasonable efforts have been taken to ensure the accuracy
18  * and reliability of the software and data, the NLM and the U.S.
19  * Government do not and cannot warrant the performance or results that
20  * may be obtained by using this software or data. The NLM and the U.S.
21  * Government disclaim all warranties, express or implied, including
22  * warranties of performance, merchantability or fitness for any particular
23  * purpose.
24  *
25  * Please cite the author in any work or product based on this material.
26  *
27  * ===========================================================================
28  *
29  * Author: Denis Vakatov
30  *
31  *
32  */
33 
34 /// @file ncbidiag.hpp
35 ///
36 /// Defines NCBI C++ diagnostic APIs, classes, and macros.
37 ///
38 /// More elaborate documentation could be found in:
39 /// http://ncbi.github.io/cxx-toolkit/pages/ch_log.html
40 
41 
42 #include <corelib/ncbi_stack.hpp>
43 #include <deque>
44 #include <vector>
45 #include <map>
46 #include <atomic>
47 #include <stdexcept>
48 
49 
50 /** @addtogroup Diagnostics
51  *
52  * @{
53  */
54 
55 
57 
58 /// Incapsulate compile time information such as
59 /// __FILE__, __LINE__, NCBI_MODULE, current function.
60 /// @note
61 /// NCBI_MODULE is used only in .cpp files
62 /// @sa
63 /// DIAG_COMPILE_INFO
65 {
66 public:
67  // DO NOT create CDiagCompileInfo directly
68  // use macro DIAG_COMPILE_INFO instead!
70  CDiagCompileInfo(void);
72  CDiagCompileInfo(const char* file,
73  int line,
74  const char* curr_funct = NULL,
75  const char* module = NULL);
77  CDiagCompileInfo(const string& file,
78  int line,
79  const string& curr_funct,
80  const string& module);
82  ~CDiagCompileInfo(void);
83 
84  const char* GetFile (void) const;
85  const char* GetModule (void) const;
86  int GetLine (void) const;
87  const string& GetClass (void) const;
88  const string& GetFunction(void) const;
89 
90 private:
91  friend class CNcbiDiag;
92 
93  void SetFile(const string& file);
94  void SetModule(const string& module);
95 
97  void SetLine(int line);
98  // Setting function also sets class if it has not been set explicitly.
99  void SetFunction(const string& func);
100  // Override any class name parsed from function name.
101  void SetClass(const string& cls);
102 
104  void ParseCurrFunctName(void) const;
105 
106  // Check if module needs to be set
107  bool x_NeedModule(void) const;
108 
109  const char* m_File;
110  const char* m_Module;
111  int m_Line;
112 
113  const char* m_CurrFunctName;
114  mutable bool m_Parsed;
115  mutable bool m_ClassSet;
116  mutable string m_ClassName;
117  mutable string m_FunctName;
118 
119  // Storage for data passed as strings rather than char*.
120  string m_StrFile;
121  string m_StrModule;
123 };
124 
125 NCBI_XNCBI_EXPORT const char* g_DiagUnknownFunction(void);
126 
127 /// Get current function name.
128 /// Defined inside of either a method or a function body only.
129 // Based on boost's BOOST_CURRENT_FUNCTION
130 
131 #if defined(__GNUC__) || (defined(__MWERKS__) && (__MWERKS__ >= 0x3000)) || (defined(__ICC) && (__ICC >= 600))
132 # define NCBI_CURRENT_FUNCTION __PRETTY_FUNCTION__
133 #elif defined(__FUNCSIG__)
134 # define NCBI_CURRENT_FUNCTION __FUNCSIG__
135 #elif (defined(__INTEL_COMPILER) && (__INTEL_COMPILER >= 600)) || (defined(__IBMCPP__) && (__IBMCPP__ >= 500))
136 # define NCBI_CURRENT_FUNCTION __FUNCTION__
137 #elif defined(__BORLANDC__) && (__BORLANDC__ >= 0x550)
138 # define NCBI_CURRENT_FUNCTION __FUNC__
139 #elif defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 199901)
140 # define NCBI_CURRENT_FUNCTION __func__
141 #else
142 # define NCBI_CURRENT_FUNCTION NCBI_NS_NCBI::g_DiagUnknownFunction()
143 #endif
144 
145 
146 /// Set default module name based on NCBI_MODULE macro
147 ///
148 /// @sa DIAG_COMPILE_INFO
149 #define NCBI_MAKE_MODULE(module) NCBI_AS_STRING(module)
150 
151 /// Make compile time diagnostic information object
152 /// to use in CNcbiDiag and CException.
153 ///
154 /// This macro along with functionality of macro NCBI_MAKE_MODULE and
155 /// of constructor CDiagCompileInfo ensures that if variable NCBI_MODULE
156 /// will be defined then its value will be used as module name, but if it
157 /// isn't defined then module name in CDiagCompileInfo will be empty.
158 /// "Checking" of definition of NCBI_MODULE is performed at the moment
159 /// of macro issuing so you can define and redefine NCBI_MODULE several
160 /// times during one cpp-file. But BE WARNED that macro NCBI_MODULE is
161 /// considered as not defined when used in any header file. So if you want
162 /// for example make some error posting from inline function defined in
163 /// hpp-file and want your custom module name to be shown in error
164 /// message then you have to use MDiagModule manipulator as following:
165 ///
166 /// ERR_POST_X(1, MDiagModule("MY_MODULE_NAME") << "Error message" );
167 ///
168 /// @sa
169 /// CDiagCompileInfo
170 #define DIAG_COMPILE_INFO \
171  NCBI_NS_NCBI::CDiagCompileInfo(__FILE__, \
172  __LINE__, \
173  NCBI_CURRENT_FUNCTION, \
174  NCBI_MAKE_MODULE(NCBI_MODULE))
175 
176 
177 
178 
179 /// Error posting with file, line number information but without error codes.
180 /// This macro is deprecated and it's strongly recomended to move
181 /// in all projects (except tests) to macro ERR_POST_X to make possible more
182 /// flexible error statistics and logging.
183 ///
184 /// @sa
185 /// ERR_POST_EX, ERR_POST_X
186 #define ERR_POST(message) \
187  ( NCBI_NS_NCBI::CNcbiDiag(DIAG_COMPILE_INFO).GetRef() \
188  << message \
189  << NCBI_NS_NCBI::Endm )
190 
191 /// Wrappers for ERR_POST family of macros checking if the desired
192 /// severity is enabled.
193 ///
194 /// @sa
195 /// ERR_POST, ERR_POST_X, ERR_POST_EX
196 #define SEVERITY_POST(severity, message) \
197  do if (NCBI_NS_NCBI::IsVisibleDiagPostLevel(NCBI_NS_NCBI::eDiag_##severity)) \
198  ERR_POST(severity << message); \
199  while(0)
200 #define WARNING_POST(message) SEVERITY_POST(Warning, message)
201 #define INFO_POST(message) SEVERITY_POST(Info, message)
202 #define TRACE_POST(message) SEVERITY_POST(Trace, message)
203 #define SEVERITY_POST_X(severity, subcode, message) \
204  do if (NCBI_NS_NCBI::IsVisibleDiagPostLevel(NCBI_NS_NCBI::eDiag_##severity)) \
205  ERR_POST_X(subcode, severity << message); \
206  while(0)
207 #define WARNING_POST_X(subcode, message) SEVERITY_POST_X(Warning, subcode, message)
208 #define INFO_POST_X(subcode, message) SEVERITY_POST_X(Info, subcode, message)
209 #define TRACE_POST_X(subcode, message) SEVERITY_POST_X(Trace, subcode, message)
210 #define SEVERITY_POST_EX(severity, errcode, subcode, message) \
211  do if (NCBI_NS_NCBI::IsVisibleDiagPostLevel(NCBI_NS_NCBI::eDiag_##severity)) \
212  ERR_POST_EX(errcode, subcode, severity << message); \
213  while(0)
214 #define WARNING_POST_EX(errcode, subcode, message) SEVERITY_POST_EX(Warning, errcode, subcode, message)
215 #define INFO_POST_EX(errcode, message) SEVERITY_POST_EX(Info, errcode, subcode, message)
216 #define TRACE_POST_EX(errcode, message) SEVERITY_POST_EX(Trace, errcode, subcode, message)
217 
218 // When printing a message in 'old' (human readable) format LOG_POST skips
219 // all fields except the message.
220 /// This macro is deprecated and it's strongly recomended to move
221 /// in all projects (except tests) to macro LOG_POST_X to make possible more
222 /// flexible error statistics and logging.
223 ///
224 /// @sa
225 /// LOG_POST_EX, LOG_POST_X
226 #define LOG_POST(message) \
227  ( NCBI_NS_NCBI::CNcbiDiag(DIAG_COMPILE_INFO, \
228  NCBI_NS_NCBI::eDiag_Error, \
229  NCBI_NS_NCBI::eDPF_Log | NCBI_NS_NCBI::eDPF_IsNote).GetRef() \
230  << message \
231  << NCBI_NS_NCBI::Endm )
232 
233 /// Posting fatal error and abort.
234 /// This macro is deprecated and it's strongly recomended to move in all
235 /// projects (except tests) to macro ERR_FATAL_X to make possible more
236 /// flexible error statistics and logging.
237 ///
238 /// @sa
239 /// ERR_FATAL_X, ERR_POST
240 #define ERR_FATAL(message) \
241  NCBI_NS_NCBI::EndmFatal(NCBI_NS_NCBI::CNcbiDiag(DIAG_COMPILE_INFO, \
242  NCBI_NS_NCBI::eDiag_Fatal).GetRef() << message )
243 
244 /// Error posting with error codes.
245 /// This macro should be used only when you need to make non-constant
246 /// error subcode. In all other cases it's strongly recomended to move
247 /// in all projects (except tests) to macro ERR_POST_X to make possible more
248 /// flexible error statistics and logging.
249 ///
250 /// @sa
251 /// ERR_POST, ERR_POST_X
252 #define ERR_POST_EX(err_code, err_subcode, message) \
253  ( NCBI_NS_NCBI::CNcbiDiag(DIAG_COMPILE_INFO).GetRef() \
254  << NCBI_NS_NCBI::ErrCode( (err_code), (err_subcode) ) \
255  << message \
256  << NCBI_NS_NCBI::Endm )
257 
258 #define LOG_POST_EX(err_code, err_subcode, message) \
259  ( NCBI_NS_NCBI::CNcbiDiag(DIAG_COMPILE_INFO, \
260  NCBI_NS_NCBI::eDiag_Error, \
261  NCBI_NS_NCBI::eDPF_Log | NCBI_NS_NCBI::eDPF_IsNote).GetRef() \
262  << NCBI_NS_NCBI::ErrCode( (err_code), (err_subcode) ) \
263  << message \
264  << NCBI_NS_NCBI::Endm )
265 
266 #define ERR_FATAL_EX(err_code, err_subcode, message) \
267  NCBI_NS_NCBI::EndmFatal(NCBI_NS_NCBI::CNcbiDiag(DIAG_COMPILE_INFO, \
268  NCBI_NS_NCBI::eDiag_Fatal).GetRef() << \
269  NCBI_NS_NCBI::ErrCode( (err_code), (err_subcode) ) << message )
270 
271 /// Define global error code name with given value (err_code) and given
272 /// maximum value of error subcode within this code. To use defined error
273 /// code you need to define symbol NCBI_USE_ERRCODE_X with name as its value.
274 /// This error code is used only in ERR_POST_X macro. Maximum
275 /// value of error subcode is being checked during compilation and
276 /// exists for developers to know what code they can use in next inserted
277 /// ERR_POST_X call (i.e. when one want to insert new ERR_POST_X call he has
278 /// to find definition of error code used in the source file, increase value
279 /// of maximum subcode and put result in ERR_POST_X call).
280 /// Definition of error code and its maximum subcode can be split into 2
281 /// independent macros to avoid recompilation of everything that includes
282 /// header with error code definition. For more information about it see
283 /// NCBI_DEFINE_ERR_SUBCODE_X.
284 /// Macro MUST be used inside ncbi scope.
285 ///
286 /// Example:
287 /// NCBI_DEFINE_ERRCODE_X(Corelib_Util, 110, 5);
288 /// ...
289 /// #define NCBI_USE_ERRCODE_X Corelib_Util
290 /// ...
291 /// ERR_POST_X(3, "My error message with variables " << var);
292 ///
293 ///
294 /// @sa
295 /// NCBI_DEFINE_ERR_SUBCODE_X, ERR_POST_X,
296 /// NCBI_ERRCODE_X, NCBI_MAX_ERR_SUBCODE_X
297 #define NCBI_DEFINE_ERRCODE_X(name, err_code, max_err_subcode) \
298  namespace err_code_x { \
299  enum { \
300  eErrCodeX_##name = err_code, \
301  eErrCodeX_Max_##name = max_err_subcode \
302  }; \
303  template <bool dummy> \
304  struct SErrCodeX_Max_##name { \
305  enum { \
306  value = max_err_subcode, \
307  dumm_dumm = int(dummy) \
308  }; \
309  }; \
310  } \
311  NCBI_EAT_SEMICOLON(err_code)
312 
313 /// Define maximum value of subcode for the error code currently in use.
314 /// Currently used error code is defined by macro NCBI_USE_ERRCODE_X. This
315 /// macro is a simplified version of NCBI_DEFINE_ERR_SUBCODE_XX and can be
316 /// handy to use when some error code is used only in one source file and no
317 /// other error code is used in the same source file.
318 /// To use this macro you must put 0 as max_err_subcode in
319 /// NCBI_DEFINE_ERRCODE_X macro. Otherwise compilation error will occur.
320 /// Macro MUST be used inside ncbi scope.
321 ///
322 /// Example:
323 /// NCBI_DEFINE_ERRCODE_X(Corelib_Util, 110, 0);
324 /// ...
325 /// #define NCBI_USE_ERRCODE_X Corelib_Util
326 /// NCBI_DEFINE_ERR_SUBCODE_X(5);
327 /// ...
328 /// ERR_POST_X(3, "My error message with variables " << var);
329 ///
330 ///
331 /// @sa
332 /// NCBI_DEFINE_ERRCODE_X, NCBI_DEFINE_ERR_SUBCODE_XX
333 #define NCBI_DEFINE_ERR_SUBCODE_X(max_err_subcode) \
334  NCBI_DEFINE_ERR_SUBCODE_XX(NCBI_USE_ERRCODE_X, max_err_subcode)
335 
336 /// Define maximum value of subcode for particular error code name.
337 /// To use this macro you must put 0 as max_err_subcode in
338 /// NCBI_DEFINE_ERRCODE_X macro. Otherwise compilation error will occur.
339 /// Macro can be used only once per compilation unit.
340 /// Macro MUST be used inside ncbi scope.
341 ///
342 /// Example:
343 /// NCBI_DEFINE_ERRCODE_X(Corelib_Util, 110, 0);
344 /// ...
345 /// NCBI_DEFINE_ERR_SUBCODE_XX(Corelib_Util, 5);
346 /// ...
347 /// #define NCBI_USE_ERRCODE_X Corelib_Util
348 /// ...
349 /// ERR_POST_X(3, "My error message with variables " << var);
350 ///
351 ///
352 /// @sa
353 /// NCBI_DEFINE_ERRCODE_X
354 #define NCBI_DEFINE_ERR_SUBCODE_XX(name, max_err_subcode) \
355  NCBI_CHECK_ERRCODE_USAGE(name) \
356  namespace err_code_x { \
357  template <> \
358  struct NCBI_NAME2(SErrCodeX_Max_, name)<true> { \
359  enum { \
360  value = max_err_subcode \
361  }; \
362  }; \
363  }
364 
365 
366 /// Returns value of error code by its name defined by NCBI_DEFINE_ERRCODE_X
367 ///
368 /// @sa NCBI_DEFINE_ERRCODE_X
369 #define NCBI_ERRCODE_X_NAME(name) \
370  NCBI_NS_NCBI::err_code_x::NCBI_NAME2(eErrCodeX_, name)
371 
372 /// Returns currently set default error code. Default error code is set by
373 /// definition of NCBI_USE_ERRCODE_X with name of error code as its value.
374 ///
375 /// @sa NCBI_DEFINE_ERRCODE_X
376 #define NCBI_ERRCODE_X NCBI_ERRCODE_X_NAME(NCBI_USE_ERRCODE_X)
377 
378 /// Returns maximum value of error subcode within error code with given name.
379 ///
380 /// @sa NCBI_DEFINE_ERRCODE_X
381 #define NCBI_MAX_ERR_SUBCODE_X_NAME(name) \
382  NCBI_NS_NCBI::err_code_x::NCBI_NAME2(SErrCodeX_Max_, name)<true>::value
383 
384 /// Returns maximum value of error subcode within current default error code.
385 ///
386 /// @sa NCBI_DEFINE_ERRCODE_X
387 #define NCBI_MAX_ERR_SUBCODE_X \
388  NCBI_MAX_ERR_SUBCODE_X_NAME(NCBI_USE_ERRCODE_X)
389 
390 
391 /// Template structure used to point out wrong error subcode in
392 /// ERR_POST_X, STD_CATCH_X and alike macros. When error subcode that is
393 /// greater than maximum defined in NCBI_DEFINE_ERRCODE_X or
394 /// NCBI_DEFINE_ERR_SUBCODE_X will be used compiler will give an error and in
395 /// text of this error you'll see the name of this structure. In parameters of
396 /// template instantiation (that will be also shown in error message) you'll
397 /// see error code currently active, error subcode used in *_POST_X macro and
398 /// maximum error subcode valid for active error code.
399 ///
400 /// @sa
401 /// NCBI_DEFINE_ERRCODE_X, NCBI_DEFINE_ERR_SUBCODE_X, ERR_POST_X
402 template <int errorCode, int errorSubcode, int maxErrorSubcode, bool isWrong>
404 
405 /// Specialization of template: when error subcode is valid existence
406 /// of this specialization will be valuable for not issuing compiler error.
407 template <int errorCode, int errorSubcode, int maxErrorSubcode>
409  <errorCode, errorSubcode, maxErrorSubcode, false> {
410  enum {valid = 1};
411 };
412 
413 /// Template structure used to point out incorrect usage of
414 /// NCBI_DEFINE_ERR_SUBCODE_X macro i.e. when it's used for error code defined
415 /// with non-zero maximum subcode in NCBI_DEFINE_ERRCODE_X macro.
416 ///
417 /// @sa
418 /// NCBI_DEFINE_ERRCODE_X, NCBI_DEFINE_ERR_SUBCODE_X
419 template <int errorCode, bool isWrong>
421 
422 /// Specialization of template: when usage of NCBI_DEFINE_ERR_SUBCODE_X is
423 /// correct existence of this specialization will be valuable for not issuing
424 /// compiler error.
425 template <int errorCode>
427  enum {valid = 1};
428 };
429 
430 /// Check that NCBI_DEFINE_ERR_SUBCODE_X is used for correctly defined error
431 /// code.
432 #define NCBI_CHECK_ERRCODE_USAGE(name) \
433  inline void NCBI_NAME2(s_ErrCodeCheck_, name) ( \
434  NCBI_NS_NCBI::WRONG_USAGE_OF_DEFINE_ERR_SUBCODE_MACRO < \
435  NCBI_ERRCODE_X_NAME(name), \
436  NCBI_NS_NCBI::err_code_x::eErrCodeX_Max_##name != 0> \
437  /*err_subcode*/) \
438  {}
439 
440 
441 /// Additional dummy function for use in NCBI_CHECK_ERR_SUBCODE_X macro
442 inline void CheckErrSubcodeX(int)
443 {}
444 
445 /// Issue compile-time error if error subcode given is not valid for given
446 /// error code name.
447 /// This design is used for all compilers except early versions of gcc.
448 /// Though for MIPSpro and ICC it's not enough to make error message clear
449 /// (see addition below).
450 ///
451 /// @sa ERR_POST_X
452 #define NCBI_CHECK_ERR_SUBCODE_X_NAME(name, subcode) \
453  NCBI_NS_NCBI::CheckErrSubcodeX( \
454  (int)sizeof(NCBI_NS_NCBI::WRONG_ERROR_SUBCODE_IN_POST_MACRO< \
455  NCBI_ERRCODE_X_NAME(name), subcode, \
456  NCBI_MAX_ERR_SUBCODE_X_NAME(name), \
457  ((unsigned int)subcode > \
458  (unsigned int)NCBI_MAX_ERR_SUBCODE_X_NAME(name)) \
459  >) \
460  )
461 
462 /// Issue compile-time error if error subcode given is not valid for current
463 /// error code.
464 #define NCBI_CHECK_ERR_SUBCODE_X(subcode) \
465  NCBI_CHECK_ERR_SUBCODE_X_NAME(NCBI_USE_ERRCODE_X, subcode)
466 
467 /// Pass subcode as argument with check of its validity for given error code.
468 #define NCBI_ERR_SUBCODE_X_NAME(name, subcode) \
469  (NCBI_CHECK_ERR_SUBCODE_X_NAME(name, subcode), subcode)
470 
471 /// Pass subcode as argument with check of its validity for current error code.
472 #define NCBI_ERR_SUBCODE_X(subcode) \
473  (NCBI_CHECK_ERR_SUBCODE_X(subcode), subcode)
474 
475 #if defined(NCBI_COMPILER_ICC) || defined(NCBI_COMPILER_MIPSPRO)
476 
477 /// Additional not implemented template structure for use in
478 /// WRONG_ERROR_SUBCODE_IN_POST_MACRO structure specialization
479 template <int x>
480 struct WRONG_ERROR_SUBCODE_IN_POST_MACRO_2;
481 
482 /// Specialization of template structure used for ICC and MIPSpro
483 /// If this specialization doesn't exist these compilers doesn't show name
484 /// of unimplemented structure in error message. But when this specialization
485 /// exists and uses recursively another not implemented template structure
486 /// then WRONG_ERROR_SUBCODE_IN_POST_MACRO appears in error message and it
487 /// becomes clearer.
488 template <int errorCode, int errorSubcode, int maxErrorSubcode>
490  <errorCode, errorSubcode, maxErrorSubcode, true> {
491  typedef char t[sizeof(WRONG_ERROR_SUBCODE_IN_POST_MACRO_2<errorCode>)];
492 };
493 
494 /// Additional not implemented template structure for use in
495 /// WRONG_USAGE_OF_DEFINE_ERR_SUBCODE_MACRO structure specialization
496 template <int x>
497 struct WRONG_USAGE_OF_DEFINE_ERR_SUBCODE_MACRO_2;
498 
499 /// Specialization of template structure used for ICC and MIPSpro
500 /// If this specialization doesn't exist these compilers doesn't show name
501 /// of unimplemented structure in error message. But when this specialization
502 /// exists and uses recursively another not implemented template structure
503 /// then WRONG_USAGE_OF_DEFINE_ERR_SUBCODE_MACRO appears in error message and
504 /// it becomes clearer.
505 template <int errorCode>
507  typedef char t[sizeof(
508  WRONG_USAGE_OF_DEFINE_ERR_SUBCODE_MACRO_2<errorCode>)];
509 };
510 
511 #endif // if defined(NCBI_COMPILER_ICC) || defined(NCBI_COMPILER_MIPSPRO)
512 
513 
514 /// Error posting with default error code and given error subcode. Also
515 /// checks subcode correctness. When error subcode is incorrect (greater than
516 /// defined in NCBI_DEFINE_ERRCODE_X) compile-time error is issued.
517 /// All calls to ERR_POST_X under the same default error code
518 /// MUST be with deferent error subcodes to make possible more
519 /// flexible error statistics and logging.
520 /// If using the macro leads to compile errors containing strings
521 /// like "err_code_x" or "ErrCodeX" in messages, it means you didn't define
522 /// error code name with NCBI_DEFINE_ERRCODE_X macro or didn't select current
523 /// default error code with valid NCBI_USE_ERRCODE_X definition.
524 /// This macro allows the use of only constant error subcodes
525 /// (integer literals or enum constants). If you need to make variable error
526 /// subcode you need to use macro ERR_POST_EX as follows:
527 ///
528 /// NCBI_DEFINE_ERRCODE_X(Corelib_Util, 110, 5);
529 /// ...
530 /// #define NCBI_USE_ERRCODE_X Corelib_Util
531 /// ...
532 /// ERR_POST_EX(NCBI_ERRCODE_X, my_subcode,
533 /// "My error message with variables " << var);
534 ///
535 /// Or in more complicated way:
536 ///
537 /// NCBI_DEFINE_ERRCODE_X(Corelib_Util, 110, 5);
538 /// ...
539 /// // no need to define NCBI_USE_ERRCODE_X
540 /// ...
541 /// ERR_POST_EX(NCBI_ERRCODE_X_NAME(Corelib_Util), my_subcode,
542 /// "My error message with variables " << var);
543 ///
544 /// It's strongly recommended to use macro NCBI_CHECK_ERR_SUBCODE_X
545 /// (or NCBI_CHECK_ERR_SUBCODE_X_NAME in complicated case) to check validity
546 /// of error subcodes in places where variable 'my_subcode' is assigned.
547 ///
548 ///
549 /// @sa NCBI_DEFINE_ERRCODE_X, NCBI_ERRCODE_X, ERR_POST_EX
550 #define ERR_POST_X(err_subcode, message) \
551  ERR_POST_XX(NCBI_USE_ERRCODE_X, err_subcode, message)
552 
553 #define LOG_POST_X(err_subcode, message) \
554  LOG_POST_XX(NCBI_USE_ERRCODE_X, err_subcode, message)
555 
556 #define ERR_FATAL_X(err_subcode, message) \
557  ERR_FATAL_XX(NCBI_USE_ERRCODE_X, err_subcode, message)
558 
559 /// Error posting with error code having given name and with given error
560 /// subcode. Macro must be placed in headers instead of ERR_POST_X to not
561 /// confuse default error codes used in sources where this header is included.
562 ///
563 /// @sa NCBI_DEFINE_ERRCODE_X, ERR_POST_X
564 #define ERR_POST_XX(error_name, err_subcode, message) \
565  ERR_POST_EX(NCBI_ERRCODE_X_NAME(error_name), \
566  NCBI_ERR_SUBCODE_X_NAME(error_name, err_subcode), \
567  message)
568 
569 #define LOG_POST_XX(error_name, err_subcode, message) \
570  LOG_POST_EX(NCBI_ERRCODE_X_NAME(error_name), \
571  NCBI_ERR_SUBCODE_X_NAME(error_name, err_subcode), \
572  message)
573 
574 #define ERR_FATAL_XX(error_name, err_subcode, message) \
575  ERR_FATAL_EX(NCBI_ERRCODE_X_NAME(error_name), \
576  NCBI_ERR_SUBCODE_X_NAME(error_name, err_subcode), \
577  message)
578 
579 /// Common code for making log or error posting only given number of times
580 /// during program execution. This macro MUST not be used outside
581 /// this header.
582 #define NCBI_REPEAT_POST_N_TIMES(post_macro, count, params) \
583  do { \
584  static atomic<int> sx_to_show(count); \
585  int to_show = sx_to_show; \
586  if ( to_show > 0 ) { \
587  sx_to_show = to_show - 1; \
588  post_macro params; /* parenthesis are in params */ \
589  } \
590  } while ( false )
591 
592 
593 /// Error posting only given number of times during program execution.
594 #define ERR_POST_N_TIMES(count, message) \
595  NCBI_REPEAT_POST_N_TIMES( ERR_POST, count, (message) )
596 
597 #define LOG_POST_N_TIMES(count, message) \
598  NCBI_REPEAT_POST_N_TIMES( LOG_POST, count, (message) )
599 
600 
601 /// Error posting only once during program execution.
602 #define ERR_POST_ONCE(message) ERR_POST_N_TIMES(1, message)
603 
604 #define LOG_POST_ONCE(message) LOG_POST_N_TIMES(1, message)
605 
606 
607 /// Error posting only given number of times during program execution
608 /// with default error code and given error subcode.
609 ///
610 /// @sa NCBI_DEFINE_ERRCODE_X, NCBI_ERRCODE_X, ERR_POST_X
611 #define ERR_POST_X_N_TIMES(count, err_subcode, message) \
612  NCBI_REPEAT_POST_N_TIMES( ERR_POST_X, count, (err_subcode, message) )
613 
614 #define LOG_POST_X_N_TIMES(count, err_subcode, message) \
615  NCBI_REPEAT_POST_N_TIMES( LOG_POST_X, count, (err_subcode, message) )
616 
617 /// Error posting only once during program execution with default
618 /// error code and given error subcode.
619 ///
620 /// @sa NCBI_DEFINE_ERRCODE_X, NCBI_ERRCODE_X, ERR_POST_X
621 #define ERR_POST_X_ONCE(err_subcode, message) \
622  ERR_POST_X_N_TIMES(1, err_subcode, message)
623 
624 #define LOG_POST_X_ONCE(err_subcode, message) \
625  LOG_POST_X_N_TIMES(1, err_subcode, message)
626 
627 /// Error posting only given number of times during program execution
628 /// with given error code name and given error subcode.
629 ///
630 /// @sa NCBI_DEFINE_ERRCODE_X, ERR_POST_XX
631 #define ERR_POST_XX_N_TIMES(count, error_name, err_subcode, message) \
632  NCBI_REPEAT_POST_N_TIMES( ERR_POST_XX, count, \
633  (error_name, err_subcode, message) )
634 
635 #define LOG_POST_XX_N_TIMES(count, error_name, err_subcode, message) \
636  NCBI_REPEAT_POST_N_TIMES( LOG_POST_XX, count, \
637  (error_name, err_subcode, message) )
638 
639 /// Error posting only once during program execution with given
640 /// error code name and given error subcode.
641 ///
642 /// @sa NCBI_DEFINE_ERRCODE_X, NCBI_ERRCODE_X, ERR_POST_XX
643 #define ERR_POST_XX_ONCE(error_name, err_subcode, message) \
644  ERR_POST_XX_N_TIMES(1, error_name, err_subcode, message)
645 
646 #define LOG_POST_XX_ONCE(error_name, err_subcode, message) \
647  LOG_POST_XX_N_TIMES(1, error_name, err_subcode, message)
648 
649 /// Severity level for the posted diagnostics.
650 enum EDiagSev {
651  eDiag_Info = 0, ///< Informational message
652  eDiag_Warning, ///< Warning message
653  eDiag_Error, ///< Error message
654  eDiag_Critical, ///< Critical error message
655  eDiag_Fatal, ///< Fatal error -- guarantees exit(or abort)
656  //
657  eDiag_Trace, ///< Trace message
658 
659  // Limits
660  eDiagSevMin = eDiag_Info, ///< Verbosity level for min. severity
661  eDiagSevMax = eDiag_Trace ///< Verbosity level for max. severity
662 };
663 
664 
665 /// Severity level change state.
667  eDiagSC_Unknown, ///< Status of changing severity is unknown (first call)
668  eDiagSC_Disable, ///< Disable change severity level
669  eDiagSC_Enable ///< Enable change severity level
670 };
671 
672 
673 /// Which parts of the diagnostic context should be posted.
674 ///
675 /// Generic appearance of the posted message is as follows:
676 ///
677 /// [<date> <time> ][T<TID> ][["[<path>]/<file>", ][line <line>]: ]
678 /// [<severity>: ][(<err_code>.<err_subcode>) ]
679 /// [<module>[::<class>]::][<function>()] - [<prefix1>::<prefix2>::<prefixN>] <message>\n[
680 /// [<err_code_message>\n]
681 /// [<err_code_explanation>\n]
682 ///
683 /// Example:
684 ///
685 /// - If all flags are set, and prefix string is set to "My prefix", and
686 /// ERR_POST(eDiag_Warning, "Take care!"):
687 /// "/home/iam/myfile.cpp", line 33: Warning: (2.11)
688 /// Module::Class::Function() - [My prefix] Take care!
689 ///
690 /// @sa
691 /// SDiagMessage::Compose()
693  eDPF_File = 1 << 0, ///< File name (not full path)
694  eDPF_LongFilename = 1 << 1, ///< Full file path
695  eDPF_Line = 1 << 2, ///< Source line
696  eDPF_Prefix = 1 << 3, ///< Prefix (default)
697  eDPF_Severity = 1 << 4, ///< Severity (default)
698  eDPF_ErrorID = 1 << 5, ///< Error code and subcode (default)
699 
700  eDPF_DateTime = 1 << 7, ///< Include date and time
701  eDPF_ErrCodeMessage = 1 << 8, ///< Error code message (default)
702  eDPF_ErrCodeExplanation = 1 << 9, ///< Error explanation (default)
703  eDPF_ErrCodeUseSeverity = 1 << 10, ///< Use severity from error code (default)
704  eDPF_Location = 1 << 11, ///< Include class and function if any
705  eDPF_TID = 1 << 13, ///< Thread ID
706 
707  eDPF_PID = 0, ///< @deprecated
708  eDPF_SerialNo = 0, ///< @deprecated
709  eDPF_SerialNo_Thread = 0, ///< @deprecated
710  eDPF_RequestId = 0, ///< @deprecated
711  eDPF_Iteration = eDPF_RequestId, ///< @deprecated
712  eDPF_UID = 0, ///< @deprecated
713 
714  eDPF_ErrCode = eDPF_ErrorID, ///< @deprecated
715  eDPF_ErrSubCode = eDPF_ErrorID, ///< @deprecated
716 
717  /// All flags (except for the "unusual" ones!)
718  eDPF_All = 0x7FFFF,
719 
720  /// Default flags to use when tracing.
721 #if defined(NCBI_THREADS)
724  eDPF_Line |
725  eDPF_Prefix |
726  eDPF_Severity |
727  eDPF_Location |
728  eDPF_PID |
729  eDPF_TID |
730  eDPF_SerialNo |
732 #else
735  eDPF_Line |
736  eDPF_Prefix |
737  eDPF_Severity |
738  eDPF_Location |
739  eDPF_PID |
741 #endif
742 
743  /// Default flags to use for exception formatting.
745 
746  /// Print the posted message only; without severity, location, prefix, etc.
747  eDPF_Log = 0,
748 
749  // "Unusual" flags -- not included in "eDPF_All"
750  eDPF_ErrCodeMsgInFront = 1 << 19, ///< Put ErrCode text in front of the message
751  eDPF_MergeLines = 1 << 21, ///< Escape EOLs.
752  eDPF_PreMergeLines = eDPF_MergeLines, ///< Obsolete. Use eDPF_MergeLines.
753  eDPF_OmitInfoSev = 1 << 22, ///< No sev. indication if eDiag_Info
754  eDPF_OmitSeparator = 1 << 23, ///< No '---' separator before message
755 
756  eDPF_AppLog = 1 << 24, ///< Post message to application log
757  eDPF_IsNote = 1 << 25, ///< Print "Note[X]" severity name.
758  eDPF_IsMessage = eDPF_IsNote, // Legacy name
759 
760  /// This flag is deprecated and ignored - all log writes are atomic.
761  /// For compatibility IsSetDiagPostFlag always returns true when
762  /// asked about this flag.
763  eDPF_AtomicWrite = 1 << 26, ///< @deprecated
764 
765  /// Send the message to 'console' regardless of it's severity.
766  /// To be set by 'Console' manipulator only.
767  eDPF_IsConsole = 1 << 27,
768 
769  /// Use global default flags (merge with).
770  /// @sa SetDiagPostFlag(), UnsetDiagPostFlag(), IsSetDiagPostFlag()
771  eDPF_Default = 1 << 28,
772 
773  /// Important bits which should be taken from the globally set flags
774  /// even if a user attempts to override (or forgets to set) them
775  /// when calling CNcbiDiag().
779 
780  /// Use flags provided by user as-is, do not allow CNcbiDiag to replace
781  /// "important" flags by the globally set ones.
782  eDPF_UseExactUserFlags = 1 << 29
783 };
784 
785 typedef int TDiagPostFlags; ///< Binary OR of "EDiagPostFlag"
786 
787 
788 /// Application execution states shown in the std prefix
790  eDiagAppState_NotSet, ///< Reserved value, never used in messages
797 };
798 
799 
800 // Forward declaration of some classes.
801 class CDiagBuffer;
802 class CDiagErrCodeInfo;
803 
804 
805 
806 /////////////////////////////////////////////////////////////////////////////
807 ///
808 /// ErrCode --
809 ///
810 /// Define composition of error code.
811 ///
812 /// Currently the error code is an ordered pair of <code, subcode> numbers.
813 
814 class ErrCode
815 {
816 public:
817  /// Constructor.
818  ErrCode(int code, int subcode = 0)
819  : m_Code(code), m_SubCode(subcode)
820  { }
821  int m_Code; ///< Major error code number
822  int m_SubCode; ///< Minor error code number
823 };
824 
825 
826 /////////////////////////////////////////////////////////////////////////////
827 ///
828 /// Severity --
829 ///
830 /// Set post severity to a given level.
831 
832 class Severity
833 {
834 public:
836  : m_Level(sev) {}
837  EDiagSev m_Level; ///< Severity level
838 };
839 
840 
841 /////////////////////////////////////////////////////////////////////////////
842 ///
843 /// SetPostFlags --
844 ///
845 /// Set specific post flags.
846 
848 {
849 public:
851  : m_Flags(flags) {}
852  TDiagPostFlags m_Flags; ///< flags to set
853 };
854 
855 
856 class CNcbiDiag;
857 
858 /////////////////////////////////////////////////////////////////////////////
859 ///
860 /// MDiagModule --
861 ///
862 /// Manipulator to set Module for CNcbiDiag
863 
865 {
866 public:
867  MDiagModule(const char* module);
868  friend const CNcbiDiag& operator<< (const CNcbiDiag& diag,
869  const MDiagModule& module);
870 private:
871  const char* m_Module;
872 };
873 
874 
875 
876 /////////////////////////////////////////////////////////////////////////////
877 ///
878 /// MDiagClass --
879 ///
880 /// Manipulator to set Class for CNcbiDiag
881 
883 {
884 public:
885  MDiagClass(const char* nclass);
886  friend const CNcbiDiag& operator<< (const CNcbiDiag& diag,
887  const MDiagClass& nclass);
888 private:
889  const char* m_Class;
890 };
891 
892 
893 
894 /////////////////////////////////////////////////////////////////////////////
895 ///
896 /// MDiagFunction --
897 ///
898 /// Manipulator to set Function for CNcbiDiag
899 
901 {
902 public:
903  MDiagFunction(const char* function);
904  friend const CNcbiDiag& operator<< (const CNcbiDiag& diag,
905  const MDiagFunction& function);
906 private:
907  const char* m_Function;
908 };
909 
910 
911 //
912 class CException;
913 class CStackTrace;
914 
915 
916 /////////////////////////////////////////////////////////////////////////////
917 ///
918 /// CNcbiDiag --
919 ///
920 /// Define the main NCBI Diagnostic class.
921 
922 
924 {
925 public:
926  /// Constructor.
928  (EDiagSev sev = eDiag_Error, ///< Severity level
929  TDiagPostFlags post_flags = eDPF_Default ///< What to post
930  );
931 
932 
933  /// Constructor -- includes the file and line number info
935  (const CDiagCompileInfo& info, ///< File, line, module
936  EDiagSev sev = eDiag_Error, ///< Severity level
937  TDiagPostFlags post_flags = eDPF_Default ///< What to post
938  );
939 
940  /// Destructor.
942 
943  /// Some compilers (e.g. GCC 3.4.0) fail to use temporary objects as
944  /// function arguments if there's no public copy constructor.
945  /// Rather than using the temporary, get a reference from this method.
946  const CNcbiDiag& GetRef(void) const { return *this; }
947 
948  /// Generic method to post to diagnostic stream.
949  template<class X> const CNcbiDiag& Put(const volatile void*, const X& x) const;
950 
951  /// Diagnostic stream manipulator
952  /// @sa Reset(), Endm()
953  /// @sa Info(), Warning(), Error(), Critical(), Fatal(), Trace()
954  typedef const CNcbiDiag& (*FManip)(const CNcbiDiag&);
955  typedef IOS_BASE& (*FIosbaseManip)(IOS_BASE&);
956  typedef CNcbiIos& (*FIosManip)(CNcbiIos&);
957 
958  /// Helper method to post error code and subcode to diagnostic stream.
959  ///
960  /// Example:
961  /// CNcbiDiag() << ErrCode(5,3) << "My message";
962  const CNcbiDiag& Put(const ErrCode*, const ErrCode& err_code) const;
963 
964  /// Helper method to set severity level.
965  ///
966  /// Example:
967  /// CNcbiDiag() << Severity(eDiag_Error) << "My message";
968  const CNcbiDiag& Put(const Severity*, const Severity& severity) const;
969 
970  /// Helper method to post an exception to diagnostic stream.
971  ///
972  /// Example:
973  /// CNcbiDiag() << ex;
974  template<class X> inline
975  const CNcbiDiag& Put(const CException*, const X& x) const {
976  return x_Put(x);
977  }
978 
979  template<class X> inline
980  const CNcbiDiag& Put(const exception*, const X& x) const {
981  const CException* xp = dynamic_cast<const CException*>(&x);
982  if ( xp ) {
983  return x_Put(*xp);
984  }
985  else {
986  string s = x.what();
987  return Put(&s, s);
988  }
989  }
990 
991  /// Helper method to post stack trace to diagnostic stream using
992  /// standard stack trace formatting.
993  ///
994  /// Example:
995  /// CNcbiDiag() << "My message" << CStackTrace();
997  const CNcbiDiag& Put(const CStackTrace*,
998  const CStackTrace& stacktrace) const;
999 
1000  /// Helper method to set specific post flags.
1001  ///
1002  /// Example:
1003  /// CNcbiDiag() << SetPostFlags(eDPF_DateTime) << "My message";
1004  const CNcbiDiag& Put(const NCBI_NS_NCBI::SetPostFlags*,
1005  const NCBI_NS_NCBI::SetPostFlags& flags) const;
1006 
1007  /// Helper method to handle various diagnostic stream manipulators.
1008  ///
1009  /// For example, to set the message severity level to INFO:
1010  /// CNcbiDiag() << Info << "My message";
1011  const CNcbiDiag& Put(const FManip, const FManip& manip) const
1012  {
1013  return manip(*this);
1014  }
1015  inline const CNcbiDiag& operator<< (FManip manip) const
1016  {
1017  return manip(*this);
1018  }
1019  const CNcbiDiag& operator<< (FIosbaseManip manip) const;
1020  const CNcbiDiag& operator<< (FIosManip manip) const;
1021 
1022  /// Post the arguments
1023  /// @sa Put()
1024  template<class X> inline const CNcbiDiag& operator<< (const X& x) const
1025  {
1026  return Put(&x, x);
1027  }
1028 
1029  // Output manipulators for CNcbiDiag.
1030 
1031  /// Reset the content of current message.
1032  friend const CNcbiDiag& Reset (const CNcbiDiag& diag);
1033 
1034  /// Flush current message, start new one.
1035  friend const CNcbiDiag& Endm (const CNcbiDiag& diag);
1036 
1037  /// Flush current message, then set a severity for the next diagnostic
1038  /// message to INFO
1039  friend const CNcbiDiag& Info (const CNcbiDiag& diag);
1040 
1041  /// Flush current message, then set a severity for the next diagnostic
1042  /// message to WARNING
1043  friend const CNcbiDiag& Warning (const CNcbiDiag& diag);
1044 
1045  /// Flush current message, then set a severity for the next diagnostic
1046  /// message to ERROR
1047  friend const CNcbiDiag& Error (const CNcbiDiag& diag);
1048 
1049  /// Flush current message, then set a severity for the next diagnostic
1050  /// message to CRITICAL ERROR
1051  friend const CNcbiDiag& Critical(const CNcbiDiag& diag);
1052 
1053  /// Flush current message, then set a severity for the next diagnostic
1054  /// message to FATAL
1055  friend const CNcbiDiag& Fatal (const CNcbiDiag& diag);
1056 
1057  /// Flush current message, then set a severity for the next diagnostic
1058  /// message to TRACE
1059  friend const CNcbiDiag& Trace (const CNcbiDiag& diag);
1060 
1061  /// Set IsMessage flag to indicate that the current post is a message.
1062  /// Do not flush current post or change the severity. The flag is reset
1063  /// by the next Flush().
1064  /// @deprecated Use Note manipulator.
1065  friend const CNcbiDiag& Message (const CNcbiDiag& diag);
1066 
1067  /// Set IsNote flag to indicate that the current post is a note.
1068  /// Do not flush current post or change the severity. The flag is reset
1069  /// by the next Flush().
1070  friend const CNcbiDiag& Note (const CNcbiDiag& diag);
1071 
1072  /// Set IsConsole flag to indicate that the current post should
1073  /// go to console regardless of its severity (in addition to the
1074  /// default output -- file etc.).
1075  /// Do not flush current post or change the severity. The flag is reset
1076  /// by the next Flush().
1077  friend const CNcbiDiag& Console (const CNcbiDiag& diag);
1078 
1079  /// Print stack trace
1080  friend const CNcbiDiag& StackTrace (const CNcbiDiag& diag);
1081 
1082  /// Get a common symbolic name for the severity levels.
1083  static const char* SeverityName(EDiagSev sev);
1084 
1085  /// Get severity from string.
1086  ///
1087  /// @param str_sev
1088  /// Can be the numeric value or a symbolic name (see
1089  /// CDiagBuffer::sm_SeverityName[]).
1090  /// @param sev
1091  /// Severity level.
1092  /// @return
1093  /// Return TRUE if severity level known; FALSE, otherwise.
1095  static bool StrToSeverityLevel(const char* str_sev, EDiagSev& sev);
1096 
1097  /// Set file name to post.
1099  const CNcbiDiag& SetFile(const char* file) const;
1100 
1101  /// Set module name.
1103  const CNcbiDiag& SetModule(const char* module) const;
1104 
1105  /// Set class name.
1107  const CNcbiDiag& SetClass(const char* nclass) const;
1108 
1109  /// Set function name.
1111  const CNcbiDiag& SetFunction(const char* function) const;
1112 
1113  /// Set line number for post.
1114  const CNcbiDiag& SetLine(size_t line) const;
1115 
1116  /// Set error code and subcode numbers.
1117  const CNcbiDiag& SetErrorCode(int code = 0, int subcode = 0) const;
1118 
1119  /// Get severity of the current message.
1120  EDiagSev GetSeverity(void) const;
1121 
1122  /// Get file used for the current message.
1123  const char* GetFile(void) const;
1124 
1125  /// Get line number for the current message.
1126  size_t GetLine(void) const;
1127 
1128  /// Get error code of the current message.
1129  int GetErrorCode(void) const;
1130 
1131  /// Get error subcode of the current message.
1132  int GetErrorSubCode(void) const;
1133 
1134  /// Get module name of the current message.
1135  const char* GetModule(void) const;
1136 
1137  /// Get class name of the current message.
1138  const char* GetClass(void) const;
1139 
1140  /// Get function name of the current message.
1141  const char* GetFunction(void) const;
1142 
1143  /// Check if filters are passed for the current message.
1144  /// In addition check an exception and all its backlog if specified.
1146  bool CheckFilters(const CException* ex = NULL) const;
1147 
1148  /// Get post flags for the current message.
1149  /// If the post flags have "eDPF_Default" set, then in the returned flags
1150  /// it will be reset and substituted by current default flags.
1152 
1153  /// Set new post flags for the current message.
1155 
1156  /// Set specific post flags for the current message.
1158 
1159  /// Clear specific post flags for the current message.
1161 
1162  /// Display fatal error message.
1163  NCBI_NORETURN NCBI_XNCBI_EXPORT
1164  static void DiagFatal(const CDiagCompileInfo& info,
1165  const char* message);
1166  /// Display trouble error message.
1168  static void DiagTrouble(const CDiagCompileInfo& info,
1169  const char* message = NULL);
1170 
1171  /// Assert specified expression and report results.
1172  NCBI_NORETURN NCBI_XNCBI_EXPORT
1173  static void DiagAssert(const CDiagCompileInfo& info,
1174  const char* expression,
1175  const char* message = NULL);
1176 
1177  /// Same as DiagAssert but only if the system message box is suppressed.
1180  const CDiagCompileInfo& info,
1181  const char* expression,
1182  const char* message = NULL);
1183 
1184  /// Display validation message.
1186  static void DiagValidate(const CDiagCompileInfo& info,
1187  const char* expression,
1188  const char* message);
1189 
1190  /// @deprecated Use ResetIsNoteFlag()
1191  void ResetIsMessageFlag(void) const { ResetIsNoteFlag(); }
1192 
1193  /// Reset IsNote flag.
1194  void ResetIsNoteFlag(void) const { m_PostFlags &= ~eDPF_IsNote; }
1195 
1196  /// Reset IsConsole flag.
1198 
1199  bool GetOmitStackTrace(void) const { return m_OmitStackTrace; }
1201 
1202  /// Set important flags to their globally set values
1203  /// @sa EDiagPostFlags
1205 
1206 private:
1207  mutable EDiagSev m_Severity; ///< Severity level of current msg
1208  mutable int m_ErrCode; ///< Error code
1209  mutable int m_ErrSubCode; ///< Error subcode
1210  CDiagBuffer& m_Buffer; ///< This thread's error msg. buffer
1211  mutable TDiagPostFlags m_PostFlags; ///< Bitwise OR of "EDiagPostFlag"
1212  mutable bool m_OmitStackTrace;
1213 
1215 
1216  /// Private replacement for Endm called from manipulators. Unlike Endm,
1217  /// does not reset ErrCode if buffer is not set.
1218  void x_EndMess(void) const;
1219 
1220  /// Helper func for the exception-related Put()
1221  /// @sa Put()
1222  NCBI_XNCBI_EXPORT const CNcbiDiag& x_Put(const CException& ex) const;
1223 
1224  /// Private copy constructor to prohibit copy.
1226 
1227  /// Private assignment operator to prohibit assignment.
1229 };
1230 
1231 template<> inline const CNcbiDiag& CNcbiDiag::operator<< (const char* const& x) const
1232 {
1233  if (!x) return operator<<("(nil)");
1234  return Put(&x, x);
1235 }
1236 
1237 
1238 /////////////////////////////////////////////////////////////////////////////
1239 // ATTENTION: the following functions are application-wide, i.e they
1240 // are not local for a particular thread
1241 /////////////////////////////////////////////////////////////////////////////
1242 
1243 
1244 /// Check if a specified flag is set.
1245 ///
1246 /// @param flag
1247 /// Flag to check
1248 /// @param flags
1249 /// If eDPF_Default is set for "flags" then use the current global flags on
1250 /// its place (merged with other flags from "flags").
1251 /// @return
1252 /// "TRUE" if the specified "flag" is set in global "flags" that describes
1253 /// the post settings.
1254 /// @sa SetDiagPostFlag(), UnsetDiagPostFlag()
1257 
1258 /// Set global post flags to "flags".
1259 /// If "flags" have flag eDPF_Default set, it will be replaced by the
1260 /// current global post flags.
1261 /// @return
1262 /// Previously set flags
1265 
1266 /// Set the specified flag (globally).
1268 extern void SetDiagPostFlag(EDiagPostFlag flag);
1269 
1270 /// Unset the specified flag (globally).
1272 extern void UnsetDiagPostFlag(EDiagPostFlag flag);
1273 
1274 /// Versions of the above for extra trace flags.
1275 /// ATTENTION: Thus set trace flags will be ADDED to the regular
1276 /// posting flags.
1277 
1280 
1282 extern void SetDiagTraceFlag(EDiagPostFlag flag);
1283 
1285 extern void UnsetDiagTraceFlag(EDiagPostFlag flag);
1286 
1288 
1289 /// Guard for collecting diag messages (affects the current thread only).
1290 ///
1291 /// Messages with the severity equal or above 'print' severity will be
1292 /// printed but not collected. Messages having severity below 'print'
1293 /// severity and equal or above 'collect' severity will be collected,
1294 /// and later can be either discarded or printed out upon the guard
1295 /// destruction or when Release() is called.
1296 /// @note
1297 /// Nested guards are allowed. Each guard takes care to restore the
1298 /// severity thresholds set by the previous one.
1300 {
1301 public:
1302  /// Action to perform in guard's destructor
1303  enum EAction {
1304  ePrint, ///< Print all collected messages as is
1305  eDiscard, ///< Discard collected messages, default
1306  ePrintCapped ///< Print collected messages at reduced severity
1307  };
1308 
1309  /// Set collectable severity and optionally applied print-severity cap
1310  /// to the current post level, Print severity is set to critical.
1311  /// The default action is eDiscard.
1312  CDiagCollectGuard(void);
1313 
1314  /// Set collectable severity and optionally applied print-severity cap
1315  /// to the current post level, Print severity is set to the specified
1316  /// value but can be ignored if it's lower than the currently set post
1317  /// level (or print severity set by a higher level guard). The
1318  /// default action is eDiscard.
1319  CDiagCollectGuard(EDiagSev print_severity);
1320 
1321  /// Create diag collect guard with the given severities and action.
1322  /// As with the other constructor variants, the optionally applied
1323  /// print-severity cap defaults to the collectable severity.
1324  /// The guard will not set print severity below the current diag
1325  /// post level (or print severity of a higher level guard).
1326  /// Collect severity should be equal or lower than the current
1327  /// diag post level or collect severity.
1328  /// The default action is eDiscard.
1329  CDiagCollectGuard(EDiagSev print_severity,
1330  EDiagSev collect_severity,
1331  EAction action = eDiscard);
1332 
1333  /// Destroy the guard, return post level to the one set before the
1334  /// guard initialization. Depending on the currently set action
1335  /// print or discard the messages.
1336  /// On ePrint all collected messages are printed (if there is no
1337  /// higher level guard) and removed from the collection.
1338  /// On eDiscard the messages are silently discarded (only when the
1339  /// last of several nested guards is destroyed).
1340  ~CDiagCollectGuard(void);
1341 
1342  /// Get current print severity
1343  EDiagSev GetPrintSeverity(void) const { return m_PrintSev; }
1344  /// Set new print severity. The new print severity can not be
1345  /// lower than the current one.
1346  void SetPrintSeverity(EDiagSev sev);
1347 
1348  /// Get current collect severity
1349  EDiagSev GetCollectSeverity(void) const { return m_CollectSev; }
1350  /// Set new collect severity. The new collect severity can not be
1351  /// higher than the current one.
1352  void SetCollectSeverity(EDiagSev sev);
1353 
1354  /// Get current severity cap for use in ePrintCapped mode.
1355  EDiagSev GetSeverityCap(void) const { return m_SeverityCap; }
1356  /// Set new severity cap for use in PrintCapped mode.
1357  void SetSeverityCap(EDiagSev sev) { m_SeverityCap = sev; }
1358 
1359  /// Get selected on-destroy action
1360  EAction GetAction(void) const { return m_Action; }
1361  /// Specify on-destroy action.
1362  void SetAction(EAction action) { m_Action = action; }
1363 
1364  /// Get the lowest thread-local post number in this guard's scope.
1365  Uint8 GetStartingPoint(void) const { return m_StartingPoint; }
1366 
1367  /// Release the guard. Perform the currently set action, stop collecting
1368  /// messages, reset severities set by this guard.
1369  void Release(void);
1370 
1371  /// Release the guard. Perform the specified action, stop collecting
1372  /// messages, reset severities set by this guard.
1373  void Release(EAction action);
1374 
1375 private:
1376  void x_Init(EDiagSev print_severity,
1377  EDiagSev collect_severity,
1378  EAction action);
1379 
1385 };
1386 
1387 
1388 /// Specify a string to prefix all subsequent error postings with.
1390 extern void SetDiagPostPrefix(const char* prefix);
1391 
1392 /// Push a string to the list of message prefixes.
1394 extern void PushDiagPostPrefix(const char* prefix);
1395 
1396 /// Pop a string from the list of message prefixes.
1398 extern void PopDiagPostPrefix(void);
1399 
1400 /// Get iteration number/request ID.
1402 extern Uint8 GetDiagRequestId(void);
1403 
1404 /// Set iteration number/request ID.
1406 extern void SetDiagRequestId(Uint8 id);
1407 
1408 
1411 {
1412  return GetDiagRequestId();
1413 }
1414 
1415 
1418 {
1419  SetDiagRequestId(id);
1420 }
1421 
1422 
1423 /////////////////////////////////////////////////////////////////////////////
1424 ///
1425 /// CDiagAutoPrefix --
1426 ///
1427 /// Define the auxiliary class to temporarily add a prefix.
1428 
1430 {
1431 public:
1432  /// Constructor.
1433  CDiagAutoPrefix(const string& prefix);
1434 
1435  /// Constructor.
1436  CDiagAutoPrefix(const char* prefix);
1437 
1438  /// Remove the prefix automagically, when the object gets out of scope.
1439  ~CDiagAutoPrefix(void);
1440 };
1441 
1442 
1443 /// Diagnostic post severity level.
1444 ///
1445 /// The value of DIAG_POST_LEVEL can be a digital value (0-9) or
1446 /// string value from CDiagBuffer::sm_SeverityName[].
1447 #define DIAG_POST_LEVEL "DIAG_POST_LEVEL"
1448 
1449 /// Set the threshold severity for posting the messages.
1450 ///
1451 /// This function has effect only if:
1452 /// - Environment variable $DIAG_POST_LEVEL is not set, and
1453 /// - Registry value of DIAG_POST_LEVEL, section DEBUG is not set
1454 ///
1455 /// Another way to do filtering is to call SetDiagFilter
1456 ///
1457 /// @param post_sev
1458 /// Post only messages with severity greater or equal to "post_sev".
1459 ///
1460 /// Special case: eDiag_Trace -- print all messages and turn on the tracing.
1461 /// @return
1462 /// Return previous post-level.
1463 /// @sa SetDiagFilter(), SetDiagTrace()
1465 extern EDiagSev SetDiagPostLevel(EDiagSev post_sev = eDiag_Error);
1466 
1467 /// Get current threshold severity for posting the messages.
1468 /// @return
1469 /// Return current post-level.
1470 /// @sa SetDiagPostLevel()
1472 extern EDiagSev GetDiagPostLevel(void);
1473 
1474 /// Compare two severities.
1475 /// @return
1476 /// The return value is negative if the first value is lower than
1477 /// the second one, positive if it's higher than the second one,
1478 /// 0 if the severities are equal.
1480 extern int CompareDiagPostLevel(EDiagSev sev1, EDiagSev sev2);
1481 
1482 /// Check if the specified severity is higher or equal to the currently
1483 /// selected post level and will be printed by ERR_POST.
1485 extern bool IsVisibleDiagPostLevel(EDiagSev sev);
1486 
1487 /// Disable change the diagnostic post level.
1488 ///
1489 /// Consecutive using SetDiagPostLevel() will not have effect.
1491 extern bool DisableDiagPostLevelChange(bool disable_change = true);
1492 
1493 /// Sets and locks the level, combining the previous two calls.
1495 extern void SetDiagFixedPostLevel(EDiagSev post_sev);
1496 
1497 /// Set the "die" (abort) level for the program.
1498 ///
1499 /// Abort the application if severity is >= "die_sev".
1500 /// Throw an exception if die_sev is not in the range
1501 /// [eDiagSevMin..eDiag_Fatal].
1502 /// @return
1503 /// Return previous die-level.
1505 extern EDiagSev SetDiagDieLevel(EDiagSev die_sev = eDiag_Fatal);
1506 
1507 /// Get the "die" (abort) level for the program.
1509 extern EDiagSev GetDiagDieLevel(void);
1510 
1511 /// Ignore the die level settings. Return previous setting.
1512 ///
1513 /// WARNING!!! -- not recommended for use unless you are real desperate:
1514 /// By passing TRUE to this function you can make your application
1515 /// never exit/abort regardless of the level set by SetDiagDieLevel().
1516 /// But be warned this is usually a VERY BAD thing to do!
1517 /// -- because any library code counts on at least "eDiag_Fatal" to exit
1518 /// unconditionally, and thus what happens once "eDiag_Fatal" has been posted,
1519 /// is, in general, totally unpredictable! Therefore, use it on your own risk.
1521 extern bool IgnoreDiagDieLevel(bool ignore);
1522 
1523 /// Abort handler function type.
1524 typedef void (*FAbortHandler)(void);
1525 
1526 /// Set/unset abort handler.
1527 ///
1528 /// If "func"==0 use default handler.
1530 extern void SetAbortHandler(FAbortHandler func = 0);
1531 
1532 /// Smart abort function.
1533 ///
1534 /// Processes user abort handler and does not pop up assert windows
1535 /// if specified (environment variable DIAG_SILENT_ABORT is "Y" or "y").
1536 NCBI_NORETURN NCBI_XNCBI_EXPORT
1537 extern void Abort(void);
1538 
1539 /// Diagnostic trace setting.
1540 #define DIAG_TRACE "DIAG_TRACE"
1541 
1542 /// Which setting disables/enables posting of "eDiag_Trace" messages.
1543 ///
1544 /// By default, trace messages are disabled unless:
1545 /// - Environment variable $DIAG_TRACE is set (to any value), or
1546 /// - Registry value of DIAG_TRACE, section DEBUG is set (to any value)
1548  eDT_Default = 0, ///< Restores the default tracing context
1549  eDT_Disable, ///< Ignore messages of severity "eDiag_Trace"
1550  eDT_Enable ///< Enable messages of severity "eDiag_Trace"
1551 };
1552 
1553 
1554 /// Set the diagnostic trace settings.
1556 extern void SetDiagTrace(EDiagTrace how, EDiagTrace dflt = eDT_Default);
1557 
1558 /// Check if traces are enabled.
1560 extern bool GetDiagTrace(void);
1561 
1562 
1563 /// Forward declarations
1564 class CTime;
1565 
1566 /// Internal structure to hold diag message string data.
1567 struct SDiagMessageData;
1568 
1569 struct SDiagMessage;
1570 
1571 /// Callback interface for stream parser. Called for every message read
1572 /// from the input stream.
1573 /// @sa SDiagMessage
1575 {
1576 public:
1577  virtual void operator()(SDiagMessage& msg) = 0;
1578  virtual ~INextDiagMessage(void) {}
1579 };
1580 
1581 
1582 /////////////////////////////////////////////////////////////////////////////
1583 ///
1584 /// SDiagMessage --
1585 ///
1586 /// Diagnostic message structure.
1587 ///
1588 /// Defines structure of the "data" message that is used with message handler
1589 /// function("func"), and destructor("cleanup").
1590 /// The "func(..., data)" to be called when any instance of "CNcbiDiagBuffer"
1591 /// has a new diagnostic message completed and ready to post.
1592 /// "cleanup(data)" will be called whenever this hook gets replaced and
1593 /// on the program termination.
1594 /// NOTE 1: "func()", "cleanup()" and "g_SetDiagHandler()" calls are
1595 /// MT-protected, so that they would never be called simultaneously
1596 /// from different threads.
1597 /// NOTE 2: By default, the errors will be written to standard error stream.
1598 
1600  typedef Uint8 TPID; ///< Process ID
1601  typedef Uint8 TTID; ///< Thread ID
1602  typedef Int8 TUID; ///< Unique process ID
1603 
1604  /// Generic type for counters (posts, requests etc.)
1605  typedef Uint8 TCount;
1606 
1607  /// Initialize SDiagMessage fields.
1608  SDiagMessage(EDiagSev severity, const char* buf, size_t len,
1609  const char* file = 0, size_t line = 0,
1610  TDiagPostFlags flags = eDPF_Default, const char* prefix = 0,
1611  int err_code = 0, int err_subcode = 0,
1612  const char* err_text = 0,
1613  const char* module = 0,
1614  const char* nclass = 0,
1615  const char* function = 0);
1616 
1617  /// Copy constructor required to store the messages and flush them when
1618  /// the diagnostics setup is finished.
1619  SDiagMessage(const SDiagMessage& message);
1620 
1621  /// Assignment of messages
1622  SDiagMessage& operator=(const SDiagMessage& message);
1623 
1624  /// Parse a string back into SDiagMessage. Optional bool argument is
1625  /// set to true if the message was parsed successfully.
1626  SDiagMessage(const string& message, bool* result = 0);
1627 
1628  ~SDiagMessage(void);
1629 
1630  /// Parse the whole string into the message.
1631  /// Return true on success, false if parsing failed.
1632  bool ParseMessage(const string& message);
1633 
1634  /// Stream parser. Reads messages from a stream and calls the callback
1635  /// for each message.
1636  static void ParseDiagStream(CNcbiIstream& in,
1637  INextDiagMessage& func);
1638 
1639  /// Type of event to report
1640  enum EEventType {
1641  eEvent_Start, ///< Application start
1642  eEvent_Stop, ///< Application exit
1643  eEvent_Extra, ///< Other application events
1644  eEvent_RequestStart, ///< Start processing request
1645  eEvent_RequestStop, ///< Finish processing request
1646  eEvent_PerfLog ///< Performance log
1647  };
1648 
1649  static string GetEventName(EEventType event);
1650 
1651  mutable EDiagSev m_Severity; ///< Severity level
1652  const char* m_Buffer; ///< Not guaranteed to be '\0'-terminated!
1653  size_t m_BufferLen; ///< Length of m_Buffer
1654  const char* m_File; ///< File name
1655  const char* m_Module; ///< Module name
1656  const char* m_Class; ///< Class name
1657  const char* m_Function; ///< Function name
1658  size_t m_Line; ///< Line number in file
1659  int m_ErrCode; ///< Error code
1660  int m_ErrSubCode; ///< Sub Error code
1661  TDiagPostFlags m_Flags; ///< Bitwise OR of "EDiagPostFlag"
1662  const char* m_Prefix; ///< Prefix string
1663  const char* m_ErrText; ///< Sometimes 'error' has no numeric code,
1664  ///< but can be represented as text
1665  TPID m_PID; ///< Process ID
1666  TTID m_TID; ///< Thread ID
1667  TCount m_ProcPost; ///< Number of the post in the process
1668  TCount m_ThrPost; ///< Number of the post in the thread
1669  TCount m_RequestId; ///< FastCGI iteration or request ID
1670 
1671  /// If the severity is eDPF_AppLog, m_Event contains event type.
1673 
1674  typedef pair<string, string> TExtraArg;
1675  typedef list<TExtraArg> TExtraArgs;
1676 
1677  /// If event type is "extra", contains the list of arguments
1679  /// Set to true if this is a typed extra message (the arguments include
1680  /// "NCBIEXTRATYPE=<extra-type>").
1682 
1683  /// Special flag indicating that the message should not be printed by
1684  /// Tee-handler.
1685  bool m_NoTee;
1686 
1687  bool m_PrintStackTrace; // Print stack trace after the message
1688 
1689  /// Convert extra arguments to string
1690  string FormatExtraMessage(void) const;
1691 
1692  /// Get UID from current context or parsed from a string
1693  TUID GetUID(void) const;
1694  /// Get time and date - current or parsed.
1695  CTime GetTime(void) const;
1696 
1697  /// Compose a message string in the standard format(see also "flags"):
1698  /// "<file>", line <line>: <severity>: [<prefix>] <message> [EOL]
1699  /// and put it to string "str", or write to an output stream "os".
1700 
1701  /// Which write flags should be output in diagnostic message.
1703  fNone = 0x0, ///< No flags
1704  fNoEndl = 0x01, ///< No end of line
1705  fNoPrefix = 0x02 ///< No std prefix
1706  };
1707 
1708  typedef int TDiagWriteFlags; /// Binary OR of "EDiagWriteFlags"
1709 
1710  /// Write to string.
1711  void Write(string& str, TDiagWriteFlags flags = fNone) const;
1712 
1713  /// Write to stream.
1715 
1716  /// Access to strings stored in SDiagMessageData.
1717  const string& GetHost(void) const;
1718  string GetClient(void) const;
1719  string GetSession(void) const;
1720  const string& GetAppName(void) const;
1721  EDiagAppState GetAppState(void) const;
1722 
1723  CNcbiOstream& x_OldWrite(CNcbiOstream& os, TDiagWriteFlags fl = fNone) const;
1724  CNcbiOstream& x_NewWrite(CNcbiOstream& os, TDiagWriteFlags fl = fNone) const;
1725  string x_GetModule(void) const;
1726 
1727  static void s_EscapeNewlines(string& buf);
1728  static void s_UnescapeNewlines(string& buf);
1729 
1730 private:
1731  // Parse extra args formatted as CGI query string. Do not check validity
1732  // of names and values. Split args by '&', split name/value by '=', do
1733  // URL-decoding.
1734  // If the string is not in the correct format (no '&' or '=') do not
1735  // parse it, return false.
1736  bool x_ParseExtraArgs(const string& str, size_t pos);
1737 
1739  eFormat_Old, // Force old post format
1740  eFormat_New, // Force new post format
1741  eFormat_Auto // Get post format from CDiagContext, default
1742  };
1743  void x_SetFormat(EFormatFlag fmt) const { m_Format = fmt; }
1744  bool x_IsSetOldFormat(void) const;
1745  friend class CDiagContext;
1746 
1747  // Initialize data with the current values
1748  void x_InitData(void) const;
1749  // Save current context properties
1750  void x_SaveContextData(void) const;
1751 
1754 
1755  // Flag indicating if bad symbols in extra argument names are allowed.
1756  // The flag can be set only by CDiagContext_Extra.
1757  friend class CDiagContext_Extra;
1759 };
1760 
1761 /// Insert message in output stream.
1763  return mess.Write(os);
1764 }
1765 
1766 
1767 
1768 /////////////////////////////////////////////////////////////////////////////
1769 ///
1770 /// CDiagContext --
1771 ///
1772 /// NCBI diagnostic context. Storage for application-wide properties.
1773 
1774 class CSpinLock;
1775 class CStopWatch;
1776 class CDiagHandler;
1777 class CNcbiRegistry;
1778 
1779 /// Where to write the application's diagnostics to.
1781  eDS_ToStdout, ///< To standard output stream
1782  eDS_ToStderr, ///< To standard error stream
1783  eDS_ToStdlog, ///< Try standard log file (app.name + ".log") in /log/
1784  ///< and current directory, use stderr if both fail.
1785  eDS_ToMemory, ///< Keep in a temp.memory buffer, see FlushMessages()
1786  eDS_Disable, ///< Don't write it anywhere
1787  eDS_User, ///< Leave as was previously set (or not set) by user
1788  eDS_AppSpecific, ///< Call the application's SetupDiag_AppSpecific()
1789  ///< @deprecated
1790  eDS_Default, ///< Try standard log file (app.name + ".log") in /log/,
1791  ///< use stderr on failure.
1792  eDS_ToSyslog ///< To system log daemon
1793 };
1794 
1795 
1796 /// Flags to control collecting messages and flushing them to the new
1797 /// destination when switching diag handlers.
1799  eDCM_Init, ///< Start collecting messages (with limit), do nothing
1800  ///< if already initialized.
1801  eDCM_InitNoLimit, ///< Start collecting messages without limit (must stop
1802  ///< collecting later using eDCM_Flush or eDCM_Discard).
1803  eDCM_NoChange, ///< Continue collecting messages if already started.
1804  eDCM_Flush, ///< Flush the collected messages and stop collecting.
1805  eDCM_Discard ///< Discard the collected messages without flushing.
1806 };
1807 
1808 
1809 /// Post number increment flag for GetProcessPostNumber() and
1810 /// GetThreadPostNumber().
1812  ePostNumber_NoIncrement, ///< Get post number without incrementing it
1813  ePostNumber_Increment ///< Increment and return the new post number
1814 };
1815 
1816 
1817 class CRequestContext;
1818 class CSharedHitId;
1819 class CRequestRateControl;
1820 class CEncodedString;
1821 
1822 
1823 template<class TKey, class TStorage> class CStrictId;
1824 
1825 /// Temporary object for holding extra message arguments. Prints all
1826 /// of the arguments on destruction.
1828 {
1829 public:
1830  /// Prints all arguments as "name1=value1&name2=value2...".
1831  ~CDiagContext_Extra(void);
1832 
1833  /// The method does not print the argument, but adds it to the string.
1834  /// Name must contain only alphanumeric chars or '_'.
1835  /// Value is URL-encoded before printing.
1836  CDiagContext_Extra& Print(const string& name, const string& value);
1837 
1838  /// Overloaded Print() for all types.
1839  CDiagContext_Extra& Print(const string& name, const char* value);
1840  CDiagContext_Extra& Print(const string& name, int value);
1841  CDiagContext_Extra& Print(const string& name, unsigned int value);
1842  CDiagContext_Extra& Print(const string& name, long value);
1843  CDiagContext_Extra& Print(const string& name, unsigned long value);
1844 #if !NCBI_INT8_IS_LONG
1845  CDiagContext_Extra& Print(const string& name, Int8 value);
1846  CDiagContext_Extra& Print(const string& name, Uint8 value);
1847 #elif SIZEOF_LONG_LONG
1848  CDiagContext_Extra& Print(const string& name, long long value);
1849  CDiagContext_Extra& Print(const string& name, unsigned long long value);
1850 #endif
1851  CDiagContext_Extra& Print(const string& name, char value);
1852  CDiagContext_Extra& Print(const string& name, signed char value);
1853  CDiagContext_Extra& Print(const string& name, unsigned char value);
1854  CDiagContext_Extra& Print(const string& name, double value);
1855  CDiagContext_Extra& Print(const string& name, bool value);
1856  template<class TKey, class TStorage>
1858  {
1859  return Print(name, value.Get());
1860  }
1861 
1862 
1865 
1866  /// The method does not print the arguments, but adds it to the string.
1867  /// Name must contain only alphanumeric chars or '_'.
1868  /// Value is URL-encoded before printing.
1869  /// The args will be modified (emptied) by the function.
1871 
1872  /// Copying the object will prevent printing it on destruction.
1873  /// The new copy should take care of printing.
1875  CDiagContext_Extra& operator=(const CDiagContext_Extra& args);
1876 
1877  /// Print the message and reset object. The object can then be
1878  /// reused to print a new log line (with a new set of arguments
1879  /// if necessary). This is only possible with 'extra' messages,
1880  /// request start/stop messages can not be reused after flush
1881  /// and will print error message instead.
1882  void Flush(void);
1883 
1884  /// Set extra message type.
1885  CDiagContext_Extra& SetType(const string& type);
1886 
1887  /// Allow bad symbols in argument names. URL-encode names the same way
1888  /// as values.
1889  /// NOTE: Avoid using this method if possible. Argument names with
1890  /// encoded symbols may be incompatible with some logging tools.
1891  /// If the flag is not set, any bad symbol is replaced with
1892  /// [ILLEGAL_APPLOG_SYMBOL:%##] string, where %## is the URL-encoded
1893  /// symbol.
1894  CDiagContext_Extra& AllowBadSymbolsInArgNames(void);
1895 
1896 private:
1897  void x_Release(void);
1898  bool x_CanPrint(void);
1899 
1900  // Can be created only by CDiagContext.
1902  // Initialize performance log entry.
1903  CDiagContext_Extra(int status,
1904  double timespan,
1905  TExtraArgs& args);
1906 
1907  // If available, add ncbi_role/ncbi_location to the arguments.
1908  CDiagContext_Extra& PrintNcbiRoleAndLocation(void);
1909  CDiagContext_Extra& PrintNcbiAppInfoOnStart(void);
1910  CDiagContext_Extra& PrintNcbiAppInfoOnRequest(void);
1911 
1912  friend class CDiagContext;
1913  friend NCBI_XNCBI_EXPORT
1914  CDiagContext_Extra g_PostPerf(int status,
1915  double timespan,
1916  SDiagMessage::TExtraArgs& args);
1917 
1921  bool m_Typed;
1922  // PerfLog data
1924  double m_PerfTime;
1927 };
1928 
1929 
1931 {
1932 public:
1933  CDiagContext(void);
1934  ~CDiagContext(void);
1935 
1936  typedef Uint8 TPID;
1937  /// Get cached PID (read real PID if not cached yet).
1938  static TPID GetPID(void);
1939  /// Reset PID cache (e.g. after fork). Return true if PID was updated.
1940  static bool UpdatePID(void);
1941  static bool UpdatePID_AsyncSafe(void);
1942 
1943  /// Actions to perform in UpdateOnFork().
1945  fOnFork_PrintStart = 1 << 0, ///< Log app-start.
1946  fOnFork_ResetTimer = 1 << 1, ///< Reset execution timer.
1947  fOnFork_AsyncSafe = 1 << 15 ///< After a fork() in a multithreaded program, the child can
1948  ///< safely call only async-signal-safe functions. So we can do
1949  ///< only a limited set of operations updating diag context there.
1950  ///< Cancels both previous flags as not async-signal-safe.
1951  };
1952  typedef int TOnForkFlags;
1953 
1954  /// Update diagnostics after fork(). Updates PID if necessary (in the
1955  /// child process). If PID has not changed (parent process), no other
1956  /// actions are performed. For this reason the method will not do anything
1957  /// after the first call, since no PID changes will be detected.
1958  /// @warning
1959  /// The program can be built using multithreaded configurations, but for safety it should
1960  /// have a single thread before fork(). Only in this case it is safe to use any code
1961  /// in the child process.
1962  /// @warning
1963  /// If your program runs many threads and you call fork() one of them, it is safe to use
1964  /// async-safe calls only, otherwise you can get a dedlock, especially if you use thread
1965  /// locking methods and synchronizations, like mutexes and etc.
1966  /// Diag API is not async-safe, because use strings, memory allocations, streams and etc.
1967  /// Also, in such cases you need to use fOnFork_AsyncSafe flag to use async safe operations
1968  /// only inside this method. Note that this flag disable some initialization of the Diag API
1969  /// after forking.
1970  ///
1971  /// @sa UpdatePID(), UpdatePID_AsyncSafe(), CCurrentProcess::GetThreadCount(), CCurrentProcess::Fork()
1972  ///
1973  static void UpdateOnFork(TOnForkFlags flags);
1974 
1976 
1977  /// Return (create if not created yet) unique diagnostic ID.
1978  TUID GetUID(void) const;
1979  /// Return string representation of UID.
1980  /// If the argument UID is 0, use the one from the diag context.
1981  string GetStringUID(TUID uid = 0) const;
1982  /// Take the source UID and replace its timestamp part with the
1983  /// current time.
1984  /// If the source UID is 0, use the one from the diag context.
1985  TUID UpdateUID(TUID uid = 0) const;
1986  /// Fill buffer with string representation of UID. The buffer size
1987  /// must be at least 17 bytes.
1988  void GetStringUID(TUID uid, char* buf, size_t buf_len) const;
1989  /// @deprecated Use GetStringUID(TUID, char*, size_t) instead.
1991  void GetStringUID(TUID uid, char* buf) const;
1992 
1993  /// Create global unique request id.
1994  string GetNextHitID(void) const;
1995  /// Deprecated version of HID generator.
1997  string GetGlobalRequestId(void) const { return GetNextHitID(); }
1998 
1999  /// Shortcut to
2000  /// CDiagContextThreadData::GetThreadData().GetRequestContext()
2001  static CRequestContext& GetRequestContext(void);
2002  /// Shortcut to
2003  /// CDiagContextThreadData::GetThreadData().SetRequestContext()
2004  static void SetRequestContext(CRequestContext* ctx);
2005 
2006  /// Set AutoWrite flag. If set, each property is posted to the current
2007  /// app-log stream when a new value is set.
2008  /// @deprecated
2010  void SetAutoWrite(bool value);
2011 
2012  /// Property visibility flag.
2013  /// @deprecated
2015  eProp_Default, ///< Auto-mode for known properties, local for others
2016  eProp_Global, ///< The property is global for the application
2017  eProp_Thread ///< The property has separate value in each thread
2018  };
2019 
2020  /// Set application context property by name.
2021  /// Write property to the log if AutoPrint flag is set.
2022  /// Property mode defines if the property is a global or a
2023  /// per-thread one. By default unknown properties are set as
2024  /// thread-local.
2025  /// @deprecated
2027  void SetProperty(const string& name,
2028  const string& value,
2029  EPropertyMode mode = eProp_Default);
2030 
2031  /// Get application context property by name, return empty string if the
2032  /// property is not set. If mode is eProp_Default and the property is
2033  /// not a known one, check thread-local properties first.
2034  /// @deprecated
2036  string GetProperty(const string& name,
2037  EPropertyMode mode = eProp_Default) const;
2038 
2039  /// Delete a property by name. If mode is eProp_Default and the property
2040  /// is not a known one, check thread-local properties first.
2041  /// @deprecated
2043  void DeleteProperty(const string& name,
2044  EPropertyMode mode = eProp_Default);
2045 
2046  /// Forced dump of all set properties.
2047  /// @deprecated
2049  void PrintProperties(void);
2050 
2051  /// Global properties
2052  static const char* kProperty_UserName;
2053  static const char* kProperty_HostName;
2054  static const char* kProperty_HostIP;
2055  static const char* kProperty_AppName;
2056  static const char* kProperty_ExitSig;
2057  static const char* kProperty_ExitCode;
2058  /// Per-thread properties
2059  static const char* kProperty_AppState;
2060  static const char* kProperty_ClientIP;
2061  static const char* kProperty_SessionID;
2062  static const char* kProperty_ReqStatus;
2063  static const char* kProperty_ReqTime;
2064  static const char* kProperty_BytesRd;
2065  static const char* kProperty_BytesWr;
2066 
2067  /// Print start/stop etc. message. If the following values are set as
2068  /// properties, they will be dumped before the message:
2069  /// host | host_ip_addr
2070  /// client_ip
2071  /// session_id
2072  /// app_name
2073  /// All messages have the following prefix:
2074  /// PID/TID/ITER UID TIME HOST CLIENT SESSION_ID APP_NAME
2075  /// Depending on its type, a message can be prefixed with the following
2076  /// properties if they are set:
2077  /// start
2078  /// stop [SIG] [EXIT_CODE] ELAPSED_TIME
2079  /// extra
2080  /// request-start
2081  /// request-stop [STATUS] [REQ_ELAPSED_TIME] [BYTES_RD] [BYTES_WR]
2082  void PrintStart(const string& message);
2083 
2084  /// Print exit message.
2085  void PrintStop(void);
2086 
2087  /// Print extra message in plain text format.
2088  /// This method is deprecated and should be replaced by a call to
2089  /// Extra() method and one or more calls to CDiagContext_Extra::Print().
2090  NCBI_DEPRECATED void PrintExtra(const string& message);
2091 
2092  /// Create a temporary CDiagContext_Extra object. The object will print
2093  /// arguments automatically from destructor. Can be used like:
2094  /// Extra().Print(name1, val1).Print(name2, val2);
2096  {
2098  }
2099 
2100  /// Print request start message (for request-driven applications)
2101  /// @deprecated Use CDiagContext_Extra version.
2102  NCBI_DEPRECATED void PrintRequestStart(const string& message);
2103  /// Create a temporary CDiagContext_Extra object. The object will print
2104  /// arguments automatically from destructor. Can be used like:
2105  /// PrintRequestStart().Print(name1, val1).Print(name2, val2);
2106  CDiagContext_Extra PrintRequestStart(void);
2107 
2108  /// Print request stop message (for request-driven applications)
2109  void PrintRequestStop(void);
2110 
2111  /// Always returns global application state.
2112  EDiagAppState GetGlobalAppState(void) const;
2113  /// Set global application state.
2114  /// Do not change state of the current thread.
2115  void SetGlobalAppState(EDiagAppState state);
2116  /// Return application state for the current thread if it's set.
2117  /// If not set, return global application state. This is a shortcut
2118  /// to the current request context's GetAppState().
2119  EDiagAppState GetAppState(void) const;
2120  /// Set application state. Application state is set globally and the
2121  /// thread's state is reset (for the current thread only).
2122  /// Request states are set for the current thread (request context) only.
2123  void SetAppState(EDiagAppState state);
2124  /// The 'mode' flag is deprecated. Use CRequestContext::SetAppState() for
2125  /// per-thread/per-request state.
2127  void SetAppState(EDiagAppState state, EPropertyMode mode);
2128 
2129  /// Check old/new format flag (for compatibility only)
2130  static bool IsSetOldPostFormat(void);
2131  /// Set old/new format flag
2132  static void SetOldPostFormat(bool value);
2133 
2134  /// Check if system TID is printed instead of CThread::GetSelf()
2135  static bool IsUsingSystemThreadId(void);
2136  /// Switch printing system TID (rather than CThread::GetSelf()) on/off
2137  static void UseSystemThreadId(bool value = true);
2138 
2139  /// Get username
2140  const string& GetUsername(void) const;
2141  /// Set username
2142  /// @sa SetDiagUserAndHost
2143  void SetUsername(const string& username);
2144 
2145  /// Get host name. The order is: cached hostname, cached hostIP,
2146  /// uname or COMPUTERNAME, SERVER_ADDR, empty string.
2147  const string& GetHost(void) const;
2148  /// URL-encoded version of GetHost()
2149  const string& GetEncodedHost(void) const;
2150 
2151  /// Get cached hostname - do not try to detect host name as GetHost() does.
2152  const string& GetHostname(void) const;
2153  /// Get URL-encoded hostname
2154  const string& GetEncodedHostname(void) const;
2155  /// Set hostname
2156  /// @sa SetDiagUserAndHost
2157  void SetHostname(const string& hostname);
2158 
2159  /// Get host IP address
2160  const string& GetHostIP(void) const { return m_HostIP; }
2161  /// Set host IP address
2162  void SetHostIP(const string& ip);
2163 
2164  /// Get application name
2165  const string& GetAppName(void) const;
2166  /// Get URL-encoded application name
2167  const string& GetEncodedAppName(void) const;
2168  /// Set application name
2169  void SetAppName(const string& app_name);
2170 
2171  /// Check if exit code has been set.
2172  bool IsSetExitCode(void) const { return m_ExitCodeSet; }
2173  /// Get exit code
2174  int GetExitCode(void) const { return m_ExitCode; }
2175  /// Set exit code
2176  void SetExitCode(int exit_code)
2177  {
2178  m_ExitCode = exit_code;
2179  m_ExitCodeSet = true;
2180  }
2181 
2182  /// Get exit signal
2183  int GetExitSignal(void) const { return m_ExitSig; }
2184  /// Set exit signal
2185  void SetExitSignal(int exit_sig) { m_ExitSig = exit_sig; }
2186 
2187  /// Get default session id. The session id may be set using
2188  /// SetDefaultSessionId(), NCBI_LOG_SESSION_ID env. variable
2189  /// or Log.Session_Id value in the INI file.
2190  string GetDefaultSessionID(void) const;
2191  /// Set new default session id. This value is used only if the per-request
2192  /// session id is not set.
2193  void SetDefaultSessionID(const string& session_id);
2194  /// Get the effective session id: the per-request session id if set,
2195  /// or the default session id.
2196  string GetSessionID(void) const;
2197  /// Get url-encoded session id.
2198  string GetEncodedSessionID(void) const;
2199 
2200  /// Get default client ip. The ip may be set using SetDefaultClientIP(),
2201  /// NCBI_LOG_CLIENT_IP env. variable or Log.Client_Ip value in the INI
2202  /// file.
2203  static string GetDefaultClientIP(void);
2204  /// Set new default client ip. This value is used only if by the time
2205  /// 'request start' is logged there's no explicit ip set in the current
2206  /// request context.
2207  static void SetDefaultClientIP(const string& client_ip);
2208 
2209  /// Get global default hit id. The hit id may be set using
2210  /// SetDefaultHitId(), HTTP_NCBI_PHID or NCBI_LOG_HIT_ID env. variables,
2211  /// or Log.Http_Hit_Id/Log.Hit_Id values in the INI file. The Http-value
2212  /// has higher priority. If none of the values is set, the default hit id
2213  /// is generated automatically.
2214  string GetDefaultHitID(void) const;
2215 
2216  /// Set new global default hit id. This value is used only if the per-request
2217  /// hit id is not set.
2218  void SetDefaultHitID(const string& hit_id);
2219 
2220  /// Get host role (DEV/QA/TRY/PROD) from /etc/ncbi/role.
2221  static const string& GetHostRole(void);
2222 
2223  /// Get host location (be-md/st-va) from /etc/ncbi/location.
2224  static const string& GetHostLocation(void);
2225 
2226  /// Write standard prefix to the stream. Use values from the message
2227  /// (PID/TID/RID etc.).
2228  void WriteStdPrefix(CNcbiOstream& ostr,
2229  const SDiagMessage& msg) const;
2230 
2231  /// Start collecting all messages (the collected messages can be flushed
2232  /// to a new destination later). Stop collecting messages when max_size
2233  /// is reached.
2234  void InitMessages(size_t max_size = 100);
2235  /// Save new message
2236  void PushMessage(const SDiagMessage& message);
2237  /// Flush the collected messages to the current diag handler.
2238  /// Does not clear the collected messages.
2239  void FlushMessages(CDiagHandler& handler);
2240  /// Discard the collected messages without printing them.
2241  void DiscardMessages(void);
2242  /// Check if message collecting is on
2243  bool IsCollectingMessages(void) const { return m_Messages.get() != 0; }
2244 
2245  /// Get log file truncation flag
2246  static bool GetLogTruncate(void);
2247  /// Set log file truncation flag
2248  static void SetLogTruncate(bool value);
2249 
2250  /// @depracated The flag is always set now, the funcion still calls
2251  /// SetupDiag() for compatibility, but has no other effects.
2252  NCBI_DEPRECATED static void SetUseRootLog(void);
2253 
2254  /// Check if the current diagnostics destination is /log/*
2255  static bool IsUsingRootLog(void);
2256 
2257  /// Application-wide diagnostics setup. Attempts to create log files
2258  /// or diag streams according to the 'ds' flag. If 'config' is set,
2259  /// gets name of the log file from the registry.
2260  static void SetupDiag(EAppDiagStream ds = eDS_Default,
2263  const char* cmd_logfile = NULL);
2264 
2266  /// Return process post number (incrementing depends on the flag).
2267  static TCount GetProcessPostNumber(EPostNumberIncrement inc);
2268  /// Return thread post number (incrementing depends on the flag).
2269  static TCount GetThreadPostNumber(EPostNumberIncrement inc);
2270 
2271  /// Get thread ID used in messages
2272  typedef Uint8 TTID;
2273  static TTID GetTID(void);
2274 
2275  /// Type of logging rate limit
2277  eLogRate_App, ///< Application log
2278  eLogRate_Err, ///< Error log
2279  eLogRate_Trace ///< Trace log
2280  };
2281 
2282  /// Logging rate control - max number of messages per period.
2283  unsigned int GetLogRate_Limit(ELogRate_Type type) const;
2284  void SetLogRate_Limit(ELogRate_Type type, unsigned int limit);
2285 
2286  /// Logging rate control - the messages control period, seconds.
2287  unsigned int GetLogRate_Period(ELogRate_Type type) const;
2288  void SetLogRate_Period(ELogRate_Type type, unsigned int period);
2289 
2290  /// Internal function, should be used only by CNcbiApplication.
2291  static void x_FinalizeSetupDiag(void);
2292 
2293  /// When using applog, the diag post level is locked to Warning.
2294  /// The following functions allow to access the lock, but should
2295  /// not be used by most applications.
2296  static bool IsApplogSeverityLocked(void)
2297  { return sm_ApplogSeverityLocked; }
2298  static void SetApplogSeverityLocked(bool lock)
2299  { sm_ApplogSeverityLocked = lock; }
2300 
2301  static bool IsMainThreadDataInitialized(void);
2302 
2303 private:
2306 
2307  // Initialize UID
2308  void x_CreateUID(void) const;
2309  void x_CreateUID_AsyncSafe(void) const;
2310 
2311  // Write message to the log using current handler
2312  void x_PrintMessage(SDiagMessage::EEventType event,
2313  const string& message);
2314  // Start request or report error if one is already running
2315  static void x_StartRequest(void);
2316  // Log environment and registry variables as an extra message.
2317  static void x_LogEnvironment(void);
2318 
2320  friend class CDiagContext_Extra;
2321 
2322  // Reset logging rates to the values stored in CParam-s
2323  void ResetLogRates(void);
2324 
2325  // Check message logging rate
2326  bool ApproveMessage(SDiagMessage& msg, bool* show_warning);
2327 
2328  static void sx_ThreadDataTlsCleanup(CDiagContextThreadData* value,
2329  void* cleanup_data);
2331  friend class CDiagBuffer;
2332  friend class CRequestContext;
2333 
2334  // Default hit id initialization flags.
2336  eHitID_NoCreate, // Do not create new hit id.
2337  eHitID_Create // Create new hit id if it's not yet set.
2338  };
2339 
2340  // Check if current state is 'PB/P/PE'.
2341  bool x_DiagAtApplicationLevel(void) const;
2342  bool x_IsSetDefaultHitID(void) const;
2343  CSharedHitId x_GetDefaultHitID(EDefaultHitIDFlags flag) const;
2344  string x_GetNextHitID(bool is_default) const;
2345  void x_LogHitID(void) const;
2346  void x_LogHitID_WithLock(void) const; // Same as above but with mutex lock.
2347 
2348  // Saved messages to be flushed after setting up log files
2349  typedef list<SDiagMessage> TMessages;
2350 
2351  // Cached process ID
2352  static TPID sm_PID;
2353 
2354  mutable TUID m_UID;
2355  mutable unique_ptr<CEncodedString> m_Host;
2356  string m_HostIP;
2357  unique_ptr<CEncodedString> m_Username;
2358  unique_ptr<CEncodedString> m_AppName;
2359  mutable bool m_AppNameSet;
2360  mutable unique_ptr<CEncodedString> m_DefaultSessionId;
2361  mutable unique_ptr<CSharedHitId> m_DefaultHitId;
2362  mutable bool m_LoggedHitId;
2368  unique_ptr<CStopWatch> m_StopWatch;
2369  unique_ptr<TMessages> m_Messages;
2372 
2373  // Lock severity changes when using applog
2375 
2376  // Rate control
2377  unique_ptr<CRequestRateControl> m_AppLogRC;
2378  unique_ptr<CRequestRateControl> m_ErrLogRC;
2379  unique_ptr<CRequestRateControl> m_TraceLogRC;
2380  atomic<bool> m_AppLogSuspended;
2381  atomic<bool> m_ErrLogSuspended;
2382  atomic<bool> m_TraceLogSuspended;
2383 };
2384 
2385 
2386 /// Get diag context instance
2388 
2389 
2390 /////////////////////////////////////////////////////////////////////////////
2391 ///
2392 /// CNcbiLogFields --
2393 ///
2394 /// Automatic logging of application/request meta-data.
2395 
2397 {
2398 public:
2399  /// Load fields to be logged from NCBI_LOG_FIELDS environment variable.
2400  CNcbiLogFields(const string& source);
2401 
2402  ~CNcbiLogFields(void);
2403 
2404  /// Log (as an extra) all names/values matching fields in NCBI_LOG_FIELDS.
2405  /// If source passed to the constructor is not empty, all names are prefixed
2406  /// with 'source.' string.
2407  template<class TEntries>
2408  void LogFields(const TEntries& entries) const
2409  {
2411  for (typename TEntries::const_iterator it = entries.begin(); it != entries.end(); ++it) {
2412  x_Match(it->first, it->second, extra);
2413  }
2414  }
2415 
2416 private:
2417  // Check if the name matches any NCBI_LOG_FIELDS entry, print matching values to the extra.
2418  void x_Match(const string& name, const string& value, CDiagContext_Extra& extra) const;
2419 
2420  typedef list<string> TFields;
2421 
2422  string m_Source;
2424 };
2425 
2426 
2427 /////////////////////////////////////////////////////////////////////////////
2428 ///
2429 /// CDiagHandler --
2430 ///
2431 /// Base diagnostic handler class.
2432 
2433 /// Type of file for the output
2435 {
2436  eDiagFile_Err, ///< Error log file
2437  eDiagFile_Log, ///< Access log file
2438  eDiagFile_Trace, ///< Trace log file
2439  eDiagFile_Perf, ///< Perf log file
2440  eDiagFile_All ///< All log files
2441 };
2442 
2444 {
2445 public:
2446  /// Destructor.
2447  virtual ~CDiagHandler(void) {}
2448 
2449  /// Post message to handler.
2450  virtual void Post(const SDiagMessage& mess) = 0;
2451  /// Post message to console regardless of its severity.
2452  virtual void PostToConsole(const SDiagMessage& mess);
2453 
2454  /// Check if the handler supports async writes.
2455  /// @sa ComposeMessage, WriteMessage
2456  virtual bool AllowAsyncWrite(const SDiagMessage& msg) const;
2457  /// Compose message without writing it. If async mode is not
2458  /// supported, return empty string.
2459  virtual string ComposeMessage(const SDiagMessage& msg,
2460  EDiagFileType* file_type) const;
2461  /// Write string to the log. The string may contain multiple messages of
2462  /// the same type.
2463  virtual void WriteMessage(const char* buf,
2464  size_t len,
2466 
2467  /// Get current diag posts destination
2468  virtual string GetLogName(void);
2469 
2471  fTruncate = 0x01, ///< Truncate file to zero size
2472  fCheck = 0x02, ///< Reopen only if necessary
2473  fDefault = 0 ///< Default reopen flags:
2474  ///< - no truncation
2475  ///< - do not check if necessary
2476  };
2477  typedef int TReopenFlags;
2478 
2479  /// Reopen file to enable log rotation.
2480  virtual void Reopen(TReopenFlags /*flags*/) {}
2481 };
2482 
2483 
2484 /// Diagnostic handler function type.
2485 typedef void (*FDiagHandler)(const SDiagMessage& mess);
2486 
2487 /// Diagnostic cleanup function type.
2488 typedef void (*FDiagCleanup)(void* data);
2489 
2490 /// Set the diagnostic handler using the specified diagnostic handler class.
2492 extern void SetDiagHandler(CDiagHandler* handler,
2493  bool can_delete = true);
2494 
2495 /// Get the currently set diagnostic handler class.
2497 extern CDiagHandler* GetDiagHandler(bool take_ownership = false,
2498  bool* current_ownership = 0);
2499 
2500 /// Set the diagnostic handler using the specified diagnostic handler
2501 /// and cleanup functions.
2503 extern void SetDiagHandler(FDiagHandler func,
2504  void* data,
2506 
2507 /// Check if diagnostic handler is set.
2508 ///
2509 /// @return
2510 /// Return TRUE if user has ever set (or unset) diag. handler.
2512 extern bool IsSetDiagHandler(void);
2513 
2514 
2515 /// Ask diagnostic handler to reopen log files if necessary.
2517 extern void DiagHandler_Reopen(void);
2518 
2519 
2520 /////////////////////////////////////////////////////////////////////////////
2521 //
2522 // Diagnostic Filter Functionality
2523 //
2524 
2525 /// Diag severity types to put the filter on
2526 ///
2527 /// @sa SetDiagFilter
2529  eDiagFilter_Trace, ///< for TRACEs only
2530  eDiagFilter_Post, ///< for all non-TRACE, non-FATAL
2531  eDiagFilter_All ///< for all non-FATAL
2532 };
2533 
2534 
2535 /// Set diagnostic filter
2536 ///
2537 /// Diagnostic filter acts as a second level filtering mechanism
2538 /// (the primary established by global error post level)
2539 /// @param what
2540 /// Filter is set for
2541 /// @param filter_str
2542 /// Filter string
2543 /// @sa SetDiagPostLevel
2545 extern void SetDiagFilter(EDiagFilter what, const char* filter_str);
2546 
2547 /// Get current diagnostic filter
2548 ///
2549 /// @param what
2550 /// Filter is set for, only eDiagFilter_Trace and eDiagFilter_Post values are allowed,
2551 /// otherwise the function returns empty string.
2552 /// @sa SetDiagFilter
2554 extern string GetDiagFilter(EDiagFilter what);
2555 
2556 /// Append diagnostic filter
2557 ///
2558 /// @param what
2559 /// Filter is set for
2560 /// @param filter_str
2561 /// Filter string
2562 /// @sa SetDiagFilter
2564 extern void AppendDiagFilter(EDiagFilter what, const char* filter_str);
2565 
2566 
2567 /////////////////////////////////////////////////////////////////////////////
2568 ///
2569 /// CStreamDiagHandler_Base --
2570 ///
2571 /// Base class for stream and file based handlers
2572 
2574 {
2575 public:
2577 
2578  virtual string GetLogName(void);
2579  virtual CNcbiOstream* GetStream(void) { return 0; }
2580 
2581 protected:
2582  void SetLogName(const string& log_name);
2583 
2584 private:
2585  char m_LogName[2048];
2586 };
2587 
2588 
2589 /////////////////////////////////////////////////////////////////////////////
2590 ///
2591 /// CStreamDiagHandler --
2592 ///
2593 /// Specialization of "CDiagHandler" for the stream-based diagnostics.
2594 
2596 {
2597 public:
2598  /// Constructor.
2599  ///
2600  /// This does *not* own the stream; users will need to clean it up
2601  /// themselves if appropriate.
2602  /// @param os
2603  /// Output stream.
2604  /// @param quick_flush
2605  /// Do stream flush after every message.
2607  bool quick_flush = true,
2608  const string& stream_name = "");
2609 
2610  /// Post message to the handler.
2611  virtual void Post(const SDiagMessage& mess);
2612  virtual CNcbiOstream* GetStream(void) { return m_Stream; }
2613 
2614 protected:
2615  CNcbiOstream* m_Stream; ///< Diagnostic stream
2616 
2617 private:
2618  bool m_QuickFlush; ///< Quick flush of stream flag
2619 };
2620 
2621 
2622 class CDiagFileHandleHolder;
2623 
2624 /////////////////////////////////////////////////////////////////////////////
2625 ///
2626 /// CFileHandleDiagHandler --
2627 ///
2628 /// Specialization of "CDiagHandler" for the file-handle based diagnostics.
2629 /// Writes messages using system write rather than stream to make the
2630 /// operation really atomic. Re-opens file periodically to make rotation
2631 /// possible.
2632 
2634 {
2635 public:
2637 
2638  /// Constructor.
2639  ///
2640  /// Open file handle.
2641  /// themselves if appropriate.
2642  /// @param fname
2643  /// Output file name.
2644  /// @param file_type
2645  /// Type of log file.
2647  /// Close file handle
2648  ~CFileHandleDiagHandler(void);
2649 
2650  /// Post message to the handler.
2651  virtual void Post(const SDiagMessage& mess);
2652 
2653  virtual bool AllowAsyncWrite(const SDiagMessage& msg) const;
2654  virtual string ComposeMessage(const SDiagMessage& msg,
2655  EDiagFileType* file_type) const;
2656  virtual void WriteMessage(const char* buf,
2657  size_t len,
2659 
2660  bool Valid(void)
2661  {
2662  return (m_FileType == eDiagFile_Perf && !m_HavePosts)
2663  || m_Handle
2664  || m_LowDiskSpace;
2665  }
2666 
2667  // Reopen file to enable log rotation.
2668  virtual void Reopen(TReopenFlags flags);
2669 
2670 protected:
2671  virtual void SetLogName(const string& log_name);
2672 
2673 private:
2680 
2681  /// Save messages if the handle is unavailable
2682  typedef deque<SDiagMessage> TMessages;
2683  unique_ptr<TMessages> m_Messages;
2684 };
2685 
2686 
2687 /////////////////////////////////////////////////////////////////////////////
2688 ///
2689 /// CFileDiagHandler --
2690 ///
2691 /// Specialization of "CDiagHandler" for the file-based diagnostics.
2692 /// Splits output into three files: .err (severity higher than the
2693 /// threshold), .trace (severity below the threshold) and .log
2694 /// (application access log). Re-opens the files periodically
2695 /// to allow safe log rotation.
2696 
2698 {
2699 public:
2701 
2702  /// Constructor. initializes log file(s) with the arguments.
2703  /// @sa SetLogFile
2704  CFileDiagHandler(void);
2705  ~CFileDiagHandler(void);
2706 
2707  /// Post message to the handler. Info and Trace messages are sent
2708  /// to file_name.trace file, all others go to file_name.err file.
2709  /// Application access messages go to file_name.log file.
2710  virtual void Post(const SDiagMessage& mess);
2711 
2712  virtual bool AllowAsyncWrite(const SDiagMessage& msg) const;
2713  virtual string ComposeMessage(const SDiagMessage& msg,
2714  EDiagFileType* file_type) const;
2715  virtual void WriteMessage(const char* buf,
2716  size_t len,
2718 
2719  /// Set new log file.
2720  ///
2721  /// @param file_name
2722  /// File name. If file_type is eDiagFile_All, the output will be written
2723  /// to file_name.(err|log|trace). Otherwise the filename is used as-is.
2724  /// Special filenames are:
2725  /// "" - disable diag messages;
2726  /// "-" - print to stderr
2727  /// "/dev/null" - never add .(err|log|trace) to the name.
2728  /// @param file_type
2729  /// Type of log file to set - error, trace or application log.
2730  /// @param quick_flush
2731  /// Do stream flush after every message.
2732  bool SetLogFile(const string& file_name,
2734  bool quick_flush);
2735 
2736  /// Get current log file name. If file_type is eDiagFile_All, always
2737  /// returns empty string.
2738  string GetLogFile(EDiagFileType file_type) const;
2739 
2740  /// Get current log stream. Return NULL if the selected destination
2741  /// is not a stream.
2742  CNcbiOstream* GetLogStream(EDiagFileType file_type);
2743 
2744  // Reopen all files to enable log rotation.
2745  virtual void Reopen(TReopenFlags flags);
2746 
2747  // Set the selected sub-handler directly with the given ownership.
2748  void SetSubHandler(CStreamDiagHandler_Base* handler,
2750  bool own);
2751 
2752  /// Change ownership for the given handler if it's currently installed.
2753  void SetOwnership(CStreamDiagHandler_Base* handler, bool own);
2754 
2755 protected:
2756  virtual void SetLogName(const string& log_name);
2757 
2758 private:
2759  // Get file type for the message.
2760  EDiagFileType x_GetDiagFileType(const SDiagMessage& msg) const;
2761  // Get sub-handler for the given file type.
2762  CStreamDiagHandler_Base* x_GetHandler(EDiagFileType file_type) const;
2763 
2764  // Check if the object is owned and if it's used as more than one handler,
2765  // update ownership or delete the handler if necessary.
2766  void x_ResetHandler(CStreamDiagHandler_Base** ptr, bool* owned);
2767  // Set the selected member to the handler, make sure only one
2768  // ownership flag is set for the handler.
2769  void x_SetHandler(CStreamDiagHandler_Base** member,
2770  bool* own_member,
2772  bool own);
2773 
2775  bool m_OwnErr;
2777  bool m_OwnLog;
2783 };
2784 
2785 
2786 //////////////////////////////////////////////////////////////////////////
2787 /// CAsyncDiagHandler --
2788 ///
2789 /// Special handler that offloads physical printing of log messages to a
2790 /// separate thread. This handler should be installed into diagnostics
2791 /// only when it is completely initialized, i.e. no earlier than
2792 /// CNcbiApplication::Run() is called. Also it shouldn't be installed
2793 /// using standard SetDiagHandler() function, you have to use
2794 /// InstallToDiag() method of this handler. And don't forget to call
2795 /// RemoveFromDiag() before your application is finished.
2796 
2797 class CAsyncDiagThread;
2798 
2800 {
2801 public:
2802  CAsyncDiagHandler(void);
2803  virtual ~CAsyncDiagHandler(void);
2804 
2805  /// Install this DiagHandler into diagnostics.
2806  /// Method should be called only when diagnostics is completely
2807  /// initialized, i.e. no earlier than CNcbiApplication::Run() is called.
2808  /// Method can throw CThreadException if dedicated thread failed
2809  /// to start.
2810  /// @deprecated Use regular diganostics instead.
2812  void InstallToDiag(void);
2813  /// Remove this DiagHandler from diagnostics.
2814  /// This method must be called if InstallToDiag was called. Object cannot
2815  /// be destroyed if InstallToDiag was called and RemoveFromDiag wasn't
2816  /// called. If InstallToDiag wasn't called then this method does nothing
2817  /// and is safe to be executed.
2818  void RemoveFromDiag(void);
2819  /// Set custom suffix to use on all threads in the server's pool.
2820  /// Value can be set only before call to InstallToDiag(), any change
2821  /// of the value after call to InstallToDiag() will be ignored.
2822  void SetCustomThreadSuffix(const string& suffix);
2823 
2824  /// Implementation of CDiagHandler
2825  virtual void Post(const SDiagMessage& mess);
2826  virtual string GetLogName(void);
2827  virtual void Reopen(TReopenFlags flags);
2828 
2829 private:
2830  /// Thread handling all physical printing of log messages
2833 };
2834 
2835 
2836 /// Output diagnostics using both old and new style handlers.
2838 NCBI_XNCBI_EXPORT extern void SetDoubleDiagHandler(void); ///< @deprecated
2839 
2840 
2841 /// Set diagnostic stream.
2842 ///
2843 /// Error diagnostics are written to output stream "os".
2844 /// This uses the SetDiagHandler() functionality.
2846 extern void SetDiagStream
2847 (CNcbiOstream* os,
2848  bool quick_flush = true, ///< Do stream flush after every message
2849  FDiagCleanup cleanup = 0, ///< Call "cleanup(cleanup_data)" if diag.
2850  void* cleanup_data = 0, ///< Stream is changed (see SetDiagHandler)
2851  const string& stream_name = "" ///< Stream name (e.g. STDERR, file.log)
2852  );
2853 
2854 // Return TRUE if "os" is the current diag. stream.
2856 extern bool IsDiagStream(const CNcbiOstream* os);
2857 
2858 /// Get current diagnostic stream (if it was set by SetDiagStream) or NULL.
2860 extern CNcbiOstream* GetDiagStream(void);
2861 
2862 /// Split log files flag. If set, the output is sent to different
2863 /// log files depending on the severity level.
2864 NCBI_XNCBI_EXPORT extern void SetSplitLogFile(bool value = true);
2865 /// Get split log files flag.
2866 NCBI_XNCBI_EXPORT extern bool GetSplitLogFile(void);
2867 
2868 /// Set log files.
2869 /// Send output to file_name or to file_name.(err|log|trace) depending
2870 /// on the split log file flag and file_type. If a single file type
2871 /// is selected, other types remain the same or are switched to
2872 /// stderr if their files have not been assigned yet.
2873 /// If split log flag is off, any file type except eDiagFile_All
2874 /// will be ignored.
2875 /// If the file_name contains one of the extensions .log, .err or .trace
2876 /// and the file type is eDiagFile_All, the extension will be removed
2877 /// before adding the new one.
2878 /// Return true on success, false if the file could not be open.
2880 extern bool SetLogFile(const string& file_name,
2882  bool quick_flush = true);
2883 
2884 /// Get log file name for the given log type. Return empty string for
2885 /// eDiagFile_All or if the log file handler is not installed.
2887 extern string GetLogFile(EDiagFileType file_type);
2888 
2889 /// Get log file name or diag handler name.
2891 extern string GetLogFile(void);
2892 
2893 
2894 /// Use RW-lock for synchronization rather than mutex.
2895 /// NOTE:
2896 /// 1. The function should never be called when there are
2897 /// several threads running. Otherwise the result may
2898 /// be unpredictable. Also, do not call it from any diagnostic
2899 /// framework functions. E.g., it can not be called from
2900 /// CSomeDiagHandler::Post(). The best place to switch
2901 /// is in the very beginning of main().
2902 /// 2. In many cases switching to RW-lock will not improve
2903 /// the performance. E.g. any stream-based diag handlers including
2904 /// stderr will have to lock a mutex before writing a message anyway.
2905 /// Significant improvement may be seen only when using file handle
2906 /// based handlers which do atomic writes without additional locks.
2907 /// 3. If a custom diag handler is installed, it must take care
2908 /// about synchronization in Post() method. The framework only sets
2909 /// read lock before Post(), so it may be called from multiple
2910 /// threads at the same time.
2911 /// If in doubt, do not turn this on.
2912 /// The returned value is true on success, false if the switching
2913 /// fails for any reason.
2915 extern void g_Diag_Use_RWLock(bool enable = true);
2916 
2917 
2918 /////////////////////////////////////////////////////////////////////////////
2919 ///
2920 /// CDiagFactory --
2921 ///
2922 /// Diagnostic handler factory.
2923 
2925 {
2926 public:
2927  virtual ~CDiagFactory() { }
2928  /// Factory method interface.
2929  virtual CDiagHandler* New(const string& s) = 0;
2930 };
2931 
2932 
2933 
2934 /////////////////////////////////////////////////////////////////////////////
2935 ///
2936 /// CDiagRestorer --
2937 ///
2938 /// Auxiliary class to limit the duration of changes to diagnostic settings.
2939 
2941 {
2942 public:
2943  CDiagRestorer (void); ///< Captures current settings
2944  ~CDiagRestorer(void); ///< Restores captured settings
2945 private:
2946  /// Private new operator.
2947  ///
2948  /// Prohibit dynamic allocation because there's no good reason to allow
2949  /// it, and out-of-order destruction is problematic.
2950  void* operator new (size_t) { throw runtime_error("forbidden"); }
2951 
2952  /// Private new[] operator.
2953  ///
2954  /// Prohibit dynamic allocation because there's no good reason to allow
2955  /// it, and out-of-order destruction is problematic.
2956  void* operator new[] (size_t) { throw runtime_error("forbidden"); }
2957 
2958  /// Private delete operator.
2959  ///
2960  /// Prohibit dynamic deallocation (and allocation) because there's no
2961  /// good reason to allow it, and out-of-order destruction is problematic.
2962  void operator delete (void*) { }
2963 
2964  /// Private delete[] operator.
2965  ///
2966  /// Prohibit dynamic deallocation (and allocation) because there's no
2967  /// good reason to allow it, and out-of-order destruction is problematic.
2968  void operator delete[] (void*) { }
2969 
2970  string m_PostPrefix; ///< Message prefix
2971  list<string> m_PrefixList; ///< List of prefixes
2972  TDiagPostFlags m_PostFlags; ///< Post flags
2973  EDiagSev m_PostSeverity; ///< Post severity
2974  EDiagSevChange m_PostSeverityChange; ///< Severity change
2975  bool m_IgnoreToDie; ///< Ignore to die on die sev
2976  EDiagSev m_DieSeverity; ///< Die level severity
2977  EDiagTrace m_TraceDefault; ///< Default trace setting
2978  bool m_TraceEnabled; ///< Trace enabled?
2979  CDiagHandler* m_Handler; ///< Class handler
2980  bool m_CanDeleteHandler; ///< Can handler be deleted?
2981  CDiagErrCodeInfo* m_ErrCodeInfo; ///< Error code information
2982  bool m_CanDeleteErrCodeInfo; ///< Can delete err code info?
2983  bool m_ApplogSeverityLocked; ///< Limiting applog post level?
2984 };
2985 
2986 
2987 
2988 /////////////////////////////////////////////////////////////////////////////
2989 ///
2990 /// SDiagErrCodeDescription --
2991 ///
2992 /// Structure used to store the errors code and subcode description.
2993 
2995  /// Constructor.
2997 
2998  /// Destructor.
2999  SDiagErrCodeDescription(const string& message, ///< Message
3000  const string& explanation, ///< Explanation of msg.
3001  int severity = -1
3002  ///< Do not override
3003  ///< if set to -1
3004  )
3005  : m_Message(message),
3006  m_Explanation(explanation),
3007  m_Severity(severity)
3008  {
3009  return;
3010  }
3011 
3012 public:
3013  string m_Message; ///< Error message (short)
3014  string m_Explanation; ///< Error message (with detailed explanation)
3016  ///< Message severity (if less that 0, then use
3017  ///< current diagnostic severity level)
3018 };
3019 
3020 
3021 
3022 /////////////////////////////////////////////////////////////////////////////
3023 ///
3024 /// CDiagErrCodeInfo --
3025 ///
3026 /// Stores mapping of error codes and their descriptions.
3027 
3029 {
3030 public:
3031  /// Constructor.
3033 
3034  /// Constructor -- can throw runtime_error.
3035  CDiagErrCodeInfo(const string& file_name);
3036 
3037  /// Constructor -- can throw runtime_error.
3039 
3040  /// Destructor.
3042 
3043  /// Read error description from specified file.
3044  ///
3045  /// Read error descriptions from the specified file,
3046  /// store it in memory.
3047  bool Read(const string& file_name);
3048 
3049  /// Read error description from specified stream.
3050  ///
3051  /// Read error descriptions from the specified stream,
3052  /// store it in memory.
3053  bool Read(CNcbiIstream& is);
3054 
3055  /// Delete all stored error descriptions from memory.
3056  void Clear(void);
3057 
3058  /// Get description for specified error code.
3059  ///
3060  /// Get description message for the error by its code.
3061  /// @return
3062  /// TRUE if error description exists for this code;
3063  /// return FALSE otherwise.
3064  bool GetDescription(const ErrCode& err_code,
3065  SDiagErrCodeDescription* description) const;
3066 
3067  /// Set error description for specified error code.
3068  ///
3069  /// If description for this code already exist, then it
3070  /// will be overwritten.
3071  void SetDescription(const ErrCode& err_code,
3072  const SDiagErrCodeDescription& description);
3073 
3074  /// Check if error description exists.
3075  ///
3076  /// Return TRUE if description for specified error code exists,
3077  /// otherwise return FALSE.
3078  bool HaveDescription(const ErrCode& err_code) const;
3079 
3080 private:
3081 
3082  /// Define map for error messages.
3084 
3085  /// Map storing error codes and descriptions.
3087 };
3088 
3089 
3090 
3091 /// Diagnostic message file.
3092 #define DIAG_MESSAGE_FILE "MessageFile"
3093 
3094 /// Set handler for processing error codes.
3095 ///
3096 /// By default this handler is unset.
3097 /// NcbiApplication can init itself only if registry key DIAG_MESSAGE_FILE
3098 /// section DEBUG) is specified. The value of this key should be a name
3099 /// of the file with the error codes explanations.
3102  bool can_delete = true);
3103 
3104 /// Indicates whether an error-code processing handler has been set.
3106 extern bool IsSetDiagErrCodeInfo();
3107 
3108 /// Get handler for processing error codes.
3110 extern CDiagErrCodeInfo* GetDiagErrCodeInfo(bool take_ownership = false);
3111 
3112 
3113 /* @} */
3114 
3115 
3116 ///////////////////////////////////////////////////////
3117 // All inline function implementations and internal data
3118 // types, etc. are in this file
3119 
3120 #include <corelib/ncbidiag.inl>
3121 
3122 
3124 
3125 
3126 #endif /* CORELIB___NCBIDIAG__HPP */
CDiagAutoPrefix –.
Definition: ncbidiag.hpp:1430
Guard for collecting diag messages (affects the current thread only).
Definition: ncbidiag.hpp:1300
Incapsulate compile time information such as __FILE__, __LINE__, NCBI_MODULE, current function.
Definition: ncbidiag.hpp:65
Thread local context data stored in TLS.
Definition: ncbidiag.cpp:447
Temporary object for holding extra message arguments.
Definition: ncbidiag.hpp:1828
CDiagErrCodeInfo –.
Definition: ncbidiag.hpp:3029
CDiagFactory –.
Definition: ncbidiag.hpp:2925
CDiagRestorer –.
Definition: ncbidiag.hpp:2941
CEncodedString –.
Definition: ncbistr.hpp:4823
CFileDiagHandler –.
Definition: ncbidiag.hpp:2698
CFileHandleDiagHandler –.
Definition: ncbidiag.hpp:2634
CNcbiDiag –.
Definition: ncbidiag.hpp:924
CNcbiLogFields –.
Definition: ncbidiag.hpp:2397
CNcbiRegistry –.
Definition: ncbireg.hpp:913
CRequestRateControl –.
Helper class to hold hit id and sub-hit counter which can be shared between multiple request contexts...
Definition: request_ctx.hpp:65
CSpinLock –.
Definition: ncbimtx.hpp:843
CStopWatch –.
Definition: ncbitime.hpp:1938
CStreamDiagHandler_Base –.
Definition: ncbidiag.hpp:2574
CStreamDiagHandler –.
Definition: ncbidiag.hpp:2596
Template class for strict ID types.
Definition: ncbimisc.hpp:893
CTime –.
Definition: ncbitime.hpp:296
ErrCode –.
Definition: ncbidiag.hpp:815
Callback interface for stream parser.
Definition: ncbidiag.hpp:1575
MDiagClass –.
Definition: ncbidiag.hpp:883
MDiagFunction –.
Definition: ncbidiag.hpp:901
MDiagModule –.
Definition: ncbidiag.hpp:865
SetPostFlags –.
Definition: ncbidiag.hpp:848
Severity –.
Definition: ncbidiag.hpp:833
void(*)(CSeq_entry_Handle seh, IWorkbench *wb, const CSerialObject &obj) handler
void Print(const CCompactSAMApplication::AlignInfo &ai)
static uch flags
static ush * file_type
static const char ip[]
Definition: des.c:75
const char * file_name[]
static void cleanup(void)
Definition: ct_dynamic.c:30
CS_CONTEXT * ctx
Definition: t0006.c:12
#define true
Definition: bool.h:35
#define false
Definition: bool.h:36
static const char * str(char *buf, int n)
Definition: stats.c:84
char data[12]
Definition: iconv.c:80
#define NULL
Definition: ncbistd.hpp:225
int m_ErrCode
Error code.
Definition: ncbidiag.hpp:1659
int m_ErrSubCode
Sub Error code.
Definition: ncbidiag.hpp:1660
TFields m_Fields
Definition: ncbidiag.hpp:2423
int GetErrorSubCode(void) const
Get error subcode of the current message.
TDiagPostFlags GetPostFlags(void) const
Get post flags for the current message.
virtual CDiagHandler * New(const string &s)=0
Factory method interface.
string m_Explanation
Error message (with detailed explanation)
Definition: ncbidiag.hpp:3014
void Write(string &str, TDiagWriteFlags flags=fNone) const
Binary OR of "EDiagWriteFlags".
Definition: ncbidiag.cpp:5355
EFormatFlag m_Format
Definition: ncbidiag.hpp:1753
void SetDiagFilter(EDiagFilter what, const char *filter_str)
Set diagnostic filter.
Definition: ncbidiag.cpp:7670
TExtraArgs m_ExtraArgs
If event type is "extra", contains the list of arguments.
Definition: ncbidiag.hpp:1678
void PushDiagPostPrefix(const char *prefix)
Push a string to the list of message prefixes.
Definition: ncbidiag.cpp:6109
void Clear(void)
Delete all stored error descriptions from memory.
void ParseCurrFunctName(void) const
Definition: logging.cpp:1339
const char * GetModule(void) const
Get module name of the current message.
void SetDescription(const ErrCode &err_code, const SDiagErrCodeDescription &description)
Set error description for specified error code.
string m_PostPrefix
Message prefix.
Definition: ncbidiag.hpp:2970
TCount m_RequestId
FastCGI iteration or request ID.
Definition: ncbidiag.hpp:1669
EDiagPostFlag
Which parts of the diagnostic context should be posted.
Definition: ncbidiag.hpp:692
EDiagSev GetDiagPostLevel(void)
Get current threshold severity for posting the messages.
Definition: ncbidiag.cpp:6151
SetPostFlags(TDiagPostFlags flags)
Definition: ncbidiag.hpp:850
void SetDiagPostFlag(EDiagPostFlag flag)
Set the specified flag (globally).
Definition: ncbidiag.cpp:6070
static const char * kProperty_UserName
Global properties.
Definition: ncbidiag.hpp:2052
EDiagSevChange
Severity level change state.
Definition: ncbidiag.hpp:666
EDiagSev m_SeverityCap
Definition: ncbidiag.hpp:1383
friend const CNcbiDiag & Message(const CNcbiDiag &diag)
Set IsMessage flag to indicate that the current post is a message.
bool m_AllowBadExtraNames
Definition: ncbidiag.hpp:1758
unique_ptr< CEncodedString > m_Username
Definition: ncbidiag.hpp:2357
int m_Code
Major error code number.
Definition: ncbidiag.hpp:821
TDiagPostFlags m_PostFlags
Bitwise OR of "EDiagPostFlag".
Definition: ncbidiag.hpp:1211
static TPID sm_PID
Definition: ncbidiag.hpp:2352
CStreamDiagHandler_Base * m_Perf
Definition: ncbidiag.hpp:2780
string m_StrCurrFunctName
Definition: ncbidiag.hpp:122
const char * m_File
File name.
Definition: ncbidiag.hpp:1654
EDiagSev m_PostSeverity
Post severity.
Definition: ncbidiag.hpp:2973
Uint8 TCount
Generic type for counters (posts, requests etc.)
Definition: ncbidiag.hpp:1605
TTID m_TID
Thread ID.
Definition: ncbidiag.hpp:1666
const char * m_Buffer
Not guaranteed to be '\0'-terminated!
Definition: ncbidiag.hpp:1652
void SetModule(const string &module)
Definition: ncbidiag.cpp:729
CStreamDiagHandler_Base * m_Trace
Definition: ncbidiag.hpp:2778
const CNcbiDiag & SetClass(const char *nclass) const
Set class name.
Definition: ncbidiag.cpp:7760
CNcbiOstream * m_Stream
Diagnostic stream.
Definition: ncbidiag.hpp:2615
EDiagSev m_CollectSev
Definition: ncbidiag.hpp:1382
CDiagErrCodeInfo(void)
Constructor.
void SetLine(int line)
Definition: ncbidiag.cpp:736
CDiagContext & GetDiagContext(void)
Get diag context instance.
Definition: logging.cpp:818
void(* FAbortHandler)(void)
Abort handler function type.
Definition: ncbidiag.hpp:1524
CDiagErrCodeInfo(CNcbiIstream &is)
Constructor – can throw runtime_error.
bool HaveDescription(const ErrCode &err_code) const
Check if error description exists.
EDiagSev m_Severity
Severity level of current msg.
Definition: ncbidiag.hpp:1207
map< string, string > TProperties
Definition: ncbidiag.hpp:2319
const CNcbiDiag &(* FManip)(const CNcbiDiag &)
Diagnostic stream manipulator.
Definition: ncbidiag.hpp:954
const char * m_Module
Definition: ncbidiag.hpp:110
void SetDiagFixedPostLevel(EDiagSev post_sev)
Sets and locks the level, combining the previous two calls.
Definition: ncbidiag.cpp:6179
void SetAction(EAction action)
Specify on-destroy action.
Definition: ncbidiag.hpp:1362
Uint8 GetStartingPoint(void) const
Get the lowest thread-local post number in this guard's scope.
Definition: ncbidiag.hpp:1365
void SetSplitLogFile(bool value=true)
Split log files flag.
Definition: ncbidiag.cpp:6705
EDiagCollectMessages
Flags to control collecting messages and flushing them to the new destination when switching diag han...
Definition: ncbidiag.hpp:1798
TExtraArgs * m_Args
Definition: ncbidiag.hpp:1919
list< string > TFields
Definition: ncbidiag.hpp:2420
const char * m_Module
Module name.
Definition: ncbidiag.hpp:1655
static const char * kProperty_AppName
Definition: ncbidiag.hpp:2055
static const char * kProperty_ClientIP
Definition: ncbidiag.hpp:2060
MDiagClass(const char *nclass)
void SetAllPostFlags(TDiagPostFlags flags) const
Set new post flags for the current message.
static bool sm_ApplogSeverityLocked
Definition: ncbidiag.hpp:2374
size_t m_MaxMessages
Definition: ncbidiag.hpp:2370
bool m_TraceEnabled
Trace enabled?
Definition: ncbidiag.hpp:2978
void DiagHandler_Reopen(void)
Ask diagnostic handler to reopen log files if necessary.
Definition: ncbidiag.cpp:6344
string GetDiagFilter(EDiagFilter what)
Get current diagnostic filter.
Definition: ncbidiag.cpp:7681
friend const CNcbiDiag & StackTrace(const CNcbiDiag &diag)
Print stack trace.
int GetExitSignal(void) const
Get exit signal.
Definition: ncbidiag.hpp:2183
virtual void Reopen(TReopenFlags)
Reopen file to enable log rotation.
Definition: ncbidiag.hpp:2480
unique_ptr< CRequestRateControl > m_TraceLogRC
Definition: ncbidiag.hpp:2379
const CNcbiDiag & Put(const FManip, const FManip &manip) const
Helper method to handle various diagnostic stream manipulators.
Definition: ncbidiag.hpp:1011
CAsyncDiagThread * m_AsyncThread
Thread handling all physical printing of log messages.
Definition: ncbidiag.hpp:2831
atomic< bool > m_ErrLogSuspended
Definition: ncbidiag.hpp:2381
const char * m_Class
Definition: ncbidiag.hpp:889
CDiagContext_Extra Extra(void) const
Create a temporary CDiagContext_Extra object.
Definition: ncbidiag.hpp:2095
void CheckErrSubcodeX(int)
Additional dummy function for use in NCBI_CHECK_ERR_SUBCODE_X macro.
Definition: ncbidiag.hpp:442
friend const CNcbiDiag & Fatal(const CNcbiDiag &diag)
Flush current message, then set a severity for the next diagnostic message to FATAL.
list< SDiagMessage > TMessages
Definition: ncbidiag.hpp:2349
TCount m_ProcPost
Number of the post in the process.
Definition: ncbidiag.hpp:1667
const CNcbiDiag & SetLine(size_t line) const
Set line number for post.
bool DisableDiagPostLevelChange(bool disable_change=true)
Disable change the diagnostic post level.
Definition: ncbidiag.cpp:6186
bool IsCollectingMessages(void) const
Check if message collecting is on.
Definition: ncbidiag.hpp:2243
CDiagErrCodeInfo(const string &file_name)
Constructor – can throw runtime_error.
int GetErrorCode(void) const
Get error code of the current message.
friend const CNcbiDiag & Console(const CNcbiDiag &diag)
Set IsConsole flag to indicate that the current post should go to console regardless of its severity ...
bool IsSetExitCode(void) const
Check if exit code has been set.
Definition: ncbidiag.hpp:2172
string m_StrModule
Definition: ncbidiag.hpp:121
virtual ~CDiagFactory()
Definition: ncbidiag.hpp:2927
int m_ErrSubCode
Error subcode.
Definition: ncbidiag.hpp:1209
const CNcbiDiag & SetErrorCode(int code=0, int subcode=0) const
Set error code and subcode numbers.
Uint8 TPID
Process ID.
Definition: ncbidiag.hpp:1600
size_t m_Line
Line number in file.
Definition: ncbidiag.hpp:1658
CNcbiDiag(const CNcbiDiag &)
Private copy constructor to prohibit copy.
void SetDiagRequestId(Uint8 id)
Set iteration number/request ID.
Definition: ncbidiag.cpp:1201
CDiagBuffer & m_Buffer
This thread's error msg. buffer.
Definition: ncbidiag.hpp:1210
static const char * kProperty_ExitSig
Definition: ncbidiag.hpp:2056
bool CheckFilters(const CException *ex=NULL) const
Check if filters are passed for the current message.
Definition: ncbidiag.cpp:7774
bool m_AppNameSet
Definition: ncbidiag.hpp:2359
~CDiagCompileInfo(void)
Definition: logging.cpp:1332
friend const CNcbiDiag & Info(const CNcbiDiag &diag)
Flush current message, then set a severity for the next diagnostic message to INFO.
bool m_CanDeleteErrCodeInfo
Can delete err code info?
Definition: ncbidiag.hpp:2982
const CNcbiDiag & Put(const CException *, const X &x) const
Helper method to post an exception to diagnostic stream.
Definition: ncbidiag.hpp:975
int TDiagPostFlags
Binary OR of "EDiagPostFlag".
Definition: ncbidiag.hpp:785
EDiagSev m_Severity
Severity level.
Definition: ncbidiag.hpp:1651
const string & GetClass(void) const
bool GetSplitLogFile(void)
Get split log files flag.
Definition: ncbidiag.cpp:6711
virtual void operator()(SDiagMessage &msg)=0
~CNcbiDiag(void)
Destructor.
Definition: ncbidiag.cpp:7732
bool m_QuickFlush
Quick flush of stream flag.
Definition: ncbidiag.hpp:2618
unique_ptr< TMessages > m_Messages
Definition: ncbidiag.hpp:2683
const CNcbiDiag & Put(const exception *, const X &x) const
Definition: ncbidiag.hpp:980
bool GetOmitStackTrace(void) const
Definition: ncbidiag.hpp:1199
friend const CNcbiDiag & Note(const CNcbiDiag &diag)
Set IsNote flag to indicate that the current post is a note.
void SetSeverityCap(EDiagSev sev)
Set new severity cap for use in PrintCapped mode.
Definition: ncbidiag.hpp:1357
EDiagWriteFlags
Compose a message string in the standard format(see also "flags"): "<file>", line <line>: <severity>:...
Definition: ncbidiag.hpp:1702
unique_ptr< CEncodedString > m_Host
Definition: ncbidiag.hpp:2355
CNcbiIos &(* FIosManip)(CNcbiIos &)
Definition: ncbidiag.hpp:956
EAppDiagStream
Where to write the application's diagnostics to.
Definition: ncbidiag.hpp:1780
EDiagTrace m_TraceDefault
Default trace setting.
Definition: ncbidiag.hpp:2977
Uint8 TTID
Get thread ID used in messages.
Definition: ncbidiag.hpp:2272
void UnsetDiagTraceFlag(EDiagPostFlag flag)
Definition: ncbidiag.cpp:6091
EPostNumberIncrement
Post number increment flag for GetProcessPostNumber() and GetThreadPostNumber().
Definition: ncbidiag.hpp:1811
const char * m_Prefix
Prefix string.
Definition: ncbidiag.hpp:1662
const char * GetFile(void) const
virtual void Post(const SDiagMessage &mess)=0
Post message to handler.
friend const CNcbiDiag & operator<<(const CNcbiDiag &diag, const MDiagFunction &function)
EDiagSev GetDiagDieLevel(void)
Get the "die" (abort) level for the program.
Definition: ncbidiag.cpp:6211
const CNcbiDiag & GetRef(void) const
Some compilers (e.g.
Definition: ncbidiag.hpp:946
string m_Message
Error message (short)
Definition: ncbidiag.hpp:3013
const CNcbiDiag & Put(const ErrCode *, const ErrCode &err_code) const
Helper method to post error code and subcode to diagnostic stream.
const CNcbiDiag & operator<<(FManip manip) const
Definition: ncbidiag.hpp:1015
virtual ~INextDiagMessage(void)
Definition: ncbidiag.hpp:1578
bool IsDiagStream(const CNcbiOstream *os)
Definition: ncbidiag.cpp:7636
size_t GetLine(void) const
Get line number for the current message.
TProperties m_Properties
Definition: ncbidiag.hpp:2367
bool IsVisibleDiagPostLevel(EDiagSev sev)
Check if the specified severity is higher or equal to the currently selected post level and will be p...
Definition: ncbidiag.cpp:6166
EEventType
Type of event to report.
Definition: ncbidiag.hpp:1640
TDiagPostFlags m_Flags
Bitwise OR of "EDiagPostFlag".
Definition: ncbidiag.hpp:1661
SDiagErrCodeDescription(const string &message, const string &explanation, int severity=-1)
Destructor.
Definition: ncbidiag.hpp:2999
bool m_NoTee
Special flag indicating that the message should not be printed by Tee-handler.
Definition: ncbidiag.hpp:1685
static CDiagContext * sm_Instance
Definition: ncbidiag.hpp:2371
EDiagSev m_DieSeverity
Die level severity.
Definition: ncbidiag.hpp:2976
const CNcbiDiag & Put(const Severity *, const Severity &severity) const
Helper method to set severity level.
map< ErrCode, SDiagErrCodeDescription > TInfo
Define map for error messages.
Definition: ncbidiag.hpp:3083
atomic< bool > m_AppLogSuspended
Definition: ncbidiag.hpp:2380
void PopDiagPostPrefix(void)
Pop a string from the list of message prefixes.
Definition: ncbidiag.cpp:6119
EDiagAppState m_AppState
Definition: ncbidiag.hpp:2366
void AppendDiagFilter(EDiagFilter what, const char *filter_str)
Append diagnostic filter.
Definition: ncbidiag.cpp:7694
static void DiagTrouble(const CDiagCompileInfo &info, const char *message=NULL)
Display trouble error message.
Definition: ncbidiag.cpp:7938
MDiagModule(const char *module)
static const char * kProperty_ReqTime
Definition: ncbidiag.hpp:2063
bool GetDiagTrace(void)
Check if traces are enabled.
Definition: ncbidiag.cpp:6240
void SetFastCGIIteration(Uint8 id)
Definition: ncbidiag.hpp:1417
CStopWatch * m_ReopenTimer
Definition: ncbidiag.hpp:2679
static void SetApplogSeverityLocked(bool lock)
Definition: ncbidiag.hpp:2298
const CNcbiDiag & SetFile(const char *file) const
Set file name to post.
Definition: ncbidiag.cpp:7746
CNcbiDiag(EDiagSev sev=eDiag_Error, TDiagPostFlags post_flags=eDPF_Default)
Constructor.
Definition: ncbidiag.cpp:7709
CStopWatch * m_ReopenTimer
Definition: ncbidiag.hpp:2782
CStreamDiagHandler_Base * m_Log
Definition: ncbidiag.hpp:2776
const string & GetHostIP(void) const
Get host IP address.
Definition: ncbidiag.hpp:2160
TCount m_ThrPost
Number of the post in the thread.
Definition: ncbidiag.hpp:1668
friend const CNcbiDiag & Trace(const CNcbiDiag &diag)
Flush current message, then set a severity for the next diagnostic message to TRACE.
EDiagSevChange m_PostSeverityChange
Severity change.
Definition: ncbidiag.hpp:2974
int m_Severity
Message severity (if less that 0, then use current diagnostic severity level)
Definition: ncbidiag.hpp:3015
int CompareDiagPostLevel(EDiagSev sev1, EDiagSev sev2)
Compare two severities.
Definition: ncbidiag.cpp:6157
static const char * kProperty_ExitCode
Definition: ncbidiag.hpp:2057
void UnsetDiagPostFlag(EDiagPostFlag flag)
Unset the specified flag (globally).
Definition: ncbidiag.cpp:6075
const char * m_Module
Definition: ncbidiag.hpp:871
unique_ptr< CStopWatch > m_StopWatch
Definition: ncbidiag.hpp:2368
CDiagHandler * GetDiagHandler(bool take_ownership=false, bool *current_ownership=0)
Get the currently set diagnostic handler class.
Definition: ncbidiag.cpp:6329
void SetDiagPostPrefix(const char *prefix)
Specify a string to prefix all subsequent error postings with.
Definition: ncbidiag.cpp:6097
void ResetIsConsoleFlag(void) const
Reset IsConsole flag.
Definition: ncbidiag.hpp:1197
void SetDoubleDiagHandler(void)
Output diagnostics using both old and new style handlers.
Definition: ncbidiag.cpp:8129
int TDiagWriteFlags
Definition: ncbidiag.hpp:1708
bool m_OmitStackTrace
Definition: ncbidiag.hpp:1212
EDiagSev SetDiagDieLevel(EDiagSev die_sev=eDiag_Fatal)
Set the "die" (abort) level for the program.
Definition: ncbidiag.cpp:6196
const char * m_Function
Definition: ncbidiag.hpp:907
EDiagFileType m_FileType
Definition: ncbidiag.hpp:2674
NCBI_XNCBI_EXPORT void Abort(void)
Smart abort function.
Definition: ncbidiag.cpp:8147
IOS_BASE &(* FIosbaseManip)(IOS_BASE &)
Definition: ncbidiag.hpp:955
void x_EndMess(void) const
Private replacement for Endm called from manipulators.
const CNcbiDiag & SetFunction(const char *function) const
Set function name.
Definition: ncbidiag.cpp:7767
static void DiagValidate(const CDiagCompileInfo &info, const char *expression, const char *message)
Display validation message.
Definition: ncbidiag.cpp:7965
list< TExtraArg > TExtraArgs
Definition: ncbidiag.hpp:1675
size_t m_BufferLen
Length of m_Buffer.
Definition: ncbidiag.hpp:1653
static const char * kProperty_HostName
Definition: ncbidiag.hpp:2053
void SetDiagErrCodeInfo(CDiagErrCodeInfo *info, bool can_delete=true)
Set handler for processing error codes.
Definition: ncbidiag.cpp:7644
static void DiagAssertIfSuppressedSystemMessageBox(const CDiagCompileInfo &info, const char *expression, const char *message=NULL)
Same as DiagAssert but only if the system message box is suppressed.
Definition: ncbidiag.cpp:7955
static TDiagPostFlags ForceImportantFlags(TDiagPostFlags flags)
Set important flags to their globally set values.
Definition: ncbidiag.cpp:7737
TDiagPostFlags SetPostFlags(TDiagPostFlags flags) const
Set specific post flags for the current message.
static const char * SeverityName(EDiagSev sev)
Get a common symbolic name for the severity levels.
EDiagSev m_PrintSev
Definition: ncbidiag.hpp:1381
EDiagSev SetDiagPostLevel(EDiagSev post_sev=eDiag_Error)
Set the threshold severity for posting the messages.
Definition: ncbidiag.cpp:6129
EDiagTrace
Which setting disables/enables posting of "eDiag_Trace" messages.
Definition: ncbidiag.hpp:1547
EAction
Action to perform in guard's destructor.
Definition: ncbidiag.hpp:1303
ELogRate_Type
Type of logging rate limit.
Definition: ncbidiag.hpp:2276
void SetExitCode(int exit_code)
Set exit code.
Definition: ncbidiag.hpp:2176
CDiagFileHandleHolder * m_Handle
Definition: ncbidiag.hpp:2677
friend const CNcbiDiag & Reset(const CNcbiDiag &diag)
Reset the content of current message.
bool m_LoggedHitId
Definition: ncbidiag.hpp:2362
friend const CNcbiDiag & Critical(const CNcbiDiag &diag)
Flush current message, then set a severity for the next diagnostic message to CRITICAL ERROR.
FOnForkAction
Actions to perform in UpdateOnFork().
Definition: ncbidiag.hpp:1944
const char * m_File
Definition: ncbidiag.hpp:109
void SetOmitStackTrace(bool value)
Definition: ncbidiag.hpp:1200
friend const CNcbiDiag & Warning(const CNcbiDiag &diag)
Flush current message, then set a severity for the next diagnostic message to WARNING.
void(* FDiagHandler)(const SDiagMessage &mess)
Diagnostic handler function type.
Definition: ncbidiag.hpp:2485
void SetExitSignal(int exit_sig)
Set exit signal.
Definition: ncbidiag.hpp:2185
SDiagMessage::EEventType m_EventType
Definition: ncbidiag.hpp:1918
const char * m_Class
Class name.
Definition: ncbidiag.hpp:1656
deque< SDiagMessage > TMessages
Save messages if the handle is unavailable.
Definition: ncbidiag.hpp:2682
int m_ErrCode
Error code.
Definition: ncbidiag.hpp:1208
EDiagSev GetSeverityCap(void) const
Get current severity cap for use in ePrintCapped mode.
Definition: ncbidiag.hpp:1355
~CDiagErrCodeInfo(void)
Destructor.
string m_HostIP
Definition: ncbidiag.hpp:2356
TDiagPostFlags m_PostFlags
Post flags.
Definition: ncbidiag.hpp:2972
CStreamDiagHandler_Base TParent
Definition: ncbidiag.hpp:2636
Severity(EDiagSev sev)
Definition: ncbidiag.hpp:835
pair< string, string > TExtraArg
Definition: ncbidiag.hpp:1674
static NCBI_XNCBI_EXPORT void DiagAssert(const CDiagCompileInfo &info, const char *expression, const char *message=NULL)
Assert specified expression and report results.
Definition: ncbidiag.cpp:7944
static const char * kProperty_BytesRd
Definition: ncbidiag.hpp:2064
string m_FunctName
Definition: ncbidiag.hpp:117
EDiagSev GetCollectSeverity(void) const
Get current collect severity.
Definition: ncbidiag.hpp:1349
SDiagMessage::TCount TCount
Definition: ncbidiag.hpp:2265
bool IsSetDiagPostFlag(EDiagPostFlag flag, TDiagPostFlags flags=eDPF_Default)
Check if a specified flag is set.
TInfo m_Info
Map storing error codes and descriptions.
Definition: ncbidiag.hpp:3086
void x_SetFormat(EFormatFlag fmt) const
Definition: ncbidiag.hpp:1743
const char * GetFunction(void) const
Get function name of the current message.
const CNcbiDiag & Put(const volatile void *, const X &x) const
Generic method to post to diagnostic stream.
virtual CNcbiOstream * GetStream(void)
Definition: ncbidiag.hpp:2612
CSpinLock * m_HandleLock
Definition: ncbidiag.hpp:2678
TDiagPostFlags m_Flags
flags to set
Definition: ncbidiag.hpp:852
EDiagFileType
CDiagHandler –.
Definition: ncbidiag.hpp:2435
EDiagAppState
Application execution states shown in the std prefix.
Definition: ncbidiag.hpp:789
friend const CNcbiDiag & Endm(const CNcbiDiag &diag)
Flush current message, start new one.
string m_ClassName
Definition: ncbidiag.hpp:116
friend const CNcbiDiag & Error(const CNcbiDiag &diag)
Flush current message, then set a severity for the next diagnostic message to ERROR.
void(* FDiagCleanup)(void *data)
Diagnostic cleanup function type.
Definition: ncbidiag.hpp:2488
CDiagCompileInfo m_CompileInfo
Definition: ncbidiag.hpp:1214
list< string > m_PrefixList
List of prefixes.
Definition: ncbidiag.hpp:2971
CStreamDiagHandler_Base * m_Err
Definition: ncbidiag.hpp:2774
bool m_ApplogSeverityLocked
Limiting applog post level?
Definition: ncbidiag.hpp:2983
Uint8 TTID
Thread ID.
Definition: ncbidiag.hpp:1601
TDiagPostFlags SetDiagTraceAllFlags(TDiagPostFlags flags)
Versions of the above for extra trace flags.
Definition: ncbidiag.cpp:6081
const CNcbiDiag & x_Put(const CException &ex) const
Helper func for the exception-related Put()
Definition: ncbidiag.cpp:7817
bool SetLogFile(const string &file_name, EDiagFileType file_type=eDiagFile_All, bool quick_flush=true)
Set log files.
Definition: ncbidiag.cpp:7528
static const char * kProperty_SessionID
Definition: ncbidiag.hpp:2061
bool IsSetDiagHandler(void)
Check if diagnostic handler is set.
Definition: ncbidiag.cpp:6324
virtual ~CDiagHandler(void)
Destructor.
Definition: ncbidiag.hpp:2447
void ResetIsMessageFlag(void) const
Definition: ncbidiag.hpp:1191
unique_ptr< CSharedHitId > m_DefaultHitId
Definition: ncbidiag.hpp:2361
const char * m_Function
Function name.
Definition: ncbidiag.hpp:1657
CNcbiOstream & operator<<(CNcbiOstream &os, const SDiagMessage &mess)
Insert message in output stream.
Definition: ncbidiag.hpp:1762
void LogFields(const TEntries &entries) const
Log (as an extra) all names/values matching fields in NCBI_LOG_FIELDS.
Definition: ncbidiag.hpp:2408
void SetDiagHandler(CDiagHandler *handler, bool can_delete=true)
Set the diagnostic handler using the specified diagnostic handler class.
Definition: ncbidiag.cpp:6288
ErrCode(int code, int subcode=0)
Constructor.
Definition: ncbidiag.hpp:818
string GetGlobalRequestId(void) const
Deprecated version of HID generator.
Definition: ncbidiag.hpp:1997
TPID m_PID
Process ID.
Definition: ncbidiag.hpp:1665
const string & GetFunction(void) const
SDiagMessage::TExtraArgs TExtraArgs
Definition: ncbidiag.hpp:1864
const char * m_ErrText
Sometimes 'error' has no numeric code, but can be represented as text.
Definition: ncbidiag.hpp:1663
atomic< bool > m_TraceLogSuspended
Definition: ncbidiag.hpp:2382
void SetDiagTrace(EDiagTrace how, EDiagTrace dflt=eDT_Default)
Set the diagnostic trace settings.
Definition: ncbidiag.cpp:6226
const char * GetClass(void) const
Get class name of the current message.
CDiagHandler * m_Handler
Class handler.
Definition: ncbidiag.hpp:2979
EDiagSev
Severity level for the posted diagnostics.
Definition: ncbidiag.hpp:650
const char * g_DiagUnknownFunction(void)
Definition: ncbidiag.cpp:8341
EEventType m_Event
If the severity is eDPF_AppLog, m_Event contains event type.
Definition: ncbidiag.hpp:1672
TDiagPostFlags SetDiagPostAllFlags(TDiagPostFlags flags)
Set global post flags to "flags".
Definition: ncbidiag.cpp:6065
bool x_NeedModule(void) const
Definition: ncbidiag.cpp:697
void SetFunction(const string &func)
Definition: ncbidiag.cpp:742
Uint8 GetDiagRequestId(void)
Get iteration number/request ID.
Definition: ncbidiag.cpp:1195
const char * GetFile(void) const
Get file used for the current message.
bool m_IgnoreToDie
Ignore to die on die sev.
Definition: ncbidiag.hpp:2975
MDiagFunction(const char *function)
Uint8 GetFastCGIIteration(void)
Definition: ncbidiag.hpp:1410
SDiagMessage::TExtraArg TExtraArg
Definition: ncbidiag.hpp:1863
CNcbiOstream * GetDiagStream(void)
Get current diagnostic stream (if it was set by SetDiagStream) or NULL.
Definition: ncbidiag.cpp:8108
unique_ptr< TMessages > m_Messages
Definition: ncbidiag.hpp:2369
static NCBI_XNCBI_EXPORT void DiagFatal(const CDiagCompileInfo &info, const char *message)
Display fatal error message.
Definition: ncbidiag.cpp:7929
bool IsSetDiagErrCodeInfo()
Indicates whether an error-code processing handler has been set.
Definition: ncbidiag.cpp:7654
CDiagErrCodeInfo * m_ErrCodeInfo
Error code information.
Definition: ncbidiag.hpp:2981
unique_ptr< CRequestRateControl > m_AppLogRC
Definition: ncbidiag.hpp:2377
static const char * kProperty_HostIP
Definition: ncbidiag.hpp:2054
const char * m_CurrFunctName
Definition: ncbidiag.hpp:113
int GetLine(void) const
static bool StrToSeverityLevel(const char *str_sev, EDiagSev &sev)
Get severity from string.
Definition: ncbidiag.cpp:7904
EPropertyMode
Property visibility flag.
Definition: ncbidiag.hpp:2014
EDiagSev GetPrintSeverity(void) const
Get current print severity.
Definition: ncbidiag.hpp:1343
static const char * kProperty_AppState
Per-thread properties.
Definition: ncbidiag.hpp:2059
int GetExitCode(void) const
Get exit code.
Definition: ncbidiag.hpp:2174
CDiagContext(const CDiagContext &)
Int8 TUID
Unique process ID.
Definition: ncbidiag.hpp:1602
void SetFile(const string &file)
Definition: ncbidiag.cpp:722
void SetClass(const string &cls)
Definition: ncbidiag.cpp:757
void SetDiagTraceFlag(EDiagPostFlag flag)
Definition: ncbidiag.cpp:6086
EDiagSev m_Level
Severity level.
Definition: ncbidiag.hpp:837
CDiagContext & operator=(const CDiagContext &)
CDiagErrCodeInfo * GetDiagErrCodeInfo(bool take_ownership=false)
Get handler for processing error codes.
Definition: ncbidiag.cpp:7659
CStreamDiagHandler_Base TParent
Definition: ncbidiag.hpp:2700
friend const CNcbiDiag & operator<<(const CNcbiDiag &diag, const MDiagModule &module)
bool m_PrintStackTrace
Definition: ncbidiag.hpp:1687
TDiagPostFlags ResetPostFlags(TDiagPostFlags flags) const
Clear specific post flags for the current message.
bool m_ExitCodeSet
Definition: ncbidiag.hpp:2364
static bool IsApplogSeverityLocked(void)
When using applog, the diag post level is locked to Warning.
Definition: ncbidiag.hpp:2296
unique_ptr< CEncodedString > m_DefaultSessionId
Definition: ncbidiag.hpp:2360
string GetLogFile(EDiagFileType file_type)
Get log file name for the given log type.
Definition: ncbidiag.cpp:7612
static const char * kProperty_BytesWr
Definition: ncbidiag.hpp:2065
void SetDiagStream(CNcbiOstream *os, bool quick_flush=true, FDiagCleanup cleanup=0, void *cleanup_data=0, const string &stream_name="")
Set diagnostic stream.
Definition: ncbidiag.cpp:8083
unique_ptr< CEncodedString > m_AppName
Definition: ncbidiag.hpp:2358
void SetAbortHandler(FAbortHandler func=0)
Set/unset abort handler.
Definition: ncbidiag.cpp:8141
void x_LogHitID(bool ignore_app_state=false) const
int m_SubCode
Minor error code number.
Definition: ncbidiag.hpp:822
CDiagCompileInfo(void)
CDiagCompileInfo::
Definition: logging.cpp:1284
friend const CNcbiDiag & operator<<(const CNcbiDiag &diag, const MDiagClass &nclass)
void ResetIsNoteFlag(void) const
Reset IsNote flag.
Definition: ncbidiag.hpp:1194
EDiagFilter
Diag severity types to put the filter on.
Definition: ncbidiag.hpp:2528
EDiagSev GetSeverity(void) const
Get severity of the current message.
EAction GetAction(void) const
Get selected on-destroy action.
Definition: ncbidiag.hpp:1360
bool m_TypedExtra
Set to true if this is a typed extra message (the arguments include "NCBIEXTRATYPE=<extra-type>").
Definition: ncbidiag.hpp:1681
CNcbiDiag & operator=(const CNcbiDiag &)
Private assignment operator to prohibit assignment.
static const char * kProperty_ReqStatus
Definition: ncbidiag.hpp:2062
void g_Diag_Use_RWLock(bool enable=true)
Use RW-lock for synchronization rather than mutex.
Definition: ncbidiag.cpp:88
const char * GetModule(void) const
SDiagMessage::TUID TUID
Definition: ncbidiag.hpp:1975
bool m_CanDeleteHandler
Can handler be deleted?
Definition: ncbidiag.hpp:2980
const CNcbiDiag & Put(const NCBI_NS_NCBI::SetPostFlags *, const NCBI_NS_NCBI::SetPostFlags &flags) const
Helper method to set specific post flags.
const CNcbiDiag & SetModule(const char *module) const
Set module name.
Definition: ncbidiag.cpp:7753
unique_ptr< CRequestRateControl > m_ErrLogRC
Definition: ncbidiag.hpp:2378
SDiagMessageData * m_Data
Definition: ncbidiag.hpp:1752
virtual CNcbiOstream * GetStream(void)
Definition: ncbidiag.hpp:2579
bool IgnoreDiagDieLevel(bool ignore)
Ignore the die level settings.
Definition: ncbidiag.cpp:6217
@ eDPF_UID
Definition: ncbidiag.hpp:712
@ eDPF_SerialNo_Thread
Definition: ncbidiag.hpp:709
@ eDPF_TID
Thread ID.
Definition: ncbidiag.hpp:705
@ eDPF_AtomicWrite
This flag is deprecated and ignored - all log writes are atomic.
Definition: ncbidiag.hpp:763
@ eDPF_ErrCodeUseSeverity
Use severity from error code (default)
Definition: ncbidiag.hpp:703
@ eDPF_Location
Include class and function if any.
Definition: ncbidiag.hpp:704
@ eDPF_PID
Definition: ncbidiag.hpp:707
@ eDPF_Iteration
Definition: ncbidiag.hpp:711
@ eDPF_OmitSeparator
No '—' separator before message.
Definition: ncbidiag.hpp:754
@ eDPF_MergeLines
Escape EOLs.
Definition: ncbidiag.hpp:751
@ eDPF_ErrCodeMsgInFront
Put ErrCode text in front of the message.
Definition: ncbidiag.hpp:750
@ eDPF_ErrCodeExplanation
Error explanation (default)
Definition: ncbidiag.hpp:702
@ eDPF_IsNote
Print "Note[X]" severity name.
Definition: ncbidiag.hpp:757
@ eDPF_DateTime
Include date and time.
Definition: ncbidiag.hpp:700
@ eDPF_ErrorID
Error code and subcode (default)
Definition: ncbidiag.hpp:698
@ eDPF_RequestId
Definition: ncbidiag.hpp:710
@ eDPF_Log
Print the posted message only; without severity, location, prefix, etc.
Definition: ncbidiag.hpp:747
@ eDPF_Severity
Severity (default)
Definition: ncbidiag.hpp:697
@ eDPF_OmitInfoSev
No sev. indication if eDiag_Info.
Definition: ncbidiag.hpp:753
@ eDPF_Default
Use global default flags (merge with).
Definition: ncbidiag.hpp:771
@ eDPF_ErrSubCode
Definition: ncbidiag.hpp:715
@ eDPF_IsConsole
Send the message to 'console' regardless of it's severity.
Definition: ncbidiag.hpp:767
@ eDPF_Line
Source line.
Definition: ncbidiag.hpp:695
@ eDPF_PreMergeLines
Obsolete. Use eDPF_MergeLines.
Definition: ncbidiag.hpp:752
@ eDPF_IsMessage
Definition: ncbidiag.hpp:758
@ eDPF_Trace
Default flags to use when tracing.
Definition: ncbidiag.hpp:722
@ eDPF_File
File name (not full path)
Definition: ncbidiag.hpp:693
@ eDPF_UseExactUserFlags
Use flags provided by user as-is, do not allow CNcbiDiag to replace "important" flags by the globally...
Definition: ncbidiag.hpp:782
@ eDPF_ImportantFlagsMask
Important bits which should be taken from the globally set flags even if a user attempts to override ...
Definition: ncbidiag.hpp:776
@ eDPF_ErrCodeMessage
Error code message (default)
Definition: ncbidiag.hpp:701
@ eDPF_ErrCode
Definition: ncbidiag.hpp:714
@ eDPF_Exception
Default flags to use for exception formatting.
Definition: ncbidiag.hpp:744
@ eDPF_LongFilename
Full file path.
Definition: ncbidiag.hpp:694
@ eDPF_AppLog
Post message to application log.
Definition: ncbidiag.hpp:756
@ eDPF_SerialNo
Definition: ncbidiag.hpp:708
@ eDPF_Prefix
Prefix (default)
Definition: ncbidiag.hpp:696
@ eDPF_All
All flags (except for the "unusual" ones!)
Definition: ncbidiag.hpp:718
@ eDiagSC_Enable
Enable change severity level.
Definition: ncbidiag.hpp:669
@ eDiagSC_Disable
Disable change severity level.
Definition: ncbidiag.hpp:668
@ eDiagSC_Unknown
Status of changing severity is unknown (first call)
Definition: ncbidiag.hpp:667
@ eDCM_Discard
Discard the collected messages without flushing.
Definition: ncbidiag.hpp:1805
@ eDCM_Init
Start collecting messages (with limit), do nothing if already initialized.
Definition: ncbidiag.hpp:1799
@ eDCM_NoChange
Continue collecting messages if already started.
Definition: ncbidiag.hpp:1803
@ eDCM_InitNoLimit
Start collecting messages without limit (must stop collecting later using eDCM_Flush or eDCM_Discard)...
Definition: ncbidiag.hpp:1801
@ eDCM_Flush
Flush the collected messages and stop collecting.
Definition: ncbidiag.hpp:1804
@ eDS_Default
Try standard log file (app.name + ".log") in /log/, use stderr on failure.
Definition: ncbidiag.hpp:1790
@ eDS_ToMemory
Keep in a temp.memory buffer, see FlushMessages()
Definition: ncbidiag.hpp:1785
@ eDS_User
Leave as was previously set (or not set) by user.
Definition: ncbidiag.hpp:1787
@ eDS_Disable
Don't write it anywhere.
Definition: ncbidiag.hpp:1786
@ eDS_AppSpecific
Call the application's SetupDiag_AppSpecific()
Definition: ncbidiag.hpp:1788
@ eDS_ToStdlog
Try standard log file (app.name + ".log") in /log/ and current directory, use stderr if both fail.
Definition: ncbidiag.hpp:1783
@ eDS_ToStdout
To standard output stream.
Definition: ncbidiag.hpp:1781
@ eDS_ToStderr
To standard error stream.
Definition: ncbidiag.hpp:1782
@ eDS_ToSyslog
To system log daemon.
Definition: ncbidiag.hpp:1792
@ ePostNumber_NoIncrement
Get post number without incrementing it.
Definition: ncbidiag.hpp:1812
@ ePostNumber_Increment
Increment and return the new post number.
Definition: ncbidiag.hpp:1813
@ eEvent_RequestStop
Finish processing request.
Definition: ncbidiag.hpp:1645
@ eEvent_RequestStart
Start processing request.
Definition: ncbidiag.hpp:1644
@ eEvent_Start
Application start.
Definition: ncbidiag.hpp:1641
@ eEvent_Extra
Other application events.
Definition: ncbidiag.hpp:1643
@ eEvent_Stop
Application exit.
Definition: ncbidiag.hpp:1642
@ eDT_Enable
Enable messages of severity "eDiag_Trace".
Definition: ncbidiag.hpp:1550
@ eDT_Disable
Ignore messages of severity "eDiag_Trace".
Definition: ncbidiag.hpp:1549
@ eDT_Default
Restores the default tracing context.
Definition: ncbidiag.hpp:1548
@ ePrint
Print all collected messages as is.
Definition: ncbidiag.hpp:1304
@ eDiscard
Discard collected messages, default.
Definition: ncbidiag.hpp:1305
@ eLogRate_Err
Error log.
Definition: ncbidiag.hpp:2278
@ eLogRate_App
Application log.
Definition: ncbidiag.hpp:2277
@ eDiagFile_Trace
Trace log file.
Definition: ncbidiag.hpp:2438
@ eDiagFile_Perf
Perf log file.
Definition: ncbidiag.hpp:2439
@ eDiagFile_Err
Error log file.
Definition: ncbidiag.hpp:2436
@ eDiagFile_All
All log files.
Definition: ncbidiag.hpp:2440
@ eDiagFile_Log
Access log file.
Definition: ncbidiag.hpp:2437
@ eDiagAppState_RequestEnd
RE.
Definition: ncbidiag.hpp:796
@ eDiagAppState_AppEnd
AE.
Definition: ncbidiag.hpp:793
@ eDiagAppState_AppBegin
AB.
Definition: ncbidiag.hpp:791
@ eDiagAppState_AppRun
A.
Definition: ncbidiag.hpp:792
@ eDiagAppState_RequestBegin
RB.
Definition: ncbidiag.hpp:794
@ eDiagAppState_NotSet
Reserved value, never used in messages.
Definition: ncbidiag.hpp:790
@ eDiagAppState_Request
R.
Definition: ncbidiag.hpp:795
@ eDiag_Trace
Trace message.
Definition: ncbidiag.hpp:657
@ eDiag_Info
Informational message.
Definition: ncbidiag.hpp:651
@ eDiag_Error
Error message.
Definition: ncbidiag.hpp:653
@ eDiag_Warning
Warning message.
Definition: ncbidiag.hpp:652
@ eDiag_Fatal
Fatal error – guarantees exit(or abort)
Definition: ncbidiag.hpp:655
@ eDiagSevMin
Verbosity level for min. severity.
Definition: ncbidiag.hpp:660
@ eDiag_Critical
Critical error message.
Definition: ncbidiag.hpp:654
@ eDiagSevMax
Verbosity level for max. severity.
Definition: ncbidiag.hpp:661
@ eProp_Default
Auto-mode for known properties, local for others.
Definition: ncbidiag.hpp:2015
@ eProp_Global
The property is global for the application.
Definition: ncbidiag.hpp:2016
@ eDiagFilter_All
for all non-FATAL
Definition: ncbidiag.hpp:2531
@ eDiagFilter_Post
for all non-TRACE, non-FATAL
Definition: ncbidiag.hpp:2530
@ eDiagFilter_Trace
for TRACEs only
Definition: ncbidiag.hpp:2529
void Read(CObjectIStream &in, TObjectPtr object, const CTypeRef &type)
Definition: serial.cpp:60
void Write(CObjectOStream &out, TConstObjectPtr object, const CTypeRef &type)
Definition: serial.cpp:55
#define NCBI_DEPRECATED
int64_t Int8
8-byte (64-bit) signed integer
Definition: ncbitype.h:104
uint64_t Uint8
8-byte (64-bit) unsigned integer
Definition: ncbitype.h:105
#define END_NCBI_SCOPE
End previously defined NCBI scope.
Definition: ncbistl.hpp:103
#define BEGIN_NCBI_SCOPE
Define ncbi namespace.
Definition: ncbistl.hpp:100
IO_PREFIX::ostream CNcbiOstream
Portable alias for ostream.
Definition: ncbistre.hpp:149
IO_PREFIX::istream CNcbiIstream
Portable alias for istream.
Definition: ncbistre.hpp:146
IO_PREFIX::ios CNcbiIos
Portable alias for ios.
Definition: ncbistre.hpp:140
#define NCBI_XNCBI_EXPORT
Definition: ncbi_export.h:1283
FILE * file
char * buf
int len
static MDB_envinfo info
Definition: mdb_load.c:37
Uint4 GetHost(TEndpointKey key)
mdb_mode_t mode
Definition: lmdb++.h:38
const GenericPointer< typename T::ValueType > T2 value
Definition: pointer.h:1227
const CharType(& source)[N]
Definition: pointer.h:1149
static void s_EscapeNewlines(const void *src_buf, size_t src_size, size_t *src_read, void *dst_buf, size_t dst_size, size_t *dst_written)
Escape newlines in the string.
Definition: ncbi_c_log.c:1145
EIPRangeType t
Definition: ncbi_localip.c:101
CDiagContext_Extra g_PostPerf(int status, double timespan, SDiagMessage::TExtraArgs &args)
Definition: ncbidiag.cpp:8347
std::istream & in(std::istream &in_, double &x_)
static const char * suffix[]
Definition: pcregrep.c:408
static const char * prefix[]
Definition: pcregrep.c:405
@ fNone
SDiagErrCodeDescription –.
Definition: ncbidiag.hpp:2994
SDiagMessage –.
Definition: ncbidiag.hpp:1599
Template structure used to point out wrong error subcode in ERR_POST_X, STD_CATCH_X and alike macros.
Definition: ncbidiag.hpp:403
Template structure used to point out incorrect usage of NCBI_DEFINE_ERR_SUBCODE_X macro i....
Definition: ncbidiag.hpp:420
Definition: inftrees.h:24
Definition: type.c:6
else result
Definition: token2.c:20
static wxAcceleratorEntry entries[3]
Modified on Wed Apr 24 14:15:13 2024 by modify_doxy.py rev. 669887