NCBI C++ ToolKit
logging.cpp
Go to the documentation of this file.

Go to the SVN repository for this file.

1 /* $Id: logging.cpp 101916 2024-03-01 17:23:59Z gouriano $
2  * ===========================================================================
3  *
4  * PUBLIC DOMAIN NOTICE
5  * National Center for Biotechnology Information
6  *
7  * This software/database is a "United States Government Work" under the
8  * terms of the United States Copyright Act. It was written as part of
9  * the author's official duties as a United States Government employee and
10  * thus cannot be copyrighted. This software/database is freely available
11  * to the public for use. The National Library of Medicine and the U.S.
12  * Government have not placed any restriction on its use or reproduction.
13  *
14  * Although all reasonable efforts have been taken to ensure the accuracy
15  * and reliability of the software and data, the NLM and the U.S.
16  * Government do not and cannot warrant the performance or results that
17  * may be obtained by using this software or data. The NLM and the U.S.
18  * Government disclaim all warranties, express or implied, including
19  * warranties of performance, merchantability or fitness for any particular
20  * purpose.
21  *
22  * Please cite the author in any work or product based on this material.
23  *
24  * ===========================================================================
25  *
26  * Author: Pavel Ivanov
27  *
28  */
29 
30 #include "task_server_pch.hpp"
31 
32 // ncbimtx.hpp is needed for proper compilation of ncbifile.hpp
33 #include <corelib/ncbimtx.hpp>
34 #include <corelib/ncbifile.hpp>
35 #include <corelib/request_ctx.hpp>
36 #include <corelib/ncbireg.hpp>
37 
38 #include "logging.hpp"
39 #include "threads_man.hpp"
40 #include "memory_man.hpp"
41 #include "server_core.hpp"
42 
43 #include <fcntl.h>
44 
45 
47 
48 extern CSrvTime s_JiffyTime;
49 
50 struct SLogData
51 {
52  char* buf;
53  char* end_ptr;
54  char* cur_ptr;
55  char* cur_msg_ptr;
57  string prefix;
58  string tmp_str;
59  bool has_params;
61 
62  const char* msg_file;
63  const char* msg_func;
64  int msg_line;
65  int err_code;
68 
69  SLogData(void)
70  : buf(0), end_ptr(0), cur_ptr(0), cur_msg_ptr(0), post_num(0),
73  {
74  }
75 };
76 
77 
78 class CLogWriter : public CSrvTask
79 {
80 public:
81  CLogWriter(void);
82  virtual ~CLogWriter(void);
83 
84 private:
85  virtual void ExecuteSlice(TSrvThreadNum thr_num);
86 };
87 
88 
90 static bool s_LogRequests = true;
91 static string s_UnkClient = "UNK_CLIENT";
92 static string s_UnkSession = "UNK_SESSION";
93 static const char* s_SevNames[] = {"Trace", "Info", "Warning", "Error", "Critical", "Fatal", "Fatal", NULL};
94 static const char* s_SoftFatalActions[] = {"abort", "shutdown", "log", NULL};
95 static int s_SoftFatal = 0;
96 static const size_t kOneRecReserve = 500;
97 static const size_t kInitLogBufSize = 10000000;
98 static size_t s_LogBufSize = kInitLogBufSize;
99 static int s_MaxFlushPeriod = 60;
100 static int s_FileReopenPeriod = 60;
101 static Uint8 s_LongCmd = 30000000;
102 static string s_CmdLine;
103 static string s_Pid;
104 static string s_AppUID;
105 static string s_FileName;
108 static bool s_InApplog = false;
110 static list<CTempString> s_WriteQueue;
112 static int s_LogFd = -1;
113 static int s_LastReopenTime = 0;
114 static bool s_NeedFatalHalt = false;
115 static bool s_FileNameInitialized = false;
116 static bool s_ThreadsStarted = false;
117 static bool s_DiskSpaceAlert = false;
119 static CFutex s_Halt;
120 
121 extern string s_AppBaseName;
122 extern SSrvThread** s_Threads;
123 
124 
125 
127 {
128  s_DiskSpaceAlert = true;
129 }
130 
131 void
132 SaveAppCmdLine(const string& cmd_line)
133 {
134  s_CmdLine = cmd_line;
135 }
136 
137 void
139 {
140  s_FileName = name;
143  }
144 }
145 
146 string GetLogFileName(void)
147 {
148  return s_FileName;
149 }
150 
151 string GetLogVisibility(void)
152 {
153  return s_SevNames[s_VisibleSev];
154 }
155 
156 string GetSoftFatalAction(void)
157 {
159 }
160 
161 static void
163 {
165  time_t t = time(0);
166  const string& host = CTaskServer::GetHostName();
167  Int8 h = 212;
168  ITERATE(string, s, host) {
169  h = h*1265 + *s;
170  }
171  h &= 0xFFFF;
172  // The low 4 bits are reserved as GUID generator version number.
173  Int8 uid = (h << 48) |
174  ((pid & 0xFFFF) << 32) |
175  ((Int8(t) & 0xFFFFFFF) << 4) |
176  1; // version #1 - fixed type conversion bug
177 
178  s_AppUID = NStr::UInt8ToString(Uint8(uid), 0, 16);
179  if (s_AppUID.size() != 16)
180  s_AppUID.insert(s_AppUID.begin(), 16 - s_AppUID.size(), '0');
182  if (s_Pid.size() < 5)
183  s_Pid.insert(s_Pid.begin(), 5 - s_Pid.size(), '0');
184 }
185 
186 static inline void
188 {
189 #ifdef NCBI_OS_LINUX
190  if (s_DiskSpaceAlert) {
191  s_DiskSpaceAlert = false;
192  unlink(s_FileName.c_str());
193  }
194  s_LogFd = open(s_FileName.c_str(), O_WRONLY | O_APPEND | O_CREAT,
195  S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH | S_IWOTH);
196 #endif
197 }
198 
199 static void
200 s_WriteLog(const char* buf, size_t size)
201 {
202  if (!buf) {
203  return;
204  }
205  if (s_LogFd == -1) {
206  s_OpenLogFile();
207  if (s_LogFd == -1)
208  return;
210  }
211 
212 #ifdef NCBI_OS_LINUX
213  if (write(s_LogFd, buf, size) != ssize_t(size)) {
214  // There's nothing we can do about it here
215  }
216 #endif
217 }
218 
219 static void
220 s_QueueLogWrite(char* buf, size_t size)
221 {
222  if (!buf) {
223  return;
224  }
226  bool need_signal = s_WriteQueue.empty();
227  s_WriteQueue.push_back(CTempString(buf, size));
229 
230  if (need_signal)
232 }
233 
234 static inline void
235 s_AllocNewBuf(SLogData* data, size_t buf_size)
236 {
237  data->buf = (char*)malloc(buf_size);
238  data->cur_ptr = data->cur_msg_ptr = data->buf;
239  data->end_ptr = data->buf ? data->buf + buf_size - 8 : data->buf;
240 }
241 
242 static void
244 {
245  char* old_buf = data->buf;
246  char* old_msg_ptr = data->cur_msg_ptr;
247  size_t old_msg_size = data->cur_ptr - data->cur_msg_ptr;
249  if (old_msg_size != 0 && data->buf) {
250  memcpy(data->buf, old_msg_ptr, old_msg_size);
251  data->cur_ptr += old_msg_size;
252  }
253  s_QueueLogWrite(old_buf, old_msg_ptr - old_buf);
254  data->last_flush_time = CSrvTime::CurSecs();
255 }
256 
257 static inline void
259 {
260  data->prefix.assign(s_Pid);
261  data->prefix.append(1, '/');
262  NStr::UInt8ToString(data->tmp_str, thr_num);
263  if (data->tmp_str.size() < 3)
264  data->prefix.append(3 - data->tmp_str.size(), '0');
265  data->prefix.append(data->tmp_str.data(), data->tmp_str.size());
266  data->prefix.append(1, '/');
267 }
268 
269 static inline bool
270 s_CheckBufSize(SLogData* data, size_t need_size)
271 {
272  if (data->cur_ptr + need_size >= data->end_ptr)
274  return data->buf != nullptr;
275 }
276 
277 static inline void
278 s_AddToLog(SLogData* data, const char* str, size_t size)
279 {
280  if (s_CheckBufSize(data, size)) {
281  memcpy(data->cur_ptr, str, size);
282  data->cur_ptr += size;
283  }
284 }
285 
286 static inline void
287 s_AddToLogStripLF(SLogData* data, const char* str, size_t size)
288 {
289  if (s_CheckBufSize(data, size)) {
290  for (; size != 0; --size, ++str) {
291  char c = *str;
292  *data->cur_ptr++ = c == '\n'? ';': c;
293  }
294  }
295 }
296 
297 static inline void
298 s_AddToLog(SLogData* data, const char* str)
299 {
300  s_AddToLog(data, str, strlen(str));
301 }
302 
303 static inline void
305 {
306  s_AddToLogStripLF(data, str, strlen(str));
307 }
308 
309 static inline void
310 s_AddToLog(SLogData* data, const string& str)
311 {
312  s_AddToLog(data, str.data(), str.size());
313 }
314 
315 static inline void
317 {
318  s_AddToLogStripLF(data, str.data(), str.size());
319 }
320 
321 static inline void
322 s_AddToLog(SLogData* data, const string& str, Uint1 min_chars)
323 {
324  if (s_CheckBufSize(data, max(str.size(), size_t(min_chars)))) {
325  s_AddToLog(data, str.data(), str.size());
326  for (Uint1 i = min_chars; i > str.size(); --i)
327  *data->cur_ptr++ = ' ';
328  }
329 }
330 
331 static inline void
333 {
334  NStr::UInt8ToString(data->tmp_str, num);
335  s_AddToLog(data, data->tmp_str);
336 }
337 
338 static inline void
340 {
341  NStr::Int8ToString(data->tmp_str, num);
342  s_AddToLog(data, data->tmp_str);
343 }
344 
345 static inline void
347 {
348  s_AddToLog(data, Uint8(num));
349 }
350 
351 static inline void
353 {
354  NStr::UInt8ToString(data->tmp_str, num);
355  if (s_CheckBufSize(data, max(data->tmp_str.size(), size_t(min_digs)))) {
356  for (Uint1 i = min_digs; i > data->tmp_str.size(); --i)
357  *data->cur_ptr++ = '0';
358  s_AddToLog(data, data->tmp_str);
359  }
360 }
361 
362 static inline void
363 s_AddToLog(SLogData* data, double num)
364 {
365  NStr::DoubleToString(data->tmp_str, num);
366  s_AddToLog(data, data->tmp_str);
367 }
368 
369 static void
371 {
372  if (!data->buf) {
373  return;
374  }
375  s_AddToLog(data, data->prefix);
376  if (!diag_ctx && thr && thr->cur_task)
377  diag_ctx = thr->cur_task->m_DiagCtx;
378 
379  Uint8 req_id = diag_ctx? diag_ctx->GetRequestID()
381  s_AddToLog(data, req_id, 4);
382  s_AddToLog(data, "/A ");
383 
385  *data->cur_ptr++ = ' ';
386 
387  Uint8 proc_post_num = AtomicAdd(s_ProcessPostNum, 1);
388  s_AddToLog(data, proc_post_num, 4);
389  *data->cur_ptr++ = '/';
390  s_AddToLog(data, ++data->post_num, 4);
391  *data->cur_ptr++ = ' ';
392 
393  CSrvTime cur_time = CSrvTime::Current();
394  if (!s_CheckBufSize(data, 50)) {
395  return;
396  }
397  Uint1 len = cur_time.Print(data->cur_ptr, CSrvTime::eFmtLogging);
398  data->cur_ptr += len;
399  *data->cur_ptr++ = ' ';
400 
402  *data->cur_ptr++ = ' ';
403 
404  string str = diag_ctx? diag_ctx->GetClientIP(): s_UnkClient;
405  if (str.empty())
406  str = s_UnkClient;
407  s_AddToLog(data, str, 15);
408  *data->cur_ptr++ = ' ';
409 
410  str = diag_ctx? diag_ctx->GetSessionID(): s_UnkSession;
411  if (str.empty())
412  str = s_UnkSession;
413  s_AddToLog(data, str, 24);
414  *data->cur_ptr++ = ' ';
415 
417  *data->cur_ptr++ = ' ';
418 }
419 
420 static void
422 {
423  if (!s_CheckBufSize(data, name.size() + 2)) {
424  return;
425  }
426  if (data->has_params)
427  *data->cur_ptr++ = '&';
428  else
429  data->has_params = true;
430  s_AddToLog(data, name.data(), name.size());
431  *data->cur_ptr++ = '=';
432 }
433 
434 static SLogData*
436 {
437  SLogData* data = new SLogData;
438  data->post_num = 0;
439  data->last_flush_time = 0;
441  s_InitLogPrefix(data, thr_num);
442  return data;
443 }
444 
445 static void
447 {
448  s_InitConstants();
451  s_AddToLog(s_MainData, "start ");
453  *s_MainData->cur_ptr++ = '\n';
455 }
456 
457 static void
459 {
460  if (s_FileName.empty()) {
461  s_FileName = CDirEntry::MakePath("/log/srv", s_AppBaseName, "log");
462  s_OpenLogFile();
463  if (s_LogFd == -1)
465  else
466  s_InApplog = true;
467  }
468  s_FileNameInitialized = true;
469 }
470 
471 NCBI_NORETURN static void
473 {
474  s_NeedFatalHalt = true;
475 #if 1
476  int cnt_halted = s_CntHaltedThreads.AddValue(1);
477  int cnt_need = GetCntRunningThreads() + 2;
478  if (!s_ThreadsStarted)
479  cnt_need = 1;
480  for (int attempt=0; attempt<500 && cnt_halted != cnt_need; ++attempt) {
482  cnt_halted = s_CntHaltedThreads.GetValue();
483  // In a very rare situation CntRunningThreads can change here
484  cnt_need = GetCntRunningThreads() + 2;
485  }
486 #endif
488  s_InitFileName();
489  ITERATE(list<CTempString>, it, s_WriteQueue) {
490  CTempString str = *it;
491  s_WriteLog(str.data(), str.size());
492  }
493  if (data->cur_ptr != data->buf)
494  s_WriteLog(data->buf, data->cur_ptr - data->buf);
495 
496 #ifdef NCBI_OS_LINUX
497  close(s_LogFd);
498 #endif
499  abort();
500 }
501 
502 static inline void
504 {
505  if (!s_NeedFatalHalt)
506  return;
507 
509  if (data->cur_ptr != data->buf)
510  s_QueueLogWrite(data->buf, data->cur_ptr - data->buf);
514 }
515 
516 void
518 {
519  s_ThreadsStarted = true;
521 }
522 
523 void
525 {
526  s_LogRequests = reg->GetBool(section, "log_requests", true);
528  reg->GetString(section, "log_thread_buf_size", "10 MB"));
529  s_MaxFlushPeriod = reg->GetInt(section, "log_flush_period", 60);
530  s_FileReopenPeriod = reg->GetInt(section, "log_reopen_period", 60);
531  string vis = reg->GetString(section, "log_visible", "Warning");
532  size_t i = 0;
533  for (i = 0; s_SevNames[i] != NULL; ++i) {
534  if (vis.compare(s_SevNames[i]) == 0) {
536  break;
537  }
538  }
539  string tmp = reg->GetString(section, "soft_fatal_action", "abort");
540  for (i = 0; s_SoftFatalActions[i] != NULL; ++i) {
541  if (tmp.compare(s_SoftFatalActions[i]) == 0) {
542  s_SoftFatal = i;
543  break;
544  }
545  }
546  s_LongCmd = Uint8(reg->GetInt(section, "log_long_cmd_after", 30000)) * kUSecsPerMSec;
547 }
548 
549 bool ReConfig_Logging(const CTempString& section, const CNcbiRegistry& new_reg, string& /*err_message*/)
550 {
551  ConfigureLogging(&new_reg, section);
552  return true;
553 }
554 
555 bool IsLongCommand(Uint8 cmd_len)
556 {
557  return cmd_len >= s_LongCmd;
558 }
559 
561 {
562  string is("\": "), iss("\": \""), eol(",\n\"");
563  task.WriteText(eol).WriteText("log_requests").WriteText(is ).WriteBool( s_LogRequests);
564  task.WriteText(eol).WriteText("log_thread_buf_size").WriteText(is ).WriteNumber( s_LogBufSize);
565  task.WriteText(eol).WriteText("log_flush_period").WriteText(is ).WriteNumber( s_MaxFlushPeriod);
566  task.WriteText(eol).WriteText("log_reopen_period").WriteText(is ).WriteNumber( s_FileReopenPeriod);
567  task.WriteText(eol).WriteText("log_visible").WriteText(iss).WriteText(GetLogVisibility()).WriteText("\"");
568  task.WriteText(eol).WriteText("soft_fatal_action").WriteText(iss).WriteText(GetSoftFatalAction()).WriteText("\"");
569  task.WriteText(eol).WriteText("log_long_cmd_after").WriteText(is).WriteNumber( s_LongCmd / kUSecsPerMSec);
570 }
571 
572 void
574 {
575  if (!s_MainData)
576  s_AllocMainData();
577 
578  s_InitFileName();
579  s_LogWriter = new CLogWriter();
580 }
581 
582 void
584 {
585  if (s_MainData->cur_ptr != s_MainData->buf) {
588  }
589 
591  s_AddToLog(s_MainData, "stop 0 ");
592  CSrvTime cur_time = CSrvTime::Current();
593  cur_time -= CTaskServer::GetStartTime();
594  s_AddToLog(s_MainData, cur_time.Sec());
595  *s_MainData->cur_ptr++ = '.';
596  s_AddToLog(s_MainData, cur_time.NSec(), 9);
597  *s_MainData->cur_ptr++ = '\n';
599 
600 #ifdef NCBI_OS_LINUX
601  close(s_LogFd);
602 #endif
603 }
604 
605 void
607 {
608  if (thr->thread_num == 0) {
609  if (!s_MainData)
610  s_AllocMainData();
611  thr->log_data = s_MainData;
612  }
613  else {
614  thr->log_data = s_AllocNewData(thr->thread_num);
615  }
616 }
617 
618 void
620 {
622 
623  SLogData* data = thr->log_data;
624  int cur_time = CSrvTime::CurSecs();
625  if (cur_time - data->last_flush_time < s_MaxFlushPeriod)
626  return;
627 
628  if (data->buf && data->cur_ptr == data->buf)
629  data->last_flush_time = cur_time;
630  else
632 }
633 
634 void
636 {
637  thr->log_data = s_AllocNewData(thr->thread_num);
638 }
639 
640 void
642 {
643  SLogData* data = thr->log_data;
644  if (data->cur_ptr != data->buf)
645  s_QueueLogWrite(data->buf, data->cur_ptr - data->buf);
646  else if (data->buf)
647  free(data->buf);
648  delete data;
650 }
651 
652 void
654 {
655  SLogData* data = thr->log_data;
656  if (data->cur_ptr != data->buf) {
657  s_WriteLog(data->buf, data->cur_ptr - data->buf);
658  data->cur_ptr = data->buf;
659  }
660 }
661 
662 static const char*
663 find_match(char lsep, char rsep, const char* start, const char* stop)
664 {
665  if (*(stop - 1) != rsep) return stop;
666  int balance = 1;
667  const char* pos = stop - 2;
668  for (; pos > start; pos--) {
669  if (*pos == rsep) {
670  balance++;
671  }
672  else if (*pos == lsep) {
673  if (--balance == 0) break;
674  }
675  }
676  return (pos <= start) ? NULL : pos;
677 }
678 
679 static const char*
680 str_rev_str(const char* begin_str, const char* end_str, const char* str_search)
681 {
682  if (begin_str == NULL)
683  return NULL;
684  if (end_str == NULL)
685  return NULL;
686  if (str_search == NULL)
687  return NULL;
688 
689  const char* search_char = str_search + strlen(str_search);
690  const char* cur_char = end_str;
691 
692  do {
693  --search_char;
694  do {
695  --cur_char;
696  } while(*cur_char != *search_char && cur_char != begin_str);
697  if (*cur_char != *search_char)
698  return NULL;
699  }
700  while (search_char != str_search);
701 
702  return cur_char;
703 }
704 
705 static void
706 s_ParseFuncName(const char* func, CTempString& class_name, CTempString& func_name)
707 {
708  if (!func || *func == '\0')
709  return;
710 
711  // Skip function arguments
712  size_t len = strlen(func);
713  const char* end_str = find_match('(', ')',
714  func,
715  func + len);
716  if (end_str == func + len) {
717  // Missing '('
718  return;
719  }
720  if (end_str) {
721  // Skip template arguments
722  end_str = find_match('<', '>', func, end_str);
723  }
724  if (!end_str)
725  return;
726  // Get a function/method name
727  const char* start_str = NULL;
728 
729  // Get a function start position.
730  const char* start_str_tmp = str_rev_str(func, end_str, "::");
731  bool has_class = start_str_tmp != NULL;
732  if (start_str_tmp != NULL) {
733  start_str = start_str_tmp + 2;
734  } else {
735  start_str_tmp = str_rev_str(func, end_str, " ");
736  if (start_str_tmp != NULL) {
737  start_str = start_str_tmp + 1;
738  }
739  }
740 
741  const char* cur_funct_name = (start_str == NULL? func: start_str);
742  size_t cur_funct_name_len = end_str - cur_funct_name;
743  func_name.assign(cur_funct_name, cur_funct_name_len);
744 
745  // Get a class name
746  if (has_class) {
747  end_str = find_match('<', '>', func, start_str - 2);
748  start_str = str_rev_str(func, end_str, " ");
749  const char* cur_class_name = (start_str == NULL? func: start_str + 1);
750  size_t cur_class_name_len = end_str - cur_class_name;
751  class_name.assign(cur_class_name, cur_class_name_len);
752  }
753 }
754 
755 static inline bool
757 {
758  SLogData* data = msg->m_Data;
759  if (!CSrvDiagMsg::IsSeverityVisible(data->severity))
760  return false;
761  if (data->cur_msg_ptr == data->cur_ptr) {
762  if (msg->m_OldStyle) {
763  msg->StartSrvLog(data->severity, data->msg_file,
764  data->msg_line, data->msg_func);
765  }
766  else {
767  SRV_FATAL("Unrecognized CSrvDiagMsg style");
768  }
769  }
770  return true;
771 }
772 
773 static inline CSrvDiagMsg::ESeverity
774 s_ConvertSeverity(EOldStyleSeverity sev)
775 {
776  switch (sev) {
777  case Trace:
778  return CSrvDiagMsg::Trace;
779  case Info:
780  return CSrvDiagMsg::Info;
781  case Warning:
782  return CSrvDiagMsg::Warning;
783  case Error:
784  return CSrvDiagMsg::Error;
785  case Critical:
786  return CSrvDiagMsg::Critical;
787  case Fatal:
788  return CSrvDiagMsg::Fatal;
789  default:
790  SRV_FATAL("Unsupported severity: " << sev);
791  }
792  return CSrvDiagMsg::Trace;
793 }
794 
795 static inline CSrvDiagMsg::ESeverity
797 {
798  switch (sev) {
799  case eDiag_Trace:
800  return CSrvDiagMsg::Trace;
801  case eDiag_Info:
802  return CSrvDiagMsg::Info;
803  case eDiag_Warning:
804  return CSrvDiagMsg::Warning;
805  case eDiag_Error:
806  return CSrvDiagMsg::Error;
807  case eDiag_Critical:
808  return CSrvDiagMsg::Critical;
809  case eDiag_Fatal:
810  return CSrvDiagMsg::Fatal;
811  default:
812  SRV_FATAL("Unsupported severity: " << sev);
813  }
814  return CSrvDiagMsg::Trace;
815 }
816 
819 {
820  static CDiagContext ctx;
821  return ctx;
822 }
823 
825 {
827 }
828 
829 void
831 {
832  string old_uid = s_AppUID;
833  s_InitConstants();
834  if (s_Threads) {
835  for (TSrvThreadNum i = 0; i <= s_MaxRunningThreads + 1; ++i) {
837  if (thr)
838  s_InitLogPrefix(thr->log_data, thr->thread_num);
839  }
840  }
841  else if (s_MainData) {
843  }
845  .PrintParam("action", "fork")
846  .PrintParam("parent_guid", old_uid);
847 }
848 
849 void
850 CDiagContext::StartCtxRequest(CRequestContext* ctx)
851 {
852  ctx->StartRequest();
853 }
854 
855 void
856 CDiagContext::StopCtxRequest(CRequestContext* ctx)
857 {
858  ctx->StopRequest();
859 }
860 
861 bool
862 CDiagContext::IsCtxRunning(CRequestContext* ctx)
863 {
864  return ctx->IsRunning();
865 }
866 
867 const string&
869 {
870  return kEmptyStr;
871 }
872 
873 const string&
875 {
876  return kEmptyStr;
877 }
878 
879 
881  : m_Thr(GetCurThread()),
882  m_Data(NULL),
883  m_OldStyle(false)
884 {
885  if (m_Thr) {
886  m_Data = m_Thr->log_data;
888  }
889  else {
890  if (!s_MainData)
891  s_AllocMainData();
892  m_Data = s_MainData;
893  }
894 }
895 
897 {
898  if (m_Data->cur_msg_ptr != m_Data->cur_ptr)
899  Flush();
900 }
901 
902 bool
904 {
905  return int(sev) >= int(s_VisibleSev);
906 }
907 
908 const CSrvDiagMsg&
910  const char* file,
911  int line,
912  const char* func) const
913 {
915  /* && *m_Data->cur_ptr != '\n' */) {
916  *m_Data->cur_ptr++ = '\n';
917  }
918  m_Data->severity = sev;
920  s_AddToLog(m_Data, s_SevNames[int(sev)]);
921  if (m_OldStyle) {
922  s_AddToLog(m_Data, ": ");
923  if (m_Data->err_code != 0 || m_Data->err_subcode != 0) {
924  s_AddToLog(m_Data, "(");
926  s_AddToLog(m_Data, ".");
928  s_AddToLog(m_Data, ")");
929  }
930  s_AddToLog(m_Data, " \"");
931  }
932  else {
933  s_AddToLog(m_Data, ": \"");
934  }
935  const char* file_name;
936  size_t name_size;
937  ExtractFileName(file, file_name, name_size);
938  s_AddToLog(m_Data, file_name, name_size);
939  s_AddToLog(m_Data, "\", line ");
940  s_AddToLog(m_Data, line);
941  s_AddToLog(m_Data, ": ");
942  CTempString class_name, func_name;
943  s_ParseFuncName(func, class_name, func_name);
944  s_AddToLog(m_Data, class_name);
945  s_AddToLog(m_Data, "::");
946  s_AddToLog(m_Data, func_name);
947  s_AddToLog(m_Data, "() --- ");
948 
949  return *this;
950 }
951 
952 const CSrvDiagMsg&
954 {
956  if (m_Thr->cur_task)
958  return StartInfo(ctx);
959 }
960 
961 const CSrvDiagMsg&
963 {
966  s_AddToLog(m_Data, "Message[W]: \"UNK_FILE\", line 0: UNK_FUNC --- ");
967  return *this;
968 }
969 
970 const CSrvDiagMsg&
971 CSrvDiagMsg::StartOldStyle(const char* file, int line, const char* func)
972 {
973  m_OldStyle = true;
975  m_Data->msg_file = file;
976  m_Data->msg_func = func;
977  m_Data->msg_line = line;
979  return *this;
980 }
981 
983 operator<< (const CSrvDiagMsg& msg, EOldStyleSeverity sev)
984 {
985  msg.m_Data->severity = s_ConvertSeverity(sev);
986  return msg;
987 }
988 
990 operator<< (const CSrvDiagMsg& msg, ErrCode err_code)
991 {
992  msg.m_Data->err_code = err_code.m_Code;
993  msg.m_Data->err_subcode = err_code.m_SubCode;
994  return msg;
995 }
996 
999 {
1001 }
1002 
1003 CSrvDiagMsg&
1005 {
1006  if (CDiagContext::IsCtxRunning(ctx)) {
1007  SRV_FATAL("Unexpected StartRequest call");
1008  }
1009  CDiagContext::StartCtxRequest(ctx);
1010  ctx->SetRequestStatus(200);
1011 
1012  if (!s_LogRequests)
1013  return *this;
1014 
1016  s_AddToLog(m_Data, "request-start ");
1017  m_Data->has_params = false;
1018 
1019  return *this;
1020 }
1021 
1022 CSrvDiagMsg&
1024 {
1025  return PrintExtra(m_Thr->cur_task->m_DiagCtx);
1026 }
1027 
1028 CSrvDiagMsg&
1030 {
1031  if (s_LogRequests) {
1033  s_AddToLog(m_Data, "extra ");
1034  m_Data->has_params = false;
1035  }
1036  return *this;
1037 }
1038 
1039 CSrvDiagMsg&
1041 {
1042  if (!s_LogRequests)
1043  return *this;
1044 
1045  s_AddParamName(m_Data, name);
1048  else
1050  return *this;
1051 }
1052 
1053 CSrvDiagMsg&
1055 {
1056  if (s_LogRequests) {
1057  s_AddParamName(m_Data, name);
1059  }
1060  return *this;
1061 }
1062 
1063 CSrvDiagMsg&
1065 {
1066  if (s_LogRequests) {
1067  s_AddParamName(m_Data, name);
1069  }
1070  return *this;
1071 }
1072 
1073 CSrvDiagMsg&
1075 {
1076  if (s_LogRequests) {
1077  s_AddParamName(m_Data, name);
1079  }
1080  return *this;
1081 }
1082 
1083 void
1085 {
1087 }
1088 
1089 void
1091 {
1092  if (!CDiagContext::IsCtxRunning(ctx)) {
1093  SRV_FATAL("Unexpected StopRequest call");
1094  }
1095 
1096  if (s_LogRequests) {
1098  s_AddToLog(m_Data, "request-stop ");
1099  s_AddToLog(m_Data, ctx->GetRequestStatus());
1100  *m_Data->cur_ptr++ = ' ';
1101  CTimeSpan span(ctx->GetRequestTimer().Elapsed());
1103  *m_Data->cur_ptr++ = '.';
1105  *m_Data->cur_ptr++ = ' ';
1106  s_AddToLog(m_Data, ctx->GetBytesRd());
1107  *m_Data->cur_ptr++ = ' ';
1108  s_AddToLog(m_Data, ctx->GetBytesWr());
1109  Flush();
1110  }
1111 
1112  CDiagContext::StopCtxRequest(ctx);
1113 }
1114 
1115 void
1117 {
1118  s_CheckBufSize(m_Data, 1);
1119  if (m_Data->buf) {
1120  *m_Data->cur_ptr++ = '\n';
1121  }
1123  if (m_Data->severity == SoftFatal) {
1124  switch (s_SoftFatal) {
1125  default:
1126  case 0: m_Data->severity = Fatal; break;
1128  case 2: break;
1129  }
1130  }
1131  if (m_Data->severity == Fatal) {
1133  }
1135 }
1136 
1139 {
1140  if (s_CheckOldStyleStart(this)) {
1141  if (s_InApplog)
1143  else
1144  s_AddToLog(m_Data, str);
1145  }
1146  return *this;
1147 }
1148 
1150 CSrvDiagMsg::operator<< (Int8 num) const
1151 {
1152  if (s_CheckOldStyleStart(this))
1153  s_AddToLog(m_Data, num);
1154  return *this;
1155 }
1156 
1159 {
1160  if (s_CheckOldStyleStart(this))
1161  s_AddToLog(m_Data, num);
1162  return *this;
1163 }
1164 
1166 CSrvDiagMsg::operator<< (double num) const
1167 {
1168  if (s_CheckOldStyleStart(this))
1169  s_AddToLog(m_Data, num);
1170  return *this;
1171 }
1172 
1174 CSrvDiagMsg::operator<< (const void* ptr) const
1175 {
1176  if (s_CheckOldStyleStart(this)) {
1179  }
1180  return *this;
1181 }
1182 
1184 CSrvDiagMsg::operator<< (const exception& ex) const
1185 {
1186  if (s_CheckOldStyleStart(this)) {
1187  if (s_InApplog)
1188  s_AddToLogStripLF(m_Data, ex.what());
1189  else
1190  s_AddToLog(m_Data, ex.what());
1191  }
1192  return *this;
1193 }
1194 
1195 
1196 void
1198 {
1199  if (!ctx) {
1200  return;
1201  }
1202  ctx->AddReference();
1203  if (!m_DiagCtx) {
1204  m_DiagCtx = ctx;
1205  if (m_DiagChain)
1206  m_DiagChain[0] = ctx;
1207  return;
1208  }
1209  if (!m_DiagChain) {
1210  m_DiagChain = (CRequestContext**)malloc(sizeof(m_DiagCtx) * 2);
1211 #if __NC_MEMMAN_USE_STD_MALLOC
1212  m_DiagChainSize = sizeof(m_DiagCtx) * 2;
1213  memset(m_DiagChain, 0, m_DiagChainSize);
1214 #else
1215  memset(m_DiagChain, 0, GetMemSize(m_DiagChain));
1216 #endif
1217  m_DiagChain[0] = m_DiagCtx;
1218  m_DiagChain[1] = m_DiagCtx = ctx;
1219  return;
1220  }
1221 
1222 #if __NC_MEMMAN_USE_STD_MALLOC
1223  Uint4 mem_cap = Uint4(m_DiagChainSize / sizeof(m_DiagCtx));
1224 #else
1225  Uint4 mem_cap = Uint4(GetMemSize(m_DiagChain) / sizeof(m_DiagCtx));
1226 #endif
1227  Uint4 cnt_in_chain = mem_cap;
1228  while (!m_DiagChain[cnt_in_chain - 1]) {
1229  if (--cnt_in_chain == 0) {
1230  SRV_FATAL("m_DiagChain broken");
1231  }
1232  }
1233  if (cnt_in_chain == mem_cap) {
1235  realloc(m_DiagChain, mem_cap * 2 * sizeof(m_DiagCtx));
1236 #if __NC_MEMMAN_USE_STD_MALLOC
1237  m_DiagChainSize = mem_cap * 2 * sizeof(m_DiagCtx);
1238  memset(&m_DiagChain[mem_cap], 0,
1239  m_DiagChainSize - mem_cap * sizeof(m_DiagCtx));
1240 #else
1241  memset(&m_DiagChain[mem_cap], 0,
1242  GetMemSize(m_DiagChain) - mem_cap * sizeof(m_DiagCtx));
1243 #endif
1244  }
1245  m_DiagChain[cnt_in_chain] = m_DiagCtx = ctx;
1246 }
1247 
1248 void
1250 {
1252  ctx->SetRequestID();
1253  SetDiagCtx(ctx);
1254 }
1255 
1256 void
1258 {
1259  CRequestContext* was_ctx = m_DiagCtx;
1261  m_DiagCtx = NULL;
1262  if (!m_DiagChain)
1263  return;
1264 
1265 #if __NC_MEMMAN_USE_STD_MALLOC
1266  Uint4 mem_cap = Uint4(m_DiagChainSize / sizeof(m_DiagCtx));
1267 #else
1268  Uint4 mem_cap = Uint4(GetMemSize(m_DiagChain) / sizeof(m_DiagCtx));
1269 #endif
1270  Uint4 cnt_in_chain = mem_cap;
1271  while (!m_DiagChain[cnt_in_chain - 1]) {
1272  if (--cnt_in_chain == 0) {
1273  SRV_FATAL("m_DiagChain broken");
1274  }
1275  }
1276  if (m_DiagChain[--cnt_in_chain] != was_ctx) {
1277  SRV_FATAL("m_DiagChain broken");
1278  }
1279  m_DiagChain[cnt_in_chain] = NULL;
1280  if (cnt_in_chain != 0)
1281  m_DiagCtx = m_DiagChain[cnt_in_chain - 1];
1282 }
1283 
1285  : m_File(""),
1286  m_Line(0),
1287  m_CurrFunctName(0),
1288  m_Parsed(false),
1289  m_StrFile(0),
1290  m_StrCurrFunctName(0)
1291 {}
1292 
1294  int line,
1295  const char* curr_funct)
1296  : m_File(file),
1297  m_Line(line),
1298  m_CurrFunctName(curr_funct),
1299  m_Parsed(false),
1300  m_StrFile(0),
1301  m_StrCurrFunctName(0)
1302 {
1303  if (!file) {
1304  m_File = "";
1305  return;
1306  }
1307 }
1308 
1310  int line,
1311  const string& curr_funct,
1312  const string& module)
1313  : m_File(""),
1314  m_Line(line),
1315  m_CurrFunctName(""),
1316  m_Parsed(false),
1317  m_StrFile(0),
1318  m_StrCurrFunctName(0)
1319 {
1320  if ( !file.empty() ) {
1321  m_StrFile = new char[file.size() + 1];
1322  strcpy(m_StrFile, file.c_str());
1323  m_File = m_StrFile;
1324  }
1325  if ( !curr_funct.empty() ) {
1326  m_StrCurrFunctName = new char[curr_funct.size() + 1];
1327  strcpy(m_StrCurrFunctName, curr_funct.c_str());
1329  }
1330 }
1331 
1333 {
1334  delete[] m_StrFile;
1335  delete[] m_StrCurrFunctName;
1336 }
1337 
1338 void
1340 {
1341  m_Parsed = true;
1342  CTempString class_name, func_name;
1343  s_ParseFuncName(m_CurrFunctName, class_name, func_name);
1344  m_FunctName.assign(func_name.data(), func_name.size());
1345  m_ClassName.assign(class_name.data(), class_name.size());
1346 }
1347 
1348 
1349 CNcbiOstream&
1350 SDiagMessage::Write(CNcbiOstream& os, int flags /* = 0 */) const
1351 {
1352  string sev = s_SevNames[s_ConvertSeverity(severity)];
1353  os << setfill(' ') << setw(13) // add 1 for space
1354  << setiosflags(IOS_BASE::left) << setw(0)
1355  << sev << ':'
1356  << resetiosflags(IOS_BASE::left)
1357  << ' ';
1358 
1359  // <module>-<err_code>.<err_subcode> or <module>-<err_text>
1360  if (err_code || err_subcode || err_text) {
1361  if (err_text) {
1362  os << '(' << err_text << ')';
1363  } else {
1364  os << '(' << err_code << '.' << err_subcode << ')';
1365  }
1366  }
1367  os << ' ';
1368 
1369  // "<file>"
1370  bool print_file = file && *file;
1371  if ( print_file ) {
1372  const char* x_file;
1373  size_t x_file_len;
1374  ExtractFileName(file, x_file, x_file_len);
1375  os << '"' << string(x_file, x_file_len) << '"';
1376  }
1377  else {
1378  os << "\"UNK_FILE\"";
1379  }
1380  // , line <line>
1381  os << ", line " << line;
1382  os << ": ";
1383 
1384  // Class::Function
1385  bool print_loc = (nclass && *nclass ) || (func && *func);
1386  if (print_loc) {
1387  // Class:: Class::Function() ::Function()
1388  if (nclass && *nclass) {
1389  os << nclass;
1390  }
1391  os << "::";
1392  if (func && *func) {
1393  os << func << "() ";
1394  }
1395  }
1396  else {
1397  os << "UNK_FUNC ";
1398  }
1399 
1400  os << "--- ";
1401 
1402  // [<prefix1>::<prefix2>::.....]
1403  if (prefix && *prefix)
1404  os << '[' << prefix << "] ";
1405 
1406  // <message>
1407  if (len)
1408  os.write(buf, len);
1409 
1410  // Endl
1411  if ((flags & fNoEndl) == 0)
1412  os << NcbiEndl;
1413 
1414  return os;
1415 }
1416 
1417 
1419 {
1420 #if __NC_TASKS_MONITOR
1421  m_TaskName = "CLogWriter";
1422 #endif
1423 }
1424 
1426 {}
1427 
1428 void
1430 {
1431 // those who add data into queue, make this runnable
1432 
1434 // if log file was open for too long, close it
1435 // so that app_log could move it
1437  {
1438 #ifdef NCBI_OS_LINUX
1439  close(s_LogFd);
1440 #endif
1441  s_LogFd = -1;
1442  }
1443 
1444 // get from the queue, write into log
1446  if (s_WriteQueue.empty()) {
1448  return;
1449  }
1450  CTempString str = s_WriteQueue.front();
1451  s_WriteQueue.pop_front();
1452  bool have_more = !s_WriteQueue.empty();
1454 
1455  s_WriteLog(str.data(), str.size());
1456  free((void*)str.data());
1457 
1458  if (have_more)
1459  SetRunnable();
1460 }
1461 
Wrapper around Linux's futex.
Definition: srv_sync.hpp:141
EWaitResult WaitValueChange(int old_value)
Wait for futex's value to change (with and without timeout).
Definition: srv_sync.cpp:44
int GetValue(void)
Read value of the futex.
Definition: srv_sync.hpp:238
int WakeUpWaiters(int cnt_to_wake)
Wake up some threads waiting on this futex.
Definition: srv_sync.cpp:98
int AddValue(int cnt_to_add)
Atomically add some amount to futex's value.
Definition: srv_sync.hpp:250
virtual ~CLogWriter(void)
Definition: logging.cpp:1425
virtual void ExecuteSlice(TSrvThreadNum thr_num)
This is the main method to do all work this task should do.
Definition: logging.cpp:1429
CLogWriter(void)
Definition: logging.cpp:1418
Mutex created to have minimum possible size (its size is 4 bytes) and to sleep using kernel capabilit...
Definition: srv_sync.hpp:193
void Unlock(void)
Unlock the mutex.
Definition: srv_sync.cpp:119
void Lock(void)
Lock the mutex.
Definition: srv_sync.cpp:108
CNcbiRegistry –.
Definition: ncbireg.hpp:913
Class used in all diagnostic logging.
Definition: srv_diag.hpp:73
~CSrvDiagMsg(void)
Definition: logging.cpp:896
const CSrvDiagMsg & StartSrvLog(ESeverity sev, const char *file, int line, const char *func) const
Starts log message which will include severity, filename, line number and function name.
Definition: logging.cpp:909
CSrvDiagMsg & PrintExtra(void)
Starts "extra" message.
Definition: logging.cpp:1023
const CSrvDiagMsg & operator<<(CTempString str) const
Converts input value to string and adds to started log message.
Definition: logging.cpp:1138
CSrvDiagMsg & StartRequest(void)
Starts "request-start" message.
Definition: logging.cpp:998
CSrvDiagMsg & PrintParam(CTempString name, CTempString value)
Adds parameter to "request-start" or "extra" message.
Definition: logging.cpp:1040
SLogData * m_Data
Log data from current thread.
Definition: srv_diag.hpp:153
CSrvDiagMsg(void)
Definition: logging.cpp:880
SSrvThread * m_Thr
Current thread created this object.
Definition: srv_diag.hpp:151
bool m_OldStyle
Flag showing if "old style" message was started.
Definition: srv_diag.hpp:155
const CSrvDiagMsg & StartInfo(void) const
Starts informational message which doesn't need to have filename, line number or function name.
Definition: logging.cpp:953
void StopRequest(void)
Prints "request-stop" message.
Definition: logging.cpp:1084
void Flush(void)
Finishes current message and prepare to start new one.
Definition: logging.cpp:1116
static bool IsSeverityVisible(ESeverity sev)
Checks if given severity level is visible, i.e.
Definition: logging.cpp:903
const CSrvDiagMsg & StartOldStyle(const char *file, int line, const char *func)
Starts the "old style" log message.
Definition: logging.cpp:971
ESeverity
Severity levels for logging.
Definition: srv_diag.hpp:79
Task controlling a socket.
CSrvSocketTask & WriteText(CTempString message)
Write text into socket.
CSrvSocketTask & WriteNumber(NumType num)
Write number into socket as string, i.e.
CSrvSocketTask & WriteBool(bool b)
Main working entity in TaskServer.
Definition: srv_tasks.hpp:88
void SetDiagCtx(CRequestContext *ctx)
Set diagnostic context for this task to work in.
Definition: logging.cpp:1197
CRequestContext ** m_DiagChain
Nested diagnostic contexts of this task.
Definition: srv_tasks.hpp:221
size_t m_DiagChainSize
Definition: srv_tasks.hpp:223
CRequestContext * m_DiagCtx
Current diagnostic context for this task.
Definition: srv_tasks.hpp:216
void SetRunnable(bool boost=false)
Set this task "runnable", i.e.
Definition: scheduler.cpp:618
void ReleaseDiagCtx(void)
Releases current diagnostic context of the task.
Definition: logging.cpp:1257
void CreateNewDiagCtx(void)
Create new diagnostic context for this task to work in.
Definition: logging.cpp:1249
Class incorporating convenient methods to work with struct timespec.
Definition: srv_time.hpp:61
static int CurSecs(void)
Current time in seconds since epoch (time_t).
time_t & Sec(void)
Read/set number of seconds since epoch stored in the object.
static CSrvTime Current(void)
Exact current time with precision up to nanoseconds.
Uint1 Print(char *buf, EFormatType fmt) const
Formats time value in the object and writes it in buf.
Definition: time_man.cpp:155
long & NSec(void)
Read/set number of nanoseconds stored in the object.
@ eFmtLogging
Format used in logs which is YYYY-MM-DDThh:mm:ss.ssssss.
Definition: srv_time.hpp:106
static const string & GetHostName(void)
Returns name of server this application is executing on.
static void RequestShutdown(ESrvShutdownType shutdown_type)
Asks server to start shutdown procedures.
static CSrvTime GetStartTime(void)
Returns time when this server application was started (when Initialize() method was called).
CTempString implements a light-weight string on top of a storage buffer whose lifetime management is ...
Definition: tempstr.hpp:65
CTimeSpan.
Definition: ncbitime.hpp:1313
ErrCode –.
Definition: ncbidiag.hpp:815
static uch flags
int close(int fd)
Definition: connection.cpp:45
const char * file_name[]
CS_CONTEXT * ctx
Definition: t0006.c:12
#define false
Definition: bool.h:36
static const char * str(char *buf, int n)
Definition: stats.c:84
static char tmp[3200]
Definition: utf8.c:42
char data[12]
Definition: iconv.c:80
#define ITERATE(Type, Var, Cont)
ITERATE macro to sequence through container elements.
Definition: ncbimisc.hpp:815
string
Definition: cgiapp.hpp:687
#define NULL
Definition: ncbistd.hpp:225
void Write(string &str, TDiagWriteFlags flags=fNone) const
Binary OR of "EDiagWriteFlags".
Definition: ncbidiag.cpp:5358
void ParseCurrFunctName(void) const
Definition: logging.cpp:1339
int m_Code
Major error code number.
Definition: ncbidiag.hpp:821
string m_StrCurrFunctName
Definition: ncbidiag.hpp:122
string GetEncodedSessionID(void) const
Get url-encoded session id.
Definition: logging.cpp:874
CDiagContext & GetDiagContext(void)
Get diag context instance.
Definition: logging.cpp:818
static bool UpdatePID(void)
Reset PID cache (e.g. after fork). Return true if PID was updated.
Definition: logging.cpp:830
static TCount GetNextRequestID(void)
Return the next available application-wide request ID.
~CDiagCompileInfo(void)
Definition: logging.cpp:1332
const char * m_File
Definition: ncbidiag.hpp:109
string m_FunctName
Definition: ncbidiag.hpp:117
string m_ClassName
Definition: ncbidiag.hpp:116
static void UpdateOnFork(TOnForkFlags flags)
Update diagnostics after fork().
Definition: logging.cpp:824
EDiagSev
Severity level for the posted diagnostics.
Definition: ncbidiag.hpp:650
const char * m_CurrFunctName
Definition: ncbidiag.hpp:113
string GetDefaultSessionID(void) const
Get default session id.
Definition: logging.cpp:868
int m_SubCode
Minor error code number.
Definition: ncbidiag.hpp:822
CDiagCompileInfo(void)
CDiagCompileInfo::
Definition: logging.cpp:1284
@ fNoEndl
No end of line.
Definition: ncbidiag.hpp:1704
@ 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
@ eDiag_Critical
Critical error message.
Definition: ncbidiag.hpp:654
void Critical(CExceptionArgs_Base &args)
Definition: ncbiexpt.hpp:1203
void Error(CExceptionArgs_Base &args)
Definition: ncbiexpt.hpp:1197
void Trace(CExceptionArgs_Base &args)
Definition: ncbiexpt.hpp:1179
void Warning(CExceptionArgs_Base &args)
Definition: ncbiexpt.hpp:1191
void Fatal(CExceptionArgs_Base &args)
Definition: ncbiexpt.hpp:1209
void Info(CExceptionArgs_Base &args)
Definition: ncbiexpt.hpp:1185
static string NormalizePath(const string &path, EFollowLinks follow_links=eIgnoreLinks)
Normalize a path.
Definition: ncbifile.cpp:820
static bool IsAbsolutePath(const string &path)
Check if a "path" is absolute for the current OS.
Definition: ncbifile.cpp:508
static string MakePath(const string &dir=kEmptyStr, const string &base=kEmptyStr, const string &ext=kEmptyStr)
Assemble a path from basic components.
Definition: ncbifile.cpp:413
static string ConcatPath(const string &first, const string &second)
Concatenate two parts of the path for the current OS.
Definition: ncbifile.cpp:776
static string GetCwd(void)
Get the current working directory.
Definition: ncbifile.cpp:3708
void RemoveReference(void) const
Remove reference to object.
Definition: ncbiobj.hpp:500
uint8_t Uint1
1-byte (8-bit) unsigned integer
Definition: ncbitype.h:99
uint32_t Uint4
4-byte (32-bit) unsigned integer
Definition: ncbitype.h:103
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
static TPid GetPid(void)
Get process identifier (pid) for the current process.
virtual bool GetBool(const string &section, const string &name, bool default_value, TFlags flags=0, EErrAction err_action=eThrow) const
Get boolean value of specified parameter name.
Definition: ncbireg.cpp:391
virtual int GetInt(const string &section, const string &name, int default_value, TFlags flags=0, EErrAction err_action=eThrow) const
Get integer value of specified parameter name.
Definition: ncbireg.cpp:362
virtual string GetString(const string &section, const string &name, const string &default_value, TFlags flags=0) const
Get the parameter string value.
Definition: ncbireg.cpp:321
#define END_NCBI_SCOPE
End previously defined NCBI scope.
Definition: ncbistl.hpp:103
#define BEGIN_NCBI_SCOPE
Define ncbi namespace.
Definition: ncbistl.hpp:100
#define NcbiEndl
Definition: ncbistre.hpp:548
IO_PREFIX::ostream CNcbiOstream
Portable alias for ostream.
Definition: ncbistre.hpp:149
static string Int8ToString(Int8 value, TNumToStringFlags flags=0, int base=10)
Convert Int8 to string.
Definition: ncbistr.hpp:5161
static string DoubleToString(double value, int precision=-1, TNumToStringFlags flags=0)
Convert double to string.
Definition: ncbistr.hpp:5189
#define kEmptyStr
Definition: ncbistr.hpp:123
static Uint8 StringToUInt8_DataSize(const CTempString str, TStringToNumFlags flags=0)
Convert string that can contain "software" qualifiers to Uint8.
Definition: ncbistr.cpp:1530
CTempString & assign(const char *src_str, size_type len)
Assign new values to the content of the a string.
Definition: tempstr.hpp:733
static void PtrToString(string &out_str, const void *ptr)
Convert pointer to string.
Definition: ncbistr.cpp:2762
const char * data(void) const
Return a pointer to the array represented.
Definition: tempstr.hpp:313
static bool NeedsURLEncoding(const CTempString str, EUrlEncode flag=eUrlEnc_SkipMarkChars)
Check if the string needs the requested URL-encoding.
Definition: ncbistr.cpp:6219
static string URLEncode(const CTempString str, EUrlEncode flag=eUrlEnc_SkipMarkChars)
URL-encode string.
Definition: ncbistr.cpp:6053
size_type size(void) const
Return the length of the represented array.
Definition: tempstr.hpp:327
static string UInt8ToString(Uint8 value, TNumToStringFlags flags=0, int base=10)
Convert UInt8 to string.
Definition: ncbistr.hpp:5170
long GetNanoSecondsAfterSecond(void) const
Get number of nanoseconds.
Definition: ncbitime.hpp:2562
long GetCompleteSeconds(void) const
Get number of complete seconds.
Definition: ncbitime.hpp:2559
unsigned int
A callback function used to compare two keys in a database.
Definition: types.hpp:1210
FILE * file
char * buf
int i
int len
static void s_InitConstants(void)
Definition: logging.cpp:162
static string s_UnkSession
Definition: logging.cpp:92
static void s_ParseFuncName(const char *func, CTempString &class_name, CTempString &func_name)
Definition: logging.cpp:706
static bool s_CheckBufSize(SLogData *data, size_t need_size)
Definition: logging.cpp:270
string s_AppBaseName
Definition: server_core.cpp:77
static const char * s_SevNames[]
Definition: logging.cpp:93
static list< CTempString > s_WriteQueue
Definition: logging.cpp:110
void AssignThreadLogging(SSrvThread *thr)
Definition: logging.cpp:606
static bool s_NeedFatalHalt
Definition: logging.cpp:114
static SLogData * s_AllocNewData(TSrvThreadNum thr_num)
Definition: logging.cpp:435
string GetLogFileName(void)
Definition: logging.cpp:146
static int s_LogFd
Definition: logging.cpp:112
void SaveAppCmdLine(const string &cmd_line)
Definition: logging.cpp:132
static Uint8 s_LongCmd
Definition: logging.cpp:101
static string s_Pid
Definition: logging.cpp:103
static CLogWriter * s_LogWriter
Definition: logging.cpp:111
void CheckLoggingFlush(SSrvThread *thr)
Definition: logging.cpp:619
static bool s_CheckOldStyleStart(const CSrvDiagMsg *msg)
Definition: logging.cpp:756
static bool s_InApplog
Definition: logging.cpp:108
static CFutex s_Halt
Definition: logging.cpp:119
void LogNoteThreadsStarted(void)
Definition: logging.cpp:517
static bool s_FileNameInitialized
Definition: logging.cpp:115
static int s_SoftFatal
Definition: logging.cpp:95
void ReleaseThreadLogging(SSrvThread *thr)
Definition: logging.cpp:653
static void s_WriteLog(const char *buf, size_t size)
Definition: logging.cpp:200
static bool s_LogRequests
Definition: logging.cpp:90
static void s_AddLogPrefix(SSrvThread *thr, SLogData *data, CRequestContext *diag_ctx=NULL)
Definition: logging.cpp:370
static Uint8 s_ProcessPostNum
Definition: logging.cpp:106
static void s_AllocNewBuf(SLogData *data, size_t buf_size)
Definition: logging.cpp:235
static void s_AddToLog(SLogData *data, const char *str, size_t size)
Definition: logging.cpp:278
void ConfigureLogging(const CNcbiRegistry *reg, CTempString section)
Definition: logging.cpp:524
static string s_FileName
Definition: logging.cpp:105
static CFutex s_CntHaltedThreads
Definition: logging.cpp:118
static void s_InitLogPrefix(SLogData *data, TSrvThreadNum thr_num)
Definition: logging.cpp:258
string GetSoftFatalAction(void)
Definition: logging.cpp:156
void WriteSetup_Logging(CSrvSocketTask &task)
Definition: logging.cpp:560
void FinalizeLogging(void)
Definition: logging.cpp:583
SSrvThread ** s_Threads
Definition: threads_man.cpp:59
void Logging_DiskSpaceAlert(void)
Definition: logging.cpp:126
static void s_QueueLogWrite(char *buf, size_t size)
Definition: logging.cpp:220
static void s_InitFileName(void)
Definition: logging.cpp:458
static string s_AppUID
Definition: logging.cpp:104
static size_t s_LogBufSize
Definition: logging.cpp:98
void StartThreadLogging(SSrvThread *thr)
Definition: logging.cpp:635
static CSrvDiagMsg::ESeverity s_ConvertSeverity(EOldStyleSeverity sev)
Definition: logging.cpp:774
static bool s_ThreadsStarted
Definition: logging.cpp:116
void InitLogging(void)
Definition: logging.cpp:573
static bool s_DiskSpaceAlert
Definition: logging.cpp:117
static void s_AddParamName(SLogData *data, CTempString name)
Definition: logging.cpp:421
static SLogData * s_MainData
Definition: logging.cpp:107
void SetLogFileName(CTempString name)
Definition: logging.cpp:138
static void s_AddToLogStripLF(SLogData *data, const char *str, size_t size)
Definition: logging.cpp:287
static void s_RotateLogBuf(SLogData *data)
Definition: logging.cpp:243
static CSrvDiagMsg::ESeverity s_VisibleSev
Definition: logging.cpp:89
static const char * str_rev_str(const char *begin_str, const char *end_str, const char *str_search)
Definition: logging.cpp:680
static void s_DoFatalAbort(SLogData *data)
Definition: logging.cpp:472
bool ReConfig_Logging(const CTempString &section, const CNcbiRegistry &new_reg, string &)
Definition: logging.cpp:549
static int s_LastReopenTime
Definition: logging.cpp:113
static void s_CheckFatalAbort(void)
Definition: logging.cpp:503
string GetLogVisibility(void)
Definition: logging.cpp:151
static const size_t kInitLogBufSize
Definition: logging.cpp:97
static CMiniMutex s_WriteQueueLock
Definition: logging.cpp:109
void StopThreadLogging(SSrvThread *thr)
Definition: logging.cpp:641
static int s_FileReopenPeriod
Definition: logging.cpp:100
static int s_MaxFlushPeriod
Definition: logging.cpp:99
const CSrvDiagMsg & operator<<(const CSrvDiagMsg &msg, EOldStyleSeverity sev)
Definition: logging.cpp:983
CSrvTime s_JiffyTime
Definition: time_man.cpp:54
static string s_UnkClient
Definition: logging.cpp:91
static const char * s_SoftFatalActions[]
Definition: logging.cpp:94
static void s_AllocMainData(void)
Definition: logging.cpp:446
static string s_CmdLine
Definition: logging.cpp:102
static void s_OpenLogFile(void)
Definition: logging.cpp:187
bool IsLongCommand(Uint8 cmd_len)
Definition: logging.cpp:555
static const char * find_match(char lsep, char rsep, const char *start, const char *stop)
Definition: logging.cpp:663
static const size_t kOneRecReserve
Definition: logging.cpp:96
size_t GetMemSize(void *ptr)
const struct ncbi::grid::netcache::search::fields::SIZE size
const GenericPointer< typename T::ValueType > T2 value
Definition: pointer.h:1227
EIPRangeType t
Definition: ncbi_localip.c:101
int ssize_t
Definition: ncbiconf_msvc.h:93
Defines classes: CDirEntry, CFile, CDir, CSymLink, CMemoryFile, CFileUtil, CFileLock,...
Multi-threading – mutexes; rw-locks; semaphore.
Process information in the NCBI Registry, including working with configuration files.
T max(T x_, T y_)
void abort()
static const char * prefix[]
Definition: pcregrep.c:405
Defines CRequestContext class for NCBI C++ diagnostic API.
void ExtractFileName(const char *file, const char *&file_name, size_t &name_size)
#define SRV_FATAL(msg)
Definition: srv_diag.hpp:173
TSrvThreadNum s_MaxRunningThreads
Definition: threads_man.cpp:71
T AtomicAdd(T volatile &var, T add_value)
Definition: srv_sync.hpp:69
@ kUSecsPerMSec
Definition: srv_time.hpp:44
char * cur_msg_ptr
Definition: logging.cpp:55
const char * msg_func
Definition: logging.cpp:63
char * end_ptr
Definition: logging.cpp:53
bool has_params
Definition: logging.cpp:59
CSrvDiagMsg::ESeverity severity
Definition: logging.cpp:60
const char * msg_file
Definition: logging.cpp:62
char * cur_ptr
Definition: logging.cpp:54
int err_code
Definition: logging.cpp:65
int last_flush_time
Definition: logging.cpp:67
SLogData(void)
Definition: logging.cpp:69
char * buf
Definition: logging.cpp:52
Uint8 post_num
Definition: logging.cpp:56
string tmp_str
Definition: logging.cpp:58
int err_subcode
Definition: logging.cpp:66
string prefix
Definition: logging.cpp:57
int msg_line
Definition: logging.cpp:64
CSrvTask * cur_task
Definition: threads_man.hpp:87
SLogData * log_data
Definition: threads_man.hpp:90
Uint2 TSrvThreadNum
Type for thread number in TaskServer.
Definition: task_server.hpp:42
@ eSrvFastShutdown
CRef< CTestThread > thr[k_NumThreadsMax]
Definition: test_mt.cpp:267
TSrvThreadNum GetCntRunningThreads(void)
SSrvThread * GetCurThread(void)
Definition: threads_man.cpp:82
void free(voidpf ptr)
voidp malloc(uInt size)
Modified on Fri Jul 19 17:13:42 2024 by modify_doxy.py rev. 669887