content: /*
   * Licensed to the Apache Software Foundation (ASF) under one or more
   * contributor license agreements.  See the NOTICE file distributed with
   * this work for additional information regarding copyright ownership.
   * The ASF licenses this file to You 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 org.apache.dolphinscheduler.api.metrics;
  
  import java.util.concurrent.TimeUnit;
  import java.util.function.Supplier;
  
  import lombok.experimental.UtilityClass;
  import io.micrometer.core.instrument.Counter;
  import io.micrometer.core.instrument.DistributionSummary;
  import io.micrometer.core.instrument.Gauge;
  import io.micrometer.core.instrument.Metrics;
  import io.micrometer.core.instrument.Timer;
  
  @UtilityClass
  public class ApiServerMetrics {
  
      private final Counter apiRequestCounter =
              Counter.builder("ds.api.request.count")
                      .description("Api request count")
                      .register(Metrics.globalRegistry);
  
      private final Counter apiResponse2xxCounter =
              Counter.builder("ds.api.response.count")
                      .tag("code", "2xx")
                      .description("Api 2xx response count")
                      .register(Metrics.globalRegistry);
  
      private final Counter apiResponse3xxCounter =
              Counter.builder("ds.api.response.count")
                      .tag("code", "3xx")
                      .description("Api 3xx response count")
                      .register(Metrics.globalRegistry);
  
      private final Counter apiResponse4xxCounter =
              Counter.builder("ds.api.response.count")
                      .tag("code", "4xx")
                      .description("Api 4xx response count")
                      .register(Metrics.globalRegistry);
  
      private final Counter apiResponse5xxCounter =
              Counter.builder("ds.api.response.count")
                      .tag("code", "5xx")
                      .description("Api 5xx response count")
                      .register(Metrics.globalRegistry);
  
      private final DistributionSummary apiResourceUploadSizeDistribution =
              DistributionSummary.builder("ds.api.resource.upload.size")
                      .baseUnit("bytes")
                      .publishPercentiles(0.5, 0.75, 0.95, 0.99)
                      .publishPercentileHistogram()
                      .description("size of upload resource files on api")
                      .register(Metrics.globalRegistry);
  
      private final DistributionSummary apiResourceDownloadSizeDistribution =
              DistributionSummary.builder("ds.api.resource.download.size")
                      .baseUnit("bytes")
                      .publishPercentiles(0.5, 0.75, 0.95, 0.99)
                      .publishPercentileHistogram()
                      .description("size of download resource files on api")
                      .register(Metrics.globalRegistry);
  
      static {
          Timer.builder("ds.api.response.time")
                  .tag("user.id", "dummy")
                  .description("response time on api")
                  .register(Metrics.globalRegistry);
      }
  
      public void incApiRequestCount() {
          apiRequestCounter.increment();
      }
  
      public void incApiResponse2xxCount() {
          apiResponse2xxCounter.increment();
      }
  
      public void incApiResponse3xxCount() {
          apiResponse3xxCounter.increment();
      }
  
      public void incApiResponse4xxCount() {
          apiResponse4xxCounter.increment();
      }
  
      public void incApiResponse5xxCount() {
          apiResponse5xxCounter.increment();
      }
  
      public void recordApiResourceUploadSize(final long size) {
          apiResourceUploadSizeDistribution.record(size);
      }
  
      public void recordApiResourceDownloadSize(final long size) {
          apiResourceDownloadSizeDistribution.record(size);
      }
  
      public void recordApiResponseTime(final long milliseconds, final int userId) {
          Metrics.globalRegistry.timer(
                  "ds.api.response.time",
                  "user.id", String.valueOf(userId)).record(milliseconds, TimeUnit.MILLISECONDS);
      }
  
      public void cleanUpApiResponseTimeMetricsByUserId(final int userId) {
          Metrics.globalRegistry.remove(
                  Metrics.globalRegistry.timer(
                          "ds.api.response.time",
                          "user.id", String.valueOf(userId)));
      }
  
      public static void registerUncachedException(final Supplier<Number> supplier) {
          Gauge.builder("ds.api.uncached.exception", supplier)
                  .description("number of uncached exception")
                  .register(Metrics.globalRegistry);
      }
  }
  