All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.apache.jena.atlas.logging.LogCtlLog4j2 Maven / Gradle / Ivy

There is a newer version: 5.2.0
Show newest version
/*
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you under the Apache License, Version 2.0 (the
 * "License"); you may not use this file except in compliance
 * with the License.  You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package org.apache.jena.atlas.logging;

import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.UncheckedIOException;
import java.net.URI;
import java.nio.charset.StandardCharsets;
import java.nio.file.Path;
import java.util.Objects;

import org.apache.commons.io.FilenameUtils;
import org.apache.logging.log4j.Level;
import org.apache.logging.log4j.Logger;
import org.apache.logging.log4j.core.config.Configuration;
import org.apache.logging.log4j.core.config.ConfigurationFactory;
import org.apache.logging.log4j.core.config.ConfigurationSource;
import org.apache.logging.log4j.core.config.Configurator;
import org.apache.logging.log4j.core.config.json.JsonConfigurationFactory;
import org.apache.logging.log4j.core.config.properties.PropertiesConfigurationFactory;
import org.apache.logging.log4j.core.config.xml.XmlConfigurationFactory;
import org.apache.logging.log4j.core.config.yaml.YamlConfigurationFactory;

/**
 * Additional logging control, for Log4j2 as used by jena-cmds.
 * 

* This class depends on log4j2-api and also log4j2-core. * These are <optional> dependencies for Jena which can use any slf4j provider. *

* This class is split out from {@link LogCtl} to decouple the dependencies. *

* This class is not used if log4j2 is not used. */ public class LogCtlLog4j2 { /** Default log4j2 setup */ public static String log4j2setup = String.join(log4jSetupSep(), log4j2setupBase(), log4j2setupJenaLib(), log4j2setupFuseki()); /** * Reset logging for log4j2. * The string is log4j2.properties format. */ public static void resetLogging(String configString) { // This method is previous naming. reconfigureLog4j2fromString(configString, SyntaxHint.PROPERTIES); } /** * Reset logging for log4j2 from a string. * The resourceName is used to determine the syntax. */ public static void resetLogging(InputStream inputStream, String resourceName) { resetLogging(inputStream, determineSyntax(resourceName)); } /** * Reset logging for log4j2 from an {@link InputStream} with the given syntax. */ public static void resetLogging(InputStream inputStream, SyntaxHint syntaxHint) { Configuration config = log4j2Configuration(inputStream, syntaxHint); reconfigureLog4j(config); } /** Check logging level of a Logger */ /*package*/ static void setLoggerlevel(String logger, Level level) { try { if ( !logger.equals("") ) org.apache.logging.log4j.core.config.Configurator.setLevel(logger, level); else org.apache.logging.log4j.core.config.Configurator.setRootLevel(level); } catch (NoClassDefFoundError ex) { Log.warnOnce(LogCtlLog4j2.class, "Log4j2 Configurator not found", LogCtl.class); } } /** Check logging level of a Logger */ /*package*/ static void setLoggerlevel(Logger logger, Level level) { try { org.apache.logging.log4j.core.config.Configurator.setLevel(logger, level); } catch (NoClassDefFoundError ex) { Log.warnOnce(LogCtlLog4j2.class, "Log4j2 Configurator not found", LogCtl.class); } } /** * Enum for possible syntax of a Log4j configuration file. *

* Note that the JSON and YAML forms, require additional jars. See * "dependencies for log4j-core" for more information. */ public enum SyntaxHint { PROPERTIES("properties"), XML("xml"), JSON("json"), YAML("yaml"); // The syntax name is assumed to be the file extension. // This can be used as the name of a syntax. private String syntaxName; SyntaxHint(String syntaxName) { this.syntaxName = syntaxName; } /** Return the {@code SyntaxHint} for a name (case insensitive) or null */ static SyntaxHint fromName(String name) { for ( SyntaxHint hint : SyntaxHint.values() ) { if ( hint.syntaxName.equalsIgnoreCase(name) ) return hint; } return null; } } /** * Reconfigure log4j2 from a file. *

* The file syntax is determined by the file extension (".properties" or ".xml"). *

* Existing loggers are reconfigured by this function. */ public static void reconfigureLog4j2fromFile(String filename) { if ( true ) { // This particular case can be done with Log4J directly. // That will extend to all plugins. Configurator.initialize(null, filename); return; } // Use the same logic as the other operations. // JSON and YAML usage require addition jars on the classpath. SyntaxHint syntax = determineSyntax(filename); Configuration config = log4j2ConfigurationFromFile(filename, syntax); reconfigureLog4j(config); } /** * Reconfigure log4j2 from a file. *

* The file syntax is determined by the syntax hint. *

* Existing loggers are reconfigured by this function. */ public static void reconfigureLog4j2fromFile(String filename, SyntaxHint syntaxHint) { Configuration config = log4j2ConfigurationFromFile(filename, syntaxHint); reconfigureLog4j(config); } /** * Reconfigure log4j2 from a string. *

* The syntax is given by the syntax hint. *

* Existing loggers are reconfigured by this function. */ public static void reconfigureLog4j2fromString(String configString, SyntaxHint syntaxHint) { Configuration config = log4j2ConfigurationFromString(configString, syntaxHint); reconfigureLog4j(config); } /** * Reconfigure log4j from a {@link Configuration}. */ private static void reconfigureLog4j(Configuration config) { config.initialize(); Configurator.reconfigure(config); } /** * Create a log4j2 {@link Configuration} from a file. *

* The file syntax is determined by the syntax hint */ private static Configuration log4j2ConfigurationFromFile(String filename, SyntaxHint syntaxHint) { URI uri = Path.of(filename).toUri(); ConfigurationSource source = ConfigurationSource.fromUri(uri); return createLog4jConfiguration(source, syntaxHint); } /** * Create a log4j2 {@link Configuration} from a string. *

* TThe string syntax is determined by the syntax hint */ private static Configuration log4j2ConfigurationFromString(String text, SyntaxHint syntaxHint) { try(InputStream input = new ByteArrayInputStream(text.getBytes(StandardCharsets.UTF_8))) { return log4j2Configuration(input, syntaxHint); } catch (IOException ex) { throw new UncheckedIOException(ex); } } /** * Create a log4j2 {@link Configuration} from an {@link InputStream}. *

* The file syntax is determined by the syntax hint */ private static Configuration log4j2Configuration(InputStream inputStream, SyntaxHint syntaxHint) { try { ConfigurationSource source = new ConfigurationSource(inputStream); return createLog4jConfiguration(source, syntaxHint); } catch (IOException ex) { throw new UncheckedIOException(ex); } } /** * Create a log4j2 {@link Configuration}. *

* @see org.apache.logging.log4j.core.config.Configurator * @see org.apache.logging.log4j.core.config.ConfigurationSource */ private static Configuration createLog4jConfiguration(ConfigurationSource source, SyntaxHint syntaxHint) { Objects.requireNonNull(source); Objects.requireNonNull(syntaxHint); ConfigurationFactory factory = switch(syntaxHint) { case PROPERTIES -> new PropertiesConfigurationFactory(); case XML -> new XmlConfigurationFactory(); case JSON -> new JsonConfigurationFactory(); case YAML -> new YamlConfigurationFactory(); default -> ConfigurationFactory.getInstance(); }; Configuration configuration = factory.getConfiguration(null, source); if ( configuration == null ) throw new UnsupportedOperationException("Can't create a configuration for '"+source+"' using '"+syntaxHint+"'"); return configuration; } /** * Filename to {@link SynatxHint}. *

* Identify the likely syntax of a file, or throw IllegalArgumentException * if no such determination can be made. */ private static SyntaxHint determineSyntax(String filename) { String ext = FilenameUtils.getExtension(filename); if ( ext == null ) throw new IllegalArgumentException("No file extension"); SyntaxHint hint = SyntaxHint.fromName(ext); if ( hint == null ) throw new IllegalArgumentException("File extension not recognized: '"+ext+"'"); return hint; } /** Line separate/blank line for concatenating log4j syntax fragments. */ private static String log4jSetupSep() { return "\n"; } /** * A basic logging setup. Time and level INFO. */ private static String log4j2setupBase() { return """ ## Log4j2 properties syntax. status = error name = JenaLoggingDft # filters = threshold # filter.threshold.type = ThresholdFilter # filter.threshold.level = ALL appender.console.type = Console appender.console.name = OUT appender.console.target = SYSTEM_OUT appender.console.layout.type = PatternLayout appender.console.layout.pattern = %d{HH:mm:ss} %-5p %-15c{1} :: %m%n # appender.console.layout.pattern = [%d{yyyy-MM-dd HH:mm:ss}] %-5p %-15c{1} :: %m%n rootLogger.level = INFO rootLogger.appenderRef.stdout.ref = OUT """; } /** Default log4j fragment needed for Jena command line tools. */ private static String log4j2setupJenaLib() { return """ logger.jena.name = org.apache.jena logger.jena.level = INFO logger.arq-exec.name = org.apache.jena.arq.exec logger.arq-exec.level = INFO logger.riot.name = org.apache.jena.riot logger.riot.level = INFO """; } /** Additional log4j fragment for Fuseki in case the general default is used with embedded Fuseki. */ private static String log4j2setupFuseki() { return """ # Fuseki. In case this logging setup gets install for embedded Fuseki. logger.fuseki.name = org.apache.jena.fuseki logger.fuseki.level = INFO logger.fuseki-fuseki.name = org.apache.jena.fuseki.Fuseki logger.fuseki-fuseki.level = INFO logger.fuseki-server.name = org.apache.jena.fuseki.Server logger.fuseki-server.level = INFO logger.fuseki-config.name = org.apache.jena.fuseki.Config logger.fuseki-config.level = INFO logger.fuseki-admin.name = org.apache.jena.fuseki.Admin logger.fuseki-admin.level = INFO logger.jetty.name = org.eclipse.jetty logger.jetty.level = WARN logger.shiro.name = org.apache.shiro logger.shiro.level = WARN # This goes out in NCSA format appender.plain.type = Console appender.plain.name = PLAIN appender.plain.layout.type = PatternLayout appender.plain.layout.pattern = %m%n logger.fuseki-request.name = org.apache.jena.fuseki.Request logger.fuseki-request.additivity = false logger.fuseki-request.level = OFF logger.fuseki-request.appenderRef.plain.ref = PLAIN """; } }





© 2015 - 2024 Weber Informatics LLC | Privacy Policy