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

com.newrelic.telemetry.metrics.json.MetricBatchJsonTelemetryBlockWriter Maven / Gradle / Ivy

/*
 * Copyright 2019 New Relic Corporation. All rights reserved.
 * SPDX-License-Identifier: Apache-2.0
 */
package com.newrelic.telemetry.metrics.json;

import static java.lang.Double.isFinite;

import com.newrelic.telemetry.metrics.*;
import java.util.Collection;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.function.Function;
import java.util.stream.Collectors;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

public class MetricBatchJsonTelemetryBlockWriter {

  private static final Logger logger =
      LoggerFactory.getLogger(MetricBatchJsonTelemetryBlockWriter.class);
  private final MetricToJson metricToJson;

  public MetricBatchJsonTelemetryBlockWriter(MetricToJson metricToJson) {
    this.metricToJson = metricToJson;
  }

  public void appendTelemetryJson(MetricBatch batch, StringBuilder builder) {
    builder.append("\"metrics\":").append("[");
    Collection metrics = batch.getTelemetry();

    AtomicInteger retainedCount = new AtomicInteger();
    builder.append(
        metrics
            .stream()
            .filter(this::isValid)
            .map(this::toJsonString)
            .peek(x -> retainedCount.getAndIncrement())
            .collect(Collectors.joining(",")));

    if (retainedCount.get() != metrics.size()) {
      logger.info(
          "Dropped "
              + (metrics.size() - retainedCount.get())
              + " metrics from batch due to invalid metric contents (you should fix this)");
      logAllInvalid(metrics);
    }
    builder.append("]");
  }

  private void logAllInvalid(Collection metrics) {
    metrics.stream().filter(this::isInvalid).forEach(this::logInvalid);
  }

  private void logInvalid(Metric invalidMetric) {
    logger.debug(
        "  * Dropped "
            + typeDispatch(
                invalidMetric,
                count -> "Count(name=" + count.getName() + ",  value = " + count.getValue() + ")",
                gauge -> "Gauge(name=" + gauge.getName() + ", value = " + gauge.getValue() + ")",
                summary -> "Summary(name=" + summary.getName() + ", value = " + summary.getSum()));
  }

  private boolean isInvalid(Metric metric) {
    return !isValid(metric);
  }

  private boolean isValid(Metric metric) {
    return typeDispatch(
        metric,
        count -> isFinite((count.getValue())),
        gauge -> isFinite((gauge.getValue())),
        summary -> isFinite(summary.getSum()));
  }

  private String toJsonString(Metric metric) {
    return typeDispatch(
        metric,
        metricToJson::writeCountJson,
        metricToJson::writeGaugeJson,
        metricToJson::writeSummaryJson);
  }

  private  T typeDispatch(
      Metric metric,
      Function countFunction,
      Function gaugeFunction,
      Function summaryFunction) {
    if (metric instanceof Count) {
      return countFunction.apply((Count) metric);
    }
    if (metric instanceof Gauge) {
      return gaugeFunction.apply((Gauge) metric);
    }
    if (metric instanceof Summary) {
      return summaryFunction.apply((Summary) metric);
    }
    throw new UnsupportedOperationException("Unknown metric type: " + metric.getClass());
  }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy