001/* 002 * Licensed to the Apache Software Foundation (ASF) under one or more 003 * contributor license agreements. See the NOTICE file distributed with 004 * this work for additional information regarding copyright ownership. 005 * The ASF licenses this file to You under the Apache license, Version 2.0 006 * (the "License"); you may not use this file except in compliance with 007 * the License. You may obtain a copy of the License at 008 * 009 * http://www.apache.org/licenses/LICENSE-2.0 010 * 011 * Unless required by applicable law or agreed to in writing, software 012 * distributed under the License is distributed on an "AS IS" BASIS, 013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 014 * See the license for the specific language governing permissions and 015 * limitations under the license. 016 */ 017package org.apache.logging.log4j.core.config.builder.impl; 018 019import java.lang.reflect.Constructor; 020import java.util.List; 021 022import org.apache.logging.log4j.Level; 023import org.apache.logging.log4j.core.Filter; 024import org.apache.logging.log4j.core.config.Configuration; 025import org.apache.logging.log4j.core.config.ConfigurationException; 026import org.apache.logging.log4j.core.config.ConfigurationSource; 027import org.apache.logging.log4j.core.config.LoggerConfig; 028import org.apache.logging.log4j.core.config.builder.api.AppenderComponentBuilder; 029import org.apache.logging.log4j.core.config.builder.api.AppenderRefComponentBuilder; 030import org.apache.logging.log4j.core.config.builder.api.Component; 031import org.apache.logging.log4j.core.config.builder.api.ComponentBuilder; 032import org.apache.logging.log4j.core.config.builder.api.ConfigurationBuilder; 033import org.apache.logging.log4j.core.config.builder.api.CustomLevelComponentBuilder; 034import org.apache.logging.log4j.core.config.builder.api.FilterComponentBuilder; 035import org.apache.logging.log4j.core.config.builder.api.LayoutComponentBuilder; 036import org.apache.logging.log4j.core.config.builder.api.LoggerComponentBuilder; 037import org.apache.logging.log4j.core.config.builder.api.RootLoggerComponentBuilder; 038import org.apache.logging.log4j.core.config.builder.api.ScriptComponentBuilder; 039import org.apache.logging.log4j.core.config.builder.api.ScriptFileComponentBuilder; 040 041/** 042 * @param <T> The BuiltConfiguration type. 043 * @since 2.4 044 */ 045public class DefaultConfigurationBuilder<T extends BuiltConfiguration> implements ConfigurationBuilder<T> { 046 047 private final Component root = new Component(); 048 private Component loggers; 049 private Component appenders; 050 private Component filters; 051 private Component properties; 052 private Component customLevels; 053 private Component scripts; 054 private final Class<T> clazz; 055 private ConfigurationSource source; 056 private int monitorInterval = 0; 057 private Level level = null; 058 private String verbosity = null; 059 private String packages = null; 060 private String shutdownFlag = null; 061 private String advertiser = null; 062 063 private String name = null; 064 065 @SuppressWarnings("unchecked") 066 public DefaultConfigurationBuilder() { 067 this((Class<T>) BuiltConfiguration.class); 068 root.addAttribute("name", "Built"); 069 } 070 071 public DefaultConfigurationBuilder(final Class<T> clazz) { 072 if (clazz == null) { 073 throw new IllegalArgumentException("A Configuration class must be provided"); 074 } 075 this.clazz = clazz; 076 final List<Component> components = root.getComponents(); 077 properties = new Component("Properties"); 078 components.add(properties); 079 scripts = new Component("Scripts"); 080 components.add(scripts); 081 customLevels = new Component("CustomLevels"); 082 components.add(customLevels); 083 filters = new Component("Filters"); 084 components.add(filters); 085 appenders = new Component("Appenders"); 086 components.add(appenders); 087 loggers = new Component("Loggers"); 088 components.add(loggers); 089 } 090 091 protected ConfigurationBuilder<T> add(final Component parent, final ComponentBuilder<?> builder) { 092 parent.getComponents().add(builder.build()); 093 return this; 094 } 095 096 @Override 097 public ConfigurationBuilder<T> add(final AppenderComponentBuilder builder) { 098 return add(appenders, builder); 099 } 100 101 @Override 102 public ConfigurationBuilder<T> add(final CustomLevelComponentBuilder builder) { 103 return add(customLevels, builder); 104 } 105 106 @Override 107 public ConfigurationBuilder<T> add(final FilterComponentBuilder builder) { 108 return add(filters, builder); 109 } 110 111 @Override 112 public ConfigurationBuilder<T> add(final ScriptComponentBuilder builder) { 113 return add(scripts, builder); 114 } 115 116 @Override 117 public ConfigurationBuilder<T> add(final ScriptFileComponentBuilder builder) { 118 return add(scripts, builder); 119 } 120 121 @Override 122 public ConfigurationBuilder<T> add(final LoggerComponentBuilder builder) { 123 return add(loggers, builder); 124 } 125 126 @Override 127 public ConfigurationBuilder<T> add(final RootLoggerComponentBuilder builder) { 128 for (final Component c : loggers.getComponents()) { 129 if (c.getPluginType().equals(LoggerConfig.ROOT)) { 130 throw new ConfigurationException("Root Logger was previously defined"); 131 } 132 } 133 return add(loggers, builder); 134 } 135 136 @Override 137 public ConfigurationBuilder<T> addProperty(final String key, final String value) { 138 properties.addComponent(newComponent(key, "Property", value).build()); 139 return this; 140 } 141 142 @Override 143 public T build() { 144 return build(true); 145 } 146 147 @Override 148 public T build(final boolean initialize) { 149 T configuration; 150 try { 151 if (source == null) { 152 source = ConfigurationSource.NULL_SOURCE; 153 } 154 final Constructor<T> constructor = clazz.getConstructor(ConfigurationSource.class, Component.class); 155 configuration = constructor.newInstance(source, root); 156 configuration.setMonitorInterval(monitorInterval); 157 configuration.getRootNode().getAttributes().putAll(root.getAttributes()); 158 if (name != null) { 159 configuration.setName(name); 160 } 161 if (level != null) { 162 configuration.getStatusConfiguration().withStatus(level); 163 } 164 if (verbosity != null) { 165 configuration.getStatusConfiguration().withVerbosity(verbosity); 166 } 167 if (packages != null) { 168 configuration.setPluginPackages(packages); 169 } 170 if (shutdownFlag != null) { 171 configuration.setShutdownHook(shutdownFlag); 172 } 173 if (advertiser != null) { 174 configuration.createAdvertiser(advertiser, source); 175 } 176 } catch (final Exception ex) { 177 throw new IllegalArgumentException("Invalid Configuration class specified", ex); 178 } 179 configuration.getStatusConfiguration().initialize(); 180 if (initialize) { 181 configuration.initialize(); 182 } 183 return configuration; 184 } 185 186 @Override 187 public ScriptComponentBuilder newScript(final String name, final String language, final String text) { 188 return new DefaultScriptComponentBuilder(this, name, language, text); 189 } 190 191 192 @Override 193 public ScriptFileComponentBuilder newScriptFile(final String path) { 194 return new DefaultScriptFileComponentBuilder(this, path, path); 195 } 196 197 @Override 198 public ScriptFileComponentBuilder newScriptFile(final String name, final String path) { 199 return new DefaultScriptFileComponentBuilder(this, name, path); 200 } 201 202 @Override 203 public AppenderComponentBuilder newAppender(final String name, final String type) { 204 return new DefaultAppenderComponentBuilder(this, name, type); 205 } 206 207 @Override 208 public AppenderRefComponentBuilder newAppenderRef(final String ref) { 209 return new DefaultAppenderRefComponentBuilder(this, ref); 210 } 211 212 @Override 213 public LoggerComponentBuilder newAsyncLogger(final String name, final Level level) { 214 return new DefaultLoggerComponentBuilder(this, name, level.toString(), "AsyncLogger", false); 215 } 216 217 @Override 218 public LoggerComponentBuilder newAsyncLogger(final String name, final Level level, final boolean includeLocation) { 219 return new DefaultLoggerComponentBuilder(this, name, level.toString(), "AsyncLogger", includeLocation); 220 } 221 222 @Override 223 public LoggerComponentBuilder newAsyncLogger(final String name, final String level) { 224 return new DefaultLoggerComponentBuilder(this, name, level, "AsyncLogger", false); 225 } 226 227 @Override 228 public LoggerComponentBuilder newAsyncLogger(final String name, final String level, final boolean includeLocation) { 229 return new DefaultLoggerComponentBuilder(this, name, level, "AsyncLogger"); 230 } 231 232 @Override 233 public RootLoggerComponentBuilder newAsyncRootLogger(final Level level) { 234 return new DefaultRootLoggerComponentBuilder(this, level.toString(), "AsyncRoot", false); 235 } 236 237 @Override 238 public RootLoggerComponentBuilder newAsyncRootLogger(final Level level, final boolean includeLocation) { 239 return new DefaultRootLoggerComponentBuilder(this, level.toString(), "AsyncRoot", includeLocation); 240 } 241 242 @Override 243 public RootLoggerComponentBuilder newAsyncRootLogger(final String level) { 244 return new DefaultRootLoggerComponentBuilder(this, level, "AsyncRoot", false); 245 } 246 247 @Override 248 public RootLoggerComponentBuilder newAsyncRootLogger(final String level, final boolean includeLocation) { 249 return new DefaultRootLoggerComponentBuilder(this, level, "AsyncRoot", includeLocation); 250 } 251 252 253 @Override 254 public <B extends ComponentBuilder<B>> ComponentBuilder<B> newComponent(final String type) { 255 return new DefaultComponentBuilder<>(this, type); 256 } 257 258 @Override 259 public <B extends ComponentBuilder<B>> ComponentBuilder<B> newComponent(final String name, final String type) { 260 return new DefaultComponentBuilder<>(this, name, type); 261 } 262 263 @Override 264 public <B extends ComponentBuilder<B>> ComponentBuilder<B> newComponent(final String name, final String type, 265 final String value) { 266 return new DefaultComponentBuilder<>(this, name, type, value); 267 } 268 269 270 @Override 271 public CustomLevelComponentBuilder newCustomLevel(final String name, final int level) { 272 return new DefaultCustomLevelComponentBuilder(this, name, level); 273 } 274 275 @Override 276 public FilterComponentBuilder newFilter(final String type, final Filter.Result onMatch, 277 final Filter.Result onMisMatch) { 278 return new DefaultFilterComponentBuilder(this, type, onMatch.name(), onMisMatch.name()); 279 } 280 281 @Override 282 public FilterComponentBuilder newFilter(final String type, final String onMatch, final String onMisMatch) { 283 return new DefaultFilterComponentBuilder(this, type, onMatch, onMisMatch); 284 } 285 286 @Override 287 public LayoutComponentBuilder newLayout(final String type) { 288 return new DefaultLayoutComponentBuilder(this, type); 289 } 290 291 292 @Override 293 public LoggerComponentBuilder newLogger(final String name, final Level level) { 294 return new DefaultLoggerComponentBuilder(this, name, level.toString(), true); 295 } 296 297 @Override 298 public LoggerComponentBuilder newLogger(final String name, final Level level, final boolean includeLocation) { 299 return new DefaultLoggerComponentBuilder(this, name, level.toString(), includeLocation); 300 } 301 302 @Override 303 public LoggerComponentBuilder newLogger(final String name, final String level) { 304 return new DefaultLoggerComponentBuilder(this, name, level, true); 305 } 306 307 @Override 308 public LoggerComponentBuilder newLogger(final String name, final String level, final boolean includeLocation) { 309 return new DefaultLoggerComponentBuilder(this, name, level, includeLocation); 310 } 311 312 @Override 313 public RootLoggerComponentBuilder newRootLogger(final Level level) { 314 return new DefaultRootLoggerComponentBuilder(this, level.toString(), true); 315 } 316 317 @Override 318 public RootLoggerComponentBuilder newRootLogger(final Level level, final boolean includeLocation) { 319 return new DefaultRootLoggerComponentBuilder(this, level.toString(), includeLocation); 320 } 321 322 @Override 323 public RootLoggerComponentBuilder newRootLogger(final String level) { 324 return new DefaultRootLoggerComponentBuilder(this, level, true); 325 } 326 327 @Override 328 public RootLoggerComponentBuilder newRootLogger(final String level, final boolean includeLocation) { 329 return new DefaultRootLoggerComponentBuilder(this, level, includeLocation); 330 } 331 332 @Override 333 public ConfigurationBuilder<T> setAdvertiser(final String advertiser) { 334 this.advertiser = advertiser; 335 return this; 336 } 337 338 /** 339 * Set the name of the configuration. 340 * 341 * @param name the name of the {@link Configuration}. By default is {@code "Assembled"}. 342 * @return this builder instance 343 */ 344 @Override 345 public ConfigurationBuilder<T> setConfigurationName(final String name) { 346 this.name = name; 347 return this; 348 } 349 350 /** 351 * Set the ConfigurationSource. 352 * 353 * @param configurationSource the {@link ConfigurationSource} 354 * @return this builder instance 355 */ 356 @Override 357 public ConfigurationBuilder<T> setConfigurationSource(final ConfigurationSource configurationSource) { 358 source = configurationSource; 359 return this; 360 } 361 362 @Override 363 public ConfigurationBuilder<T> setMonitorInterval(final String intervalSeconds) { 364 monitorInterval = Integer.parseInt(intervalSeconds); 365 return this; 366 } 367 368 @Override 369 public ConfigurationBuilder<T> setPackages(final String packages) { 370 this.packages = packages; 371 return this; 372 } 373 374 @Override 375 public ConfigurationBuilder<T> setShutdownHook(final String flag) { 376 this.shutdownFlag = flag; 377 return this; 378 } 379 380 @Override 381 public ConfigurationBuilder<T> setStatusLevel(final Level level) { 382 this.level = level; 383 return this; 384 } 385 386 @Override 387 public ConfigurationBuilder<T> setVerbosity(final String verbosity) { 388 this.verbosity = verbosity; 389 return this; 390 } 391 392 @Override 393 public ConfigurationBuilder<T> addRootProperty(final String key, final String value) { 394 root.getAttributes().put(key, value); 395 return this; 396 } 397}