Coverage Report

Created: 2026-05-30 06:57

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/logging-log4cxx/src/main/cpp/loglog.cpp
Line
Count
Source
1
/*
2
 * Licensed to the Apache Software Foundation (ASF) under one or more
3
 * contributor license agreements.  See the NOTICE file distributed with
4
 * this work for additional information regarding copyright ownership.
5
 * The ASF licenses this file to You under the Apache License, Version 2.0
6
 * (the "License"); you may not use this file except in compliance with
7
 * the License.  You may obtain a copy of the License at
8
 *
9
 *      http://www.apache.org/licenses/LICENSE-2.0
10
 *
11
 * Unless required by applicable law or agreed to in writing, software
12
 * distributed under the License is distributed on an "AS IS" BASIS,
13
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14
 * See the License for the specific language governing permissions and
15
 * limitations under the License.
16
 */
17
18
#include <log4cxx/logstring.h>
19
#include <log4cxx/helpers/loglog.h>
20
#include <log4cxx/helpers/transcoder.h>
21
#include <iostream>
22
#if !defined(LOG4CXX)
23
  #define LOG4CXX 1
24
#endif
25
#include <log4cxx/private/log4cxx_private.h>
26
#include <log4cxx/helpers/aprinitializer.h>
27
#include <log4cxx/helpers/date.h>
28
#include <log4cxx/helpers/stringhelper.h>
29
#include <log4cxx/helpers/systemerrwriter.h>
30
#include <log4cxx/helpers/optionconverter.h>
31
#include <mutex>
32
33
using namespace LOG4CXX_NS;
34
using namespace LOG4CXX_NS::helpers;
35
36
struct LogLog::LogLogPrivate {
37
  LogLogPrivate() :
38
0
    debugEnabled(false),
39
0
    quietMode(false){}
40
41
  ~LogLogPrivate()
42
0
  {
43
0
    quietMode = true; // Prevent output after deletion by onexit processing chain.
44
0
  }
45
46
  bool debugEnabled;
47
48
  /**
49
       In quietMode not even errors generate any output.
50
   */
51
  bool quietMode;
52
  std::mutex mutex;
53
  LogString errorPrefix;
54
  LogString warnPrefix;
55
  LogString debugPrefix;
56
  LogString suffix;
57
  void setColorEnabled(bool newValue)
58
0
  {
59
0
    if (newValue)
60
0
    {
61
0
      this->errorPrefix = LOG4CXX_STR("\x1B[31m"); //red
62
0
      this->warnPrefix = LOG4CXX_STR("\x1B[33m"); //yellow
63
0
      this->debugPrefix = LOG4CXX_STR("\x1B[32m"); //green
64
0
      this->suffix = LOG4CXX_STR("\x1B[0m"); // none
65
0
    }
66
0
    else
67
0
    {
68
0
      this->errorPrefix.clear();
69
0
      this->warnPrefix.clear();
70
0
      this->debugPrefix.clear();
71
0
      this->suffix.clear();
72
0
    }
73
0
  }
74
  LogString elapsedMicroseconds()
75
0
  {
76
0
    LogString result;
77
0
    auto microsecondInterval = Date::currentTime() - APRInitializer::getStartTime();
78
0
    StringHelper::toString(microsecondInterval, result);
79
0
    return result;
80
0
  }
81
};
82
83
LogLog::LogLog() :
84
0
  m_priv(std::make_unique<LogLogPrivate>())
