Coverage Report

Created: 2025-10-10 06:53

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/systemerrwriter.h>
28
#include <log4cxx/helpers/optionconverter.h>
29
#include <mutex>
30
31
using namespace LOG4CXX_NS;
32
using namespace LOG4CXX_NS::helpers;
33
34
struct LogLog::LogLogPrivate {
35
  LogLogPrivate() :
36
0
    debugEnabled(false),
37
0
    quietMode(false){}
38
39
  ~LogLogPrivate()
40
0
  {
41
0
    quietMode = true; // Prevent output after deletion by onexit processing chain.
42
0
  }
43
44
  bool debugEnabled;
45
46
  /**
47
       In quietMode not even errors generate any output.
48
   */
49
  bool quietMode;
50
  std::mutex mutex;
51
  LogString errorPrefix;
52
  LogString warnPrefix;
53
  LogString debugPrefix;
54
  LogString suffix;
55
  void setColorEnabled(bool newValue)
56
0
  {
57
0
    if (newValue)
58
0
    {
59
0
      this->errorPrefix = LOG4CXX_STR("\x1B[31m"); //red
60
0
      this->warnPrefix = LOG4CXX_STR("\x1B[33m"); //yellow
61
0
      this->debugPrefix = LOG4CXX_STR("\x1B[32m"); //green
62
0
      this->suffix = LOG4CXX_STR("\x1B[0m"); // none
63
0
    }
64
0
    else
65
0
    {
66
0
      this->errorPrefix.clear();
67
0
      this->warnPrefix.clear();
68
0
      this->debugPrefix.clear();
69
0
      this->suffix.clear();
70
0
    }
71
0
  }
72
};
73
74
LogLog::LogLog() :
75
0
  m_priv(std::make_unique<LogLogPrivate>())
