Coverage Report

Created: 2026-05-30 06:57

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/logging-log4cxx/src/main/cpp/fallbackerrorhandler.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/varia/fallbackerrorhandler.h>
19
#include <log4cxx/helpers/loglog.h>
20
#include <log4cxx/helpers/stringhelper.h>
21
#include <log4cxx/hierarchy.h>
22
#include <log4cxx/logmanager.h>
23
#if LOG4CXX_ABI_VERSION <= 15
24
#include <log4cxx/logger.h>
25
#include <log4cxx/asyncappender.h>
26
#endif
27
#include <list>
28
29
using namespace LOG4CXX_NS;
30
using namespace LOG4CXX_NS::helpers;
31
using namespace LOG4CXX_NS::spi;
32
using namespace LOG4CXX_NS::varia;
33
34
IMPLEMENT_LOG4CXX_OBJECT(FallbackErrorHandler)
35
36
struct FallbackErrorHandler::FallbackErrorHandlerPrivate
37
{
38
  std::list<AppenderPtr> backup;
39
  AppenderWeakPtr primary;
40
  std::map<LogString, spi::AppenderAttachableWeakPtr> appenderHolders;
41
  bool errorReported = false;
42
};
43
44
FallbackErrorHandler::FallbackErrorHandler()
45
0
  : m_priv(std::make_unique<FallbackErrorHandlerPrivate>())
46
0
{
47
0
}
Unexecuted instantiation: log4cxx::varia::FallbackErrorHandler::FallbackErrorHandler()
Unexecuted instantiation: log4cxx::varia::FallbackErrorHandler::FallbackErrorHandler()
48
49
0
FallbackErrorHandler::~FallbackErrorHandler() {}
50
51
void FallbackErrorHandler::addAppenderHolder(const LogString& name, const spi::AppenderAttachablePtr& clx)
52
0
{
53
0
  if (LogLog::isDebugEnabled())
54
0
  {
55
0
    LogLog::debug(((LogString) LOG4CXX_STR("FB: Adding appender holder ["))
56
0
      + name + LOG4CXX_STR("]."));
57
0
  }
58
0
  m_priv->appenderHolders.emplace(name, clx);
59
0
}
60
61
void FallbackErrorHandler::setLogger(const LoggerPtr& logger)
62
0
{
63
0
  if (LogLog::isDebugEnabled())
64
0
  {
65
0
    LogLog::debug(((LogString) LOG4CXX_STR("FB: Adding logger ["))
66
0
      + logger->getName() + LOG4CXX_STR("]."));
67
0
  }
68
0
  m_priv->appenderHolders.emplace(logger->getName(), logger);
69
0
}
70
71
void FallbackErrorHandler::error(const LogString& message) const
72
0
{
73
0
  LogLog::warn(message);
74
0
  m_priv->errorReported = true;
75
0
}
76
77
void FallbackErrorHandler::error
78
  ( const LogString& message
79
  , const std::exception& ex
80
  , int errorCode
81
  ) const
82
0
{
83
0
  error(message, ex, errorCode, 0);
84
0
}
85
86
void FallbackErrorHandler::error
87
  ( const LogString& message
88
  , const std::exception& ex
89
  , int errorCode
90
  , const spi::LoggingEventPtr& event
91
  ) const
92
0
{
93
0
  if (LogLog::isDebugEnabled())
94
0
  {
95
0
    LogString msg{ LOG4CXX_STR("FB: error code ") };
96
0
    StringHelper::toString(errorCode, msg);
97
0
    LogLog::debug(msg);
98
0
  }
99
0
  LogLog::warn(message, ex);
100
101
0
  AppenderPtr primaryLocked = m_priv->primary.lock();
102
0
  AppenderPtr backupLocked;
103
0
  if (!m_priv->backup.empty())
104
0
  {
105
0
    backupLocked = m_priv->backup.front();
106
0
    m_priv->backup.pop_front();
107
0
  }
108
109
0
  if ( !primaryLocked || !backupLocked )
110
0
  {
111
0
    return;
112
0
  }
113
114
0
  for (auto& item : m_priv->appenderHolders)
115
0
  {
116
0
    auto holderLocked = item.second.lock();
117
0
    if (!holderLocked)
118
0
      continue;
119
0
    if (LogLog::isDebugEnabled())
120
0
    {
121
0
      LogLog::debug(LOG4CXX_STR("FB: Replacing [")
122
0
        + primaryLocked->getName() + LOG4CXX_STR("] with [")
123
0
        + backupLocked->getName() + LOG4CXX_STR("] in [")
124
0
        + item.first + LOG4CXX_STR("]."));
125
0
    }
126
0
#if LOG4CXX_ABI_VERSION <= 15
127
0
    bool ok{ false };
128
0
    if (auto logger = LOG4CXX_NS::cast<Logger>(holderLocked))
129
0
      ok = logger->replaceAppender(primaryLocked, backupLocked);
130
0
    else if (auto asyncAppender = LOG4CXX_NS::cast<AsyncAppender>(holderLocked))
131
0
      ok = asyncAppender->replaceAppender(primaryLocked, backupLocked);
132
0
    if (!ok)
133
#else
134
    if (!holderLocked->replaceAppender(primaryLocked, backupLocked))
135
#endif
136
0
    {
137
0
      LogLog::debug(LOG4CXX_STR("FB: Failed to replace [")
138
0
        + primaryLocked->getName() + LOG4CXX_STR("] with [")
139
0
        + backupLocked->getName() + LOG4CXX_STR("] in [")
140
0
        + item.first + LOG4CXX_STR("]."));
141
0
    }
142
0
  }
143
0
  m_priv->errorReported = true;
144
0
  if (event)
145
0
    {
146
0
    backupLocked->doAppend(event);
147
0
    }
148
0
  m_priv->primary = backupLocked;
149
0
}
150
151
void FallbackErrorHandler::setAppender(const AppenderPtr& primary1)
152
0
{
153
0
  if (LogLog::isDebugEnabled())
154
0
  {
155
0
    LogLog::debug(((LogString) LOG4CXX_STR("FB: Setting primary appender to ["))
156
0
      + primary1->getName() + LOG4CXX_STR("]."));
157
0
  }
158
0
  m_priv->primary = primary1;
159
0
}
160
161
void FallbackErrorHandler::setBackupAppender(const AppenderPtr& backup1)
162
0
{
163
0
  if (LogLog::isDebugEnabled())
164
0
  {
165
0
    LogLog::debug(((LogString) LOG4CXX_STR("FB: Setting backup appender to ["))
166
0
      + backup1->getName() + LOG4CXX_STR("]."));
167
0
  }
168
0
  m_priv->backup.push_back(backup1);
169
0
}
170
171
#if LOG4CXX_ABI_VERSION <= 15
172
void FallbackErrorHandler::activateOptions(Pool&)
173
0
{
174
0
}
175
#endif
176
177
void FallbackErrorHandler::setOption(const LogString&, const LogString&)
178
0
{
179
0
}
180
181
bool FallbackErrorHandler::errorReported() const
182
0
{
183
0
  return m_priv->errorReported;
184
0
}