Use deprecation logger holder in byte size value (#53928)

If a setting is touched during bootstrap before logging is configured,
and that setting uses a byte size value, the deprecation logger for
ByteSizeValue will be initialized. However, this means a logger will be
configured before log4j is initialized, which we reject at startup. This
commit puts this deprecation logger in a holder pattern so that it is
not initialized until first use, which will happen after logging is
configured.
This commit is contained in:
Jason Tedor 2020-03-23 17:06:12 -04:00 committed by GitHub
parent f0a015cae7
commit bc7b995523
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
1 changed files with 11 additions and 2 deletions

View File

@ -27,6 +27,8 @@ import org.elasticsearch.common.io.stream.StreamInput;
import org.elasticsearch.common.io.stream.StreamOutput; import org.elasticsearch.common.io.stream.StreamOutput;
import org.elasticsearch.common.io.stream.Writeable; import org.elasticsearch.common.io.stream.Writeable;
import org.elasticsearch.common.logging.DeprecationLogger; import org.elasticsearch.common.logging.DeprecationLogger;
import org.elasticsearch.common.logging.LogConfigurator;
import org.elasticsearch.common.settings.Setting;
import org.elasticsearch.common.xcontent.ToXContentFragment; import org.elasticsearch.common.xcontent.ToXContentFragment;
import org.elasticsearch.common.xcontent.XContentBuilder; import org.elasticsearch.common.xcontent.XContentBuilder;
@ -36,7 +38,14 @@ import java.util.Objects;
public class ByteSizeValue implements Writeable, Comparable<ByteSizeValue>, ToXContentFragment { public class ByteSizeValue implements Writeable, Comparable<ByteSizeValue>, ToXContentFragment {
private static final DeprecationLogger deprecationLogger = new DeprecationLogger(LogManager.getLogger(ByteSizeValue.class)); /**
* We have to lazy initialize the deprecation logger as otherwise a static logger here would be constructed before logging is configured
* leading to a runtime failure (see {@link LogConfigurator#checkErrorListener()} ). The premature construction would come from any
* {@link Setting} object constructed in, for example, settings in {@link org.elasticsearch.common.network.NetworkService}.
*/
static class DeprecationLoggerHolder {
static DeprecationLogger deprecationLogger = new DeprecationLogger(LogManager.getLogger(ByteSizeValue.class));
}
public static final ByteSizeValue ZERO = new ByteSizeValue(0, ByteSizeUnit.BYTES); public static final ByteSizeValue ZERO = new ByteSizeValue(0, ByteSizeUnit.BYTES);
@ -237,7 +246,7 @@ public class ByteSizeValue implements Writeable, Comparable<ByteSizeValue>, ToXC
} catch (final NumberFormatException e) { } catch (final NumberFormatException e) {
try { try {
final double doubleValue = Double.parseDouble(s); final double doubleValue = Double.parseDouble(s);
deprecationLogger.deprecated( DeprecationLoggerHolder.deprecationLogger.deprecated(
"Fractional bytes values are deprecated. Use non-fractional bytes values instead: [{}] found for setting [{}]", "Fractional bytes values are deprecated. Use non-fractional bytes values instead: [{}] found for setting [{}]",
initialInput, settingName); initialInput, settingName);
return new ByteSizeValue((long) (doubleValue * unit.toBytes(1))); return new ByteSizeValue((long) (doubleValue * unit.toBytes(1)));