

# 在 Amazon EC2 实例上设置和配置 Prometheus 指标集合
<a name="CloudWatch-Agent-PrometheusEC2"></a>

以下部分介绍如何在 EC2 实例上安装具有 Prometheus 监控功能的 CloudWatch 代理，以及如何配置代理以抓取其他目标。它还提供了设置示例工作负载以使用 Prometheus 监控进行测试的教程。

同时支持 Linux 和 Windows 实例。

有关 CloudWatch 代理支持的操作系统的信息，请参阅 [使用 CloudWatch 代理采集指标、日志和跟踪数据](Install-CloudWatch-Agent.md)

**VPC 安全组要求**

如果您使用的是 VPC，则以下要求适用。
+ Prometheus 工作负载的安全组的入口规则必须向 CloudWatch 代理打开 Prometheus 端口，以便通过私有 IP 抓取 Prometheus 指标。
+ CloudWatch 代理的安全组的出口规则必须允许 CloudWatch 代理通过私有 IP 连接到 Prometheus 工作负载的端口。

**Topics**
+ [步骤 1：安装 CloudWatch 代理](#CloudWatch-Agent-PrometheusEC2-install)
+ [步骤 2：抓取 Prometheus 源并导入指标](#CloudWatch-Agent-PrometheusEC2-configure)
+ [示例：为 Prometheus 指标测试设置 Java/JMX 示例工作负载](#CloudWatch-Agent-Prometheus-Java)

## 步骤 1：安装 CloudWatch 代理
<a name="CloudWatch-Agent-PrometheusEC2-install"></a>

第一步是在 EC2 实例上安装 CloudWatch 代理。有关说明，请参阅[安装 CloudWatch 代理](install-CloudWatch-Agent-on-EC2-Instance.md)。

## 步骤 2：抓取 Prometheus 源并导入指标
<a name="CloudWatch-Agent-PrometheusEC2-configure"></a>

具有 Prometheus 监控功能的 CloudWatch 代理需要两种配置来抓取 Prometheus 指标。一种是 Prometheus 文档的 [<scrape\$1config>](https://prometheus.io/docs/prometheus/latest/configuration/configuration/#scrape_config) 中记录的标准 Prometheus 配置。另一种配置是 CloudWatch 代理配置文件。

### Prometheus 抓取配置
<a name="CloudWatch-Agent-PrometheusEC2-configure-scrape"></a>

CloudWatch 代理支持标准的 Prometheus 抓取配置，如 Prometheus 文档中的 [<scrape\$1config>](https://prometheus.io/docs/prometheus/latest/configuration/configuration/#scrape_config) 所述。您可以编辑此部分以更新此文件中已有的配置，并添加其他 Prometheus 抓取目标。示例配置文件包含以下全局配置行：

```
PS C:\ProgramData\Amazon\AmazonCloudWatchAgent> cat prometheus.yaml
global:
  scrape_interval: 1m
  scrape_timeout: 10s
scrape_configs:
- job_name: MY_JOB
  sample_limit: 10000
  file_sd_configs:
    - files: ["C:\\ProgramData\\Amazon\\AmazonCloudWatchAgent\\prometheus_sd_1.yaml", "C:\\ProgramData\\Amazon\\AmazonCloudWatchAgent\\prometheus_sd_2.yaml"]
```

`global` 部分指定在所有配置上下文中有效的参数。它们还用作其他配置部分的默认值。它包含以下参数：
+ `scrape_interval` – 定义抓取目标的频率。
+ `scrape_timeout` – 定义在抓取请求超时之前等待的时间。

`scrape_configs` 部分指定了一组目标和参数，用于定义如何抓取它们。它包含以下参数：
+ `job_name` – 默认情况下分配给已抓取指标的任务名称。
+ `sample_limit` – 将被接受的抓取样本数量的每次抓取限制。
+ `file_sd_configs` – 文件服务发现配置的列表。它读取一组包含零个或多个静态配置列表的文件。`file_sd_configs` 部分包含 `files` 参数，该参数定义从中提取目标组的文件的模式。

CloudWatch 代理支持以下服务发现配置类型。

**`static_config`** 允许指定目标列表及其公用标签集。它是在抓取配置中指定静态目标的规范方法。

以下是用于从本地主机中抓取 Prometheus 指标的示例静态配置。如果 Prometheus 端口对运行代理的服务器打开，也可以从其他服务器中抓取指标。

```
PS C:\ProgramData\Amazon\AmazonCloudWatchAgent> cat prometheus_sd_1.yaml
- targets:
    - 127.0.0.1:9404
  labels:
    key1: value1
    key2: value2
```

该示例包括以下参数：
+ `targets` – 由静态配置抓取的目标。
+ `labels` – 分配给从目标中抓取的所有指标的标签。

**`ec2_sd_config`** 允许从 Amazon EC2 实例中检索抓取目标。以下为示例 `ec2_sd_config` 从 EC2 实例列表中抓取 Prometheus 指标。这些实例的 Prometheus 端口必须向运行 CloudWatch 代理的服务器打开。运行 CloudWatch 代理的 EC2 实例的 IAM 角色必须包含 `ec2:DescribeInstance` 权限。例如，您可以将托管式策略 **AmazonEC2ReadOnlyAccess** 附加到运行 CloudWatch 代理的实例。

```
PS C:\ProgramData\Amazon\AmazonCloudWatchAgent> cat prometheus.yaml
global:
  scrape_interval: 1m
  scrape_timeout: 10s
scrape_configs:
  - job_name: MY_JOB
    sample_limit: 10000
    ec2_sd_configs:
      - region: us-east-1
        port: 9404
        filters:
          - name: instance-id
            values:
              - i-98765432109876543
              - i-12345678901234567
```

该示例包括以下参数：
+ `region` – 目标 EC2 实例所在的 Amazon 区域。如果将此项保留空白，则使用实例元数据中的区域。
+ `port` – 要从中抓取指标的端口。
+ `filters` – 用于筛选实例列表的可选筛选条件。此示例基于 EC2 实例 ID 进行筛选。有关可以筛选的更多条件，请参阅 [DescribeInstances](https://docs.amazonaws.cn/AWSEC2/latest/APIReference/API_DescribeInstances.html)。

### Prometheus 的 CloudWatch 代理配置
<a name="CloudWatch-Agent-PrometheusEC2-configure-agent"></a>

CloudWatch 代理配置文件包含 `logs` 和 `metrics_collected` 下的 `prometheus` 部分。它包括以下参数。
+ **cluster\$1name** – 指定要在日志事件中添加为标签的集群名称。该字段是可选的。
+ **log\$1group\$1name** – 指定已抓取 Prometheus 指标的日志组名称。
+ **prometheus\$1config\$1path** – 指定 Prometheus 抓取配置文件路径。
+ **emf\$1processor** – 指定嵌入式指标格式处理器配置。有关嵌入式指标格式的更多信息，请参阅[在日志中嵌入指标](CloudWatch_Embedded_Metric_Format.md)。

  `emf_processor` 部分可能包括以下参数：
  + **metric\$1declaration\$1dedup** – 设置为 true，则启用嵌入式指标格式指标的重复数据消除功能。
  + **metric\$1namespace** – 指定发射的 CloudWatch 指标的指标命名空间。
  + **metric\$1unit** – 指定指标名称：指标单位映射。有关受支持指标单位的信息，请参阅 [MetricDatum](https://docs.amazonaws.cn/AmazonCloudWatch/latest/APIReference/API_MetricDatum.html)。
  + **metric\$1declaration** – 是指定要生成的采用嵌入式指标格式的日志数组的部分。默认情况下，CloudWatch 代理从中进行导入的每个 Prometheus 源都有 `metric_declaration` 部分。这些部分各包括以下字段：
    + `source_labels` 指定由 `label_matcher` 行检查的标签的值。
    + `label_matcher` 是一个正则表达式，用于检查 `source_labels` 中列出的标签的值。匹配的指标将启用，以包含在发送到 CloudWatch 的嵌入式指标格式中。
    + `metric_selectors` 是一个正则表达式，用于指定要收集并发送到 CloudWatch 的指标。
    + `dimensions` 是要用作每个选定指标的 CloudWatch 维度的标签列表。

以下是 Prometheus 的 CloudWatch 代理配置示例。

```
{
   "logs":{
      "metrics_collected":{
         "prometheus":{
            "cluster_name":"prometheus-cluster",
            "log_group_name":"Prometheus",
            "prometheus_config_path":"C:\\ProgramData\\Amazon\\AmazonCloudWatchAgent\\prometheus.yaml",
            "emf_processor":{
               "metric_declaration_dedup":true,
               "metric_namespace":"CWAgent-Prometheus",
               "metric_unit":{
                  "jvm_threads_current": "Count",
                  "jvm_gc_collection_seconds_sum": "Milliseconds"
               },
               "metric_declaration":[
                  {
                     "source_labels":[
                        "job", "key2"
                     ],
                     "label_matcher":"MY_JOB;^value2",
                     "dimensions":[
                        [
                           "key1", "key2"
                        ],
                        [
                           "key2"
                        ]
                     ],
                     "metric_selectors":[
                        "^jvm_threads_current$",
                        "^jvm_gc_collection_seconds_sum$"
                     ]
                  }
               ]
            }
         }
      }
   }
}
```

前一个示例配置嵌入式指标格式部分，以便在满足以下条件时作为日志事件发送：
+ 标签 `job` 的值为 `MY_JOB`
+ 标签 `key2` 的值为 `value2`
+ Prometheus 指标 `jvm_threads_current` 和 `jvm_gc_collection_seconds_sum` 同时包含 `job` 和 `key2` 标签。

发送的日志事件包括以下突出显示的部分。

```
{
    "CloudWatchMetrics": [
        {
            "Metrics": [
                {
                    "Unit": "Count",
                    "Name": "jvm_threads_current"
                },
                {
                    "Unit": "Milliseconds",
                    "Name": "jvm_gc_collection_seconds_sum"
                }
            ],
            "Dimensions": [
                [
                    "key1",
                    "key2"
                ],
                [
                    "key2"
                ]
            ],
            "Namespace": "CWAgent-Prometheus"
        }
    ],
    "ClusterName": "prometheus-cluster",
    "InstanceId": "i-0e45bd06f196096c8",
    "Timestamp": "1607966368109",
    "Version": "0",
    "host": "EC2AMAZ-PDDOIUM",
    "instance": "127.0.0.1:9404",
    "jvm_threads_current": 2,
    "jvm_gc_collection_seconds_sum": 0.006000000000000002,
    "prom_metric_type": "gauge",
    ...
}
```

## 示例：为 Prometheus 指标测试设置 Java/JMX 示例工作负载
<a name="CloudWatch-Agent-Prometheus-Java"></a>

JMX Exporter 是 Prometheus 的官方导出程序，可以将 JMX MBeans 作为 Prometheus 指标进行抓取和公开。有关详细信息，请参阅 [prometheus/jmx\$1exporter](https://github.com/prometheus/jmx_exporter)。

CloudWatch 代理可以从 EC2 实例上的 JMX Exporter 的 Java 虚拟机 (JVM)、Hjava 和 Tomcat (Catalina) 中收集预定义的 Prometheus 指标。

### 步骤 1：安装 CloudWatch 代理
<a name="CloudWatch-Agent-PrometheusJava-install"></a>

第一步是在 EC2 实例上安装 CloudWatch 代理。有关说明，请参阅[安装 CloudWatch 代理](install-CloudWatch-Agent-on-EC2-Instance.md)。

### 步骤 2：启动 Java/JMX 工作负载
<a name="CloudWatch-Agent-PrometheusJava-start"></a>

下一步是启动 Java/JMX 工作负载。

首先，从以下位置下载最新的 JMX Exporter jar 文件：[prometheus/jmx\$1exporter](https://github.com/prometheus/jmx_exporter)。

 **为您的示例应用程序使用 jar**

以下各部分中的示例命令使用 `SampleJavaApplication-1.0-SNAPSHOT.jar` 作为 jar 文件。将命令的这些部分替换为应用程序的 jar。

#### 准备 JMX Exporter 配置
<a name="CloudWatch-Agent-PrometheusJava-start-config"></a>

`config.yaml` 文件是 JMX Exporter 配置文件。有关更多信息，请参阅 JMX Exporter 文档中的[配置](https://github.com/prometheus/jmx_exporter#Configuration)。

以下是 Java 和 Tomcat 的示例配置。

```
---
lowercaseOutputName: true
lowercaseOutputLabelNames: true

rules:
- pattern: 'java.lang<type=OperatingSystem><>(FreePhysicalMemorySize|TotalPhysicalMemorySize|FreeSwapSpaceSize|TotalSwapSpaceSize|SystemCpuLoad|ProcessCpuLoad|OpenFileDescriptorCount|AvailableProcessors)'
  name: java_lang_OperatingSystem_$1
  type: GAUGE

- pattern: 'java.lang<type=Threading><>(TotalStartedThreadCount|ThreadCount)'
  name: java_lang_threading_$1
  type: GAUGE

- pattern: 'Catalina<type=GlobalRequestProcessor, name=\"(\w+-\w+)-(\d+)\"><>(\w+)'
  name: catalina_globalrequestprocessor_$3_total
  labels:
    port: "$2"
    protocol: "$1"
  help: Catalina global $3
  type: COUNTER

- pattern: 'Catalina<j2eeType=Servlet, WebModule=//([-a-zA-Z0-9+&@#/%?=~_|!:.,;]*[-a-zA-Z0-9+&@#/%=~_|]), name=([-a-zA-Z0-9+/$%~_-|!.]*), J2EEApplication=none, J2EEServer=none><>(requestCount|maxTime|processingTime|errorCount)'
  name: catalina_servlet_$3_total
  labels:
    module: "$1"
    servlet: "$2"
  help: Catalina servlet $3 total
  type: COUNTER

- pattern: 'Catalina<type=ThreadPool, name="(\w+-\w+)-(\d+)"><>(currentThreadCount|currentThreadsBusy|keepAliveCount|pollerThreadCount|connectionCount)'
  name: catalina_threadpool_$3
  labels:
    port: "$2"
    protocol: "$1"
  help: Catalina threadpool $3
  type: GAUGE

- pattern: 'Catalina<type=Manager, host=([-a-zA-Z0-9+&@#/%?=~_|!:.,;]*[-a-zA-Z0-9+&@#/%=~_|]), context=([-a-zA-Z0-9+/$%~_-|!.]*)><>(processingTime|sessionCounter|rejectedSessions|expiredSessions)'
  name: catalina_session_$3_total
  labels:
    context: "$2"
    host: "$1"
  help: Catalina session $3 total
  type: COUNTER

- pattern: ".*"
```

#### 使用 Prometheus 导出程序启动 Java 应用程序
<a name="CloudWatch-Agent-PrometheusJava-start-start"></a>

启动示例应用程序。这会将 Prometheus 指标发送到端口 9404。请务必将入口点 `com.gubupt.sample.app.App` 替换为您示例 java 应用程序的正确信息。

在 Linux 操作系统上，输入以下命令。

```
$ nohup java -javaagent:./jmx_prometheus_javaagent-0.14.0.jar=9404:./config.yaml -cp  ./SampleJavaApplication-1.0-SNAPSHOT.jar com.gubupt.sample.app.App &
```

在 Windows 操作系统上，输入以下命令。

```
PS C:\> java -javaagent:.\jmx_prometheus_javaagent-0.14.0.jar=9404:.\config.yaml -cp  .\SampleJavaApplication-1.0-SNAPSHOT.jar com.gubupt.sample.app.App
```

#### 验证 Prometheus 指标发射
<a name="CloudWatch-Agent-PrometheusJava-start-verify"></a>

验证是否正在发射 Prometheus 指标。

在 Linux 操作系统上，输入以下命令。

```
$ curl localhost:9404
```

在 Windows 操作系统上，输入以下命令。

```
PS C:\> curl  http://localhost:9404
```

Linux 上的输出示例：

```
StatusCode        : 200
StatusDescription : OK
Content           : # HELP jvm_classes_loaded The number of classes that are currently loaded in the JVM
                    # TYPE jvm_classes_loaded gauge
                    jvm_classes_loaded 2526.0
                    # HELP jvm_classes_loaded_total The total number of class...
RawContent        : HTTP/1.1 200 OK
                    Content-Length: 71908
                    Content-Type: text/plain; version=0.0.4; charset=utf-8
                    Date: Fri, 18 Dec 2020 16:38:10 GMT

                    # HELP jvm_classes_loaded The number of classes that are currentl...
Forms             : {}
Headers           : {[Content-Length, 71908], [Content-Type, text/plain; version=0.0.4; charset=utf-8], [Date, Fri, 18
                    Dec 2020 16:38:10 GMT]}
Images            : {}
InputFields       : {}
Links             : {}
ParsedHtml        : System.__ComObject
RawContentLength  : 71908
```

### 步骤 3：配置 CloudWatch 代理以抓取 Prometheus 指标
<a name="CloudWatch-Agent-PrometheusJava-agent"></a>

接下来，在 CloudWatch 代理配置文件中设置 Prometheus 抓取配置。

**为 Java/JMX 示例设置 Prometheus 抓取配置**

1. 设置 `file_sd_config` 和 `static_config` 配置。

   在 Linux 操作系统上，输入以下命令。

   ```
   $ cat /opt/aws/amazon-cloudwatch-agent/var/prometheus.yaml
   global:
     scrape_interval: 1m
     scrape_timeout: 10s
   scrape_configs:
     - job_name: jmx
       sample_limit: 10000
       file_sd_configs:
         - files: [ "/opt/aws/amazon-cloudwatch-agent/var/prometheus_file_sd.yaml" ]
   ```

   在 Windows 操作系统上，输入以下命令。

   ```
   PS C:\ProgramData\Amazon\AmazonCloudWatchAgent> cat prometheus.yaml
   global:
     scrape_interval: 1m
     scrape_timeout: 10s
   scrape_configs:
     - job_name: jmx
       sample_limit: 10000
       file_sd_configs:
         - files: [ "C:\\ProgramData\\Amazon\\AmazonCloudWatchAgent\\prometheus_file_sd.yaml" ]
   ```

1. 设置抓取目标配置。

   在 Linux 操作系统上，输入以下命令。

   ```
   $ cat /opt/aws/amazon-cloudwatch-agent/var/prometheus_file_sd.yaml
   - targets:
     - 127.0.0.1:9404
     labels:
       application: sample_java_app
       os: linux
   ```

   在 Windows 操作系统上，输入以下命令。

   ```
   PS C:\ProgramData\Amazon\AmazonCloudWatchAgent> cat prometheus_file_sd.yaml
   - targets:
     - 127.0.0.1:9404
     labels:
       application: sample_java_app
       os: windows
   ```

1. 通过 `ec2_sc_config` 设置 Prometheus 抓取配置。用正确的 EC2 实例 ID 替代 *your-ec2-instance-id*。

   在 Linux 操作系统上，输入以下命令。

   ```
   $ cat .\prometheus.yaml
   global:
     scrape_interval: 1m
     scrape_timeout: 10s
   scrape_configs:
     - job_name: jmx
       sample_limit: 10000
       ec2_sd_configs:
         - region: us-east-1
           port: 9404
           filters:
             - name: instance-id
               values:
                 - your-ec2-instance-id
   ```

   在 Windows 操作系统上，输入以下命令。

   ```
   PS C:\ProgramData\Amazon\AmazonCloudWatchAgent> cat prometheus_file_sd.yaml
   - targets:
     - 127.0.0.1:9404
     labels:
       application: sample_java_app
       os: windows
   ```

1. 设置 CloudWatch 代理配置。首先，导航到正确的目录。在 Linux 上，它是 `/opt/aws/amazon-cloudwatch-agent/var/cwagent-config.json`。在 Windows 上，它是 `C:\ProgramData\Amazon\AmazonCloudWatchAgent\cwagent-config.json`。

   以下是定义了 Java/JHX Prometheus 指标的示例配置。请务必使用正确的路径替换 *path-to-Prometheus-Scrape-Configuration-file*。

   ```
   {
     "agent": {
       "region": "us-east-1"
     },
     "logs": {
       "metrics_collected": {
         "prometheus": {
           "cluster_name": "my-cluster",
           "log_group_name": "prometheus-test",
           "prometheus_config_path": "path-to-Prometheus-Scrape-Configuration-file",
           "emf_processor": {
             "metric_declaration_dedup": true,
             "metric_namespace": "PrometheusTest",
             "metric_unit":{
               "jvm_threads_current": "Count",
               "jvm_classes_loaded": "Count",
               "java_lang_operatingsystem_freephysicalmemorysize": "Bytes",
               "catalina_manager_activesessions": "Count",
               "jvm_gc_collection_seconds_sum": "Seconds",
               "catalina_globalrequestprocessor_bytesreceived": "Bytes",
               "jvm_memory_bytes_used": "Bytes",
               "jvm_memory_pool_bytes_used": "Bytes"
             },
             "metric_declaration": [
               {
                 "source_labels": ["job"],
                 "label_matcher": "^jmx$",
                 "dimensions": [["instance"]],
                 "metric_selectors": [
                   "^jvm_threads_current$",
                   "^jvm_classes_loaded$",
                   "^java_lang_operatingsystem_freephysicalmemorysize$",
                   "^catalina_manager_activesessions$",
                   "^jvm_gc_collection_seconds_sum$",
                   "^catalina_globalrequestprocessor_bytesreceived$"
                 ]
               },
               {
                 "source_labels": ["job"],
                 "label_matcher": "^jmx$",
                 "dimensions": [["area"]],
                 "metric_selectors": [
                   "^jvm_memory_bytes_used$"
                 ]
               },
               {
                 "source_labels": ["job"],
                 "label_matcher": "^jmx$",
                 "dimensions": [["pool"]],
                 "metric_selectors": [
                   "^jvm_memory_pool_bytes_used$"
                 ]
               }
             ]
           }
         }
       },
       "force_flush_interval": 5
     }
   }
   ```

1. 通过输入以下命令之一，重新启动 CloudWatch 代理。

   在 Linux 操作系统上，输入以下命令。

   ```
   sudo /opt/aws/amazon-cloudwatch-agent/bin/amazon-cloudwatch-agent-ctl -a fetch-config -m ec2 -s -c file:/opt/aws/amazon-cloudwatch-agent/var/cwagent-config.json
   ```

   在 Windows 操作系统上，输入以下命令。

   ```
   & "C:\Program Files\Amazon\AmazonCloudWatchAgent\amazon-cloudwatch-agent-ctl.ps1" -a fetch-config -m ec2 -s -c file:C:\ProgramData\Amazon\AmazonCloudWatchAgent\cwagent-config.json
   ```

### 查看 Prometheus 指标和日志
<a name="CloudWatch-Agent-PrometheusJava-view"></a>

您现在可以查看正在收集的 Java/JMX 指标。

**查看 Java/JMX 示例工作负载的指标**

1. 通过 [https://console.aws.amazon.com/cloudwatch/](https://console.amazonaws.cn/cloudwatch/) 打开 CloudWatch 控制台。

1. 在运行集群的区域中，选择左侧导航窗格中的 **Metrics（指标）**。查找 **PrometheusTest** 命名空间以查看指标。

1. 要查看 CloudWatch Logs 事件，请在导航窗格中选择 **Log groups（日志组）**。这些事件位于日志组 **prometheus-test** 中。