Coverage Report

Created: 2025-10-13 07:02

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