代理中用户定义的指标

本指南介绍如何配置 Monitoring 代理以识别您的应用指标并将其导出到 Cloud Monitoring。

Monitoring 代理是一个 collectd 守护进程。除了将许多预定义的系统和第三方指标导出到 Cloud Monitoring 之外,该代理还可以将您自己 collectd 应用指标作为用户定义指标导出到 Monitoring。您的 collectd 插件也可以导出到 Monitoring。

将应用指标导出到 Monitoring 的另一种方法是使用 StatsD。Cloud Monitoring 提供将 StatsD 指标映射到用户定义指标的默认配置。如果您对该映射感到满意,则不需要执行下述自定义步骤。如需了解详情,请参阅 StatsD 插件

如需详细了解指标,请参阅以下文档:

此功能仅适用于在 Linux 上运行的代理。此功能不适用于 Windows。

准备工作

  • 在虚拟机实例上安装最新的 Monitoring 代理,并验证其是否能正常工作。要更新您的代理,请参阅更新代理

  • 配置 collectd,以便从应用中获得监控数据。 Collectd 通过其读取插件支持多个应用框架和标准监控端点。找到适合您的读取插件。

  • (可选)为方便起见,您可以将代理的 collectd 参考文档添加到您系统的 man 页面,方法是更新 MANPATH 变量并运行 mandb

    export MANPATH="$MANPATH:/opt/stackdriver/collectd/share/man"
    sudo mandb
    

    手册页面适用于 stackdriver-collectd

重要文件和目录

通过安装代理创建的以下文件和目录与使用 Monitoring 代理 (collectd) 相关:

/etc/stackdriver/collectd.conf

代理使用的 collectd 配置文件。请修改此文件以更改常规配置。

/etc/stackdriver/collectd.d/

用户添加的配置文件的目录。如需通过代理发送用户定义的指标,您应该将下方讨论的所需配置文件置于此目录中。为了实现向后兼容性,代理还会在 /opt/stackdriver/collectd/etc/collectd.d/ 中查找文件。

