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

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

There is a newer version: 9999.0
Show newest version
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 javax.annotation.Nonnull;
import javax.annotation.Nullable;
import java.net.InetAddress;
import java.time.Duration;
import java.util.function.Function;

/**
 * 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