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