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

org.elasticsearch.common.logging.DeprecationLogger Maven / Gradle / Ivy

There is a newer version: 8.14.0
Show newest version
/*
 * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
 * or more contributor license agreements. Licensed under the Elastic License
 * 2.0 and the Server Side Public License, v 1; you may not use this file except
 * in compliance with, at your election, the Elastic License 2.0 or the Server
 * Side Public License, v 1.
 */

package org.elasticsearch.common.logging;

import org.apache.logging.log4j.Level;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.elasticsearch.common.regex.Regex;
import org.elasticsearch.common.settings.Settings;

import java.security.AccessController;
import java.security.PrivilegedAction;
import java.util.Collections;
import java.util.List;

/**
 * A logger that logs deprecation notices. Logger should be initialized with a class or name which will be used
 * for deprecation logger. For instance DeprecationLogger.getLogger("org.elasticsearch.test.SomeClass") will
 * result in a deprecation logger with name org.elasticsearch.deprecation.test.SomeClass. This allows to use a
 * deprecation logger defined in log4j2.properties.
 * 

* Logs are emitted at the custom {@link #CRITICAL} level, and routed wherever they need to go using log4j. For example, * to disk using a rolling file appender, or added as a response header using {@link HeaderWarningAppender}. *

* Deprecation messages include a key, which is used for rate-limiting purposes. The log4j configuration * uses {@link RateLimitingFilter} to prevent the same message being logged repeatedly in a short span of time. This * key is combined with the X-Opaque-Id request header value, if supplied, which allows for per-client * message limiting. */ public class DeprecationLogger { /** * Deprecation messages are logged at this level. * More serious than WARN by 1, but less serious than ERROR */ public static Level CRITICAL = Level.forName("CRITICAL", Level.WARN.intLevel() - 1); private static volatile List skipTheseDeprecations = Collections.emptyList(); private final Logger logger; /** * Creates a new deprecation logger for the supplied class. Internally, it delegates to * {@link #getLogger(String)}, passing the full class name. */ public static DeprecationLogger getLogger(Class aClass) { return getLogger(toLoggerName(aClass)); } /** * Creates a new deprecation logger based on the parent logger. Automatically * prefixes the logger name with "deprecation", if it starts with "org.elasticsearch.", * it replaces "org.elasticsearch" with "org.elasticsearch.deprecation" to maintain * the "org.elasticsearch" namespace. */ public static DeprecationLogger getLogger(String name) { return new DeprecationLogger(name); } /** * The DeprecationLogger uses the "deprecation.skip_deprecated_settings" setting to decide whether to log a deprecation for a setting. * This is a node setting. This method initializes the DeprecationLogger class with the node settings for the node in order to read the * "deprecation.skip_deprecated_settings" setting. This only needs to be called once per JVM. If it is not called, the default behavior * is to assume that the "deprecation.skip_deprecated_settings" setting is not set. * @param nodeSettings The settings for this node */ public static void initialize(Settings nodeSettings) { skipTheseDeprecations = nodeSettings == null ? Collections.emptyList() : nodeSettings.getAsList("deprecation.skip_deprecated_settings"); } private DeprecationLogger(String parentLoggerName) { this.logger = LogManager.getLogger(getLoggerName(parentLoggerName)); } private static String getLoggerName(String name) { if (name.startsWith("org.elasticsearch")) { name = name.replace("org.elasticsearch.", "org.elasticsearch.deprecation."); } else { name = "deprecation." + name; } return name; } private static String toLoggerName(final Class cls) { String canonicalName = cls.getCanonicalName(); return canonicalName != null ? canonicalName : cls.getName(); } /** * Logs a message at the {@link DeprecationLogger#CRITICAL} level. * This log will indicate that a change will break in next version. * The message is also sent to the header warning logger, * so that it can be returned to the client. */ public DeprecationLogger critical(final DeprecationCategory category, final String key, final String msg, final Object... params) { return logDeprecation(CRITICAL, category, key, msg, params); } /** * Logs a message at the {@link Level#WARN} level for less critical deprecations * that won't break in next version. * The message is also sent to the header warning logger, * so that it can be returned to the client. */ public DeprecationLogger warn(final DeprecationCategory category, final String key, final String msg, final Object... params) { return logDeprecation(Level.WARN, category, key, msg, params); } private DeprecationLogger logDeprecation(Level level, DeprecationCategory category, String key, String msg, Object[] params) { if (Regex.simpleMatch(skipTheseDeprecations, key) == false) { String opaqueId = HeaderWarning.getXOpaqueId(); String productOrigin = HeaderWarning.getProductOrigin(); ESLogMessage deprecationMessage = new DeprecatedMessage(category, key, opaqueId, productOrigin, msg, params); doPrivilegedLog(level, deprecationMessage); } return this; } private void doPrivilegedLog(Level level, ESLogMessage deprecationMessage) { AccessController.doPrivileged((PrivilegedAction) () -> { logger.log(level, deprecationMessage); return null; }); } }





© 2015 - 2024 Weber Informatics LLC | Privacy Policy