76
0
{
77
0
  LogString log4cxxDebug = OptionConverter::getSystemProperty(LOG4CXX_STR("LOG4CXX_DEBUG"), LOG4CXX_STR("false"));
78
0
  m_priv->debugEnabled = OptionConverter::toBoolean(log4cxxDebug, false);
79
0
  auto color = OptionConverter::getSystemProperty(LOG4CXX_STR("LOG4CXX_COLOR"), LOG4CXX_STR("true"));
80
0
  m_priv->setColorEnabled(OptionConverter::toBoolean(color, true));
81
0
}
82
83
LogLog::~LogLog()
84
0
{ m_priv.reset(); }
85
86
LogLog& LogLog::getInstance()
87
0
{
88
0
  static WideLife<LogLog> internalLogger;
89
90
0
  return internalLogger;
91
0
}
92
93
bool LogLog::isDebugEnabled()
94
0
{
95
0
  auto p = getInstance().m_priv.get();
96
0
  return p && !p->quietMode // Not deleted by onexit processing?
97
0
       && p->debugEnabled;
98
0
}
99
100
void LogLog::setInternalDebugging(bool debugEnabled1)
101
0
{
102
0
  auto p = getInstance().m_priv.get();
103
0
  if (p && !p->quietMode) // Not deleted by onexit processing?
104
0
    p->debugEnabled = debugEnabled1;
105
0
}
106
107
bool LogLog::isColorEnabled()
108
0
{
109
0
  auto p = getInstance().m_priv.get();
110
0
  return p && !p->errorPrefix.empty();
111
0
}
112
113
void LogLog::setColorEnabled(bool newValue)
114
0
{
115
0
  if (auto p = getInstance().m_priv.get())
116
0
    p->setColorEnabled(newValue);
117
0
}
118
119
void LogLog::debug(const LogString& msg)
120
0
{
121
0
  auto p = getInstance().m_priv.get();
122
0
  if (p && !p->quietMode) // Not deleted by onexit processing?
123
0
  {
124
0
    if (!p->debugEnabled)
125
0
    {
126
0
      return;
127
0
    }
128
129
0
    std::lock_guard<std::mutex> lock(p->mutex);
130
131
0
    emit_log(p->debugPrefix, msg, p->suffix);
132
0
  }
133
0
}
134
135
void LogLog::debug(const LogString& msg, const std::exception& e)
136
0
{
137
0
  auto p = getInstance().m_priv.get();
138
0
  if (p && !p->quietMode) // Not deleted by onexit processing?
139
0
  {
140
0
    if (!p->debugEnabled)
141
0
      return;
142
143
0
    std::lock_guard<std::mutex> lock(p->mutex);
144
0
    emit_log(p->debugPrefix, msg, p->suffix);
145
0
    emit_log(p->debugPrefix, e, p->suffix);
146
0
  }
147
0
}
148
149
150
void LogLog::error(const LogString& msg)
151
0
{
152
0
  auto p = getInstance().m_priv.get();
153
0
  if (p && !p->quietMode) // Not deleted by onexit processing?
154
0
  {
155
0
    std::lock_guard<std::mutex> lock(p->mutex);
156
157
0
    emit_log(p->errorPrefix, msg, p->suffix);
158
0
  }
159
0
}
160
161
void LogLog::error(const LogString& msg, const std::exception& e)
162
0
{
163
0
  auto p = getInstance().m_priv.get();
164
0
  if (p && !p->quietMode) // Not deleted by onexit processing?
165
0
  {
166
0
    std::lock_guard<std::mutex> lock(p->mutex);
167
0
    emit_log(p->errorPrefix, msg, p->suffix);
168
0
    emit_log(p->errorPrefix, e, p->suffix);
169
0
  }
170
0
}
171
172
void LogLog::setQuietMode(bool quietMode1)
173
0
{
174
0
  auto p = getInstance().m_priv.get();
175
0
  std::lock_guard<std::mutex> lock(p->mutex);
176
177
0
  p->quietMode = quietMode1;
178
0
}
179
180
void LogLog::warn(const LogString& msg)
181
0
{
182
0
  auto p = getInstance().m_priv.get();
183
0
  if (p && !p->quietMode) // Not deleted by onexit processing?
184
0
  {
185
0
    std::lock_guard<std::mutex> lock(p->mutex);
186
0
    emit_log(p->warnPrefix, msg, p->suffix);
187
0
  }
188
0
}
189
190
void LogLog::warn(const LogString& msg, const std::exception& e)
191
0
{
192
0
  auto p = getInstance().m_priv.get();
193
0
  if (p && !p->quietMode) // Not deleted by onexit processing?
194
0
  {
195
0
    std::lock_guard<std::mutex> lock(p->mutex);
196
0
    emit_log(p->warnPrefix, msg, p->suffix);
197
0
    emit_log(p->warnPrefix, e, p->suffix);
198
0
  }
199
0
}
200
201
void LogLog::emit_log(const LogString& prefix, const LogString& msg, const LogString& suffix)
202
0
{
203
0
  LogString out(LOG4CXX_STR("log4cxx: "));
204
0
  out.append(prefix);
205
0
  out.append(msg);
206
0
  out.append(suffix);
207
0
  out.append(1, (logchar) 0x0A);
208
209
0
  SystemErrWriter::write(out);
210
0
}
211
212
void LogLog::emit_log(const LogString& prefix, const std::exception& ex, const LogString& suffix)
213
0
{
214
0
  LogString out(LOG4CXX_STR("log4cxx: "));
215
0
  out.append(prefix);
216
0
  const char* raw = ex.what();
217
218
0
  if (raw != 0)
219
0
  {
220
0
    Transcoder::decode(raw, out);
221
0
  }
222
0
  else
223
0
  {
224
0
    out.append(LOG4CXX_STR("std::exception::what() == null"));
225
0
  }
226
227
0
  out.append(suffix);
228
0
  out.append(1, (logchar) 0x0A);
229
230
0
  SystemErrWriter::write(out);
231
0
}