当前位置: 首页 > news >正文

Observability:使用 OpenTelemetry 手动检测 .NET 应用程序

作者:David Hope

在快节奏的软件开发领域,尤其是在云原生领域,DevOps 和 SRE 团队日益成为应用程序稳定性和增长的重要合作伙伴。

DevOps 工程师不断优化软件交付,而 SRE 团队则充当应用程序可靠性、可扩展性和顶级性能的管理者。 挑战? 这些团队需要一种尖端的可观察性解决方案,该解决方案包含全栈洞察,使他们能够在潜在的干扰最终导致运营挑战之前快速管理、监控和纠正它们。

现代分布式软件生态系统中的可观察性不仅仅是监控 —— 它需要无限的数据收集、处理的精确性以及将这些数据与可操作的见解相关联。 然而,实现这一整体视图的道路充满了障碍,从解决版本不兼容性到与限制性专有代码作斗争。

OpenTelemetry (OTel) 将为采用它的用户带来以下好处:

  • 通过 OTel 摆脱供应商限制,将自己从供应商锁定中解放出来,并确保一流的可观察性。
  • 查看统一日志、指标和跟踪的和谐统一,以提供完整的系统视图。
  • 通过更丰富和增强的工具来改善你的应用程序监督。
  • 利用向后兼容性的优势来保护你之前的检测投资。
  • 通过简单的学习曲线踏上 OpenTelemetry 之旅,简化入门和可扩展性。
  • 依靠经过验证的、面向未来的标准来增强你对每项投资的信心。
  • 探索手动仪器,实现定制数据收集以满足你的独特需求。
  • 使用标准化的可观测性数据框架确保跨层监控的一致性。
  • 将开发与运营脱钩,从而提高两者的最高效率。

在这篇文章中,我们将深入探讨使用 Docker 手动检测 .NET 应用程序的方法。

这篇文章涵盖什么?

  • 手动检测 .NET 应用程序
  • 使用内置的 OpenTelemetry 工具为 .NET 应用程序创建 Docker 映像
  • 安装并运行 OpenTelemetry .NET Profiler 以进行自动检测

先决条件

  1. 了解 Docker 和 .NET
  2. Elastic Cloud
  3. Docker 安装在你的计算机上(我们推荐 docker 桌面版)

查看示例源代码

完整的源代码,包括本博客中使用的 Dockerfile,可以在 GitHub 上找到。 该存储库还包含相同的应用程序,但没有检测。 这使你可以比较每个文件并查看差异。

以下步骤将向你展示如何检测此应用程序并在命令行或 Docker 中运行它。 如果你对更完整的 OTel 示例感兴趣,请查看此处的 docker-compose 文件,它将显示完整的项目。

分步指南

本博客假设你有 Elastic Cloud 帐户 - 如果没有,请按照说明开始使用 Elastic Cloud。

步骤 1. 开始使用

在我们的演示中,我们将手动检测 .NET Core 应用程序 - 登录。 该应用程序模拟一个简单的用户登录服务。 在此示例中,我们仅关注跟踪,因为 OpenTelemetry 日志记录工具目前处于混合成熟度,如此处所述。

该应用程序具有以下文件:

  1. 程序.cs
  2. 启动.cs
  3. 遥测.cs
  4. 登录控制器.cs

步骤 2. 检测应用程序

当谈到 OpenTelemetry 时,.NET 生态系统呈现出一些独特的方面。 虽然 OpenTelemetry 提供其 API,但 .NET 利用其原生 System.Diagnostics API 来实现 OpenTelemetry 的跟踪 API。 ActivitySource 和 Activity 等预先存在的构造被适当地重新调整用途以符合 OpenTelemetry。

也就是说,了解 OpenTelemetry API 及其术语对于 .NET 开发人员仍然至关重要。 它对于获得对应用程序检测的完全控制至关重要,并且正如我们所见,它还扩展到理解 System.Diagnostics API 的元素。

对于那些可能倾向于使用原始 OpenTelemetry API 而不是 System.Diagnostics API 的人来说,还有一种方法。 OpenTelemetry 提供了一个可供你使用的用于跟踪的 API 填充程序。 它使开发人员能够切换到 OpenTelemetry API,你可以在 OpenTelemetry API Shim 文档中找到有关它的更多详细信息。

通过将此类实践集成到 .NET 应用程序中,你可以充分利用 OpenTelemetry 提供的强大功能,无论你使用的是 OpenTelemetry 的 API 还是 System.Diagnostics API。

在本博客中,我们坚持使用默认方法并使用 System.Diagnostics API 规定的 activity 约定。

要手动检测 .NET 应用程序,你需要对每个文件进行更改。 我们来一一看看这些变化。

Program.cs

这是我们应用程序的入口点。 在这里,我们使用默认配置创建 IHostBuilder 的实例。 请注意我们如何使用 Serilog 设置控制台记录器。

public static void Main(string[] args)
{Log.Logger = new LoggerConfiguration().WriteTo.Console().CreateLogger();CreateHostBuilder(args).Build().Run();
}

Startup.cs

在 Startup.cs 文件中,我们使用 ConfigureServices 方法添加 OpenTelemetry Tracing。

public void ConfigureServices(IServiceCollection services)
{services.AddOpenTelemetry().WithTracing(builder => builder.AddOtlpExporter().AddSource("Login").AddAspNetCoreInstrumentation().AddOtlpExporter()  .ConfigureResource(resource =>resource.AddService(serviceName: "Login")));services.AddControllers();
}

WithTracing 方法支持在 OpenTelemetry 中进行跟踪。 我们添加了 OTLP(OpenTelemetry Protocol)导出器,它是一种通用遥测数据传输协议。 我们还添加了 AspNetCoreInstrumentation,它将自动从我们的应用程序收集跟踪。 这是 OpenTelemetry 文档中未提及的极其重要的步骤。 如果不添加此方法,则仪器无法为我的登录应用程序工作。

Telemetry.cs

该文件包含我们的 ActivitySource 的定义。 ActivitySource 表示遥测活动的来源。 它以你的应用程序的服务名称命名,该名称可以来自配置文件、常量文件等。我们可以使用此 ActivitySource 来启动活动。

using System.Diagnostics;public static class Telemetry
{//...// Name it after the service name for your app.// It can come from a config file, constants file, etc.public static readonly ActivitySource LoginActivitySource = new("Login");//...
}

在我们的例子中,我们创建了一个名为 Login 的 ActivitySource。 在我们的 LoginController.cs 中,当我们开始操作时,我们使用此 LoginActivitySource 来启动一个新 activity。

using (Activity activity = Telemetry.LoginActivitySource.StartActivity("SomeWork"))
{// Perform operations here
}

这段代码启动一个名为 SomeWork 的新 activity,执行一些操作(在本例中,生成随机用户并登录),然后结束该活动。 这些活动可以被跟踪并在以后进行分析以了解操作的性能。

此 ActivitySource 是 OpenTelemetry 手动检测的基础。 它代表活动的来源并提供启动和停止 activity 的方法。

LoginController.cs

在 LoginController.cs 文件中,我们跟踪 GET 和 POST 方法执行的操作。 我们在开始操作之前启动一项新活动 SomeWork,并在完成后将其处理掉。

using (Activity activity = Telemetry.LoginActivitySource.StartActivity("SomeWork"))
{var user = GenerateRandomUserResponse();Log.Information("User logged in: {UserName}", user);return user;
}

这将跟踪这些操作所花费的时间,并通过 OTLP 导出器将此数据发送到任何配置的遥测后端。

步骤 3. 基础镜像设置

现在我们已经创建并检测了应用程序源代码,是时候创建一个 Dockerfile 来构建和运行我们的 .NET 登录服务了。

从 Dockerfile 基础层的 .NET 运行时映像开始:

FROM ${ARCH}mcr.microsoft.com/dotnet/aspnet:7.0. AS base
WORKDIR /app
EXPOSE 8000

在这里,我们正在设置应用程序的运行时环境。

步骤 4. 构建 .NET 应用程序

Docker 的这个特性是最好的。 在这里,我们编译 .NET 应用程序。 我们将使用 SDK 映像。 在过去的糟糕日子里,我们曾经在不同的平台上构建,然后将编译后的代码放入 Docker 容器中。 这样,我们更有信心通过使用 Docker 来将我们的构建从开发人员桌面复制到生产中。

FROM --platform=$BUILDPLATFORM mcr.microsoft.com/dotnet/sdk:8.0-preview AS build
ARG TARGETPLATFORMWORKDIR /src
COPY ["login.csproj", "./"]
RUN dotnet restore "./login.csproj"
COPY . .
WORKDIR "/src/."
RUN dotnet build "login.csproj" -c Release -o /app/build

本节确保我们的 .NET 代码得到正确恢复和编译。

步骤 5. 发布应用程序

构建完成后,我们将发布该应用程序:

FROM build AS publish
RUN dotnet publish "login.csproj" -c Release -o /app/publish

步骤 6. 准备最终镜像

现在,让我们设置最终的运行时映像:

FROM base AS final
WORKDIR /app
COPY --from=publish /app/publish .

步骤 7. 入口点设置

最后,将 Docker 映像的入口点设置为 OpenTelemetry 工具的源,这会设置引导 .NET Profiler 所需的环境变量,然后启动 .NET 应用程序:

ENTRYPOINT ["/bin/bash", "-c", "dotnet login.dll"]

步骤 8. 使用环境变量运行 Docker 镜像

要构建并运行 Docker 映像,你通常需要执行以下步骤:

构建 Docker 镜像

首先,你需要从 Dockerfile 构建 Docker 映像。 假设 Dockerfile 位于当前目录中,并且你想要命名/标记你的映像 dotnet-login-otel-image。

docker build -t dotnet-login-otel-image .

运行 Docker 镜像

构建镜像后,你可以使用指定的环境变量运行它。 为此,将 docker run 命令与每个环境变量的 -e 标志一起使用。

  docker run \-e OTEL_EXPORTER_OTLP_HEADERS="Authorization=Bearer ${ELASTIC_APM_SECRET_TOKEN}" \-e OTEL_EXPORTER_OTLP_ENDPOINT="${ELASTIC_APM_SERVER_URL}" \-e OTEL_METRICS_EXPORTER="otlp" \-e OTEL_RESOURCE_ATTRIBUTES="service.version=1.0,deployment.environment=production" \-e OTEL_SERVICE_NAME="dotnet-login-otel-manual" \-e OTEL_TRACES_EXPORTER="otlp" \dotnet-login-otel-image

确保在 shell 环境中设置 ${ELASTIC_APM_SECRET_TOKEN} 和 ${ELASTIC_APM_SERVER_URL},将它们替换为来自云的实际值,如下所示。

获取 Elastic Cloud 变量

你可以从 Kibana 的路径 “/app/home#/tutorial/apm” 下复制端点和令牌。

如果你有多个环境变量,你还可以将环境文件与 docker run --env-file 一起使用,以使命令更加简洁。

启动并运行此程序后,你可以 ping 检测服务的端点(在我们的示例中为 /login),你应该会看到该应用程序出现在 Elastic APM 中,如下所示:

它将首先跟踪 SRE 需要关注的吞吐量和延迟关键指标。

深入研究,我们可以看到所有交易的概述。

看看具体的 transactions,包括我们在上面的代码中创建的 “SomeWork” activity/span:

这里显然有一个异常值,一笔交易花费了 20 毫秒以上。 这可能是由于 CLR 预热所致。

总结一下

通过此处的代码检测和 Dockerfile 引导应用程序,你已将简单的 .NET 应用程序转换为使用 OpenTelemetry 检测的应用程序。 这将极大地有助于了解应用程序性能、跟踪错误以及深入了解用户如何与软件交互。

请记住,可观察性是现代应用程序开发的一个重要方面,尤其是在分布式系统中。 借助 OpenTelemetry 等工具,理解复杂系统变得更加容易。

在这篇博客中,我们讨论了以下内容:

  • 如何使用 OpenTelemetry 手动检测 .NET。
  • 使用 Docker 文件中的标准命令,构建并启动了我们的检测应用程序。
  • 使用 OpenTelemetry 及其对多种语言的支持,DevOps 和 SRE 团队可以轻松地检测其应用程序,立即了解整个应用程序堆栈的运行状况并缩短平均解决时间 (MTTR)。

由于 Elastic 可以支持多种提取数据的方法,无论是使用开源 OpenTelemetry 的自动检测还是使用其本机 APM 代理进行手动检测,因此你可以先关注一些应用程序,然后使用 OpenTelemety 来规划向 OTel 的迁移 稍后以最适合你的业务需求的方式跨你的应用程序。

还没有 Elastic Cloud 帐户? 注册 Elastic Cloud 并尝试我上面讨论的检测功能。 我很想了解你对使用 Elastic 了解应用程序堆栈的体验的反馈。

本文中描述的任何特性或功能的发布和时间安排均由 Elastic 自行决定。 当前不可用的任何特性或功能可能无法按时交付或根本无法交付。

相关文章:

Observability:使用 OpenTelemetry 手动检测 .NET 应用程序

作者:David Hope 在快节奏的软件开发领域,尤其是在云原生领域,DevOps 和 SRE 团队日益成为应用程序稳定性和增长的重要合作伙伴。 DevOps 工程师不断优化软件交付,而 SRE 团队则充当应用程序可靠性、可扩展性和顶级性能的管理者。…...

生产事故:redis主从的坑

一、问题 昨天生产redis缩容,3主3从模式,重启了服务器,重启了redis; 结果今天发现生产服务报错了,连接不上redis。 排查发现,由于生产后台只配置了一个redis的ip,本来是主redis的ip的&#x…...

maven本地仓库有依赖包,还会远程下载的问题

maven本地仓库有依赖包,还会远程下载的问题 传送门...

动作捕捉系统处理单点多点丢点问题

在动作捕捉数据采集过程中,丢点是经常容易遇到的问题。NOKOV度量动作捕捉软件可以方便地解决丢点问题。 一、单点丢点的处理 如下图,已经采集了动捕数据。 查看是否有丢点,在形影软件左上角选择“窗口分割”,在下方分割出一个空…...

FIFO 位宽转换

从8位转32位 module tb_fifo();reg clk,rst; initial beginclk0;forever #4.545 clk~clk; end initial beginrst1;#9.09 rst0; endreg [31:0] cnts; always (posedge clk or posedge rst) beginif(rst)begincnts < 32d0;endelsebegincnts < cnts 1b1;end endreg […...

瑞明达:聚“追梦”之力,共圆“经济梦”

矢志不渝&#xff0c;笃行不怠&#xff0c;争当“一心一意同国行”的无悔“追梦人”。过往几年&#xff0c;国际形势风高浪急&#xff0c;国内环境复杂多变&#xff0c;在后疫情时代、经济恢复压力等多种超预期的因素冲击下&#xff0c;瑞明达团队全面贯彻落实国家发展政策&…...

UE5数字孪生制作(一) - QGIS 学习笔记

1.下载 QGIS是免费的GIS工具&#xff0c;下载地址&#xff1a; https://www.qgis.org/en/site/ 2.安装 - 转中文 按照步骤安装&#xff0c;完成后&#xff0c;在菜单 设置settings里&#xff0c;选择options&#xff0c;修改语言 确定后&#xff0c;需要重启下软件 3.学习视…...

STM32 使用HAL库,HAL_Delay()会卡死, 程序一直卡在 HAL_GetTick( ) 函数中(已解决)

今天遇到个很奇怪的问题, 不知道为什么, 单片机运行一会之后, 系统就没反应了, 经过调试发现, 系统卡在HAL_Delay()中了. 之前也遇到过这个问题后来把HAL_Delay 去掉了. 然后发现不行, 还是得有它.不然发串口数据发的太快会乱掉. 得慢点发. 然后调试到HAL_Delay()方法的内部发…...

Maven Repository使用

1.Maven Repository网站 https://mvnrepository.com/https://mvnrepository.com/ 2.查询需要的依赖 3.参考例子 <!-- https://mvnrepository.com/artifact/org.freeswitch.esl.client/org.freeswitch.esl.client --> <dependency> <groupId>org.freesw…...

智安网络|保护您的应用程序免受攻击:重要的安全强化措施

在今天的数字化时代&#xff0c;应用程序安全成为了企业和个人必须重视的重要领域。应用程序普遍存在的安全漏洞成为黑客们进行攻击的一个突破口。为了保护敏感数据和个人隐私&#xff0c;我们必须了解并实施一系列的关键措施来加固应用程序的安全性。 首先&#xff0c;一个关…...

python3.8 use async getting invalid sysntax

python3.8 use async getting invalid sysntax 加载fever-drqa时报错&#xff1a; File "/data/yangjun/fact/wikifact/scripts/search_module.py", line 2, in <module> from drq…...

Mac 解决 APP 快捷键冲突

打开 Mac 系统设置键盘->键盘快捷键->App快捷键->添加快捷键&#xff08;加号&#xff09;->标题需要和tab名称完全一致&#xff08;包括中英文、标点符号等&#xff0c;如下图&#xff09;设置快捷键即可 Reference&#xff1a; https://www.cnblogs.com/Questio…...

mysql之事务

&#xff08;一&#xff09;事务 1、事务是一种机制一个操作序列&#xff0c;包含了一组数据库的操作命令&#xff0c;所有命令都是一个整体&#xff0c;向系统提交或者撤销的操作&#xff0c;要么都执行&#xff0c;要么都不执行 2、不可分割的单位 &#xff08;二&#xf…...

组件化npm包打包和使用

背景&#xff1a;本地环境对功能组件提取&#xff0c;开发环境下通过本地路径引用&#xff0c;发布模式下走npm包引用 1、项目下新建packages/HelloWorld文件夹&#xff0c;在此文件夹下运行终端 npm init 新建packages/HelloWorld/index.vue文件 新建packages/HelloWorld/ind…...

Windows 内置Linux子系统的配置(From WSL1 to WSL2)

目录 我是如何从WSL1转到WSL2的? WSL1与WSL2的功能区别: 配置下载源 SSH配置 优雅使用windows的Linux子系统 我是如何从WSL1转到WSL2的? 第一次安装的子系统是WSL1的&#xff0c;因为不能使用systemctl &#xff0c;以及因为WSL1没有完整的Linux内核,所以使得WSL1很多命令…...

2023-11-03 android app TextView 滚动,ScrollView 之外的另外一种方法

一、布局xml文件中TextView 增加下面属性 android:maxLines "AN_INTEGER" android:scrollbars "vertical" 二、在java代码中添加下面代码&#xff0c;就可以滚动了。 m_TextView.setMovementMethod(new ScrollingMovementMethod())...

SAP 获取GOS附件清单及URL数据方法

很久没有更新了&#xff0c;断更了快两个月了&#xff0c;最近准备软考考试&#xff0c;刚考完不知道这次能不能通过 回归正题 SAP中很多业务中都是可以上传附件或者是上传URL的路径的&#xff0c;上传附件长时间会占用SAP的空间&#xff0c;使用GOS大多数都是采用上传URL的方式…...

VUE批量下载图片打包成zip下载

import JSZip from jszip; import { saveAs } from file-saver; downloadImages() {var zip new JSZip();// 创建images文件夹//imageUrls[本地路径,或者网络路径];var imgFolder zip.folder("images");let flag 0 // 判断加载了几张图片的标识for (let i 0; i …...

微信小程序-form表单-获取用户输入文本框的值

微信小程序-form表单-获取用户输入文本框的值 data: {userName: ,userPwd:""},//获取用户输入的用户名 userNameInput:function(e) {this.setData({userName: e.detail.value}) }, passWdInput:function(e) {this.setData({userPwd: e.detail.value}) }, //获取用户输…...

Docker(1)

文章目录 Docker物理机部署的缺点虚拟机Docker 与虚拟机的区别Docker 的优势 Docker 概念安装 DockerDocker 架构镜像加速Docker 命令进程服务相关命令 镜像相关文件命令容器相关的命令 镜像加载的原理UnionFS(联合文件系统)docker 镜像加载原理 容器的数据卷数据卷概念配置数据…...

axios 实现请求重试

前景提要&#xff1a; ts 简易封装 axios&#xff0c;统一 API 实现在 config 中配置开关拦截器 请求重试的核心是可以重放请求&#xff0c;具体实现就是在 axios 中&#xff0c;拿到当前请求的 config 对象&#xff0c;再用 axios 实例&#xff0c;就能重放请求。 在无感刷新…...

SSE加速随笔

Intel Intrinsics Guide 搞懂SSE 寄存器与指令数据细节 SSE指令集推出时&#xff0c;Intel公司在Pentium III CPU中增加了8个128位的SSE指令专用寄存器&#xff0c;称作XMM0到XMM7。这些XMM寄存器用于4个单精度浮点数运算的SIMD执行&#xff0c;并可以与MMX整数运算或x87浮点运…...

【TES720D】青翼科技基于复旦微的FMQL20S400全国产化ARM核心模

板卡概述 TES720D是一款基于上海复旦微电子FMQL20S400的全国产化核心模块。该核心模块将复旦微的FMQL20S400&#xff08;兼容FMQL10S400&#xff09;的最小系统集成在了一个50*70mm的核心板上&#xff0c;可以作为一个核心模块&#xff0c;进行功能性扩展&#xff0c;特别是用…...

arcgis删除细长图斑的方法

1、有一张图斑数据如下&#xff1a; 如上图&#xff0c;有很多细长的面要素&#xff0c;需要保留的仅是图中的块状要素。 2、首先要将被合并的要素进行拆分&#xff0c;具体拆分步骤如下&#xff1a; 将所有要素选中&#xff0c;点击高级编辑中的拆分按钮。 3、拆分后图斑就…...

Flutter笔记:Flutter的WidgetsBinding.instance的window属性

Flutter笔记 Flutter的WidgetsBinding.instance的window属性 作者&#xff1a;李俊才 &#xff08;jcLee95&#xff09;&#xff1a;https://blog.csdn.net/qq_28550263 邮箱 &#xff1a;291148484163.com 本文地址&#xff1a;https://blog.csdn.net/qq_28550263/article/det…...

element UI DatePicker 日期选择器 点击时间点可选限制范围前后十五天

<el-date-picker v-model"timeRange" type"datetimerange" align"right" :default-timedefaultTimevalue-format"yyyy-MM-dd HH:mm:dd" range-separator"至" start-placeholder"开始日期"end-placeholder"…...

【自用】vmware workstation建立主机window与虚拟机ubuntu之间的共享文件夹

1.在windows中建立1个文件夹 在vmware中设置为共享文件夹 参考博文&#xff1a; https://zhuanlan.zhihu.com/p/650638983 2.解决&#xff1a; &#xff08;1&#xff09;fuse: mountpoint is not empty &#xff08;2&#xff09;普通用户也能使用共享目录 参考博文&#x…...

【2023年MathorCup高校数学建模挑战赛-大数据竞赛】赛道A:基于计算机视觉的坑洼道路检测和识别 python 代码解析

【2023年MathorCup高校数学建模挑战赛-大数据竞赛】赛道A&#xff1a;基于计算机视觉的坑洼道路检测和识别 python 代码解析 1 题目 坑洼道路检测和识别是一种计算机视觉任务&#xff0c;旨在通过数字图像&#xff08;通常是地表坑洼图像&#xff09;识别出存在坑洼的道路。这…...

Mozilla Firefox 119 现已可供下载

Mozilla Firefox 119 开源网络浏览器现在可以下载了&#xff0c;是时候先看看它的新功能和改进了。 Firefox 119 改进了 Firefox View 功能&#xff0c;现在可以提供更多内容&#xff0c;如最近关闭的标签页和浏览历史&#xff0c;你可以按日期或网站排序&#xff0c;还支持查…...

What is 哈希?

哈希 ​ 前言&#xff1a;大一大二就一直听说哈希哈希&#xff0c;但一直都没有真正的概念&#xff1a;What is 哈希&#xff1f;这篇博客就浅浅聊一下作者认知中的哈希。 理解哈希 ​ 哈希&#xff08;Hash&#xff09;也可以称作散列&#xff0c;实质就是一种映射&#xf…...