/opt/stackdriver/collectd/share/man/*

代理的 collectd 版本的文档。您可以将这些页面添加到系统的一组 man 页面;如需了解详情,请参阅准备工作

/etc/init.d/stackdriver-agent

代理的 init 脚本。

Monitoring 如何处理 collectd 指标

在后台,Monitoring 代理会处理 collectd 指标并将其发送到 Monitoring,Monitoring 会将每个指标视为以下类别中的一个:

  • 用户定义的指标。系统会将具有元数据键 stackdriver_metric_type 和单一数据源的 collectd 指标作为用户定义的指标处理,并使用 Monitoring API 中的 projects.timeSeries.create 方法发送至 Monitoring。

  • 特选指标。所有其他 collectd 指标都是通过内部 API 发送到 Monitoring 的。仅接受和处理特选指标列表中的指标。

  • 舍弃的指标。不在精选指标列表中且不是用户定义的指标的 collectd 指标将被 Monitoring 以静默方式舍弃。代理本身不知道哪些指标被接受或被舍弃。

使用代理写入用户定义的指标

您要配置代理,以将指标数据点发送到 Monitoring。每个数据点必须与一个用户定义的指标相关联,该指标由您通过指标描述符定义。如需简要了解这些概念,请参阅指标、时序和资源;如需详细了解这些概念,请参阅时序的结构用户定义的指标概览

通过向 collectd 指标添加适当的元数据,您可以使该指标被视为用户定义的指标:

  • stackdriver_metric_type:(必填)导出的指标的名称。 示例:custom.googleapis.com/my_custom_metric

  • label:[LABEL]:(可选)导出指标的附加标签。例如,如果您想要一个名为 color 的 Monitoring STRING 标签,则您的元数据键将为 label:color,该键的值可以是 "blue"。每个指标类型最多可以有 10 个标签。

您可以使用 collectd 过滤条件链来修改指标的元数据。由于过滤条件链无法修改数据源列表,且用户定义的指标仅支持单一数据源,因此您想要与 collectd 过滤条件链一同使用的 collectd 指标必须具备单一数据源。

示例

在此示例中,我们将监控来自两个 Nginx 服务(my_service_amy_service_b)的活动 Nginx 连接。我们将使用用户定义的指标将这些连接发送到 Monitoring。具体步骤如下:

  1. 识别每个 Nginx 服务的 collectd 指标。

  2. 定义 Monitoring 指标描述符。

  3. 配置 collectd 过滤条件链,以将元数据添加到 collectd 指标,从而满足 Monitoring 代理的期望。

传入的 collectd 指标

Collectd 预计指标将由以下组件组成:前五个组件构成指标的 collectd 标识符

    Host, Plugin, Plugin-instance, Type, Type-instance, [value]

在本例中,您想要作为用户定义的指标发送的指标具有以下值:

组件 预期值
主机 任何
插件 curl_json
插件实例 nginx_my_service_a
nginx_my_service_b1
类型 gauge
类型实例 active-connections
[value] 任意值2

备注
1 在此示例中,该值对应用 (Nginx) 和已连接服务的名称进行编码。
2 该值通常是一个时间戳,且是双精度数字。Monitoring 负责处理关于解读各类值的详细信息。Monitoring 代理不支持复合值。

Monitoring 指标描述符和时间序列

在 Monitoring 中,为您的用户定义指标设计指标描述符。以下描述符是本示例中数据的合理选择:

  • 名称:custom.googleapis.com/nginx/active_connections
  • 标签:
    • service_name(STRING):与 Nginx 关联的服务的名称。
  • 种类:GAUGE
  • 类型:DOUBLE

设计好指标描述符后,您可以使用 projects.metricDescriptors.create 进行创建,也可以借助时序元数据自动创建(如下文所述)。如需了解详情,请参阅此页面中的创建指标描述符

鉴于指标描述符的定义方式,该指标描述符的时间序列数据必须包含以下信息:

  • 指标类型:custom.googleapis.com/nginx/active_connections
  • 指标标签值:
    • service_name"my_service_a""my_service_b"

对于所有指标,代理会自动获取其他时间序列信息,包括相关联的受监控资源(发送数据的虚拟机实例)和指标的数据点。您无需执行任何特殊操作。

您的过滤条件链

创建一个文件,/opt/stackdriver/collectd/etc/collectd.d/nginx_curl_json.conf,其中包含以下代码:

LoadPlugin match_regex
LoadPlugin target_set
LoadPlugin target_replace

# Insert a new rule in the default "PreCache" chain, to divert your metrics.
PreCacheChain "PreCache"
<Chain "PreCache">
  <Rule "jump_to_custom_metrics_from_curl_json">
    # If the plugin name and instance match, this is PROBABLY a metric we're looking for:
    <Match regex>
      Plugin "^curl_json$"
      PluginInstance "^nginx_"
    </Match>
    <Target "jump">
      # Go execute the following chain; then come back.
      Chain "PreCache_curl_json"
    </Target>
  </Rule>
  # Continue processing metrics in the default "PreCache" chain.
</Chain>

# Following is a NEW filter chain, just for your metric.
# It is only executed if the default chain "jumps" here.
<Chain "PreCache_curl_json">

  # The following rule does all the work for your metric:
  <Rule "rewrite_curl_json_my_special_metric">
    # Do a careful match for just your metrics; if it fails, drop down
    # to the next rule:
    <Match regex>
      Plugin "^curl_json$"                   # Match on plugin.
      PluginInstance "^nginx_my_service_.*$" # Match on plugin instance.
      Type "^gauge$"                         # Match on type.
      TypeInstance "^active-connections$"    # Match on type instance.
    </Match>

    <Target "set">
      # Specify the metric descriptor type:
      MetaData "stackdriver_metric_type" "custom.googleapis.com/nginx/active_connections"
      # Specify a value for the "service_name" label; clean it up in the next Target:
      MetaData "label:service_name" "%{plugin_instance}"
    </Target>

    <Target "replace">
      # Remove the "nginx_" prefix in the service_name to get the real service name:
      MetaData "label:service_name" "nginx_" ""
    </Target>
  </Rule>

  # The following rule is run after rewriting your metric, or
  # if the metric wasn't one of your user-defined metrics. The rule returns
  # to the default "PreCache" chain. The default processing
  # will write all metrics to Cloud Monitoring,
  # which will drop any unrecognized metrics: ones that aren't
  # in the list of curated metrics and don't have
  # the user-defined metric metadata.
  <Rule "go_back">
    Target "return"
  </Rule>
</Chain>

加载新配置

通过在虚拟机实例上执行以下命令,重启您的代理以选择新配置:

sudo service stackdriver-agent restart

您的用户定义的指标信息会开始传输至 Monitoring。

参考和最佳做法

指标描述符和时间序列

如需了解 Cloud Monitoring 指标,请参阅指标、时间序列和资源。如需了解详情,请参阅用户定义的指标概览时序的结构

指标描述符。指标描述符具备以下重要部分:

  • 类型,格式为 custom.googleapis.com/[NAME1]/.../[NAME0]。例如:

    custom.googleapis.com/my_measurement
    custom.googleapis.com/instance/network/received_packets_count
    custom.googleapis.com/instance/network/sent_packets_count
    

    建议采用层次化命名,使指标更易于跟踪。指标类型不能包含连字符;如需了解确切的命名规则,请参阅命名指标类型和标签

  • 最多 10 个标签,用于为指标数据添加注释,例如 device_namefault_typeresponse_code。标签的值不在指标描述符中指定。

  • 数据点的种类和值类型,如“double 类型的 gauge 值”。如需了解详情,请参阅 MetricKindValueType

时间序列。指标数据点具备以下重要部分:

  • 关联的指标描述符的类型。

  • 所有指标描述符标签的值。

  • 与指标描述符的值类型和种类一致的带时间戳的值。

  • 数据所属的受监控的资源,通常是虚拟机实例。资源的空间是内置的,因此描述符不需要单独的标签。

创建指标描述符

您不必提前创建指标描述符。 当数据点到达 Monitoring 时,系统可使用该数据点的指标类型、标签和值自动创建 gauge 或 cumulative 指标描述符。如需了解详情,请参阅自动创建指标描述符

不过,自行创建指标描述符具有以下优势:

  • 您可以为指标及其标签添加一些周到的文档。

  • 您可以指定其他指标种类和类型。代理仅支持下列(种类,类型)组合:(GAUGE, DOUBLE) 和 (CUMULATIVE, INT64)。如需了解详情,请参阅指标种类和值类型

  • 您可以指定除 STRING 以外的标签类型。

如果您将使用未定义指标类型的数据点写入 Monitoring,则系统会为该数据点创建新的指标描述符。如果您正在对写入指标数据的代码进行调试,这可能会造成问题:指标类型拼写错误将产生虚假的指标描述符。

在您创建指标描述符后,或者系统为您创建指标描述符后,该指标描述符便无法更改。例如,您无法添加或移除标签。您只能删除指标描述符(此操作将删除其所有数据),然后以您想要的方式重新创建描述符。

如需详细了解如何创建指标描述符,请参阅创建指标

价格

一般来说,Cloud Monitoring 系统指标是免费的,而来自外部系统、代理或应用的指标则需要付费。可计费指标按注入的字节数或样本数计费。

如需详细了解 Cloud Monitoring 的价格,请参阅以下文档:

限制

Cloud Monitoring 对每个项目中的指标时间序列数量和用户定义的指标描述符数量有限制。如需了解详情,请参阅配额和限制

如果您发现已创建不再需要的指标描述符,可以使用 Monitoring API 查找和删除描述符。如需了解详情,请参阅 projects.metricDescriptors

问题排查

本部分介绍如何配置 Monitoring 代理的 write_log 插件以输出整套指标数据点,包括元数据。此方法可用于确定需要转换的数据点,并确保您的转换按预期方式进行。

启用 write_log

write_log 插件包含在 stackdriver-agent 程序包中。要启用该插件,请执行以下操作:

  1. root 身份修改以下配置文件:

    /etc/stackdriver/collectd.conf
    
  2. LoadPlugin write_gcm 之后添加:

    LoadPlugin write_log
    
  3. <Plugin "write_gcm">…</Plugin> 之后添加:

    <Plugin "write_log">
      Format JSON
    </Plugin>
    
  4. 搜索 <Target "write">…</Target>,并在每个 Plugin "write_gcm" 之后添加:

    Plugin "write_log"
    
  5. 保存更改并重启代理:

    sudo service stackdriver-agent restart
    

这些更改将为报告的每个指标值(包括完整的 collectd 标识符、元数据条目和值)打印一行日志。

write_log 的输出

如果您成功完成上一步,则应该会在系统日志中看到 write_log 的输出:

  • 基于 Debian 的 Linux/var/log/syslog
  • 基于 Red Hat 的 Linux/var/log/messages

在本文中,为了更便于您阅读,我们对以下几行示例内容的格式进行了设置。

Dec  8 15:13:45 test-write-log collectd[1061]: write_log values:#012[{
    "values":[1933524992], "dstypes":["gauge"], "dsnames":["value"],
    "time":1481210025.252, "interval":60.000,
    "host":"test-write-log.c.test-write-log.internal",
    "plugin":"df", "plugin_instance":"udev", "type":"df_complex", "type_instance":"free"}]

Dec  8 15:13:45 test-write-log collectd[1061]: write_log values:#012[{
    "values":[0], "dstypes":["gauge"], "dsnames":["value"],
    "time":1481210025.252, "interval":60.000,
    "host":"test-write-log.c.test-write-log.internal",
    "plugin":"df", "plugin_instance":"udev", "type":"df_complex", "type_instance":"reserved"}]