• 作者:老汪软件技巧
  • 发表时间:2024-09-10 17:01
  • 浏览量:

这篇文章是《前端体验优化实战》小册第二节发布后半年追加的重写优化版。

使用了最新版的 Grafana Alloy 作为演示,并且配套视频教程,致力于解决大家在安装过程中遇到的报错、数据未上报等问题。

有了获取用户体验数据的工具web-vitals,许多人会直接在本地开发环境或内部测试环境获取用户体验指标数据,用于评估优化效果,但是这样的做法有显著的问题:

所以,只在开发测试环境使用web-vitals收集用户体验指标数据是远远不够的,我们需要到广阔无垠的生产环境中收集最广大用户的真实数据,以便准确了解现状、确定优化目标、评估优化效果。

笔者在此推荐一套经过实践检验、开发体验较好的生产环境数据采集工具:Prometheus 和 Grafana。

一、 Prometheus 及 Grafana 简介

Prometheus 是一款开源的数据监控解决方案,主要包括以下模块:

具有强大的拓展能力,可以方便快速地融合进已有的项目中,作为数据监控中台的工具使用。

Grafana 是一款开源的数据可视化工具,主要有以下特性:

将 Prometheus 与 Grafana 整合进我们的项目中就能实现强大的数据收集、可视化能力。

下面我们以Node.js为例,演示如何接入这2款工具。

二、 接入手把手教学

为了便于各位操作,我录制了完整演示视频:【手把手教你前端优化神器Grafana】 …

大家可以对照着图文内容参考。

1. 本地运行数据收集应用

运行数据收集 Node.js 应用推荐使用笔者编写的本书配套数据收集示例应用:/JuniorTour/…

1. 克隆数据收集示例应用:node-prometheus-grafana-demo

我们可以直接 git clone 本书配套数据收集示例应用:/JuniorTour/…

克隆到本地后,运行也很简单,只需要执行:

npm install
npm run start

运行npm run start后,prom-client就会自动开始采集一批默认的 Node.js 应用数据。

2. 核心逻辑讲解

数据收集示例应用:node-prometheus-grafana-demo的核心代码逻辑是下列代码,主要功能是:

初始化prom-client:const register = new Registry();启用采集默认指标:.collectDefaultMetrics({ register });新增路径为/metrics的 HTTP 接口,向外部提供数据。

// 1. src/prom-client.js
const client = require('prom-client');
const Registry = client.Registry;
const register = new Registry();
client.collectDefaultMetrics({ register });
module.exports = {
  register,
};
// 2. src/app.js
const express = require('express');
const { register, useCounter, useGauge } = require('./prom-client');
const app = express();
const metricPath = '/metrics';
app.get(metricPath, async (_req, res) => {
  try {
    res.set('Content-Type', register.contentType);
    res.end(await register.metrics());
  } catch (err) {
    res.status(500).end(err);
  }
});

3. 检查确认数据收集应用

数据收集应用运行成功后,访问应用的/metrics接口(:4001/metrics),应该能看到页面响应了许多数据,这些就是prom-client收集到的数据,示例如图:

如果这个接口没有正确响应数据,建议检查报错和代码逻辑,或使用npm run dev("dev": "node --inspect-brk ./src/app.js",)调试/metrics接口的逻辑。

2. 安装配置Grafana Alloy

Grafana Alloy 是 Grafana 官方推出的数据上报应用,核心功能是把本地收集到的数据,定时刮取、上报到远端的 Grafana。

Grafana提供了分步骤的插件,帮助我们方便地完成这一阶段,具体步骤是:

1. 添加连接

注册、登录 Grafana 后,通过Home - Connections - Add new connection - 搜索 Node.js,在页面中选择添加Node.js作为数据源,继而选择使用 Grafana Alloy:

2. 安装配置

点击 Configure using Grafana Alloy 后,按照页面中的分步骤指引,分别完成:

1. 选择平台2. 下载安装 Alloy:

安装的同时也会生成一份默认的配置文件,路径是:

