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