85
0
{
86
0
  LogString log4cxxDebug = OptionConverter::getSystemProperty(LOG4CXX_STR("LOG4CXX_DEBUG"), LOG4CXX_STR("false"));
87
0
  m_priv->debugEnabled = OptionConverter::toBoolean(log4cxxDebug, false);
88
0
  auto color = OptionConverter::getSystemProperty(LOG4CXX_STR("LOG4CXX_COLOR"), LOG4CXX_STR("true"));
89
0
  m_priv->setColorEnabled(OptionConverter::toBoolean(color, true));
90
0
}
91
92
LogLog::~LogLog()
93
0
{ m_priv.reset(); }
94
95
LogLog& LogLog::getInstance()
96
0
{
97
0
  static WideLife<LogLog> internalLogger;
98
99
0
  return internalLogger;
100
0
}
101
102
bool LogLog::isDebugEnabled()
103
0
{
104
0
  auto p = getInstance().m_priv.get();
105
0
  return p && !p->quietMode // Not deleted by onexit processing?
106
0
       && p->debugEnabled;
107
0
}
108
109
bool LogLog::isDebugEnabledFor(const LoggerPtr& category)
110
0
{
111
0
  return isDebugEnabled() && category && category->isDebugEnabled();
112
0
}
113
114
bool LogLog::isTraceEnabledFor(const LoggerPtr& category)
115
0
{
116
0
  return isDebugEnabled() && category && category->isTraceEnabled();
117
0
}
118
119
void LogLog::setInternalDebugging(bool debugEnabled1)
120
0
{
121
0
  auto p = getInstance().m_priv.get();
122
0
  if (p && !p->quietMode) // Not deleted by onexit processing?
123
0
    p->debugEnabled = debugEnabled1;
124
0
}
125
126
bool LogLog::isColorEnabled()
127
0
{
128
0
  auto p = getInstance().m_priv.get();
129
0
  return p && !p->errorPrefix.empty();
130
0
}
131
132
void LogLog::setColorEnabled(bool newValue)
133
0
{
134
0
  if (auto p = getInstance().m_priv.get())
135
0
    p->setColorEnabled(newValue);
136
0
}
137
138
void LogLog::debug(const LogString& msg)
139
0
{
140
0
  auto p = getInstance().m_priv.get();
141
0
  if (p && !p->quietMode) // Not deleted by onexit processing?
142
0
  {
143
0
    if (!p->debugEnabled)
144
0
    {
145
0
      return;
146
0
    }
147
148
0
    std::lock_guard<std::mutex> lock(p->mutex);
149
0
    emit_log(p->debugPrefix, msg, p->suffix);
150
0
  }
151
0
}
152
153
void LogLog::debug(const LogString& msg, const std::exception& e)
154
0
{
155
0
  auto p = getInstance().m_priv.get();
156
0
  if (p && !p->quietMode) // Not deleted by onexit processing?
157
0
  {
158
0
    if (!p->debugEnabled)
159
0
      return;
160
161
0
    std::lock_guard<std::mutex> lock(p->mutex);
162
0
    emit_log(p->debugPrefix, msg, p->suffix);
163
0
    emit_log(p->debugPrefix, e, p->suffix);
164
0
  }
165
0
}
166
167
168
void LogLog::error(const LogString& msg)
169
0
{
170
0
  auto p = getInstance().m_priv.get();
171
0
  if (p && !p->quietMode) // Not deleted by onexit processing?
172
0
  {
173
0
    std::lock_guard<std::mutex> lock(p->mutex);
174
175
0
    emit_log(p->errorPrefix, msg, p->suffix);
176
0
  }
177
0
}
178
179
void LogLog::error(const LogString& msg, const std::exception& e)
180
0
{
181
0
  auto p = getInstance().m_priv.get();
182
0
  if (p && !p->quietMode) // Not deleted by onexit processing?
183
0
  {
184
0
    std::lock_guard<std::mutex> lock(p->mutex);
185
0
    emit_log(p->errorPrefix, msg, p->suffix);
186
0
    emit_log(p->errorPrefix, e, p->suffix);
187
0
  }
188
0
}
189
190
#if !LOG4CXX_LOGCHAR_IS_UTF8
191
void LogLog::trace(const LoggerPtr& category, const std::string& msg)
192
{
193
  LOG4CXX_DECODE_CHAR(lsMsg, msg);
194
  trace(category, lsMsg);
195
}
196
#endif
197
198
void LogLog::trace(const LoggerPtr& category, const LogString& msg)
199
0
{
200
0
  auto p = getInstance().m_priv.get();
201
0
  if (p && !p->quietMode) // Not deleted by onexit processing?
202
0
  {
203
0
    if (!p->debugEnabled)
204
0
    {
205
0
      return;
206
0
    }
207
208
0
    std::lock_guard<std::mutex> lock(p->mutex);
209
0
    emit_log(p->debugPrefix, p->elapsedMicroseconds() + LOG4CXX_STR(" ") + category->getName() + LOG4CXX_STR("::") + msg, p->suffix);
210
0
  }
211
0
}
212
213
void LogLog::setQuietMode(bool quietMode1)
214
0
{
215
0
  auto p = getInstance().m_priv.get();
216
0
  std::lock_guard<std::mutex> lock(p->mutex);
217
218
0
  p->quietMode = quietMode1;
219
0
}
220
221
void LogLog::warn(const LogString& msg)
222
0
{
223
0
  auto p = getInstance().m_priv.get();
224
0
  if (p && !p->quietMode) // Not deleted by onexit processing?
225
0
  {
226
0
    std::lock_guard<std::mutex> lock(p->mutex);
227
0
    emit_log(p->warnPrefix, msg, p->suffix);
228
0
  }
229
0
}
230
231
void LogLog::warn(const LogString& msg, const std::exception& e)
232
0
{
233
0
  auto p = getInstance().m_priv.get();
234
0
  if (p && !p->quietMode) // Not deleted by onexit processing?
235
0
  {
236
0
    std::lock_guard<std::mutex> lock(p->mutex);
237
0
    emit_log(p->warnPrefix, msg, p->suffix);
238
0
    emit_log(p->warnPrefix, e, p->suffix);
239
0
  }
240
0
}
241
242
void LogLog::emit_log(const LogString& prefix, const LogString& msg, const LogString& suffix)
243
0
{
244
0
  LogString out(LOG4CXX_STR("log4cxx: "));
245
0
  out.append(prefix);
246
0
  out.append(msg);
247
0
  out.append(suffix);
248
0
  out.append(1, (logchar) 0x0A);
249
250
0
  SystemErrWriter().write(out);
251
0
}
252
253
void LogLog::emit_log(const LogString& prefix, const std::exception& ex, const LogString& suffix)
254
0
{
255
0
  LogString out(LOG4CXX_STR("log4cxx: "));
256
0
  out.append(prefix);
257
0
  const char* raw = ex.what();
258
259
0
  if (raw != 0)
260
0
  {
261
0
    Transcoder::decode(raw, out);
262
0
  }
263
0
  else
264
0
  {
265
0
    out.append(LOG4CXX_STR("std::exception::what() == null"));
266
0
  }
267
268
0
  out.append(suffix);
269
0
  out.append(1, (logchar) 0x0A);
270
271
0
  SystemErrWriter().write(out);
272
0
}