2 * Copyright 2008, Google Inc.
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are
9 * * Redistributions of source code must retain the above copyright
10 * notice, this list of conditions and the following disclaimer.
11 * * Redistributions in binary form must reproduce the above
12 * copyright notice, this list of conditions and the following disclaimer
13 * in the documentation and/or other materials provided with the
15 * * Neither the name of Google Inc. nor the names of its
16 * contributors may be used to endorse or promote products derived from
17 * this software without specific prior written permission.
19 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
20 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
21 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
22 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
23 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
24 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
25 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
26 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
27 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
28 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
29 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
33 * NaCl Server Runtime logging code.
35 #include "native_client/include/portability.h"
41 #define NON_THREAD_SAFE_DETAIL_CHECK 1
43 * If set, check detail_level without grabbing a mutex. This makes
44 * logging much cheaper, but implies that the verbosity level should
45 * only be changed prior to going multithreaded.
48 #include "native_client/service_runtime/gio.h"
49 #include "native_client/service_runtime/nacl_sync.h"
50 #include "native_client/service_runtime/nacl_log.h"
51 #include "native_client/service_runtime/nacl_threads.h"
52 #include "native_client/service_runtime/nacl_timestamp.h"
54 static struct NaClMutex log_mu
;
56 static int verbosity
= 0;
57 static struct Gio
*log_stream
= NULL
;
58 static struct GioFile log_file_stream
;
59 static int timestamp_enabled
= 1;
61 void NaClLogModuleInit()
63 NaClMutexCtor(&log_mu
);
66 void NaClLogModuleFini()
68 NaClMutexDtor(&log_mu
);
73 NaClMutexLock(&log_mu
);
76 void NaClLogUnlock(void)
78 NaClMutexUnlock(&log_mu
);
81 static INLINE
struct Gio
*NaClLogGetGio_mu()
83 if (NULL
== log_stream
) {
84 (void) GioFileRefCtor(&log_file_stream
, stderr
);
85 log_stream
= (struct Gio
*) &log_file_stream
;
90 void NaClLogSetVerbosity(int verb
)
97 void NaClLogIncrVerbosity(void)
104 int NaClLogGetVerbosity(void)
115 void NaClLogSetGio(struct Gio
*stream
)
118 if (NULL
!= log_stream
) {
119 (void) (*log_stream
->vtbl
->Flush
)(log_stream
);
125 struct Gio
*NaClLogGetGio(void)
130 s
= NaClLogGetGio_mu();
136 void NaClLogEnableTimestamp(void)
138 timestamp_enabled
= 1;
141 void NaClLogDisableTimestamp(void)
143 timestamp_enabled
= 0;
147 * Output a printf-style formatted message if the log verbosity level
148 * is set higher than the log output's detail level. Note that since
149 * this is not a macro, log message arguments that have side effects
150 * will have their side effects regardless of whether the
151 * corresponding log message is printed or not. This is good from a
152 * consistency point of view, but it means that should a logging
153 * argument be expensive to compute, the log statement needs to be
154 * surrounded by something like
156 * if (detail_level <= NaClLogGetVerbosity()) {
157 * NaClLog(detail_level, "format string", expensive_arg(), ...);
160 * The log message, if written, is prepended by a microsecond
161 * resolution timestamp on linux and a millisecond resolution
162 * timestamp on windows. This means that if the NaCl app can read its
163 * own logs, it can distinguish which host OS it is running on.
165 void NaClLogV_mu(int detail_level
,
172 s
= NaClLogGetGio_mu();
174 if (detail_level
<= verbosity
) {
175 if (timestamp_enabled
) {
178 gprintf(s
, "[%d,%u:%s] ",
181 NaClTimeStampString(timestamp
, sizeof timestamp
));
184 (void) gvprintf(s
, fmt
, ap
);
185 (void) (*s
->vtbl
->Flush
)(s
);
188 if (LOG_FATAL
== detail_level
) {
193 void NaClLogV(int detail_level
,
197 #if NON_THREAD_SAFE_DETAIL_CHECK
198 if (detail_level
> verbosity
) {
203 NaClLogV_mu(detail_level
, fmt
, ap
);
207 void NaClLog(int detail_level
,
213 #if NON_THREAD_SAFE_DETAIL_CHECK
214 if (detail_level
> verbosity
) {
221 NaClLogV_mu(detail_level
, fmt
, ap
);