def apply()

in thrift/src/main/scala/com/twitter/finatra/thrift/filters/StatsFilter.scala [25:120]


    def apply(stats: StatsReceiver): ThriftMethodStats =
      ThriftMethodStats(
        failuresCounter = stats.counter("failures"),
        failuresScope = stats.scope("failures"),
        ignoredCounter = stats.counter("ignored"),
        ignoredScope = stats.scope("ignored"),
        latencyStat = stats.stat("latency_ms"),
        successCounter = stats.counter("success"),
        successesScope = stats.scope("success"),
        requestsCounter = stats.counter("requests")
      )
  }

  /** INTENDED FOR INTERNAL USE ONLY */
  case class ThriftMethodStats(
    failuresCounter: Counter,
    failuresScope: StatsReceiver,
    ignoredCounter: Counter,
    ignoredScope: StatsReceiver,
    latencyStat: Stat,
    successCounter: Counter,
    successesScope: StatsReceiver,
    requestsCounter: Counter)
}

/**
 * Tracks "per method" statistics scoped under `per_method_stats/<method>` including:
 *  - success/failure (with exceptions) counters
 *  - latency_ms histogram
 *
 * Example stats for a successful request to a method named `foo`:
 *
 * {{{
 *   per_method_stats/foo/failures 0
 *   per_method_stats/foo/ignored 0
 *   per_method_stats/foo/requests 1
 *   per_method_stats/foo/success 1
 *   per_method_stats/foo/latency_ms 43.000000 [43.0]
 * }}}
 *
 * Example stats, for a failed request to a method named `foo`:
 *
 * {{{
 *   exceptions 1
 *   exceptions/java.lang.Exception 1
 *   per_method_stats/foo/failures 1
 *   per_method_stats/foo/failures/java.lang.Exception 1
 *   per_method_stats/foo/ignored 0
 *   per_method_stats/foo/requests 1
 *   per_method_stats/foo/success 0
 *   per_method_stats/foo/latency_ms 43.000000 [43.0]
 * }}}
 *
 * Example stats, for a failed request to a method named `foo` with a [[ResponseClassifier]] which
 * classifies [[java.lang.Exception]] as Ignorable:
 *
 * {{{
 *   exceptions 1
 *   exceptions/java.lang.Exception 1
 *   per_method_stats/foo/failures 0
 *   per_method_stats/foo/ignored 1
 *   per_method_stats/foo/ignored/java.lang.Exception 1
 *   per_method_stats/foo/requests 1
 *   per_method_stats/foo/success 0
 *   per_method_stats/foo/latency_ms 43.000000 [43.0]
 * }}}
 *
 * requests == success + failures + ignored
 * The logical success rate for a method can be calculated as `success / (success + failures)`
 *
 * @note It is expected that this Filter is inserted ABOVE the [[ExceptionMappingFilter]] in a
 *       given filter chain, e.g., `StatsFilter.andThen(ExceptionMappingFilter)`.
 *       For the response flow, [[StatsFilter]] would happen AFTER [[ExceptionMappingFilter]] and
 *       calculate mapped result.
 * @param statsReceiver      the [[com.twitter.finagle.stats.StatsReceiver]] to which
 *                           to record stats.
 * @param responseClassifier a [[ThriftResponseClassifier]] used to determine when a response
 *                           is successful or not.
 */
@Singleton
class StatsFilter @Inject() (
  statsReceiver: StatsReceiver,
  responseClassifier: ThriftResponseClassifier)
    extends Filter.TypeAgnostic {
  import StatsFilter._

  /* Public */

  /**
   * Secondary constructor which accepts a [[StatsReceiver]]. The [[ThriftResponseClassifier]]
   * is defaulted to [[ThriftResponseClassifier.ThriftExceptionsAsFailures]].
   *
   * @param statsReceiver the [[com.twitter.finagle.stats.StatsReceiver]] to which
   *                      to record stats.
   */
  def this(statsReceiver: StatsReceiver) {