3. 选择配置:

这一步一般不需要操作,因为前几步已经选择了对应平台的配置。

4. 准备配置文件(重要!):首先,教程中指引我们编写 Node.js 代码,初始化上传数据逻辑,这部分工作就是我们在上一节“1. 本地运行数据收集应用”中完成的步骤。其次,第二部分需要我们修改配置文件,增加对 Node.js 的集成。增加的配置共有3段:

discovery.relabel "metrics_integrations_integrations_nodejs" {
 # 1...
}
prometheus.scrape "metrics_integrations_integrations_nodejs" {
 # 2...
}
prometheus.relabel "metrics_integrations_integrations_nodejs" {
 # 3...
}

5. 重启 Alloy 并检测连接

修改配置文件后,需要重启 Alloy 才能生效。

# For Windows
sc stop "Alloy" 
sc start "Alloy" 
sc query "Alloy" | find "STATE" 
# 打印 RUNNING 表示启动完成
# For Mac
brew services restart alloy

重启成功后,点击 Test Connection 即可验证连接效果。

手把手带你学会前端优化神器《Grafana》视频+图文教程__手把手带你学会前端优化神器《Grafana》视频+图文教程

如果连接没有成功,请向下翻到第4节:《Alloy 问题排查》。

官方GitHub:/grafana/all…

配置上报指标文档:/docs/alloy/…

▶点击展开完整配置示例(不要简单复制,其中包含了身份验证用的 basic_auth.password ,每个账户都不一样):

prometheus.exporter.self "alloy_check" { }
discovery.relabel "alloy_check" {
  targets = prometheus.exporter.self.alloy_check.targets
  rule {
    target_label = "instance"
    replacement  = constants.hostname
  }
  rule {
    target_label = "alloy_hostname"
    replacement  = constants.hostname
  }
  rule {
    target_label = "job"
    replacement  = "integrations/alloy-check"
  }
}
prometheus.scrape "alloy_check" {
  targets    = discovery.relabel.alloy_check.output
  forward_to = [prometheus.relabel.alloy_check.receiver]  
  scrape_interval = "60s"
}
prometheus.relabel "alloy_check" {
  forward_to = [prometheus.remote_write.metrics_service.receiver]
  rule {
    source_labels = ["__name__"]
    regex         = "(prometheus_target_sync_length_seconds_sum|prometheus_target_scrapes_.*|prometheus_target_interval.*|prometheus_sd_discovered_targets|alloy_build.*|prometheus_remote_write_wal_samples_appended_total|process_start_time_seconds)"
    action        = "keep"
  }
}
prometheus.remote_write "metrics_service" {
  endpoint {
    url = "https://prometheus-prod-18-prod-ap-southeast-0.grafana.net/api/prom/push"
    basic_auth {
      username = "698333"
      password = "glc_eyJvIjoiNz....TAifX0="
    }
  }
}
loki.write "grafana_cloud_loki" {
  endpoint {
    url = "https://logs-prod-011.grafana.net/loki/api/v1/push"
    basic_auth {
      username = "348136"
      password = "glc_eyJvIj....TAifX0="
    }
  }
}
discovery.relabel "metrics_integrations_integrations_nodejs" {
	targets = [{
		__address__ = "localhost:4001",
	}]
	rule {
		target_label = "instance"
		replacement  = constants.hostname
	}
}
prometheus.scrape "metrics_integrations_integrations_nodejs" {
	targets    = discovery.relabel.metrics_integrations_integrations_nodejs.output
	forward_to = [prometheus.relabel.metrics_integrations_integrations_nodejs.receiver]
	job_name   = "integrations/nodejs"
}
prometheus.relabel "metrics_integrations_integrations_nodejs" {
	forward_to = [prometheus.remote_write.metrics_service.receiver]
	rule {
		source_labels = ["__name__"]
		regex         = ".+"
		action        = "keep"
	}
}
logging {
  level  = "info"
  format = "logfmt"
}

6. 导入预配置图表

