OpenTelemetry OpenTelemetry

使用 Receiver 收集日志与基础设施指标

使用 filelog、hostmetrics、kubeletstats 和 prometheus receiver,并从追踪中派生指标。

14 min 中级

使用 OpenTelemetry SDK 的应用会推送它们自己的遥测数据,但你需要观测的很多东西并不会:日志文件、主机资源、kubelet,以及已经暴露 Prometheus 指标的服务。Collector 通过 receiver 把这些拉进来。本指南展示最有用的那些,全部以配置的形式。组件的选项名称在不同版本之间会变化,所以请查看你所运行版本的每个 receiver 的 README。所有这些都在 contrib 和 Kubernetes 发行版中。

使用 filelog 收集日志文件

filelog receiver 跟踪文件并把行变成日志记录。

receivers:
  filelog:
    include:
      - /var/log/myapp/*.log
    exclude:
      - /var/log/myapp/*.gz
    start_at: end            # or "beginning" to read existing content
    include_file_path: true
    operators:
      - type: json_parser
        timestamp:
          parse_from: attributes.time
          layout: '%Y-%m-%dT%H:%M:%S.%LZ'
        severity:
          parse_from: attributes.level

Operator 构成对每个条目运行的一个小型解析管线。常见的有 json_parser、regex_parser、move、add、remove,以及 recombine(把多行堆栈跟踪重新合并为一条记录)。一个多行的示例:

    operators:
      - type: recombine
        combine_field: body
        is_first_entry: body matches "^\\d{4}-\\d{2}-\\d{2}"
        source_identifier: attributes["log.file.path"]

要在重启后既不重复读取也不跳过数据,请给 receiver 一个存储扩展:

extensions:
  file_storage:
    directory: /var/lib/otelcol/storage

receivers:
  filelog:
    include: [/var/log/myapp/*.log]
    storage: file_storage

service:
  extensions: [file_storage]

在 Kubernetes 上,容器日志位于 /var/log/pods/*/*/*.log 下。Helm chart 的 logsCollection preset 会配置这个 receiver、挂载宿主机路径,并为你解析容器运行时格式,所以请优先使用它,而不是手写 receiver。

使用 hostmetrics 收集主机指标

在虚拟机或节点上,hostmetrics receiver 从操作系统读取 CPU、内存、磁盘、文件系统和网络数据:

receivers:
  hostmetrics:
    collection_interval: 30s
    scrapers:
      cpu:
      memory:
      load:
      disk:
      filesystem:
        exclude_mount_points:
          mount_points: [/dev/*, /proc/*, /sys/*, /run/*]
          match_type: regexp
      network:
      paging:

请在每个主机上的 agent 中运行它。在容器中,除非你挂载宿主机的文件系统并设置 root_path,否则它报告的是容器的视图,所以在依赖它之前请查看 receiver 的 README。添加 resourcedetection processor,用主机、云或 Kubernetes 的详细信息为指标打标签:

processors:
  resourcedetection:
    detectors: [env, system]
    timeout: 5s
    override: false

Kubernetes 指标

节点和 pod 的资源使用情况通过 kubeletstats 来自 kubelet,作为 DaemonSet 运行:

receivers:
  kubeletstats:
    collection_interval: 30s
    auth_type: serviceAccount
    endpoint: ${env:K8S_NODE_NAME}:10250
    insecure_skip_verify: true
    metric_groups: [node, pod, container]

通过 downward API 传入节点名称:

env:
  - name: K8S_NODE_NAME
    valueFrom:
      fieldRef:
        fieldPath: spec.nodeName

insecure_skip_verify 很常见,因为 kubelet 的证书通常是自签名的;在可以的地方请使用正确的 CA 配置。service account 需要读取 nodes/stats 的权限,Helm preset 会授予它。

集群级状态(deployment 副本数、pod 阶段、节点状况)来自 k8s_cluster receiver,Kubernetes 事件来自 k8sobjects。请在单副本的 Deployment 中每个集群只运行一次这两者,否则你会收集到重复的数据。两者都可作为 Helm preset 使用(clusterMetrics 和 kubernetesEvents)。

抓取 Prometheus 端点

prometheus receiver 接受标准的 Prometheus 抓取配置,所以现有的目标无需重写就能迁移过来:

receivers:
  prometheus:
    config:
      scrape_configs:
        - job_name: node-exporter
          scrape_interval: 30s
          static_configs:
            - targets: ["node-exporter:9100"]
        - job_name: kubernetes-pods
          kubernetes_sd_configs:
            - role: pod
          relabel_configs:
            - source_labels: [__meta_kubernetes_pod_annotation_prometheus_io_scrape]
              action: keep
              regex: "true"

两个陷阱:在 Collector 配置中,Prometheus 正则或替换中的字面美元符号要写成 $$,否则 Collector 会尝试把它作为变量展开;并且,如果你运行多个都抓取同一批目标的副本,你会得到重复数据。OpenTelemetry Operator 的 Target Allocator 存在的目的就是在各个 Collector 副本之间对目标分片,运行一个抓取副本也是如此。

多个 receiver,一条管线

Receiver 馈入相同信号类型的管线:

service:
  pipelines:
    metrics:
      receivers: [otlp, hostmetrics, kubeletstats, prometheus]
      processors: [memory_limiter, resourcedetection, batch]
      exporters: [otlphttp/prometheus]
    logs:
      receivers: [otlp, filelog]
      processors: [memory_limiter, batch]
      exporters: [otlphttp/loki]

你也可以为每种信号拆分成多条管线(metrics/infra、metrics/apps),对每个来源应用不同的 processor。

使用 spanmetrics connector 从追踪生成指标

如果你的服务发出追踪但没有请求指标,spanmetrics connector 会从 span 派生出请求计数、错误计数和延迟直方图。connector 在一条管线中是 exporter,在另一条中是 receiver:

connectors:
  spanmetrics:
    histogram:
      explicit:
        buckets: [10ms, 50ms, 100ms, 250ms, 500ms, 1s, 2.5s, 5s]
    dimensions:
      - name: http.request.method
      - name: http.response.status_code

service:
  pipelines:
    traces:
      receivers: [otlp]
      processors: [memory_limiter, batch]
      exporters: [otlp/tempo, spanmetrics]
    metrics/spanmetrics:
      receivers: [spanmetrics]
      processors: [batch]
      exporters: [otlphttp/prometheus]

每个维度都会使时间序列的数量成倍增加,所以只添加取值集合小而有界的属性。永远不要使用用户 ID 或带标识符的 URL。把 connector 放在任何采样之前,这样数字才能反映全部流量(参见采样指南)。

验证

向管线的副本添加带 verbosity: detailed 的 debug exporter,并在前台运行 Collector。你应该会看到带有已解析严重级别的日志记录,或像 system.cpu.time、k8s.pod.cpu.usage 或 traces.span.metrics.calls 这样的指标名称(命名可能因版本而异)。如果没有任何东西出现,请检查 filelog 的文件权限、kubeletstats 的节点名称变量,以及每个 receiver 都被列在某条管线中。

热门指南