Add request field to operations_counts metric

This way we can tell from the metric which and how many operations are
executed for a certain request kind. Knowing this is interesting. E.g.
if we want to improve the performance of a certain REST endpoint it
tells us which operations are involved. Looking at the operations
metric we know how long these operations take and based on this we can
decide which operations are most critical and should be optimised first.

Signed-off-by: Edwin Kempin <ekempin@google.com>
Change-Id: I723faeff699330526de375c3f69119b3f73a54db
diff --git a/java/com/google/gerrit/server/PerformanceMetrics.java b/java/com/google/gerrit/server/PerformanceMetrics.java
index e4e4db5..fa6e22c 100644
--- a/java/com/google/gerrit/server/PerformanceMetrics.java
+++ b/java/com/google/gerrit/server/PerformanceMetrics.java
@@ -15,7 +15,7 @@
 package com.google.gerrit.server;
 
 import com.google.gerrit.common.Nullable;
-import com.google.gerrit.metrics.Counter2;
+import com.google.gerrit.metrics.Counter3;
 import com.google.gerrit.metrics.Description;
 import com.google.gerrit.metrics.Field;
 import com.google.gerrit.metrics.MetricMaker;
@@ -34,7 +34,7 @@
   private static final String OPERATION_COUNT_METRIC_NAME = "performance/operations_count";
 
   public final Timer3<String, String, String> operationsLatency;
-  public final Counter2<String, String> operationsCounter;
+  public final Counter3<String, String, String> operationsCounter;
 
   @Inject
   PerformanceMetrics(MetricMaker metricMaker) {
@@ -47,6 +47,8 @@
         Field.ofString("change_identifier", (metadataBuilder, fieldValue) -> {}).build();
     Field<String> traceIdField =
         Field.ofString("trace_id", (metadataBuilder, fieldValue) -> {}).build();
+    Field<String> requestField =
+        Field.ofString("request", (metadataBuilder, fieldValue) -> {}).build();
 
     this.operationsLatency =
         metricMaker.newTimer(
@@ -62,7 +64,8 @@
             OPERATION_COUNT_METRIC_NAME,
             new Description("Number of performed operations").setRate(),
             operationNameField,
-            traceIdField);
+            traceIdField,
+            requestField);
   }
 
   @Override
@@ -86,7 +89,8 @@
     operationsLatency.record(
         operation, formatChangeIdentifier(metadata), traceId, durationMs, TimeUnit.MILLISECONDS);
 
-    operationsCounter.increment(operation, traceId);
+    String requestTag = TraceContext.getTag(TraceRequestListener.TAG_REQUEST).orElse("");
+    operationsCounter.increment(operation, traceId, requestTag);
   }
 
   private String formatChangeIdentifier(@Nullable Metadata metadata) {
diff --git a/java/com/google/gerrit/server/TraceRequestListener.java b/java/com/google/gerrit/server/TraceRequestListener.java
index e7c2605..6cc0982 100644
--- a/java/com/google/gerrit/server/TraceRequestListener.java
+++ b/java/com/google/gerrit/server/TraceRequestListener.java
@@ -28,7 +28,8 @@
  */
 @Singleton
 public class TraceRequestListener implements RequestListener {
-  private static String TAG_REQUEST = "request";
+  public static String TAG_REQUEST = "request";
+
   private static String TAG_PROJECT = "project";
   private static String SECTION_TRACING = "tracing";
 
diff --git a/java/com/google/gerrit/server/logging/TraceContext.java b/java/com/google/gerrit/server/logging/TraceContext.java
index fb2d34d..e333824 100644
--- a/java/com/google/gerrit/server/logging/TraceContext.java
+++ b/java/com/google/gerrit/server/logging/TraceContext.java
@@ -277,6 +277,10 @@
         .findFirst();
   }
 
+  public static Optional<String> getTag(String tagName) {
+    return LoggingContext.getInstance().getTagsAsMap().get(tagName).stream().findFirst();
+  }
+
   public TraceContext enableAclLogging() {
     if (stopAclLoggingOnClose) {
       return this;