View Javadoc
1   /*
2    * Copyright 2021 TiKV Project Authors.
3    *
4    * Licensed under the Apache License, Version 2.0 (the "License");
5    * you may not use this file except in compliance with the License.
6    * You may obtain a copy of the License at
7    *
8    * http://www.apache.org/licenses/LICENSE-2.0
9    *
10   * Unless required by applicable law or agreed to in writing, software
11   * distributed under the License is distributed on an "AS IS" BASIS,
12   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13   * See the License for the specific language governing permissions and
14   * limitations under the License.
15   *
16   */
17  
18  package org.tikv.common;
19  
20  import io.prometheus.client.exporter.HTTPServer;
21  import io.prometheus.client.hotspot.DefaultExports;
22  import org.slf4j.Logger;
23  import org.slf4j.LoggerFactory;
24  
25  public class MetricsServer {
26    private static final Logger logger = LoggerFactory.getLogger(MetricsServer.class);
27  
28    private static MetricsServer METRICS_SERVER_INSTANCE = null;
29    private static int metricsServerRefCount = 0;
30  
31    private final int port;
32    private final HTTPServer server;
33  
34    public static MetricsServer getInstance(TiConfiguration conf) {
35      if (!conf.isMetricsEnable()) {
36        return null;
37      }
38  
39      synchronized (MetricsServer.class) {
40        int port = conf.getMetricsPort();
41        if (METRICS_SERVER_INSTANCE != null) {
42          if (port != METRICS_SERVER_INSTANCE.port) {
43            throw new IllegalArgumentException(
44                String.format(
45                    "Do dot support multiple tikv.metrics.port, which are %d and %d",
46                    port, METRICS_SERVER_INSTANCE.port));
47          }
48        } else {
49          METRICS_SERVER_INSTANCE = new MetricsServer(port);
50        }
51        metricsServerRefCount += 1;
52        return METRICS_SERVER_INSTANCE;
53      }
54    }
55  
56    private MetricsServer(int port) {
57      try {
58        this.port = port;
59        DefaultExports.initialize();
60        this.server = new HTTPServer(port, true);
61        logger.info("http server is up " + this.server.getPort());
62      } catch (Exception e) {
63        logger.error("http server not up");
64        throw new RuntimeException(e);
65      }
66    }
67  
68    public void close() {
69      synchronized (MetricsServer.class) {
70        if (metricsServerRefCount == 1) {
71          if (server != null) {
72            server.stop();
73            logger.info("Metrics server on " + server.getPort() + " is stopped");
74          }
75          METRICS_SERVER_INSTANCE = null;
76        }
77  
78        if (metricsServerRefCount >= 1) {
79          metricsServerRefCount -= 1;
80        }
81      }
82    }
83  }