39 #if defined(NCBI_OS_UNIX)
44 # include <sys/utsname.h>
45 # include <sys/time.h>
46 # include <sys/types.h>
47 # if !defined(__CYGWIN__)
48 # include <sys/syscall.h>
51 # include <sys/errno.h>
53 #elif defined(NCBI_OS_MSWIN)
54 # include <sys/types.h>
55 # include <sys/timeb.h>
61 # if defined(NCBI_OS_MSWIN)
62 # define NCBI_WIN32_THREADS
63 # elif defined(NCBI_OS_UNIX)
64 # define NCBI_POSIX_THREADS
66 # define NCBI_NO_THREADS
69 # define NCBI_NO_THREADS
72 #if defined(NCBI_POSIX_THREADS)
77 #if !defined(NDEBUG) && !defined(_DEBUG)
87 #define TROUBLE s_Abort(__LINE__, 0)
88 #define TROUBLE_MSG(msg) s_Abort(__LINE__, msg)
95 # define verify(expr) while ( expr ) break
97 # define verify(expr) assert(expr)
109 # define VERIFY(expr) do { if ( !(expr) ) s_ReportError(__LINE__, #expr); } while ( 0 )
111 # define VERIFY(expr) do { if ( !(expr) ) s_Abort(__LINE__, #expr); s_ReportError(__LINE__, #expr); } while ( 0 )
115 # define VERIFY_CATCH(expr) do { if ( !(expr) ) { s_ReportError(__LINE__, #expr); goto __catch_error; } } while ( 0 )
117 # define VERIFY_CATCH(expr) do { if ( !(expr) ) { s_Abort(__LINE__, #expr); goto __catch_error; } } while ( 0 )
131 #define CATCH __catch_error
133 #if defined(__GNUC__)
134 # define UNUSED_ARG(x) x##_UNUSED __attribute__((unused))
136 # define UNUSED_ARG(x) x##_UNUSED
140 #define min_value(a,b) ((a) < (b) ? (a) : (b))
143 #if defined(NCBI_OS_MSWIN)
144 # define DIR_SEPARATOR '\\'
145 #elif defined(NCBI_OS_UNIX)
146 # define DIR_SEPARATOR '/'
155 #define UNKNOWN_HOST "UNK_HOST"
156 #define UNKNOWN_CLIENT "UNK_CLIENT"
157 #define UNKNOWN_SESSION "UNK_SESSION"
158 #define UNKNOWN_HITID ""
159 #define UNKNOWN_APPNAME "UNK_APP"
197 static void s_Abort(
long line,
const char* msg)
200 char* v = getenv(
"DIAG_SILENT_ABORT");
203 fprintf(stderr,
"Critical error: %s, %s, line %ld\n", msg, __FILE__, line);
205 fprintf(stderr,
"Critical error at %s, line %ld\n", __FILE__, line);
207 if (v && (*v ==
'Y' || *v ==
'y' || *v ==
'1')) {
210 if (v && (*v ==
'N' || *v ==
'n' || *v ==
'0')) {
233 char* v = getenv(
"NCBI_CLOG_REPORT_ERRORS");
234 if (!v || !(*v ==
'Y' || *v ==
'y' || *v ==
'1')) {
238 const char* m = (msg && *msg) ? msg :
"unknown";
239 fprintf(stderr,
"\nCLog error: %s, %s, line %ld\n", m, __FILE__, line);
249 #if defined(NCBI_POSIX_THREADS)
251 #elif defined(NCBI_WIN32_THREADS)
260 #if defined(NCBI_POSIX_THREADS)
280 #elif defined(NCBI_WIN32_THREADS)
312 #define kMTLock_magic_number 0x4C0E681F
327 #define MT_LOCK_VALID \
328 if (sx_MTLock) assert(sx_MTLock->magic_number == kMTLock_magic_number)
337 #define MT_LOCK_Do(action) (sx_MTLock ? s_MTLock_Do((action)) : -1)
341 #define MT_INIT verify(MT_LOCK_Do(eNcbiLog_MT_Init) != 0)
342 #define MT_LOCK verify(MT_LOCK_Do(eNcbiLog_MT_Lock) != 0)
343 #define MT_UNLOCK verify(MT_LOCK_Do(eNcbiLog_MT_Unlock) != 0)
344 #define MT_DESTROY verify(MT_LOCK_Do(eNcbiLog_MT_Destroy) != 0)
384 #if defined(NCBI_POSIX_THREADS)
386 #elif defined(NCBI_WIN32_THREADS)
395 #if defined(NCBI_POSIX_THREADS)
401 #elif defined(NCBI_WIN32_THREADS)
414 #if defined(NCBI_POSIX_THREADS)
416 #elif defined(NCBI_WIN32_THREADS)
429 #if defined(NCBI_POSIX_THREADS)
430 ptr = pthread_getspecific(
sx_Tls);
431 #elif defined(NCBI_WIN32_THREADS)
432 ptr = TlsGetValue(
sx_Tls);
434 assert(GetLastError() == ERROR_SUCCESS);
446 #if defined(NCBI_POSIX_THREADS)
448 #elif defined(NCBI_WIN32_THREADS)
462 #define MT_LOCK_API \
464 while (!sx_IsEnabled) { \
466 s_SleepMicroSec(10); \
474 #define CHECK_APP_START(ctx) \
475 if (sx_Info->state == eNcbiLog_NotSet) { \
476 s_AppStart(ctx, NULL); \
496 #if defined(NCBI_OS_MSWIN)
497 Sleep((mc_sec + 500) / 1000);
498 #elif defined(NCBI_OS_UNIX)
499 struct timeval delay;
500 delay.tv_sec = (long)(mc_sec / 1000000);
501 #if defined(NCBI_OS_DARWIN)
502 delay.tv_usec = (
int)(mc_sec % 1000000);
504 delay.tv_usec = (long)(mc_sec % 1000000);
506 while (select(0, (fd_set*) 0, (fd_set*) 0, (fd_set*) 0, &delay) < 0) {
530 const char* p1,
size_t p1_len,
531 const char* p2,
size_t p2_len,
542 if (p1_len + p2_len + 2 >= dst_size) {
545 memcpy(dst, p1, p1_len);
550 memcpy(dst +
n, p2, p2_len);
566 return s_ConcatPathEx(p1, strlen(p1), p2, strlen(p2), dst, dst_size);
575 static const char* host =
NULL;
577 #if defined(NCBI_OS_UNIX)
583 if ( (p = getenv(
"NCBI_HOST")) !=
NULL && *p ) {
587 #if defined(NCBI_OS_UNIX)
588 if (uname(&
buf) == 0) {
591 #elif defined(NCBI_OS_MSWIN)
593 if ( (p = getenv(
"COMPUTERNAME")) !=
NULL && *p ) {
611 fp = fopen(filename,
"rt");
622 while (*p && !(*p ==
' ' || *p ==
'\n')) p++;
632 static const char* role =
NULL;
633 const char* p =
NULL;
637 if ( (p = getenv(
"NCBI_ROLE")) !=
NULL && *p ) {
651 const char* p =
NULL;
655 if ( (p = getenv(
"NCBI_LOCATION")) !=
NULL && *p ) {
670 #if defined(NCBI_OS_UNIX)
672 #elif defined(NCBI_OS_MSWIN)
673 sx_PID = GetCurrentProcessId();
686 #if defined(NCBI_NO_THREADS)
688 #elif defined(NCBI_OS_UNIX)
689 # if defined(SYS_gettid)
698 #elif defined(NCBI_OS_MSWIN)
699 tid = GetCurrentThreadId();
718 for (s = host; *s !=
'\0'; s++) {
719 h = h*1265 + (
unsigned char)(*s);
729 ((pid & 0xFFFF) << 32) |
730 ((
t & 0xFFFFFFF) << 4) |
760 static int s_GetTimeT(time_t* time_sec,
unsigned long* time_ns)
762 #if defined(NCBI_OS_MSWIN)
763 struct _timeb timebuffer;
764 #elif defined(NCBI_OS_UNIX)
767 if (!time_sec || ! time_ns) {
770 #if defined(NCBI_OS_MSWIN)
772 *time_sec = timebuffer.time;
773 *time_ns = (long) timebuffer.millitm * 1000000;
776 if (gettimeofday(&tp,0) != 0) {
779 *time_sec = tp.tv_sec;
780 *time_ns = (
unsigned long)((
double)tp.tv_usec * 1000);
786 if (*time_sec == (time_t)(-1)) {
809 ts = ((double)time_end.
sec - (
double)time_start.
sec) +
810 ((
double)time_end.
ns - (double)time_start.
ns)/1000000000;
820 unsigned long time_ns
823 #ifdef HAVE_LOCALTIME_R
837 #ifdef HAVE_LOCALTIME_R
838 localtime_r(&time_sec, &temp);
841 t = localtime(&time_sec);
848 n = sprintf(
buf,
"%04u-%02u-%02uT%02u:%02u:%02u.%03u",
855 (
unsigned int)(time_ns / 1000000)
870 int internal, external;
876 internal = (p = getenv(
"HTTP_CAF_INTERNAL")) !=
NULL && *p ? 1 : 0;
877 external = (((p = getenv(
"HTTP_CAF_EXTERNAL")) !=
NULL && *p) ||
878 ((p = getenv(
"HTTP_NCBI_EXTERNAL")) !=
NULL && *p)) ? 1 : 0;
879 if (
internal || !external ) {
880 if ( (p = getenv(
"HTTP_CLIENT_HOST")) !=
NULL && *p ) {
885 if ( (p = getenv(
"HTTP_CAF_PROXIED_HOST")) !=
NULL && *p ) {
889 if ( (p = getenv(
"PROXIED_IP")) !=
NULL && *p ) {
893 if ( (p = getenv(
"HTTP_X_REAL_IP")) !=
NULL && *p ) {
897 if ( (p = getenv(
"REMOTE_ADDR")) !=
NULL && *p ) {
910 static const char* session =
NULL;
916 if ( (p = getenv(
"HTTP_NCBI_SID")) !=
NULL && *p ) {
920 if ( (p = getenv(
"NCBI_LOG_SESSION_ID")) !=
NULL && *p ) {
933 static const char* phid =
NULL;
939 if ( (p = getenv(
"HTTP_NCBI_PHID")) !=
NULL && *p ) {
943 if ( (p = getenv(
"NCBI_LOG_HIT_ID")) !=
NULL && *p ) {
956 if ( (p = getenv(env_var_name)) !=
NULL && *p ) {
958 unsigned long v = strtoul(p, &e, 10);
959 if (v <= UINT_MAX && !*e) {
974 "%00",
"%01",
"%02",
"%03",
"%04",
"%05",
"%06",
"%07",
975 "%08",
"%09",
"%0A",
"%0B",
"%0C",
"%0D",
"%0E",
"%0F",
976 "%10",
"%11",
"%12",
"%13",
"%14",
"%15",
"%16",
"%17",
977 "%18",
"%19",
"%1A",
"%1B",
"%1C",
"%1D",
"%1E",
"%1F",
978 "+",
"!",
"%22",
"%23",
"$",
"%25",
"%26",
"'",
979 "(",
")",
"*",
"%2B",
",",
"-",
".",
"%2F",
980 "0",
"1",
"2",
"3",
"4",
"5",
"6",
"7",
981 "8",
"9",
"%3A",
"%3B",
"%3C",
"%3D",
"%3E",
"%3F",
982 "%40",
"A",
"B",
"C",
"D",
"E",
"F",
"G",
983 "H",
"I",
"J",
"K",
"L",
"M",
"N",
"O",
984 "P",
"Q",
"R",
"S",
"T",
"U",
"V",
"W",
985 "X",
"Y",
"Z",
"%5B",
"%5C",
"%5D",
"%5E",
"_",
986 "%60",
"a",
"b",
"c",
"d",
"e",
"f",
"g",
987 "h",
"i",
"j",
"k",
"l",
"m",
"n",
"o",
988 "p",
"q",
"r",
"s",
"t",
"u",
"v",
"w",
989 "x",
"y",
"z",
"%7B",
"%7C",
"%7D",
"%7E",
"%7F",
990 "%80",
"%81",
"%82",
"%83",
"%84",
"%85",
"%86",
"%87",
991 "%88",
"%89",
"%8A",
"%8B",
"%8C",
"%8D",
"%8E",
"%8F",
992 "%90",
"%91",
"%92",
"%93",
"%94",
"%95",
"%96",
"%97",
993 "%98",
"%99",
"%9A",
"%9B",
"%9C",
"%9D",
"%9E",
"%9F",
994 "%A0",
"%A1",
"%A2",
"%A3",
"%A4",
"%A5",
"%A6",
"%A7",
995 "%A8",
"%A9",
"%AA",
"%AB",
"%AC",
"%AD",
"%AE",
"%AF",
996 "%B0",
"%B1",
"%B2",
"%B3",
"%B4",
"%B5",
"%B6",
"%B7",
997 "%B8",
"%B9",
"%BA",
"%BB",
"%BC",
"%BD",
"%BE",
"%BF",
998 "%C0",
"%C1",
"%C2",
"%C3",
"%C4",
"%C5",
"%C6",
"%C7",
999 "%C8",
"%C9",
"%CA",
"%CB",
"%CC",
"%CD",
"%CE",
"%CF",
1000 "%D0",
"%D1",
"%D2",
"%D3",
"%D4",
"%D5",
"%D6",
"%D7",
1001 "%D8",
"%D9",
"%DA",
"%DB",
"%DC",
"%DD",
"%DE",
"%DF",
1002 "%E0",
"%E1",
"%E2",
"%E3",
"%E4",
"%E5",
"%E6",
"%E7",
1003 "%E8",
"%E9",
"%EA",
"%EB",
"%EC",
"%ED",
"%EE",
"%EF",
1004 "%F0",
"%F1",
"%F2",
"%F3",
"%F4",
"%F5",
"%F6",
"%F7",
1005 "%F8",
"%F9",
"%FA",
"%FB",
"%FC",
"%FD",
"%FE",
"%FF"
1015 (
const void* src_buf,
1023 unsigned char* src = (
unsigned char*) src_buf;
1024 unsigned char* dst = (
unsigned char*) dst_buf;
1028 if (!src_size || !dst_size || !dst || !src)
1031 for ( ; *src_read != src_size && *dst_written != dst_size;
1032 (*src_read)++, (*dst_written)++, src++, dst++)
1035 if (*subst !=
'%') {
1037 }
else if (*dst_written < dst_size - 2) {
1039 *(++dst) = *(++subst);
1040 *(++dst) = *(++subst);
1063 (
const void* src_buf,
1071 unsigned char* src = (
unsigned char*) src_buf;
1072 unsigned char* dst = (
unsigned char*) dst_buf;
1076 if (!src_size || !dst_size || !dst || !src)
1079 for ( ; *src_read != src_size && *dst_written != dst_size;
1080 (*src_read)++, src++, dst++)
1082 unsigned char c = *src;
1083 unsigned char subst = 0;
1102 if (*dst_written + 2 > dst_size) {
1114 if (*dst_written + 4 > dst_size) {
1119 *(++dst) = (
unsigned char)(
'0' + v);
1121 *(++dst) = (
unsigned char)(
'0' + v);
1123 *(++dst) = (
unsigned char)(
'0' + v);
1145 (
const void* src_buf,
1153 char* src = (
char*) src_buf;
1154 char* dst = (
char*) dst_buf;
1158 if (!src_size || !dst_size || !dst || !src)
1161 for ( ; *src_read != src_size && *dst_written != dst_size;
1162 src++, (*src_read)++,
1163 dst++, (*dst_written)++)
1169 if (*dst_written + 2 > dst_size) {
1191 const char* p = path;
1196 for (s = p; *p; ++p ) {
1197 if ((*p ==
'/') || (*p ==
'\\') || (*p ==
':')) {
1199 while ((*p ==
'/') || (*p ==
'\\') || (*p ==
':')) {
1208 while ((p > s) && ((*--p ==
'/') || (*p ==
'\\')));
1221 #if defined(NCBI_OS_MSWIN)
1223 while ((p > s) && (*--p !=
'.'));
1319 static const char* log_path =
NULL;
1320 static const char kSectionName[] =
"[Web_dir_to_port]";
1324 char *line, *token, *p;
1325 int inside_section = 0 ;
1333 fp = fopen(
"/etc/toolkitrc",
"rt");
1340 line_size =
sizeof(
buf) - 1;
1343 while (fgets(line, (
int)line_size,
fp) !=
NULL)
1345 if (inside_section) {
1346 if (line[0] ==
'#') {
1350 if (line[0] ==
'[') {
1354 p = strchr(line,
'=');
1362 while ((p > line) && (*--p ==
' '));
1365 if (line[0] ==
'/') {
1386 while (*token ==
' ') token++;
1388 while (*p && !(*p ==
' ' || *p ==
'\n')) p++;
1400 if (memcmp(line, kSectionName,
sizeof(kSectionName)) >= 0) {
1440 #if NCBILOG_USE_FILE_DESCRIPTORS
1449 #if NCBILOG_USE_FILE_DESCRIPTORS
1458 #if NCBILOG_USE_FILE_DESCRIPTORS
1467 #if NCBILOG_USE_FILE_DESCRIPTORS
1502 #if NCBILOG_USE_FILE_DESCRIPTORS
1503 int flags = O_CREAT | O_APPEND | O_WRONLY;
1517 #if NCBILOG_USE_FILE_DESCRIPTORS
1528 #if NCBILOG_USE_FILE_DESCRIPTORS
1542 #if NCBILOG_USE_FILE_DESCRIPTORS
1556 #if NCBILOG_USE_FILE_DESCRIPTORS
1580 assert(path_with_base_name);
1582 n = strlen(path_with_base_name);
1584 assert((
n + 5 ) <=
sizeof(path));
1585 memcpy(path, path_with_base_name,
n);
1587 strcpy(path +
n,
".log");
1589 strcpy(path +
n,
".trace");
1591 strcpy(path +
n,
".err");
1593 strcpy(path +
n,
".perf");
1613 #if defined(NCBI_OS_UNIX)
1616 const char* filename =
NULL;
1630 int x_guid_hi, x_guid_lo;
1644 filelen = (size_t)nbuf;
1645 filename = filename_buf;
1649 #if defined(NCBI_OS_UNIX)
1663 filelen = (size_t)nbuf;
1664 filename = filename_buf;
1669 filelen = strlen(filename);
1674 assert((
n + 1 + filelen + 5) <=
sizeof(path));
1689 #if NCBILOG_USE_FILE_DESCRIPTORS
1702 -- use regular behavior with reopening user files as well
1807 #if defined(NCBI_OS_UNIX)
1808 cwd = getcwd(
NULL, 0);
1809 #elif defined(NCBI_OS_MSWIN)
1810 cwd = _getcwd(
NULL, 0);
1827 #if NCBILOG_USE_FILE_DESCRIPTORS
1840 #if NCBILOG_USE_FILE_DESCRIPTORS
1860 if (host && *host) {
1892 if (session && *session) {
1894 size_t len, r_len, w_len;
1895 len = strlen(session);
1907 if (hit_id && *hit_id) {
1910 size_t len, r_len, w_len;
1911 len = strlen(hit_id);
1943 if (use_logging_api) {
1953 hi = (
int)((uid >> 32) & 0xFFFFFFFF);
1954 lo = (
int) (uid & 0xFFFFFFFF);
1972 unsigned int b0, b1, b2, b3;
1974 unsigned long time_ns;
1988 b3 = (
unsigned int)((hi >> 32) & 0xFFFFFFFF);
1989 b2 = (
unsigned int)(hi & 0xFFFFFFFF);
1990 tid = (
s_GetTID() & 0xFFFFFF) << 40;
1994 us = (time_ns/1000/16) & 0xFFFF;
1996 lo = tid | rid | us;
1997 b1 = (
unsigned int)((lo >> 32) & 0xFFFFFFFF);
1998 b0 = (
unsigned int)(lo & 0xFFFFFFFF);
1999 n = sprintf(dst,
"%08X%08X%08X%08X", b3, b2, b1, b0);
2055 #if NCBILOG_USE_FILE_DESCRIPTORS
2059 const char* ptr = (
const char*)
buf;
2067 n_written = write(fd, ptr,
n);
2068 if (n_written == 0) {
2071 if ( n_written < 0 ) {
2072 if (errno == EINTR) {
2077 n -= (size_t)n_written;
2094 #if NCBILOG_USE_FILE_DESCRIPTORS
2133 #if NCBILOG_USE_FILE_DESCRIPTORS
2163 "NS",
"PB",
"P",
"PE",
"RB",
"R",
"RE"
2177 const char *x_state, *x_host, *x_client, *x_session, *x_appname;
2179 int x_guid_hi, x_guid_lo;
2220 x_rid =
ctx->rid ?
ctx->rid : 0;
2225 if (inside_request &&
ctx->is_client_set) {
2231 if (inside_request &&
ctx->is_session_set) {
2245 x_guid_hi, x_guid_lo,
2283 size_t len, r_len, w_len;
2290 if (!
key ||
key[0] ==
'\0') {
2329 if (params->
key[0] !=
'\0') {
2365 memcpy(dst + pos, params,
len);
2376 "Trace",
"Info",
"Warning",
"Error",
"Critical",
"Fatal"
2384 size_t pos, r_len, w_len;
2403 if (severity < sx_Info->post_level) {
2417 if (print_as_note) {
2447 size_t len, r_len, w_len;
2478 #if defined(NCBI_C_LOG_APPNAME)
2479 #define MACRO2STR_(x) #x
2480 #define MACRO2STR(x) MACRO2STR_(x)
2481 app = MACRO2STR(NCBI_C_LOG_APPNAME);
2483 app = (
char*)appname;
2486 if (!(app && *app)) {
2566 #if defined(NCBI_OS_MSWIN)
2567 int is_init = InterlockedCompareExchange(&
sx_IsInit, 1, 0);
2574 #elif defined(NCBI_OS_UNIX)
2697 #if !defined(NDEBUG)
2755 char* logfile =
NULL;
2763 const char* port_str = getenv(
"SERVER_PORT");
2764 if (port_str && *port_str) {
2766 unsigned long port = strtoul(port_str, &e, 10);
2779 logfile = getenv(
"NCBI_CONFIG__LOG__FILE");
2784 if (
strcmp(logfile,
"-") == 0) {
2803 const char* logfile = logfile_base;
2810 if (!logfile && !*logfile ) {
2816 if (
strcmp(logfile,
"-") == 0) {
2835 unsigned int port,
const char* logsite)
2837 char* logfile =
NULL;
2847 logfile = getenv(
"NCBI_CONFIG__LOG__FILE");
2852 if (
strcmp(logfile,
"-") == 0) {
2906 TROUBLE_MSG(
"NcbiLog_SetRequestId() can be used after NcbiLog_AppRun() only");
2955 ctx->is_client_set = 1;
2976 TROUBLE_MSG(
"NcbiLog_AppGetSession() can be used after NcbiLog_AppStart() only");
2996 if (
ctx->session[0]) {
3015 ctx->is_session_set = 1;
3036 ctx->is_session_set = 1;
3046 assert(hit_id && hit_id[0]);
3056 assert(subhit_id && subhit_id[0]);
3070 TROUBLE_MSG(
"NcbiLog_AppSetHitID() can be used before NcbiLog_App[Start/Run]() only");
3090 if ( !(
ctx->phid[0] &&
strcmp(
ctx->phid, hit_id) == 0) ) {
3122 TROUBLE_MSG(
"NcbiLog_AppGetHitID() can be used after NcbiLog_AppStart() only");
3158 char* hit_id =
NULL;
3159 unsigned int* sub_id =
NULL;
3161 size_t prefix_len = 0;
3168 prefix_len = strlen(
prefix);
3176 sub_id = &
ctx->phid_sub_id;
3189 if (need_increment) {
3193 if (*sub_id <= sx_Info->phid_sub_id_limit) {
3194 n = sprintf(
buf,
"%d", *sub_id);
3221 char* subhit_id =
NULL;
3229 TROUBLE_MSG(
"NcbiLog_GetCurrentSubHitID() can be used after NcbiLog_AppStart() only");
3247 char* subhit_id =
NULL;
3255 TROUBLE_MSG(
"NcbiLog_GetNextSubHitID() can be used after NcbiLog_AppStart() only");
3340 pos += (size_t) sprintf(
buf + pos,
"%-13s",
"start");
3345 for (
i = 0; argv[
i] !=
NULL; ++
i) {
3346 pos += (size_t) sprintf(
buf + pos,
" %s", argv[
i]);
3426 if (execution_time < 0) {
3430 if ( exit_signal ) {
3432 "stop", exit_status, execution_time, exit_signal);
3435 "stop", exit_status, execution_time);
3459 if (!
ctx->is_client_set) {
3463 ctx->is_client_set = 1;
3469 if (!
ctx->is_session_set) {
3478 ctx->is_session_set = 1;
3517 memset((
char*)ext, 0,
sizeof(ext));
3524 ext[ext_idx].
key =
"ncbi_role";
3534 ext[ext_idx].
key =
"ncbi_location";
3549 size_t prev, pos = 0;
3577 size_t prev, pos = 0;
3615 if (!
ctx->phid[0]) {
3656 "request-stop", status, timespan,
3657 (
unsigned long)bytes_rd, (
unsigned long)bytes_wr);
3665 ctx->client[0] =
'\0';
ctx->is_client_set = 0;
3666 ctx->session[0] =
'\0';
ctx->is_session_set = 0;
3667 ctx->phid[0] =
'\0';
ctx->phid_sub_id = 0;
3684 pos += (size_t) sprintf(
buf + pos,
"%-13s ",
"extra");
3705 pos += (size_t) sprintf(
buf + pos,
"%-13s ",
"extra");
3741 size_t pos, pos_prev;
3743 char* hit_id =
NULL;
3755 pos += (size_t) sprintf(
buf + pos,
"%-13s %d %f ",
"perf", status, timespan);
3785 size_t pos, pos_prev;
3787 char* hit_id =
NULL;
3799 pos += (size_t) sprintf(
buf + pos,
"%-13s %d %f ",
"perf", status, timespan);
3811 if (hit_id && hit_id[0]) {
3871 #if NCBILOG_USE_FILE_DESCRIPTORS
3910 if (
len > (
size_t)(ptr - line) + 5) {
3911 if (
strncmp(ptr,
"perf", 4) == 0) {
3914 if (
strncmp(ptr,
"Trace", 5) == 0 ||
3915 strncmp(ptr,
"Info" , 4) == 0) {
3934 #if NCBILOG_USE_FILE_DESCRIPTORS
3943 n = fprintf(
f,
"%s\n", line);
3956 #define kIdBufSize 128
3958 int old_guid_hi, old_guid_lo;
3966 #if defined(NCBI_OS_UNIX)
3968 #elif defined(NCBI_OS_MSWIN)
3971 if (old_pid == new_pid) {
4001 old_guid_hi, old_guid_lo, old_pid);
void(*)(CSeq_entry_Handle seh, IWorkbench *wb, const CSerialObject &obj) handler
static const char location[]
static void cleanup(void)
static const struct name_t names[]
static DLIST_TYPE *DLIST_NAME() prev(DLIST_LIST_TYPE *list, DLIST_TYPE *item)
char * NcbiLog_AppGetSession(void)
Get session ID (SID) for the whole application.
void NcbiLog_InitMT(const char *appname)
Version of NcbiLog_Init with default MT lock implementation.
TNcbiLog_UInt8 TNcbiLog_TID
ENcbiLog_Destination NcbiLog_SetDestinationFile(const char *logfile_base)
Variant of NcbiLog_SetDestination for logging to a specific file (eNcbiLog_File).
void NcbiLog_MTLock_Delete(TNcbiLog_MTLock lock)
Call cleanup action on the handler, then destroy it.
void NcbiLog_AppSetClient(const char *client)
Set client for the whole application.
void NcbiLog_AppSetSession(const char *session)
Set session ID (SID) for the whole application.
ENcbiLog_AppState NcbiLog_GetState(void)
Get current logging execution state (context and thread specific).
void NcbiLog_AppStopSignal(int exit_status, int exit_signal)
The same as NcbiLog_AppStop(), except it also accepts a signal number, if application exited due to a...
void NcbiLog_InitForAttachedContextST(const char *appname)
Version of NcbiLog_InitForAttachedContext() intended to use in single-threaded applications.
void NcbiLog_AppStop(int exit_status)
Should be called immediately prior to the application exit.
char * NcbiLog_GetCurrentSubHitID_Prefix(const char *prefix)
Get the last generated sub-hit ID.
ENcbiLog_MTLock_Action
The action passed to user defined MT lock handler.
void NcbiLog_Info(const char *msg)
Writes a message to the <appname>.trace file at level 'INFO'.
void NcbiLog_UpdateOnFork(TNcbiLog_OnForkFlags flags)
Update logging internal information after fork().
void NcbiLog_Extra(const SNcbiLog_Param *params)
Can be called at any time.
const char * NcbiLog_GetHostRole(void)
Get host role string.
void NcbiLog_SetHitID(const char *hit_id)
Set hit ID (HID, a.k.a.
TNcbiLog_Context NcbiLog_Context_Create(void)
Create new thread-specific logging context object.
ENcbiLog_Destination NcbiLog_SetDestination(ENcbiLog_Destination ds)
Set up diagnostics destination.
void NcbiLog_AppNewSession(void)
Auto-generate and then set brand-new application-wide session ID (SID).
void NcbiLog_ReqStart(const SNcbiLog_Param *params)
Should be called once application startup is complete, before any request processing code is run.
const char * NcbiLog_GetHostName(void)
Get host name.
void NcbiLog_Error(const char *msg)
Writes a message to the <appname>.err log at level 'ERROR'.
void NcbiLog_Context_Destroy(TNcbiLog_Context ctx)
Destroy context structure.
void NcbiLog_InitST(const char *appname)
Version of NcbiLog_Init to use in single-threaded applications.
void NcbiLog_SetRequestId(TNcbiLog_Counter rid)
Set current request ID (RID).
int NcbiLog_Default_MTLock_Handler(void *user_data_UNUSED, ENcbiLog_MTLock_Action action)
Default implementation of simple MT locking callback.
TNcbiLog_Counter NcbiLog_GetRequestId(void)
Get current request ID (RID).
ENcbiLog_AppState
Application execution states shown in the std prefix.
void NcbiLog_SetProcessId(TNcbiLog_PID pid)
Set process ID (PID).
TNcbiLog_UInt8 TNcbiLog_Counter
void NcbiLog_SetHost(const char *host)
Set the host name.
void NcbiLog_Context_Detach(void)
Detach logging context object from the C Logging API.
ENcbiLog_Destination
Where to write the application's diagnostics to.
void NcbiLog_NewSession(void)
Auto-generate and then set brand-new session ID (SID) for the request.
char * NcbiLog_GetCurrentSubHitID(void)
void NcbiLog_NewHitID(void)
ENcbiLog_Severity NcbiLog_SetPostLevel(ENcbiLog_Severity sev)
Set new posting severity threshold.
void NcbiLog_Destroy(void)
Destroy NcbiLog API.
char * NcbiLog_GetNextSubHitID(void)
char * NcbiLog_GetSession(void)
Get sessio ID (SID) for the request.
ENcbiLog_Severity
Severity level for the posted diagnostics.
TNcbiLog_UInt8 TNcbiLog_PID
Process, thread and counter types.
void NcbiLog_AppStart(const char *argv[])
Should be called as soon as possible during application initialization.
void NcbiLog_ReqStop(int status, size_t bytes_rd, size_t bytes_wr)
Should be called once request processing is complete.
void NcbiLog_SetSplitLogFile(int value)
Set split log files flag.
unsigned __int64 TNcbiLog_UInt8
void NcbiLog_FreeMemory(void *ptr)
Free memory allocated inside the C logging API.
void NcbiLog_Perf(int status, double timespan, const SNcbiLog_Param *params)
Can be called at any time.
void NcbiLog_SetClient(const char *client)
Set client for the request.
void NcbiLog_Warning(const char *msg)
Writes a message to the <appname>.err log at level 'WARNING'.
int TNcbiLog_OnForkFlags
Binary OR of "ENcbiLog_OnForkAction".
char * NcbiLog_AppGetHitID(void)
Get hit ID (HID, a.k.a.
ENcbiLog_MTLock_Ownership
Type of ownership for MT lock handle.
void NcbiLog_SetThreadId(TNcbiLog_TID tid)
Set thread ID (TID).
void NcbiLog_Fatal(const char *msg)
Writes a message to the <appname>.err log at level 'FATAL' and then terminate the application.
struct SNcbiLog_Context_tag * TNcbiLog_Context
void NcbiLog_InitForAttachedContext(const char *appname)
Version of NcbiLog_Init to use with NcbiLog_Context_* functions only.
void NcbiLog_Critical(const char *msg)
Writes a message to the <appname>.err log at level 'CRITICAL'.
void NcbiLog_Trace(const char *msg)
Writes a message to the <appname>.trace file at level 'TRACE'.
char * NcbiLog_GetHitID(void)
Get hit ID (HID, a.k.a.
int NcbiLog_Context_Attach(TNcbiLog_Context ctx)
Attach logging context object to the C Logging API.
char * NcbiLog_GetNextSubHitID_Prefix(const char *prefix)
Generate a sub-hit ID based on the currently effective (whether it's request-specific or application-...
void NcbiLog_Destroy_Thread(void)
Destroy thread-specific NcbiLog API information.
void NcbiLog_ReqRun(void)
Should be called once request processing initialization is complete.
int(* FNcbiLog_MTLock_Handler)(void *user_data, ENcbiLog_MTLock_Action action)
MT locking callback.
void NcbiLog_AppRun(void)
Should be called after the application is initialized and before its main part.
__int64 TNcbiLog_Int8
Big integer type.
TNcbiLog_MTLock NcbiLog_MTLock_Create(void *user_data, FNcbiLog_MTLock_Handler handler)
Create new MT lock.
void NcbiLog_SetTime(time_t time_sec, unsigned long time_ns)
Set the posting date and time.
const char * NcbiLog_GetHostLocation(void)
Get host location string.
void NcbiLog_AppSetHitID(const char *hit_id)
Set hit ID (HID, a.k.a.
#define NCBILOG_UINT8_FORMAT_SPEC
void NcbiLog_Init(const char *appname, TNcbiLog_MTLock mt_lock, ENcbiLog_MTLock_Ownership mt_lock_ownership)
Initializing NcbiLog API.
void NcbiLog_AppNewHitID(void)
void NcbiLog_Note(ENcbiLog_Severity severity, const char *msg)
Writes a message using "Note[X]" notation for severity.
void NcbiLog_SetSession(const char *session)
Set session ID (SID) for the request.
@ eNcbiLog_MT_Unlock
Unlock.
@ eNcbiLog_MT_Init
Init the locker (call first)
@ eNcbiLog_MT_Destroy
Unlock and cleanup (call last)
@ fNcbiLog_OnFork_ResetTimer
Reset execution timer.
@ fNcbiLog_OnFork_PrintStart
Log app-start.
@ eNcbiLog_NotSet
Reserved value, never used in messages.
@ eNcbiLog_RequestBegin
RB.
@ eNcbiLog_Disable
Don't write it anywhere.
@ eNcbiLog_Stdlog
Try /log/<*>/<appname>.log; fallback to .
@ eNcbiLog_File
To specific file, see NcbiLog_SetDestinationFile()
@ eNcbiLog_Stderr
To standard error stream.
@ eNcbiLog_Stdout
To standard output stream.
@ eNcbiLog_Default
Try /log/<*>/<appname>.log; fallback to STDERR.
@ eNcbiLog_Info
Informational message.
@ eNcbiLog_Fatal
Fatal error – guarantees exit (or abort)
@ eNcbiLog_Warning
Warning message.
@ eNcbiLog_Trace
Trace message.
@ eNcbiLog_Error
Error message.
@ eNcbiLog_Critical
Critical error message.
@ eNcbiLog_MT_TakeOwnership
NcbiLog API takes ownership of MT lock.
@ eNcbiLog_MT_NoOwnership
No ownership relationship.
@ eDiag_Trace
Trace message.
unsigned int
A callback function used to compare two keys in a database.
const struct ncbi::grid::netcache::search::fields::SIZE size
const struct ncbi::grid::netcache::search::fields::KEY key
int strncmp(const char *str1, const char *str2, size_t count)
int strcmp(const char *str1, const char *str2)
static TNcbiLog_UInt8 s_CreateUID(void)
Create unique process ID.
static volatile pthread_key_t sx_Tls
static volatile TNcbiLog_Info * sx_Info
TNcbiLog_Context NcbiLogP_GetContextPtr(void)
int NcbiLogP_DisableChecks(int disable)
Enable/disable internal checks (enabled by default) Used by ncbi_applog.
#define kMTLock_magic_number
static char * s_GetSubHitID(TNcbiLog_Context ctx, int need_increment, const char *prefix)
static const char * s_ReadFileString(const char *filename)
Read first string from specified file.
static void s_TlsDestroy(void)
static const char * s_ConcatPathEx(const char *p1, size_t p1_len, const char *p2, size_t p2_len, char *dst, size_t dst_size)
Concatenate two parts of the path for the current OS.
static const char * s_GetToolkitRCLogLocation()
Determine logs location on the base of TOOLKITRC_FILE.
static const unsigned char sx_EncodeTable[256][4]
void NcbiLogP_Raw(const char *line)
Post already prepared line in applog format to the applog.
static int s_IsInsideRequest(TNcbiLog_Context ctx)
const char * NcbiLogP_GetHitID_Env(void)
This routine is called during start up and again in NcbiLog_ReqStart().
const char * NcbiLogP_GenerateHitID(char *buf, size_t n, TNcbiLog_UInt8 uid)
Generate new Hit ID string.
static double s_DiffTime(const STime time_start, const STime time_end)
Get time difference, time_end >- time_start.
const char * NcbiLogP_GenerateSID(char *buf, size_t n, TNcbiLog_UInt8 uid)
Generate new SID string.
ENcbiLog_Destination NcbiLogP_SetDestination(ENcbiLog_Destination ds, unsigned int port, const char *logsite)
Variant of NcbiLog_SetDestination.
static void * s_TlsGetValue(void)
static volatile int sx_DisableChecks
static const char * sx_AppStateStr[]
#define CHECK_APP_START(ctx)
static pthread_mutex_t sx_MT_handle
static char * s_GenerateSID_Str(char *dst)
static void s_Init(const char *appname)
static TNcbiLog_Context s_GetContext(void)
Get pointer to the thread-specific context.
static int s_SetLogFilesDir(const char *dir, int is_applog)
(Re)Initialize logging file streams.
static char * s_GenerateHitID_Str_Ex(char *dst, int is_api_call, TNcbiLog_UInt8 uid)
static void s_URL_Encode(const void *src_buf, size_t src_size, size_t *src_read, void *dst_buf, size_t dst_size, size_t *dst_written)
URL-encode up to "src_size" symbols(bytes) from buffer "src_buf".
#define VERIFY_CATCH(expr)
static void s_SetState(TNcbiLog_Context ctx, ENcbiLog_AppState state)
Set application state – internal version without MT locking.
void NcbiLogP_ReqStartStr(const char *params)
Variant of NcbiLog_ReqStart, that use already prepared string with parameters.
static size_t s_PrintParamsStr(char *dst, size_t pos, const char *params)
Print parameters to message buffer (string version).
void NcbiLogP_ReInit(void)
static size_t s_ReqStart(TNcbiLog_Context ctx)
static void s_SetSession(char *dst, const char *session)
static const char * sx_SeverityStr[]
static void s_Abort(long line, const char *msg)
TNcbiLog_Info * NcbiLogP_GetInfoPtr(void)
static void s_Extra(TNcbiLog_Context ctx, const SNcbiLog_Param *params)
static int s_GetTime(STime *t)
Get current GMT time with nanoseconds (STime version)
static volatile int sx_IsEnabled
static volatile TNcbiLog_Context sx_ContextST
void NcbiLogP_AppStop(int exit_status, int exit_signal, double execution_time)
Should be called immediately prior to the application exit.
static void s_CloseLogFiles(int cleanup)
Close log files for a current destination.
static char * s_StrDup(const char *str)
strdup() doesn't exists on all platforms, and we cannot check this here.
static volatile TNcbiLog_PID sx_PID
static void s_TlsSetValue(void *ptr)
static void s_InitDestination(const char *logfile_path)
(Re)Initialize destination.
TNcbiLog_UInt8 NcbiLogP_GenerateUID(void)
Generate new unique process ID.
void NcbiLogP_ExtraStr(const char *params)
Variant of NcbiLog_Extra, that use already prepared string with parameters.
static int s_SetLogFiles(const char *path_with_base_name, int is_applog)
(Re)Initialize logging file streams.
static void s_ReportError(long line, const char *msg)
static char * s_GenerateHitID_Str(char *dst)
static TNcbiLog_PID s_GetPID(void)
Get current process ID.
static TNcbiLog_Context s_CreateContext(void)
Create thread-specific context.
static size_t s_Write(int fd, const void *buf, size_t count)
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.
static int s_OpenLogFiles(void)
Open file streams.
const char * NcbiLogP_GetSessionID_Env(void)
This routine is called during start up and again in NcbiLog_ReqStart().
static void s_AppStart(TNcbiLog_Context ctx, const char *argv[])
Print "start" message.
static struct TNcbiLog_MTLock_tag sx_MTLock_Default
static const char * s_GetClient_Env(void)
This routine is called during start up and again in NcbiLog_ReqStart().
static void s_SetClient(char *dst, const char *client)
void NcbiLogP_PerfStr(int status, double timespan, const char *params)
Variant of NcbiLog_Perf, that use already prepared string with parameters.
static void s_TlsInit(void)
static size_t s_PrintParamsPair(char *dst, size_t pos, const char *key, const char *value)
Print one parameter's pair (key, value) to message buffer.
static TNcbiLog_TID s_GetTID(void)
Get current thread ID.
static void s_LogHitID(TNcbiLog_Context ctx, const char *hit_id)
int NcbiLogP_GetEnv_UInt(const char *env_var_name, unsigned int *value)
Get value from numeric-based environment variables.
void s_SleepMicroSec(unsigned long mc_sec)
Sleep the specified number of microseconds.
static const char * kBaseLogDir
static void s_Post(TNcbiLog_Context ctx, ENcbiLog_DiagFile diag)
Post prepared message into the log.
static void s_LogSubHitID(TNcbiLog_Context ctx, const char *subhit_id)
static const char * s_ConcatPath(const char *p1, const char *p2, char *dst, size_t dst_size)
Concatenate two parts of the path (zero-terminated strings) for the current OS.
static char * s_GetAppBaseName(const char *path)
Get base name of application.
static void s_DestroyContext(void)
Destroy thread-specific context.
static void s_SetHost(const char *host)
static volatile TNcbiLog_MTLock sx_MTLock
void NcbiLogP_Raw2(const char *line, size_t len)
Variant of NcbiLogP_Raw with already known line size to avoid double length calculation.
static volatile int sx_MTLock_Own
static size_t s_PrintCommonPrefix(TNcbiLog_Context ctx)
Print common prefix to message buffer.
static size_t s_PrintReqStartExtraParams(size_t pos)
Print extra parameters for request start.
static int s_GetTimeStr(char *buf, time_t time_sec, unsigned long time_ns)
Get current local time in format 'YYYY-MM-DDThh:mm:ss.sss'.
static void s_PrintMessage(ENcbiLog_Severity severity, const char *msg, int print_as_note)
Print a message with severity to message buffer.
static int s_MTLock_Do(ENcbiLog_MTLock_Action action)
static int s_AddParamsPair(SNcbiLog_Param params[], int index, const char *key, const char *value)
Add parameters pair to the list if not empty.
static volatile int sx_IsInit
static int s_AttachContext(TNcbiLog_Context ctx)
Attach thread-specific context.
static int s_GetTimeT(time_t *time_sec, unsigned long *time_ns)
Update current UID with new timestamp.
static char * s_GenerateSID_Str_Ex(char *dst, int use_logging_api, TNcbiLog_UInt8 uid)
static void s_SetHitID(char *dst, const char *hit_id)
static size_t s_PrintParams(char *dst, size_t pos, const SNcbiLog_Param *params)
Print parameters to message buffer.
static void s_ExtraStr(TNcbiLog_Context ctx, const char *params)
static volatile int sx_TlsIsInit
#define NO_LOG
Logging going not to /log (local file, stderr, etc)
#define NCBILOG_HITID_MAX
#define NCBILOG_ENTRY_MIN
ENcbiLog_DiagFile
Type of file for the output.
#define NCBILOG_ENTRY_MAX
#define NCBILOG_CLIENT_MAX
#define CLOSE_FOR_REOPEN
Regular file closure for later reopeng.
#define NCBILOG_ENTRY_MAX_ALLOC
Maximum length of each log entry, all text after this position will be truncated.
#define kInvalidFileHandle
#define CLOSE_CLEANUP
Force logfiles cleanup.
#define NCBILOG_APPNAME_MAX
#define TO_LOG
Logging going to /log.
#define NCBILOG_SESSION_MAX
double f(double x_, const double &y_)
static const char * prefix[]
static CNamedPipeClient * client
static const char * str(char *buf, int n)
Application access log and error postings info structure (global).
unsigned int server_port
$SERVER_PORT on calling/current host
char * file_trace_name
Saved file names for log files.
char client[256+1]
App-wide client IP address (UNK_CLIENT if unknown)
ENcbiLog_Destination destination
Current logging destination.
TNcbiLog_Counter rid
Request ID (e.g.
const char * logsite
Pointer to logsite name.
const char * host_location
Host location (NULL if unknown or not set)
char * app_base_name
Pointer to application base name.
const char * host_role
Host role (NULL if unknown or not set)
TNcbiLog_PID pid
Process ID.
int remote_logging
1 if logging request is going from remote host
time_t last_reopen_time
Last reopen time for log files.
ENcbiLog_AppState state
Application state.
unsigned int phid_sub_id
App-wide sub-hit ID counter.
char * message
Buffer used to collect a message and log it.
ENcbiLog_Severity post_level
Posting level.
int phid_inherit
1 if PHID set explicitly and should be inherited (by requests)
char host[256+1]
Name of the host where the process runs (UNK_HOST if unknown)
int reuse_file_names
File names where not changed, reuse it.
int split_log_file
Split log files flag.
int user_posting_time
If 1 use post_time as is, and never change it.
unsigned int phid_sub_id_limit
Initializes from LOG_ISSUED_SUBHIT_LIMIT env variable.
int is_applog
1 if logging going to /log
char appname[3 *1024+1]
Name of the application (UNK_APP if unknown)
char * app_full_name
Pointer to a full application name (argv[0])
TNcbiLog_Counter psn
Serial number of the posting within the process.
TFileHandle file_trace
Saved files for log files.
char phid[3 *1024+1]
App-wide hit ID (empty string if unknown)
TNcbiLog_UInt8 guid
Globally unique process ID.
char session[3 *256+1]
App-wide session ID (UNK_SESSION if unknown)
STime app_start_time
Application start time.
STime post_time
GMT time at which the message was posted, use current time if it is not specified (equal to 0)
Thread-specific context data.
Structure to describe pairs 'key=value', used to posting parameters.
Application access log and error postings info structure.
unsigned long ns
Nanosecond part of the time.
unsigned int magic_number
Used internally to make sure it's init'd.
FNcbiLog_MTLock_Handler handler
Handler function.
void * user_data
For "handler()".