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/defaultconfigurator.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/logstring.h>
18
#include <log4cxx/defaultconfigurator.h>
19
#include <log4cxx/logmanager.h>
20
#include <log4cxx/spi/loggerrepository.h>
21
#include <log4cxx/file.h>
22
#include <log4cxx/helpers/loglog.h>
23
#include <log4cxx/helpers/optionconverter.h>
24
#include <log4cxx/helpers/stringhelper.h>
25
#include <log4cxx/helpers/system.h>
26
#include <log4cxx/xml/domconfigurator.h>
27
#include <log4cxx/propertyconfigurator.h>
28
#if !defined(LOG4CXX)
29
  #define LOG4CXX 1
30
#endif
31
#include <log4cxx/private/log4cxx_private.h>
32
33
using namespace LOG4CXX_NS;
34
using namespace spi;
35
using namespace helpers;
36
37
void DefaultConfigurator::setConfigurationFileName(const LogString& path)
38
0
{
39
0
  Configurator::properties().setProperty(LOG4CXX_STR("LOG4CXX_CONFIGURATION"), path);
40
0
}
41
42
void DefaultConfigurator::setConfigurationWatchSeconds(int seconds)
43
0
{
44
0
  LogString strSeconds;
45
0
  StringHelper::toString(seconds, strSeconds);
46
0
  Configurator::properties().setProperty(LOG4CXX_STR("LOG4CXX_CONFIGURATION_WATCH_SECONDS"), strSeconds);
47
0
}
48
49
ConfigurationStatus DefaultConfigurator::tryConfigure()
50
0
{
51
0
  auto r = LogManager::getLoggerRepository();
52
0
  configure(r);
53
0
  return r->isConfigured() ? ConfigurationStatus::Configured : ConfigurationStatus::NotConfigured;
54
0
}
55
56
void DefaultConfigurator::configure(LoggerRepositoryPtr repository)
57
0
{
58
59
0
  LogString configurationFileName = getConfigurationFileName();
60
0
  File configuration;
61
62
0
  if (configurationFileName.empty())
63
0
  {
64
0
    LogString names[4] =
65
0
      { LOG4CXX_STR("log4cxx.xml")
66
0
      , LOG4CXX_STR("log4cxx.properties")
67
0
      , LOG4CXX_STR("log4j.xml")
68
0
      , LOG4CXX_STR("log4j.properties")
69
0
      };
70
71
0
    for (int i = 0; i < 4; i++)
72
0
    {
73
0
      File candidate(names[i]);
74
75
0
      if (LogLog::isDebugEnabled())
76
0
      {
77
0
        LogString debugMsg = LOG4CXX_STR("Checking file ");
78
0
        debugMsg.append(names[i]);
79
0
        LogLog::debug(debugMsg);
80
0
      }
81
0
      if (candidate.exists())
82
0
      {
83
0
        configuration = candidate;
84
0
        break;
85
0
      }
86
0
    }
87
0
  }
88
0
  else
89
0
  {
90
0
    configuration.setPath(configurationFileName);
91
0
  }
92
93
0
  if (configuration.exists())
94
0
  {
95
0
    if (LogLog::isDebugEnabled())
96
0
    {
97
0
      LogString msg(LOG4CXX_STR("Using configuration file ["));
98
0
      msg += configuration.getPath();
99
0
      msg += LOG4CXX_STR("] for automatic log4cxx configuration");
100
0
      LogLog::debug(msg);
101
0
    }
102
103
0
    LoggerRepositoryPtr repo(repository);
104
0
    OptionConverter::selectAndConfigure(
105
0
      configuration,
106
0
      getConfiguratorClass(),
107
0
      repo,
108
0
      getConfigurationWatchDelay()
109
0
      );
110
    // TBD: Report a failure
111
0
  }
112
0
  else if (LogLog::isDebugEnabled())
113
0
  {
114
0
    if (configurationFileName.empty())
115
0
    {
116
0
      LogLog::debug(LOG4CXX_STR("Could not find default configuration file."));
117
0
    }
118
0
    else
119
0
    {
120
0
      LogString msg(LOG4CXX_STR("Could not find configuration file: ["));
121
0
      msg += configurationFileName;
122
0
      msg += LOG4CXX_STR("].");
123
0
      LogLog::debug(msg);
124
0
    }
125
0
  }
126
127
0
}
128
129
const LogString DefaultConfigurator::getConfiguratorClass()
130
0
{
131
0
  auto result = System::getProperty(LOG4CXX_STR("LOG4CXX_CONFIGURATOR_CLASS"));
132
0
#if LOG4CXX_VERSION_MAJOR <= 1
133
0
  if (result.empty())
134
0
    result = System::getProperty(LOG4CXX_STR("log4j.configuratorClass"));
135
0
#endif
136
0
  return result;
137
0
}
138
139
140
const LogString DefaultConfigurator::getConfigurationFileName()
141
0
{
142
0
  auto& props = Configurator::properties();
143
0
  LogString configurationFileName = props.getProperty(LOG4CXX_STR("LOG4CXX_CONFIGURATION"));
144
0
  bool isEnvVar = false;
145
0
  if (configurationFileName.empty())
146
0
  {
147
0
    configurationFileName = System::getProperty(LOG4CXX_STR("LOG4CXX_CONFIGURATION"));
148
0
    isEnvVar = true;
149
0
  }
150
0
#if LOG4CXX_VERSION_MAJOR <= 1
151
0
  if (configurationFileName.empty())
152
0
  {
153
0
    configurationFileName = System::getProperty(LOG4CXX_STR("log4j.configuration"));
154
0
    isEnvVar = true;
155
0
  }
156
0
#endif
157
#if !LOG4CXX_EXPAND_CONFIG_ENV_VAR
158
  if (isEnvVar)
159
    return configurationFileName;
160
#endif
161
0
  try
162
0
  {
163
0
    return OptionConverter::substVars(configurationFileName, props);
164
0
  }
165
0
  catch (IllegalArgumentException& e)
166
0
  {
167
0
    LogLog::warn(LOG4CXX_STR("Could not perform variable substitution."), e);
168
0
    return configurationFileName;
169
0
  }
170
0
}
171
172
173
int DefaultConfigurator::getConfigurationWatchDelay()
174
0
{
175
0
  LogString optionStr = Configurator::properties().getProperty(LOG4CXX_STR("LOG4CXX_CONFIGURATION_WATCH_SECONDS"));
176
0
  if (optionStr.empty())
177
0
    optionStr = System::getProperty(LOG4CXX_STR("LOG4CXX_CONFIGURATION_WATCH_SECONDS"));
178
0
  int milliseconds = 0;
179
0
  if (!optionStr.empty())
180
0
  {
181
0
    static const int MillisecondsPerSecond = 1000;
182
0
    milliseconds = StringHelper::toInt(optionStr) * MillisecondsPerSecond;
183
0
  }
184
0
  return milliseconds;
185
0
}
186
187
std::tuple<ConfigurationStatus,LogString>
188
DefaultConfigurator::configureFromFile(const std::vector<LogString>& directories, const std::vector<LogString>& filenames)
189
0
{
190
0
  auto result = std::tuple<ConfigurationStatus, LogString>
191
0
    { ConfigurationStatus::NotConfigured, LogString() };
192
0
  auto r = LogManager::getLoggerRepository();
193
194
0
  for (auto& dir : directories )
195
0
  {
196
0
    for (auto& fname : filenames )
197
0
    {
198
0
      setConfigurationFileName(dir + LOG4CXX_STR("/") + fname);
199
0
      auto candidate_str = getConfigurationFileName();
200
0
      File candidate(candidate_str);
201
202
0
      if (LogLog::isDebugEnabled())
203
0
        LogLog::debug(LOG4CXX_STR("Checking file ") + candidate_str);
204
0
      if (candidate.exists())
205
0
      {
206
0
        std::get<1>(result) = candidate_str;
207
0
        configure(r);
208
0
        if (r->isConfigured())
209
0
        {
210
0
          std::get<0>(result) = ConfigurationStatus::Configured;
211
0
          return result;
212
0
        }
213
0
      }
214
0
    }
215
0
  }
216
0
  return result;
217
0
}