Coverage Report

Created: 2025-07-01 06:08

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