Coverage Report

Created: 2025-07-18 06:17

/src/logging-log4cxx/src/main/cpp/loglog.cpp
Line
Count
Source (jump to first uncovered line)
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
};
52
53
LogLog::LogLog() :
54
0
  m_priv(std::make_unique<LogLogPrivate>())
55
0
{
56
0
  LogString log4cxxDebug = OptionConverter::getSystemProperty(LOG4CXX_STR("LOG4CXX_DEBUG"), LOG4CXX_STR("false"));
57
0
  m_priv->debugEnabled = OptionConverter::toBoolean(log4cxxDebug, false);
58
0
}
59
60
LogLog::~LogLog()
61
0
{ m_priv.reset(); }
62
63
LogLog& LogLog::getInstance()
64
0
{
65
0
  static WideLife<LogLog> internalLogger;
66
67
0
  return internalLogger;
68
0
}
69
70
bool LogLog::isDebugEnabled()
71
0
{
72
0
  auto p = getInstance().m_priv.get();
73
0
  return p && !p->quietMode // Not deleted by onexit processing?
74
0
       && p->debugEnabled;
75
0
}
76
77
void LogLog::setInternalDebugging(bool debugEnabled1)
78
0
{
79
0
  auto p = getInstance().m_priv.get();
80
0
  if (p && !p->quietMode) // Not deleted by onexit processing?
81
0
    p->debugEnabled = debugEnabled1;
82
0
}
83
84
void LogLog::debug(const LogString& msg)
85
0
{
86
0
  auto p = getInstance().m_priv.get();
87
0
  if (p && !p->quietMode) // Not deleted by onexit processing?
88
0
  {
89
0
    if (!p->debugEnabled)
90
0
    {
91
0
      return;
92
0
    }
93
94
0
    std::lock_guard<std::mutex> lock(p->mutex);
95
96
0
    emit_log(msg);
97
0
  }
98
0
}
99
100
void LogLog::debug(const LogString& msg, const std::exception& e)
101
0
{
102
0
  auto p = getInstance().m_priv.get();
103
0
  if (p && !p->quietMode) // Not deleted by onexit processing?
104
0
  {
105
0
    if (!p->debugEnabled)
106
0
      return;
107
108
0
    std::lock_guard<std::mutex> lock(p->mutex);
109
0
    emit_log(msg);
110
0
    emit_log(e);
111
0
  }
112
0
}
113
114
115
void LogLog::error(const LogString& msg)
116
0
{
117
0
  auto p = getInstance().m_priv.get();
118
0
  if (p && !p->quietMode) // Not deleted by onexit processing?
119
0
  {
120
0
    std::lock_guard<std::mutex> lock(p->mutex);
121
122
0
    emit_log(msg);
123
0
  }
124
0
}
125
126
void LogLog::error(const LogString& msg, const std::exception& e)
127
0
{
128
0
  auto p = getInstance().m_priv.get();
129
0
  if (p && !p->quietMode) // Not deleted by onexit processing?
130
0
  {
131
0
    std::lock_guard<std::mutex> lock(p->mutex);
132
0
    emit_log(msg);
133
0
    emit_log(e);
134
0
  }
135
0
}
136
137
void LogLog::setQuietMode(bool quietMode1)
138
0
{
139
0
  auto p = getInstance().m_priv.get();
140
0
  std::lock_guard<std::mutex> lock(p->mutex);
141
142
0
  p->quietMode = quietMode1;
143
0
}
144
145
void LogLog::warn(const LogString& msg)
146
0
{
147
0
  auto p = getInstance().m_priv.get();
148
0
  if (p && !p->quietMode) // Not deleted by onexit processing?
149
0
  {
150
0
    std::lock_guard<std::mutex> lock(p->mutex);
151
0
    emit_log(msg);
152
0
  }
153
0
}
154
155
void LogLog::warn(const LogString& msg, const std::exception& e)
156
0
{
157
0
  auto p = getInstance().m_priv.get();
158
0
  if (p && !p->quietMode) // Not deleted by onexit processing?
159
0
  {
160
0
    std::lock_guard<std::mutex> lock(p->mutex);
161
0
    emit_log(msg);
162
0
    emit_log(e);
163
0
  }
164
0
}
165
166
void LogLog::emit_log(const LogString& msg)
167
0
{
168
0
  LogString out(LOG4CXX_STR("log4cxx: "));
169
170
0
  out.append(msg);
171
0
  out.append(1, (logchar) 0x0A);
172
173
0
  SystemErrWriter::write(out);
174
0
}
175
176
void LogLog::emit_log(const std::exception& ex)
177
0
{
178
0
  LogString out(LOG4CXX_STR("log4cxx: "));
179
0
  const char* raw = ex.what();
180
181
0
  if (raw != 0)
182
0
  {
183
0
    Transcoder::decode(raw, out);
184
0
  }
185
0
  else
186
0
  {
187
0
    out.append(LOG4CXX_STR("std::exception::what() == null"));
188
0
  }
189
190
0
  out.append(1, (logchar) 0x0A);
191
192
0
  SystemErrWriter::write(out);
193
0
}