1 // Module: Log4CPLUS
2 // File: loglog.cxx
3 // Created: 6/2001
4 // Author: Tad E. Smith
5 //
6 //
7 // Copyright 2001-2013 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 <log4cplus/streams.h>
22 #include <log4cplus/helpers/loglog.h>
23 #include <log4cplus/thread/syncprims-pub-impl.h>
24 #include <log4cplus/thread/threads.h>
25 #include <log4cplus/internal/env.h>
26 #include <log4cplus/consoleappender.h>
27 #include <ostream>
28 #include <stdexcept>
29
30
31 namespace log4cplus { namespace helpers {
32
33 namespace
34 {
35
36 static tchar const PREFIX[] = LOG4CPLUS_TEXT("log4cplus: ");
37 static tchar const WARN_PREFIX[] = LOG4CPLUS_TEXT("log4cplus:WARN ");
38 static tchar const ERR_PREFIX[] = LOG4CPLUS_TEXT("log4cplus:ERROR ");
39
40 } // namespace
41
42
43 LogLog *
getLogLog()44 LogLog::getLogLog()
45 {
46 return &helpers::getLogLog ();
47 }
48
49
LogLog()50 LogLog::LogLog()
51 : debugEnabled(TriUndef)
52 , quietMode(TriUndef)
53 { }
54
55
~LogLog()56 LogLog::~LogLog()
57 { }
58
59
60 void
setInternalDebugging(bool enabled)61 LogLog::setInternalDebugging(bool enabled)
62 {
63 thread::MutexGuard guard (mutex);
64
65 debugEnabled = enabled ? TriTrue : TriFalse;
66 }
67
68
69 void
setQuietMode(bool quietModeVal)70 LogLog::setQuietMode(bool quietModeVal)
71 {
72 thread::MutexGuard guard (mutex);
73
74 quietMode = quietModeVal ? TriTrue : TriFalse;
75 }
76
77
78 void
debug(const log4cplus::tstring & msg) const79 LogLog::debug(const log4cplus::tstring& msg) const
80 {
81 logging_worker (tcout, &LogLog::get_debug_mode, PREFIX, msg);
82 }
83
84
85 void
debug(tchar const * msg) const86 LogLog::debug(tchar const * msg) const
87 {
88 logging_worker (tcout, &LogLog::get_debug_mode, PREFIX, msg);
89 }
90
91
92 void
warn(const log4cplus::tstring & msg) const93 LogLog::warn(const log4cplus::tstring& msg) const
94 {
95 logging_worker (tcerr, &LogLog::get_not_quiet_mode, WARN_PREFIX, msg);
96 }
97
98
99 void
warn(tchar const * msg) const100 LogLog::warn(tchar const * msg) const
101 {
102 logging_worker (tcerr, &LogLog::get_not_quiet_mode, WARN_PREFIX, msg);
103 }
104
105
106 void
error(const log4cplus::tstring & msg,bool throw_flag) const107 LogLog::error(const log4cplus::tstring& msg, bool throw_flag) const
108 {
109 logging_worker (tcerr, &LogLog::get_not_quiet_mode, ERR_PREFIX, msg,
110 throw_flag);
111 }
112
113
114 void
error(tchar const * msg,bool throw_flag) const115 LogLog::error(tchar const * msg, bool throw_flag) const
116 {
117 logging_worker (tcerr, &LogLog::get_not_quiet_mode, ERR_PREFIX, msg,
118 throw_flag);
119 }
120
121
122 bool
get_quiet_mode() const123 LogLog::get_quiet_mode () const
124 {
125 if (quietMode == TriUndef)
126 set_tristate_from_env (&quietMode,
127 LOG4CPLUS_TEXT ("LOG4CPLUS_LOGLOG_QUIETMODE"));
128
129 return quietMode == TriTrue;
130 }
131
132
133 bool
get_not_quiet_mode() const134 LogLog::get_not_quiet_mode () const
135 {
136 return ! get_quiet_mode ();
137 }
138
139
140 bool
get_debug_mode() const141 LogLog::get_debug_mode () const
142 {
143 if (debugEnabled == TriUndef)
144 set_tristate_from_env (&debugEnabled,
145 LOG4CPLUS_TEXT ("LOG4CPLUS_LOGLOG_DEBUGENABLED"));
146
147 return debugEnabled && ! get_quiet_mode ();
148 }
149
150
151 void
set_tristate_from_env(TriState * result,tchar const * envvar_name)152 LogLog::set_tristate_from_env (TriState * result, tchar const * envvar_name)
153 {
154 tstring envvar_value;
155 bool exists = internal::get_env_var (envvar_value, envvar_name);
156 bool value = false;
157 if (exists && internal::parse_bool (value, envvar_value) && value)
158 *result = TriTrue;
159 else
160 *result = TriFalse;
161 }
162
163
164 template <typename StringType>
165 void
logging_worker(tostream & os,bool (LogLog::* cond)()const,tchar const * prefix,StringType const & msg,bool throw_flag) const166 LogLog::logging_worker (tostream & os, bool (LogLog:: * cond) () const,
167 tchar const * prefix, StringType const & msg, bool throw_flag) const
168 {
169 bool output;
170 {
171 thread::MutexGuard guard (mutex);
172 output = (this->*cond) ();
173 }
174
175 if (LOG4CPLUS_UNLIKELY (output))
176 {
177 // XXX This is potential recursive lock of
178 // ConsoleAppender::outputMutex.
179 thread::MutexGuard outputGuard (ConsoleAppender::getOutputMutex ());
180 os << prefix << msg << std::endl;
181 }
182
183 if (LOG4CPLUS_UNLIKELY (throw_flag))
184 throw std::runtime_error (LOG4CPLUS_TSTRING_TO_STRING (msg));
185 }
186
187
188 } } // namespace log4cplus { namespace helpers {
189