1 // Module: Log4CPLUS
2 // File: loglog.cxx
3 // Created: 6/2001
4 // Author: Tad E. Smith
5 //
6 //
7 // Copyright 2001-2010 Tad E. Smith
8 //
9 // Licensed under the Apache License, Version 2.0 (the "License");
10 // you may not use this file except in compliance with the License.
11 // You may obtain a copy of the License at
12 //
13 // http://www.apache.org/licenses/LICENSE-2.0
14 //
15 // Unless required by applicable law or agreed to in writing, software
16 // distributed under the License is distributed on an "AS IS" BASIS,
17 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
18 // See the License for the specific language governing permissions and
19 // limitations under the License.
20
21 #include "dcmtk/oflog/streams.h"
22 #include "dcmtk/oflog/helpers/loglog.h"
23 #include "dcmtk/oflog/thread/syncpub.h"
24 #include "dcmtk/oflog/thread/threads.h"
25 #include "dcmtk/oflog/internal/env.h"
26 #include "dcmtk/oflog/consap.h"
27 #include <ostream>
28 #include <stdexcept>
29
30
31 namespace dcmtk {
32 namespace log4cplus { namespace helpers {
33
34 namespace
35 {
36
37 static tchar const PREFIX[] = DCMTK_LOG4CPLUS_TEXT("log4cplus: ");
38 static tchar const WARN_PREFIX[] = DCMTK_LOG4CPLUS_TEXT("log4cplus:WARN ");
39 static tchar const ERR_PREFIX[] = DCMTK_LOG4CPLUS_TEXT("log4cplus:ERROR ");
40
41 } // namespace
42
43
44 LogLog *
getLogLog()45 LogLog::getLogLog()
46 {
47 return &helpers::getLogLog ();
48 }
49
50
LogLog()51 LogLog::LogLog()
52 : debugEnabled(TriUndef)
53 , quietMode(TriUndef)
54 , mutex()
55 { }
56
57
~LogLog()58 LogLog::~LogLog()
59 { }
60
61
62 void
setInternalDebugging(bool enabled)63 LogLog::setInternalDebugging(bool enabled)
64 {
65 thread::MutexGuard guard (mutex);
66
67 debugEnabled = enabled ? TriTrue : TriFalse;
68 }
69
70
71 void
setQuietMode(bool quietModeVal)72 LogLog::setQuietMode(bool quietModeVal)
73 {
74 thread::MutexGuard guard (mutex);
75
76 quietMode = quietModeVal ? TriTrue : TriFalse;
77 }
78
79
80 void
debug(const log4cplus::tstring & msg) const81 LogLog::debug(const log4cplus::tstring& msg) const
82 {
83 logging_worker (tcout, &LogLog::get_debug_mode, PREFIX, msg.c_str());
84 }
85
86
87 void
debug(tchar const * msg) const88 LogLog::debug(tchar const * msg) const
89 {
90 logging_worker (tcout, &LogLog::get_debug_mode, PREFIX, msg);
91 }
92
93
94 void
warn(const log4cplus::tstring & msg) const95 LogLog::warn(const log4cplus::tstring& msg) const
96 {
97 logging_worker (tcerr, &LogLog::get_not_quiet_mode, WARN_PREFIX, msg.c_str());
98 }
99
100
101 void
warn(tchar const * msg) const102 LogLog::warn(tchar const * msg) const
103 {
104 logging_worker (tcerr, &LogLog::get_not_quiet_mode, WARN_PREFIX, msg);
105 }
106
107
108 void
error(const log4cplus::tstring & msg,bool throw_flag) const109 LogLog::error(const log4cplus::tstring& msg, bool throw_flag) const
110 {
111 logging_worker (tcerr, &LogLog::get_not_quiet_mode, ERR_PREFIX, msg.c_str(),
112 throw_flag);
113 }
114
115
116 void
error(tchar const * msg,bool throw_flag) const117 LogLog::error(tchar const * msg, bool throw_flag) const
118 {
119 logging_worker (tcerr, &LogLog::get_not_quiet_mode, ERR_PREFIX, msg,
120 throw_flag);
121 }
122
123
124 bool
get_quiet_mode() const125 LogLog::get_quiet_mode () const
126 {
127 if (quietMode == TriUndef)
128 set_tristate_from_env (&quietMode,
129 DCMTK_LOG4CPLUS_TEXT ("DCMTK_LOG4CPLUS_LOGLOG_QUIETMODE"));
130
131 return quietMode == TriTrue;
132 }
133
134
135 bool
get_not_quiet_mode() const136 LogLog::get_not_quiet_mode () const
137 {
138 return ! get_quiet_mode ();
139 }
140
141
142 bool
get_debug_mode() const143 LogLog::get_debug_mode () const
144 {
145 if (debugEnabled == TriUndef)
146 set_tristate_from_env (&debugEnabled,
147 DCMTK_LOG4CPLUS_TEXT ("DCMTK_LOG4CPLUS_LOGLOG_DEBUGENABLED"));
148
149 return debugEnabled && ! get_quiet_mode ();
150 }
151
152
153 void
set_tristate_from_env(TriState * result,tchar const * envvar_name)154 LogLog::set_tristate_from_env (TriState * result, tchar const * envvar_name)
155 {
156 tstring envvar_value;
157 bool exists = internal::get_env_var (envvar_value, envvar_name);
158 bool value = false;
159 if (exists && internal::parse_bool (value, envvar_value) && value)
160 *result = TriTrue;
161 else
162 *result = TriFalse;
163 }
164
165
166 void
logging_worker(tostream & os,bool (LogLog::* cond)()const,tchar const * prefix,tchar const * msg,bool throw_flag) const167 LogLog::logging_worker (tostream & os, bool (LogLog:: * cond) () const,
168 tchar const * prefix, tchar const * msg, bool throw_flag) const
169 {
170 bool output;
171 {
172 thread::MutexGuard guard (mutex);
173 output = (this->*cond) ();
174 }
175
176 if (DCMTK_LOG4CPLUS_UNLIKELY (output))
177 {
178 // XXX This is potential recursive lock of
179 // ConsoleAppender::outputMutex.
180 thread::MutexGuard outputGuard (ConsoleAppender::getOutputMutex ());
181 os << prefix << msg << OFendl;
182 }
183
184 if (DCMTK_LOG4CPLUS_UNLIKELY (throw_flag))
185 throw STD_NAMESPACE runtime_error (DCMTK_LOG4CPLUS_TSTRING_TO_STRING (msg));
186 }
187
188
189 } } // namespace log4cplus { namespace helpers {
190 } // end namespace dcmtk
191