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

com.wavefront.agent.channel.CachingHostnameLookupResolver Maven / Gradle / Ivy

package com.wavefront.agent.channel;

import com.github.benmanes.caffeine.cache.Caffeine;
import com.github.benmanes.caffeine.cache.LoadingCache;
import com.google.common.annotations.VisibleForTesting;
import com.yammer.metrics.Metrics;
import com.yammer.metrics.core.Gauge;
import com.yammer.metrics.core.MetricName;
import java.net.InetAddress;
import java.time.Duration;
import java.util.function.Function;
import javax.annotation.Nonnull;
import javax.annotation.Nullable;

/**
 * Convert {@link InetAddress} to {@link String}, either by performing reverse DNS lookups (cached,
 * as the name implies), or by converting IP addresses into their string representation.
 *
 * @author [email protected]
 */
public class CachingHostnameLookupResolver implements Function {

  private final Function resolverFunc;
  private final LoadingCache rdnsCache;
  private final boolean disableRdnsLookup;

  /**
   * Create a new instance with default cache settings: - max 5000 elements in the cache - 5 minutes
   * refresh TTL - 1 hour expiry TTL
   *
   * @param disableRdnsLookup if true, simply return a string representation of the IP address
   * @param metricName if specified, use this metric for the cache size gauge.
   */
  public CachingHostnameLookupResolver(boolean disableRdnsLookup, @Nullable MetricName metricName) {
    this(disableRdnsLookup, metricName, 5000, Duration.ofMinutes(5), Duration.ofHours(1));
  }

  /**
   * Create a new instance with specific cache settings:
   *
   * @param disableRdnsLookup if true, simply return a string representation of the IP address.
   * @param metricName if specified, use this metric for the cache size gauge.
   * @param cacheSize max cache size.
   * @param cacheRefreshTtl trigger cache refresh after specified duration
   * @param cacheExpiryTtl expire items after specified duration
   */
  public CachingHostnameLookupResolver(
      boolean disableRdnsLookup,
      @Nullable MetricName metricName,
      int cacheSize,
      Duration cacheRefreshTtl,
      Duration cacheExpiryTtl) {
    this(
        InetAddress::getHostAddress,
        disableRdnsLookup,
        metricName,
        cacheSize,
        cacheRefreshTtl,
        cacheExpiryTtl);
  }

  @VisibleForTesting
  CachingHostnameLookupResolver(
      @Nonnull Function resolverFunc,
      boolean disableRdnsLookup,
      @Nullable MetricName metricName,
      int cacheSize,
      Duration cacheRefreshTtl,
      Duration cacheExpiryTtl) {
    this.resolverFunc = resolverFunc;
    this.disableRdnsLookup = disableRdnsLookup;
    this.rdnsCache =
        disableRdnsLookup
            ? null
            : Caffeine.newBuilder()
                .maximumSize(cacheSize)
                .refreshAfterWrite(cacheRefreshTtl)
                .expireAfterAccess(cacheExpiryTtl)
                .build(key -> InetAddress.getByAddress(key.getAddress()).getHostName());

    if (metricName != null) {
      Metrics.newGauge(
          metricName,
          new Gauge() {
            @Override
            public Long value() {
              return disableRdnsLookup ? 0 : rdnsCache.estimatedSize();
            }
          });
    }
  }

  @Override
  public String apply(InetAddress addr) {
    return disableRdnsLookup ? resolverFunc.apply(addr) : rdnsCache.get(addr);
  }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy