React 前端应用中快速实践 OpenTelemetry 云原生可观测性(SigNoz/K8S)

OpenTelemetry 可用于跟踪 React 应用程序的性能问题和错误。您可以跟踪从前端 web 应用程序到下游服务的用户请求。OpenTelemetry 是云原生计算基金会(CNCF)下的一个开源项目,旨在标准化遥测数据的生成和收集。已成为下一代可观测平台的事实标准。
React(也称为 React.js 或 ReactJS )是一个免费的开源前端 JavaScript 库,用于基于 UI 组件构建用户界面。它是由 Meta (以前的 Facebook)和一个由个人开发者和公司组成的社区维护的。React 可以作为使用 Next.js 等框架开发单页、移动或服务器渲染应用程序的基础。
然而,React 只关心状态管理和将状态呈现给 DOM,因此创建 React 应用程序通常需要使用额外的库进行路由,以及某些客户端功能。
使用 opentelemetry-js 库,你可以让你的 React 应用生成跟踪数据。您可以跟踪从前端 web 应用程序到下游服务的用户请求。
在演示如何实现 OpenTelemetry 库之前,让我们简要概述一下 OpenTelmetry。
什么是 OpenTelemetry?
OpenTelemetry 是一套与第三方厂商无关的开源工具、API 和 SDK,用于检测应用程序,以创建和管理遥测数据(日志、指标和跟踪)。

OpenTelemetry 库的 instrument(采集程序) 应用程序代码生成遥测数据,然后发送到可观察性工具进行存储和可视化
OpenTelemetry 是建立可观测性框架的基础。它还为您提供了选择后端分析工具的自由。
OpenTelemetry 与 SigNoz
在本文中,我们将使用 SigNoz 作为后端分析工具。SigNoz 是一个全栈开源 APM 工具,可用于存储和可视化 OpenTelemetry 收集的遥测数据。它是在 OpenTelemetry 上原生构建的,并适用于 OTLP 数据格式。
SigNoz 为最终用户提供了查询和可视化功能,并附带了用于应用程序度量和跟踪的开箱即用图表。
现在,让我们开始了解如何使用 opentelemetry-js 库,然后在 SigNoz 中可视化收集的数据。
快速实践
实验环境
DigitalOcean 托管集群(k8s v1.24.13)。
Helm 一键安装 SigNoz
helm repo add signoz https://charts.signoz.io
helm install signoz signoz/signoz -n apm --create-namespace \
--set otelCollector.config.receivers.otlp.protocols.http.include_metadata=true \
--set otelCollector.config.receivers.otlp.protocols.http.cors.allowed_origins='https://apm-demo.react-admin.com'
注意:cors 跨域设置,我这里 React 应用域名是 https://apm-demo.react-admin.com 。
查看 Pod
kubectl get po -n apm
NAME READY STATUS RESTARTS AGE
chi-signoz-clickhouse-cluster-0-0-0 1/1 Running 0 3m51s
signoz-alertmanager-0 1/1 Running 0 4m5s
signoz-clickhouse-operator-54b6d79f58-b47ff 2/2 Running 2 (4m2s ago) 4m5s
signoz-frontend-564b8c4868-88grm 1/1 Running 0 4m5s
signoz-k8s-infra-otel-agent-dqh5c 1/1 Running 0 4m6s
signoz-k8s-infra-otel-agent-jdvnh 1/1 Running 0 4m6s
signoz-k8s-infra-otel-agent-tb8sp 1/1 Running 0 4m6s
signoz-k8s-infra-otel-deployment-dc85b496f-n6dhm 1/1 Running 0 4m5s
signoz-otel-collector-655cff46d8-7z5wn 1/1 Running 0 4m5s
signoz-otel-collector-metrics-7775fc9857-mb8wv 1/1 Running 0 4m5s
signoz-query-service-0 1/1 Running 0 4m5s
signoz-zookeeper-0 1/1 Running 0 4m5s
暴露采集器 Server
此集群 Ingress Controller 是 Traefik,配置如下:
apiVersion: traefik.containo.us/v1alpha1
kind: IngressRoute
metadata:
name: ingest
namespace: apm
spec:
entryPoints:
- web
routes:
- match: PathPrefix(`/`) && Host(`ingest.doge-data.com`)
kind: Rule
services:
- name: signoz-otel-collector
port: 4318
示例应用
测试地址:
仓库:
OpenTelemetry-JS
仓库:
官方文档:
Tracing 示例核心源码
位于示例仓库:src/helpers/tracing/index.ts
import { context, trace, Span, SpanStatusCode } from "@opentelemetry/api";
import { WebTracerProvider } from "@opentelemetry/sdk-trace-web";
import { Resource } from "@opentelemetry/resources";
import { SimpleSpanProcessor } from "@opentelemetry/sdk-trace-base";
import { OTLPTraceExporter } from "@opentelemetry/exporter-trace-otlp-http";
import { ZoneContextManager } from "@opentelemetry/context-zone";
import { FetchInstrumentation } from "@opentelemetry/instrumentation-fetch";
import { FetchError } from "@opentelemetry/instrumentation-fetch/build/src/types";
import { registerInstrumentations } from "@opentelemetry/instrumentation";
const serviceName = "link-frontend";
const resource = new Resource({ "service.name": serviceName });
const provider = new WebTracerProvider({ resource });
const collector = new OTLPTraceExporter({
url: "https://ingest.doge-data.com/v1/traces",
// headers: {
// "signoz-access-token": "SigNoz-Cloud-Ingestion-Token-HERE"
// }
});
provider.addSpanProcessor(new SimpleSpanProcessor(collector));
provider.register({ contextManager: new ZoneContextManager() });
const webTracerWithZone = provider.getTracer(serviceName);
declare const window: any;
var bindingSpan: Span | undefined;
window.startBindingSpan = (
traceId: string,
spanId: string,
traceFlags: number
) => {
bindingSpan = webTracerWithZone.startSpan("");
bindingSpan.spanContext().traceId = traceId;
bindingSpan.spanContext().spanId = spanId;
bindingSpan.spanContext().traceFlags = traceFlags;
};
registerInstrumentations({
instrumentations: [
new FetchInstrumentation({
propagateTraceHeaderCorsUrls: ["/.*/g"],
clearTimingResources: true,
applyCustomAttributesOnSpan: (
span: Span,
request: Request | RequestInit,
result: Response | FetchError
) => {
const attributes = (span as any).attributes;
if (attributes.component === "fetch") {
span.updateName(
`${attributes["http.method"]} ${attributes["http.url"]}`
);
}
if (result instanceof Error) {
span.setStatus({
code: SpanStatusCode.ERROR,
message: result.message,
});
span.recordException(result.stack || result.name);
}
},
}),
],
});
export function traceSpan<F extends (...args: any) => ReturnType<F>>(
name: string,
func: F
): ReturnType<F> {
var singleSpan: Span;
if (bindingSpan) {
const ctx = trace.setSpan(context.active(), bindingSpan);
singleSpan = webTracerWithZone.startSpan(name, undefined, ctx);
bindingSpan = undefined;
} else {
singleSpan = webTracerWithZone.startSpan(name);
}
return context.with(trace.setSpan(context.active(), singleSpan), () => {
try {
const result = func();
singleSpan.end();
return result;
} catch (error) {
singleSpan.setStatus({ code: SpanStatusCode.ERROR });
singleSpan.end();
throw error;
}
});
}
在 React 组件中使用
位于示例仓库:src/components/TracingButton/index.tsx
import { Button } from '@mui/material'
import { traceSpan } from 'helpers/tracing'
interface Props {
label: string;
id?: string;
secondary?: boolean;
onClick: () => void;
}
export default (props: Props) => {
const onClick = (): void =>
traceSpan(`'${props.label}' button clicked`, props.onClick);
return (
<div>
<Button
id={props.id}
variant={"contained"}
color={props.secondary ? "secondary" : "primary"}
onClick={onClick}
>
{props.label}
</Button>
</div>
);
};
测试 React 应用上报
转到 https://apm-demo.react-admin.com , 单击 FETCH LINKS。

