1
2 /*
3 * Copyright (C) Igor Sysoev
4 * Copyright (C) NGINX, Inc.
5 */
6
7 #include <nxt_main.h>
8 #include <nxt_runtime.h>
9
10
11 static nxt_time_string_t nxt_log_error_time_cache;
12 static u_char *nxt_log_error_time(u_char *buf, nxt_realtime_t *now,
13 struct tm *tm, size_t size, const char *format);
14 static nxt_time_string_t nxt_log_debug_time_cache;
15 static u_char *nxt_log_debug_time(u_char *buf, nxt_realtime_t *now,
16 struct tm *tm, size_t size, const char *format);
17
18
19 void nxt_cdecl
nxt_log_time_handler(nxt_uint_t level,nxt_log_t * log,const char * fmt,...)20 nxt_log_time_handler(nxt_uint_t level, nxt_log_t *log, const char *fmt, ...)
21 {
22 u_char *p, *end;
23 #if 0
24 u_char *syslogmsg;
25 #endif
26 va_list args;
27 nxt_thread_t *thr;
28 nxt_time_string_t *time_cache;
29 u_char msg[NXT_MAX_ERROR_STR];
30
31 thr = nxt_thread();
32
33 end = msg + NXT_MAX_ERROR_STR;
34
35 time_cache = (log->level != NXT_LOG_DEBUG) ? &nxt_log_error_time_cache:
36 &nxt_log_debug_time_cache;
37
38 p = nxt_thread_time_string(thr, time_cache, msg);
39
40 #if 0
41 syslogmsg = p;
42 #endif
43
44 #if 0
45 nxt_fid_t fid;
46 const char *id;
47 nxt_fiber_t *fib;
48
49 fib = nxt_fiber_self(thr);
50
51 if (fib != NULL) {
52 id = "[%V] %PI#%PT#%PF ";
53 fid = nxt_fiber_id(fib);
54
55 } else {
56 id = "[%V] %PI#%PT ";
57 fid = 0;
58 }
59
60 p = nxt_sprintf(p, end, id, &nxt_log_levels[level], nxt_pid,
61 nxt_thread_tid(thr), fid);
62 #else
63 p = nxt_sprintf(p, end, "[%V] %PI#%PT ", &nxt_log_levels[level], nxt_pid,
64 nxt_thread_tid(thr));
65 #endif
66
67 if (log->ident != 0) {
68 p = nxt_sprintf(p, end, "*%D ", log->ident);
69 }
70
71 va_start(args, fmt);
72 p = nxt_vsprintf(p, end, fmt, args);
73 va_end(args);
74
75 if (level != NXT_LOG_DEBUG && log->ctx_handler != NULL) {
76 p = log->ctx_handler(log->ctx, p, end);
77 }
78
79 if (p > end - nxt_length("\n")) {
80 p = end - nxt_length("\n");
81 }
82
83 *p++ = '\n';
84
85 (void) nxt_write_console(nxt_stderr, msg, p - msg);
86
87 #if 0
88 if (level == NXT_LOG_ALERT) {
89 *(p - nxt_length("\n")) = '\0';
90
91 /*
92 * The syslog LOG_ALERT level is enough, because
93 * LOG_EMERG level broadcasts a message to all users.
94 */
95 nxt_write_syslog(LOG_ALERT, syslogmsg);
96 }
97 #endif
98 }
99
100
101 static nxt_time_string_t nxt_log_error_time_cache = {
102 (nxt_atomic_uint_t) -1,
103 nxt_log_error_time,
104 "%4d/%02d/%02d %02d:%02d:%02d ",
105 nxt_length("1970/09/28 12:00:00 "),
106 NXT_THREAD_TIME_LOCAL,
107 NXT_THREAD_TIME_SEC,
108 };
109
110
111 static u_char *
nxt_log_error_time(u_char * buf,nxt_realtime_t * now,struct tm * tm,size_t size,const char * format)112 nxt_log_error_time(u_char *buf, nxt_realtime_t *now, struct tm *tm, size_t size,
113 const char *format)
114 {
115 return nxt_sprintf(buf, buf + size, format,
116 tm->tm_year + 1900, tm->tm_mon + 1, tm->tm_mday,
117 tm->tm_hour, tm->tm_min, tm->tm_sec);
118 }
119
120
121 static nxt_time_string_t nxt_log_debug_time_cache = {
122 (nxt_atomic_uint_t) -1,
123 nxt_log_debug_time,
124 "%4d/%02d/%02d %02d:%02d:%02d.%03d ",
125 nxt_length("1970/09/28 12:00:00.000 "),
126 NXT_THREAD_TIME_LOCAL,
127 NXT_THREAD_TIME_MSEC,
128 };
129
130
131 static u_char *
nxt_log_debug_time(u_char * buf,nxt_realtime_t * now,struct tm * tm,size_t size,const char * format)132 nxt_log_debug_time(u_char *buf, nxt_realtime_t *now, struct tm *tm, size_t size,
133 const char *format)
134 {
135 return nxt_sprintf(buf, buf + size, format,
136 tm->tm_year + 1900, tm->tm_mon + 1, tm->tm_mday,
137 tm->tm_hour, tm->tm_min, tm->tm_sec,
138 now->nsec / 1000000);
139 }
140