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/appenderattachableimpl.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
#include <log4cxx/helpers/appenderattachableimpl.h>
18
#include <algorithm>
19
#include <mutex>
20
21
using namespace LOG4CXX_NS;
22
using namespace LOG4CXX_NS::helpers;
23
24
IMPLEMENT_LOG4CXX_OBJECT(AppenderAttachableImpl)
25
26
struct AppenderAttachableImpl::priv_data
27
{
28
  /** Array of appenders. */
29
  AppenderList  appenderList;
30
  mutable std::mutex m_mutex;
31
};
32
33
AppenderAttachableImpl::AppenderAttachableImpl()
34
6
{
35
6
}
Unexecuted instantiation: log4cxx::helpers::AppenderAttachableImpl::AppenderAttachableImpl()
log4cxx::helpers::AppenderAttachableImpl::AppenderAttachableImpl()
Line
Count
Source
34
6
{
35
6
}
36
37
#if LOG4CXX_ABI_VERSION <= 15
38
AppenderAttachableImpl::AppenderAttachableImpl(Pool& pool)
39
0
  : m_priv()
40
0
{
41
0
}
Unexecuted instantiation: log4cxx::helpers::AppenderAttachableImpl::AppenderAttachableImpl(log4cxx::helpers::Pool&)
Unexecuted instantiation: log4cxx::helpers::AppenderAttachableImpl::AppenderAttachableImpl(log4cxx::helpers::Pool&)
42
#endif
43
44
AppenderAttachableImpl::~AppenderAttachableImpl()
45
6
{
46
47
6
}
48
49
void AppenderAttachableImpl::addAppender(const AppenderPtr newAppender)
50
1.46k
{
51
  // Null values for newAppender parameter are strictly forbidden.
52
1.46k
  if (!newAppender)
53
0
  {
54
0
    return;
55
0
  }
56
1.46k
  if (!m_priv)
57
2
    m_priv = std::make_unique<AppenderAttachableImpl::priv_data>();
58
59
1.46k
  std::lock_guard<std::mutex> lock( m_priv->m_mutex );
60
1.46k
  AppenderList::iterator it = std::find(
61
1.46k
      m_priv->appenderList.begin(), m_priv->appenderList.end(), newAppender);
62
63
1.46k
  if (it == m_priv->appenderList.end())
64
1.46k
  {
65
1.46k
    m_priv->appenderList.push_back(newAppender);
66
1.46k
  }
67
1.46k
}
68
69
int AppenderAttachableImpl::appendLoopOnAppenders(
70
  const spi::LoggingEventPtr& event,
71
  Pool& p)
72
221k
{
73
221k
  int numberAppended = 0;
74
221k
  if (m_priv)
75
206k
  {
76
    // FallbackErrorHandler::error() may modify our list of appenders
77
    // while we are iterating over them (if it holds the same logger).
78
    // So, make a local copy of the appenders that we want to iterate over
79
    // before actually iterating over them.
80
206k
    AppenderList allAppenders = getAllAppenders();
81
206k
    for (auto appender : allAppenders)
82
206k
    {
83
206k
      appender->doAppend(event, p);
84
206k
      numberAppended++;
85
206k
    }
86
206k
  }
87
88
221k
  return numberAppended;
89
221k
}
90
91
AppenderList AppenderAttachableImpl::getAllAppenders() const
92
213k
{
93
213k
  AppenderList result;
94
213k
  if (m_priv)
95
210k
  {
96
210k
    std::lock_guard<std::mutex> lock( m_priv->m_mutex );
97
210k
    result = m_priv->appenderList;
98
210k
  }
99
213k
  return result;
100
213k
}
101
102
AppenderPtr AppenderAttachableImpl::getAppender(const LogString& name) const
103
0
{
104
0
  AppenderPtr result;
105
0
  if (m_priv && !name.empty())
106
0
  {
107
0
    std::lock_guard<std::mutex> lock( m_priv->m_mutex );
108
0
    for (auto appender : m_priv->appenderList)
109
0
    {
110
0
      if (name == appender->getName())
111
0
      {
112
0
        result = appender;
113
0
        break;
114
0
      }
115
0
    }
116
0
  }
117
0
  return result;
118
0
}
Unexecuted instantiation: log4cxx::helpers::AppenderAttachableImpl::getAppender(std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&) const
Unexecuted instantiation: log4cxx::helpers::AppenderAttachableImpl::getAppender(std::__1::basic_string<wchar_t, std::__1::char_traits<wchar_t>, std::__1::allocator<wchar_t> > const&) const
119
120
bool AppenderAttachableImpl::isAttached(const AppenderPtr appender) const
121
0
{
122
0
  bool result = false;
123
0
  if (m_priv && appender)
124
0
  {
125
0
    std::lock_guard<std::mutex> lock( m_priv->m_mutex );
126
0
    result = std::find(m_priv->appenderList.begin(), m_priv->appenderList.end(), appender) != m_priv->appenderList.end();
127
0
  }
128
0
  return result;
129
0
}
130
131
void AppenderAttachableImpl::removeAllAppenders()
132
2.94k
{
133
2.94k
  if (m_priv)
134
1.47k
  {
135
1.47k
    for (auto a : getAllAppenders())
136
2
      a->close();
137
1.47k
    std::lock_guard<std::mutex> lock( m_priv->m_mutex );
138
1.47k
    m_priv->appenderList.clear();
139
1.47k
  }
140
2.94k
}
141
142
void AppenderAttachableImpl::removeAppender(const AppenderPtr appender)
143
1.46k
{
144
1.46k
  if (m_priv && appender)
145
1.46k
  {
146
1.46k
    std::lock_guard<std::mutex> lock( m_priv->m_mutex );
147
1.46k
    auto it = std::find(m_priv->appenderList.begin(), m_priv->appenderList.end(), appender);
148
1.46k
    if (it != m_priv->appenderList.end())
149
1.46k
    {
150
1.46k
      m_priv->appenderList.erase(it);
151
1.46k
    }
152
1.46k
  }
153
1.46k
}
154
155
void AppenderAttachableImpl::removeAppender(const LogString& name)
156
0
{
157
0
  if (m_priv && !name.empty())
158
0
  {
159
0
    std::lock_guard<std::mutex> lock( m_priv->m_mutex );
160
0
    auto it = std::find_if(m_priv->appenderList.begin(), m_priv->appenderList.end()
161
0
      , [&name](const AppenderPtr& appender) -> bool
162
0
      {
163
0
        return name == appender->getName();
164
0
      });
Unexecuted instantiation: appenderattachableimpl.cpp:log4cxx::helpers::AppenderAttachableImpl::removeAppender(std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&)::$_0::operator()(std::__1::shared_ptr<log4cxx::Appender> const&) const
Unexecuted instantiation: appenderattachableimpl.cpp:log4cxx::helpers::AppenderAttachableImpl::removeAppender(std::__1::basic_string<wchar_t, std::__1::char_traits<wchar_t>, std::__1::allocator<wchar_t> > const&)::$_0::operator()(std::__1::shared_ptr<log4cxx::Appender> const&) const
165
0
    if (it != m_priv->appenderList.end())
166
0
      m_priv->appenderList.erase(it);
167
0
  }
168
0
}
Unexecuted instantiation: log4cxx::helpers::AppenderAttachableImpl::removeAppender(std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&)
Unexecuted instantiation: log4cxx::helpers::AppenderAttachableImpl::removeAppender(std::__1::basic_string<wchar_t, std::__1::char_traits<wchar_t>, std::__1::allocator<wchar_t> > const&)
169
170
bool AppenderAttachableImpl::replaceAppender(const AppenderPtr& oldAppender, const AppenderPtr& newAppender)
171
0
{
172
0
  bool found = false;
173
0
  if (m_priv && oldAppender && newAppender)
174
0
  {
175
0
    auto oldName = oldAppender->getName();
176
0
    std::lock_guard<std::mutex> lock( m_priv->m_mutex );
177
0
    auto it = std::find_if(m_priv->appenderList.begin(), m_priv->appenderList.end()
178
0
      , [&oldName](const AppenderPtr& appender) -> bool
179
0
      {
180
0
        return oldName == appender->getName();
181
0
      });
182
0
    if (it != m_priv->appenderList.end())
183
0
    {
184
0
      *it = newAppender;
185
0
      found = true;
186
0
    }
187
0
  }
188
0
  return found;
189
0
}
190
191
void AppenderAttachableImpl::replaceAppenders(const AppenderList& newList)
192
2
{
193
2
  auto oldAppenders = getAllAppenders();
194
2
  if (!m_priv)
195
2
    m_priv = std::make_unique<AppenderAttachableImpl::priv_data>();
196
2
  std::lock_guard<std::mutex> lock( m_priv->m_mutex );
197
2
  for (auto a : oldAppenders)
198
0
    a->close();
199
2
  m_priv->appenderList = newList;
200
2
}
201
202