Grafana 为 Node.js 准备了一套预配置的示例图表,点击 Install 按钮就可以复制到自己的看板上:

如果在这套预配置图表中能看到数据,就说明我们的安装配置初步完成了。

7. 修改配置,支持上传自定义指标

Alloy默认的配置中,用regex字段写死了收集指标的指定名称:

prometheus.relabel "metrics_integrations_integrations_nodejs" {
	forward_to = [prometheus.remote_write.metrics_service.receiver]
	rule {
		source_labels = ["__name__"]
		regex         = "up|process_resident_memory_bytes|process_cpu_seconds_total|...."
		action        = "keep"
	}
}

但是我们的目标是上报收集任意名称的指标,所以需要修改regex字段配置为".+",表示任意字符的指标,都可以被收集上报:

prometheus.relabel "metrics_integrations_integrations_nodejs" {
	forward_to = [prometheus.remote_write.metrics_service.receiver]
	rule {
		source_labels = ["__name__"]
		regex         = ".+"
		action        = "keep"
	}
}

修改配置后,别忘了再次重启Alloy:

# For Windows
sc stop "Alloy" 
sc start "Alloy" 
sc query "Alloy" | find "STATE" 
# 打印 RUNNING 表示启动完成
# For Mac
brew services restart alloy

如果以上步骤,一切顺利就可以愉快地进行下一步:《3. 上报自定义指标并创建可视化图表》了。

如果遇到了各种问题、报错,也很正常,不用担心,毕竟咱们工程师就是解决问题的人。

我也总结了一些常见的问题排查思路,供各位参考:

3. Alloy问题排查法一:使用自带UI排查

Grafana Alloy启动后,访问 :12345 就可以使用自带的UI网页检查运行状况,正常情况下,各个Components应该都是 Healthy 状态:

如果某一项 Component 不是 Healthy 状态,点击 View 按钮,跳转到详情页,一般会有更多上下文信息,供我们排查解决。

法二:检查 Alloy 连接状况

在 Grafana 页面中访问Home - Connections - Collector - 搜索 Alloy 并选择 - Configure可以检查 Alloy 在 Grafana 云端的连接状况。

Alloy 连接状况页面 path 是: /a/grafana-collector-app/alloy/monitoring ,其中域名需要替换为你的 Grafana 实例域名。

例如我的域名URL:/a/grafana-c…

如果你的 Alloy 运行正常,应该能看到图表中绘制出类似下图的数据。

如果这些图表并未展示任何数据,那可能意味着你的 Alloy 安装配置,还未完成,请检查上述安装配置步骤。

如果中间的图表《Scrape Failures》有某项指标大于 0,也意味着你的 Alloy 运行时有报错,建议根据报错指标名称进行搜索,排查修复问题。

法三:检查 Log

通过检查 Alloy 运行时记录的 log,也有助于判断遇到的问题。

Log默认并未开启,开启log的具体做法是,找到你的 Alloy 配置文件,增加 配置:

logging {
  level  = "info"
  format = "logfmt"
}

config修改之后,记得再次重启 Alloy:

# For Windows
sc stop "Alloy" 
sc start "Alloy" 
sc query "Alloy" | find "STATE" 
# 打印 RUNNING 表示启动完成
# For Mac
brew services restart alloy

不同的系统,log分别存放在不同的位置,文档:

:默认保存在 事件查看器 Event Viewer 中,右键 windows 按钮 - 事件查看器即可打开:入口UI

$(brew --prefix)一般是 /opt/homebrew

其他系统 Log 配置文档:/docs/grafan…

如果在 log 中发现了ERROR报错信息,可以在官方 GitHub 中搜索或创建 Issue 提问:/grafana/all…

其他问题QA收集问题解决方案

Mac 系统无数据上报,error log 报错 panic: pattern "GET /debug/pprof/" (registered at /usr/lib/go/src/net/http/pprof/pprof.go:100) conflicts with pattern

参考:/grafana/all… ,把Go 语言 运行时降级到 1.22。