SigNoz 后台面板查看,聚合指标等



总结
本篇文章侧重于快速实践,OpenTelemetry 本身很复杂,涉及很多基础概念,大家自行翻阅文档。
SigNoz 作为后端分析与可视化工具。虽相对于 ELK Stack 还有很多不足,但它号称是基于 OpenTelemetry 生态原生构建的下一代开源可观测平台,期待它后续发展。
有兴趣的朋友,也可以二次开发 SigNoz,增加自身项目需求。目前也还比较容易的。
React 前端应用中快速实践 OpenTelemetry 云原生可观测性(SigNoz/K8S)的更多相关文章
- immutable.js 在React、Redux中的实践以及常用API简介
immutable.js 在React.Redux中的实践以及常用API简介 学习下 这个immutable Data 是什么鬼,有什么优点,好处等等 mark : https://yq.aliyu ...
- 云原生 • Kubernetes 认识 k8s、k8s 架构、核心概念点介绍
云原生 • Kubernetes 认识 k8s.k8s 架构.核心概念点介绍 一.Kubernetes 简介Kubernetes 简称 k8s,是支持云原生部署的一个平台,起源于谷歌.谷歌早在十几年之 ...
- Immutable.js 以及在 react+redux 项目中的实践
来自一位美团大牛的分享,相信可以帮助到你. 原文链接:https://juejin.im/post/5948985ea0bb9f006bed7472?utm_source=tuicool&ut ...
- OpenTelemetry - 云原生下可观测性的新标准
CNCF 简介 CNCF(Cloud Native Computing Foundation),中文为"云原生计算基金会",CNCF是Linux基金会旗下的基金会,可以理解为一个非 ...
- 从零搭建云原生技术kubernetes(K8S)环境-通过kubesPhere的AllInOne方式
前言 k8s云原生搭建,步骤有点多,但通过kubesphere,可以快速搭建k8s环境,同时有一个以 Kubernetes 为内核的云原生分布式操作系统-kubesphere,本文将从零开始进行kub ...
- 云原生下基于K8S声明式GitOps持续部署工具ArgoCD实战-上
@ 目录 概述 定义 工作原理 主要组件 核心概念 环境准备 概述 安装Kubekey 创建K8S 安装K9S OpenLB 安装ArgoCD 安装 ArgoCD CLI 从Git库中创建一个应用程序 ...
- Longhorn,企业级云原生容器分布式存储 - K8S 资源配置示例
内容来源于官方 Longhorn 1.1.2 英文技术手册. 系列 Longhorn 是什么? Longhorn 企业级云原生容器分布式存储解决方案设计架构和概念 Longhorn 企业级云原生容器分 ...
- 使用 Yarn workspace,TypeScript,esbuild,React 和 Express 构建 K8S 云原生应用(一)
本文将指导您使用 K8S ,Docker,Yarn workspace ,TypeScript,esbuild,Express 和 React 来设置构建一个基本的云原生 Web 应用程序. 在本教程 ...
- 柯基数据通过Rainbond完成云原生改造,实现离线持续交付客户
1.关于柯基数据 南京柯基数据科技有限公司成立于2015年,提供一站式全生命周期知识图谱构建和运维.智能应用服务,致力于"链接海量数据,从大数据中挖掘智慧".帮助企业运用知识 ...
- 阿里云如何基于标准 K8s 打造边缘计算云原生基础设施
作者 | 黄玉奇(徙远) 阿里巴巴高级技术专家 关注"阿里巴巴云原生"公众号,回复关键词 1219 即可下载本文 PPT 及实操演示视频. 导读:伴随 5G.IoT 的发展,边缘 ...
随机推荐
- boot-admin整合flowable官方editor-app源码进行BPMN2-0建模(续)
boot-admin整合flowable官方editor-app源码进行BPMN2-0建模(续) 书接上回 项目源码仓库github 项目源码仓库gitee boot-admin 是一款采用前后端分离 ...
- 快速上手Linux核心命令(五):文本处理三剑客
@ 目录 前言 正则表达式 第一剑客 grep 第二剑客 sed 第三 剑客 awk 小结 剑仙镇楼~ O(∩_∩)O 前言 上一篇中已经预告,我们这篇主要说Linux文本处理三剑客.他们分别是gre ...
- linux安装tomcat,mysql
环境:centos7.6 ssh连接工具:tabby 安装tomcat 创建目录 mkdir /opt/tomcat 获取tomcat: 1.自己百度下载 2.我这里提供百度网盘 链接:https:/ ...
- Windows的Mysql5.7社区版的安装详细操作,从无到有,安装配置一条龙服务。(压缩包自行安装,非installer安装)
换了一个电脑,所有软件.环境都得重新来安装一次,安装到Mysql的时候,发现网上有两种安装方式,一种是Mysql的压缩包安装方式,这种方式直接到官网下载Mysql的压缩包,解压之后做些配置就可以了,另 ...
- 用go设计开发一个自己的轻量级登录库/框架吧(项目维护篇)
用go设计开发一个自己的轻量级登录库/框架吧(项目维护篇) 本篇将开始讲讲开发库/框架的最开始阶段,也就是搭建一个项目 源码:weloe/token-go: a light login library ...
- 2023-04-12:使用 Go 重写 FFmpeg 的 extract_mvs.c 工具程序,提取视频中的运动矢量信息。
2023-04-12:使用 Go 重写 FFmpeg 的 extract_mvs.c 工具程序,提取视频中的运动矢量信息. 答案2023-04-12: 主要的过程包括: 打开输入视频文件并查找视频流信 ...
- 2022-11-25:连续出现的数字。编写一个 SQL 查询,查找所有至少连续出现三次的数字。 答案是输出1,原因是1是唯一连续出现三次的数字。 DROP TABLE IF EXISTS logs;
2022-11-25:连续出现的数字.编写一个 SQL 查询,查找所有至少连续出现三次的数字. 答案是输出1,原因是1是唯一连续出现三次的数字. DROP TABLE IF EXISTS logs; ...
- 2022-03-13:golang项目代码push到gogs上,如何自动编译、打镜像、k8s上运行?
2022-03-13:golang项目代码push到gogs上,如何自动编译.打镜像.k8s上运行? 答案2022-03-13: 2022-02-23:如何搭建k8s单机环境(用k3s),并且搭建da ...
- [AGC001E] BBQ Hard题解
Problem [AGC001E] BBQ Hard 计算: \[\sum_{i=1}^{n}\sum_{j=i+1}^n\binom{a_i+b_i+a_j+b_j}{a_i+a_j} \] 其中\ ...
- javascript中的错误类型
javascript 中的错误类型: SyntaxError TypeError ReferenceError RangeError URLError Error SyntaxError 语法错误 / ...