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

com.spotify.apollo.metrics.semantic.SemanticRequestMetrics Maven / Gradle / Ivy

There is a newer version: 1.6.4
Show newest version
/*
 * -\-\-
 * Spotify Apollo Metrics Module
 * --
 * Copyright (C) 2013 - 2016 Spotify AB
 * --
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 * 
 *      http://www.apache.org/licenses/LICENSE-2.0
 * 
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 * -/-/-
 */
package com.spotify.apollo.metrics.semantic;

import com.codahale.metrics.Histogram;
import com.codahale.metrics.Meter;
import com.codahale.metrics.Timer;
import com.spotify.apollo.Request;
import com.spotify.apollo.Response;
import com.spotify.apollo.StatusType;
import com.spotify.apollo.metrics.RequestMetrics;

import java.util.Optional;
import java.util.function.Consumer;

import okio.ByteString;

import static com.spotify.apollo.StatusType.Family.INFORMATIONAL;
import static com.spotify.apollo.StatusType.Family.SUCCESSFUL;
import static java.util.Objects.requireNonNull;

// Optional fields are fine; they enable the use of the 'ifPresent' idiom which is more readable
// than if statements
@SuppressWarnings("OptionalUsedAsFieldOrParameterType")
class SemanticRequestMetrics implements RequestMetrics {

  private final Optional>> requestRateCounter;
  private final Optional fanoutHistogram;
  private final Optional requestSizeHistogram;
  private final Optional responseSizeHistogram;
  private final Optional timerContext;
  private final Optional droppedRequests;
  private final Meter sentReplies;
  private final Meter sentErrors;

  SemanticRequestMetrics(
      Optional>> requestRateCounter,
      Optional fanoutHistogram,
      Optional responseSizeHistogram,
      Optional requestSizeHistogram,
      Optional timerContext,
      Optional droppedRequests,
      Meter sentReplies,
      Meter sentErrors) {

    this.requestRateCounter = requireNonNull(requestRateCounter);
    this.fanoutHistogram = requireNonNull(fanoutHistogram);
    this.responseSizeHistogram = requireNonNull(responseSizeHistogram);
    this.requestSizeHistogram = requireNonNull(requestSizeHistogram);
    this.timerContext = requireNonNull(timerContext);
    this.droppedRequests = requireNonNull(droppedRequests);
    this.sentReplies = requireNonNull(sentReplies);
    this.sentErrors = requireNonNull(sentErrors);
  }

  @Override
  public void incoming(Request request) {
    requestSizeHistogram
        .ifPresent(histogram -> request.payload()
            .ifPresent(payload -> histogram.update(payload.size())));
  }

  @Override
  public void fanout(int requests) {
    fanoutHistogram.ifPresent(histogram -> histogram.update(requests));
  }

  @Override
  public void response(Response response) {
    requestRateCounter.ifPresent(consumer -> consumer.accept(response));
    responseSizeHistogram
        .ifPresent(histogram -> response.payload()
            .ifPresent(payload -> histogram.update(payload.size())));

    sentReplies.mark();
    timerContext.ifPresent(Timer.Context::stop);

    StatusType.Family family = response.status().family();
    if (family != INFORMATIONAL && family != SUCCESSFUL) {
      sentErrors.mark();
    }
  }

  @Override
  public void drop() {
    droppedRequests.ifPresent(Meter::mark);
    timerContext.ifPresent(Timer.Context::stop);
  }
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy