Coverage Report

Created: 2025-07-18 06:17

/src/logging-log4cxx/src/main/cpp/appenderattachableimpl.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
#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
4
{
35
4
}
Unexecuted instantiation: log4cxx::helpers::AppenderAttachableImpl::AppenderAttachableImpl()
log4cxx::helpers::AppenderAttachableImpl::AppenderAttachableImpl()
Line
Count
Source
34
4
{
35
4
}
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
4
{
46
47
4
}
48
49
void AppenderAttachableImpl::addAppender(const AppenderPtr newAppender)
50
525
{
51
  // Null values for newAppender parameter are strictly forbidden.
52
525
  if (!newAppender)
53
0
  {
54
0
    return;
55
0
  }
56
525
  if (!m_priv)
57
1
    m_priv = std::make_unique<AppenderAttachableImpl::priv_data>();
58
59
525
  std::lock_guard<std::mutex> lock( m_priv->m_mutex );
60
525
  AppenderList::iterator it = std::find(
61
525
      m_priv->appenderList.begin(), m_priv->appenderList.end(), newAppender);
62
63
525
  if (it == m_priv->appenderList.end())
64
525
  {
65
525
    m_priv->appenderList.push_back(newAppender);
66
525
  }
67
525
}
68
69
int AppenderAttachableImpl::appendLoopOnAppenders(
70
  const spi::LoggingEventPtr& event,
71
  Pool& p)
72
489k
{
73
489k
  int numberAppended = 0;
74
489k
  if (m_priv)
75
484k
  {
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
484k
    AppenderList allAppenders = getAllAppenders();
81
484k
    for (auto appender : allAppenders)
82
484k
    {
83
484k
      appender->doAppend(event, p);
84
484k
      numberAppended++;
85
484k
    }
86
484k
  }
87
88
489k
  return numberAppended;
89
489k
}
90
91
AppenderList AppenderAttachableImpl::getAllAppenders() const
92
487k
{
93
487k
  AppenderList result;
94
487k
  if (m_priv)
95
486k
  {
96
486k
    std::lock_guard<std::mutex> lock( m_priv->m_mutex );
97
486k
    result = m_priv->appenderList;
98
486k
  }
99
487k
  return result;
100
487k
}
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
1.05k
{
133
1.05k
  if (m_priv)
134
528
  {
135
528
    for (auto a : getAllAppenders())
136
2
      a->close();
137
528
    std::lock_guard<std::mutex> lock( m_priv->m_mutex );
138
528
    m_priv->appenderList.clear();
139
528
  }
140
1.05k
}
141
142
void AppenderAttachableImpl::removeAppender(const AppenderPtr appender)
143
525
{
144
525
  if (m_priv && appender)
145
525
  {
146
525
    std::lock_guard<std::mutex> lock( m_priv->m_mutex );
147
525
    auto it = std::find(m_priv->appenderList.begin(), m_priv->appenderList.end(), appender);
148
525
    if (it != m_priv->appenderList.end())
149
525
    {
150
525
      m_priv->appenderList.erase(it);
151
525
    }
152
525
  }
153
525
}
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