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

io.opentelemetry.sdk.internal.ThrottlingLogger Maven / Gradle / Ivy

There is a newer version: 1.44.1
Show newest version
/*
 * Copyright The OpenTelemetry Authors
 * SPDX-License-Identifier: Apache-2.0
 */

package io.opentelemetry.sdk.internal;

import static java.util.concurrent.TimeUnit.MINUTES;

import io.opentelemetry.sdk.common.Clock;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicBoolean;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.annotation.Nullable;

/**
 * Will limit the number of log messages emitted, so as not to spam when problems are happening.
 *
 * 

This class is internal and is hence not for public use. Its APIs are unstable and can change * at any time. */ public class ThrottlingLogger { private static final double RATE_LIMIT = 5; private static final double THROTTLED_RATE_LIMIT = 1; private static final TimeUnit rateTimeUnit = MINUTES; private final Logger delegate; private final AtomicBoolean throttled = new AtomicBoolean(false); private final RateLimiter fastRateLimiter; private final RateLimiter throttledRateLimiter; /** Create a new logger which will enforce a max number of messages per minute. */ public ThrottlingLogger(Logger delegate) { this(delegate, Clock.getDefault()); } // visible for testing ThrottlingLogger(Logger delegate, Clock clock) { this.delegate = delegate; this.fastRateLimiter = new RateLimiter(RATE_LIMIT / rateTimeUnit.toSeconds(1), RATE_LIMIT, clock); this.throttledRateLimiter = new RateLimiter(RATE_LIMIT / rateTimeUnit.toSeconds(1), THROTTLED_RATE_LIMIT, clock); } /** Log a message at the given level. */ public void log(Level level, String message) { log(level, message, null); } /** Log a message at the given level with a throwable. */ public void log(Level level, String message, @Nullable Throwable throwable) { if (!isLoggable(level)) { return; } if (throttled.get()) { if (throttledRateLimiter.trySpend(1.0)) { doLog(level, message, throwable); } return; } if (fastRateLimiter.trySpend(1.0)) { doLog(level, message, throwable); return; } if (throttled.compareAndSet(false, true)) { // spend the balance in the throttled one, so that it starts at zero. throttledRateLimiter.trySpend(THROTTLED_RATE_LIMIT); delegate.log( level, "Too many log messages detected. Will only log once per minute from now on."); doLog(level, message, throwable); } } private void doLog(Level level, String message, @Nullable Throwable throwable) { if (throwable != null) { delegate.log(level, message, throwable); } else { delegate.log(level, message); } } /** * Returns whether the current wrapped logger is set to log at the given level. * * @return true if the logger set to log at the requested level. */ public boolean isLoggable(Level level) { return delegate.isLoggable(level); } }





© 2015 - 2024 Weber Informatics LLC | Privacy Policy