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"
43 # include <sys/types.h>
47 #define NON_THREAD_SAFE_DETAIL_CHECK 1
49 * If set, check detail_level without grabbing a mutex. This makes
50 * logging much cheaper, but implies that the verbosity level should
51 * only be changed prior to going multithreaded.
54 #include "native_client/service_runtime/gio.h"
55 #include "native_client/service_runtime/nacl_sync.h"
56 #include "native_client/service_runtime/nacl_log.h"
57 #include "native_client/service_runtime/nacl_threads.h"
58 #include "native_client/service_runtime/nacl_timestamp.h"
60 static struct NaClMutex log_mu
;
62 static int verbosity
= 0;
63 static struct Gio
*log_stream
= NULL
;
64 static struct GioFile log_file_stream
;
65 static int timestamp_enabled
= 1;
67 void NaClLogModuleInit()
69 NaClMutexCtor(&log_mu
);
72 void NaClLogModuleFini()
74 NaClMutexDtor(&log_mu
);
77 INLINE
void NaClLogLock()
79 NaClMutexLock(&log_mu
);
82 INLINE
void NaClLogUnlock(void)
84 NaClMutexUnlock(&log_mu
);
87 static INLINE
struct Gio
*NaClLogGetGio_mu()
89 if (NULL
== log_stream
) {
90 (void) GioFileRefCtor(&log_file_stream
, stderr
);
91 log_stream
= (struct Gio
*) &log_file_stream
;
96 void NaClLogSetVerbosity(int verb
)
103 void NaClLogIncrVerbosity(void)
110 int NaClLogGetVerbosity(void)
121 void NaClLogSetGio(struct Gio
*stream
)
124 if (NULL
!= log_stream
) {
125 (void) (*log_stream
->vtbl
->Flush
)(log_stream
);
131 struct Gio
*NaClLogGetGio(void)
136 s
= NaClLogGetGio_mu();
142 void NaClLogEnableTimestamp(void)
144 timestamp_enabled
= 1;
147 void NaClLogDisableTimestamp(void)
149 timestamp_enabled
= 0;
153 * Output a printf-style formatted message if the log verbosity level
154 * is set higher than the log output's detail level. Note that since
155 * this is not a macro, log message arguments that have side effects
156 * will have their side effects regardless of whether the
157 * corresponding log message is printed or not. This is good from a
158 * consistency point of view, but it means that should a logging
159 * argument be expensive to compute, the log statement needs to be
160 * surrounded by something like
162 * if (detail_level <= NaClLogGetVerbosity()) {
163 * NaClLog(detail_level, "format string", expensive_arg(), ...);
166 * The log message, if written, is prepended by a microsecond
167 * resolution timestamp on linux and a millisecond resolution
168 * timestamp on windows. This means that if the NaCl app can read its
169 * own logs, it can distinguish which host OS it is running on.
171 void NaClLogV_mu(int detail_level
,
178 s
= NaClLogGetGio_mu();
180 if (detail_level
<= verbosity
) {
181 if (timestamp_enabled
) {
188 gprintf(s
, "[%d,%u:%s] ",
191 NaClTimeStampString(timestamp
, sizeof timestamp
));
194 (void) gvprintf(s
, fmt
, ap
);
195 (void) (*s
->vtbl
->Flush
)(s
);
198 if (LOG_FATAL
== detail_level
) {
203 void NaClLogV(int detail_level
,
207 #if NON_THREAD_SAFE_DETAIL_CHECK
208 if (detail_level
> verbosity
) {
213 NaClLogV_mu(detail_level
, fmt
, ap
);
217 void NaClLog(int detail_level
,
223 #if NON_THREAD_SAFE_DETAIL_CHECK
224 if (detail_level
> verbosity
) {
231 NaClLogV_mu(detail_level
, fmt
, ap
);