opentelemetry-demo currency cpp 项目编译流程分享

opentelemetry-demo是opentelemetry的官方演示,项目是一个多语言的完整项目,各个子项目是行业专家写的初级项目,项目代码少难度低,非常适合初学者学习生产级的项目框架。

首先从github上下载GitHub - open-telemetry/opentelemetry-demo: This repository contains the OpenTelemetry Astronomy Shop, a microservice-based distributed system intended to illustrate the implementation of OpenTelemetry in a near real-world environment.https://github.com/open-telemetry/opentelemetry-demo用vsc打开src/currency目录

使用docker编译项目

启动docker desktop后在项目目录终端中运行docker compose build currency(参考README.md) 能够直接编译成功,几乎没有遇到什么问题。

docker run --rm ghcr.io/open-telemetry/demo:latest-currency

在容器中运行容器时遇到问题

terminate called after throwing an instance of 'std::logic_error'

what(): basic_string: construction from null is not valid

通过对server.cpp分区注释编译运行发现错误在第85行的

std::string version = std::getenv("VERSION");

cpp 复制代码
std::string version = std::getenv("VERSION"); 

这行代码的功能是读取环境变量,并且创建一个string对象。当前环境中没有定义VERSION环境变量,所以运行时报错。

解决方案:添加环境变量启动docker

设置VERSION为空字符串就可以成功启动

bash 复制代码
docker run --rm -e VERSION= ghcr.io/open-telemetry/demo:latest-currency

输出 Usage: currency <port>

提示是没有指定端口号,那么如何在命令行中指定port参数呢?

查看dockerfile 发现entrypoint通过环境变量currency_port来指定端口号。

我们修改docker命令添加CURRENCY_PORT环境变量

docker run --rm -e VERSION= -e CURRENCY_PORT=9999 ghcr.io/open-telemetry/demo:latest-currency

控制台输出

Error\] File: /opentelemetry-cpp/exporters/otlp/src/otlp_grpc_log_record_exporter.cc:173 \[OTLP LOG GRPC Exporter\] Export() failed: failed to connect to all addresses; last error: UNKNOWN: ipv4:127.0.0.1:4317: Failed to connect to remote host: Connection refused 这是因为默认连接到本机的opentelemetry-collector。连接到正确的opentelemetry-collector不是本文章的学习范围。 用vsc查看代码时发现有大量错误,代码阅读体验很差。有必要在开发环境中做好配置以学习项目源码。 ## 用wsl ubuntu编译项目 在查看currency项目的源码时发现大量头文件不存在。![](https://i-blog.csdnimg.cn/direct/6d1f79bf14dc481aa749dc613fa6ad1b.png) 在linux上安装grpc库来解决这个问题,执行 ```bash sudo apt install libgrpc-dev ``` 上面的问题消失 但是cmake 在configure时报错 \[cmake\] CMake Error at CMakeLists.txt:7 (find_package): \[cmake\] Could not find a package configuration file provided by "Protobuf" with any \[cmake\] of the following names: \[cmake

cmake\] ProtobufConfig.cmake \[cmake\] protobuf-config.cmake \[cmake

cmake\] Add the installation prefix of "Protobuf" to CMAKE_PREFIX_PATH or set \[cmake\] "Protobuf_DIR" to a directory containing one of the above files. If \[cmake\] "Protobuf" provides a separate development package or SDK, be sure it has \[cmake\] been installed. \[cmake

意思是cmake没有找到protobufconfig.cmake配置。下面来安装protobuf试试

bash 复制代码
sudo apt install libprotobuf-dev

安装以后依然提示上面的错误。继续分析,这里补充一个知识点:linux环境下的dev程序包应该在cmake目录下有相应的cmake配置,才能被cmake环境识别到。

我们用ubuntu的dpkg命令来分析protobuf的所有文件,发现没有与cmake相关的配置文件

我们再用dpkg命令来分析grpc包的文件,有期望的输出结果

经过进一步搜索发现ubuntu的protobuf库没有使用cmake进行编译,而是用autotool进行编译的,因此没有生成cmake相关配置。

参考这篇文章Compiling grpc on Ubuntu 22.04 with system libprotobuf

而alipne linux的protobuf-dev库是用cmake编译的,有cmake配置文件。参考

Package index - Alpine Linux packages

这种问题也是c++开发中经常遇到的问题,排查非常消耗时间。

事已至此,怎么解决这个问题呢?

能想到的方案是去找包含cmake配置的libprotobuf-dev,

UbuntuUpdates - Package Search (all versions of libprotobuf-dev)

但是页面上所有的包都没有cmake配置。

还有一种方法是从源码用cmake编译protobuf,从github下载,protobuf还有不少依赖,构建过程十分复杂。

最后一种方案是使用vcpkg包管理器,vcpkg安装包基本上不会出错,vcpkg会自动解决多级依赖问题,省心省力。

安装好vcpkg后在根目录下创建一个CMakePresets.json文件,写入如下内容

{

"version": 3,

"configurePresets": [

{

"name": "vcpkg",

"cacheVariables": {

"CMAKE_TOOLCHAIN_FILE": "$env{VCPKG_ROOT}/scripts/buildsystems/vcpkg.cmake"

}

}

]

}

重启vsc以刷新cmake插件

cmake配置成功后会出现如下项目

构建currency可执行目标,报错

fatal error: grpcpp/generic/async_generic_service.h: No such file or directory

这个头文件为什么不存在呢,明明已经安装了libgrpc-dev库,通过查看dpkg -L libgrpc-dev 确实没有看到grpcpp目录的头文件。原来是包安装错了,用下面的命令行安装正确的包

bash 复制代码
sudo apt install  libgrpc++-dev

继续编译,报错

build\] /usr/include/grpcpp/impl/codegen/config_protobuf.h:93:9: error: 'Status' in namespace 'google::protobuf::util' does not name a type 这种问题首先考虑的是protobuf和grpcpp的版本不匹配, 执行vcpkg list protobuf 输出 protobuf:x64-linux 5.29.5#3 Google's language-neutral, platform-neutral, ext... 安装的protobuf是5.29.5版本,从github上看是2年前发布的 [GitHub - protocolbuffers/protobuf at v5.29.5](https://github.com/protocolbuffers/protobuf/tree/v5.29.5 "GitHub - protocolbuffers/protobuf at v5.29.5") 执行 dpkg -l libgrpc++-dev 输出 Desired=Unknown/Install/Remove/Purge/Hold \| Status=Not/Inst/Conf-files/Unpacked/halF-conf/Half-inst/trig-aWait/Trig-pend \|/ Err?=(none)/Reinst-required (Status,Err: uppercase=bad) \|\|/ Name Version Architecture Description +++-===================-================-============-==================================================== ii libgrpc++-dev:amd64 1.51.1-4.1build5 amd64 high performance general RPC framework (development) 从github上看是4年前发布的 [​​​​​​GitHub - grpc/grpc at v1.51.1](https://github.com/grpc/grpc/tree/v1.51.1 "​​​​​​GitHub - grpc/grpc at v1.51.1") 这已经是ubuntu上能用apt安装的最新版本了。在这个场景下升级grpc的只能用vcpkg了。 来,使用vcpkg install grpc vcpkg编译项目要消耗很高的cpu和内存,经过27分钟的等待后继续编译。 ![](https://i-blog.csdnimg.cn/direct/e76f296e545248cb9f519884d5ea96d7.png) 这次发生的错误是opentelemetry没找到。 执行下面的命令安装opentelemetry: sudo apt install opentelemetry-cpp 不幸的是报错了 ```bash E: Unable to locate package opentelemetry-cpp ``` 我们去[Ubuntu -- Ubuntu Packages Search](https://packages.ubuntu.com/ "Ubuntu – Ubuntu Packages Search") 搜索opentelemetry-cpp [Ubuntu -- Package Search Results -- opentelemetry-cpp](https://packages.ubuntu.com/search?keywords=opentelemetry-cpp&searchon=names&suite=all§ion=all "Ubuntu – Package Search Results -- opentelemetry-cpp") ![](https://i-blog.csdnimg.cn/direct/905267040c314ebcac24ed86060ecb71.png) 既然ubuntu上有库为什么我安装不了呢? 原来是ubuntu版本的问题。我的wsl运行的是ubuntu 24 noble版本。ubuntu仓库中并没有支持noble版本的opentelemetry-cpp包。升级wsl版本太重了,用一些轻量的方法来操作,对,就是用vcpkg来安装opentelemetry-cpp。而且currency项目自带的dockerfile也是通过git下载opentelemetry-cpp编译安装的。 执行 ```bash vcpkg install opentelemetry-cpp ``` 这次执行非常快,不到2分钟就编译完成了 ![](https://i-blog.csdnimg.cn/direct/d161683fa4564d6f9bdf452159bbc837.png) 继续编译报错 ![](https://i-blog.csdnimg.cn/direct/d2e9bf4c2e6447b98ee1bd5b6800426a.png) 原来opentelemetry-cpp编译时默认不带 otlp-grpc功能,重新编译opentelemetry-cpp包 ```bash vcpkg install opentelemetry-cpp[otlp-grpc] --recurse ``` 这次编译也很快,不到3分钟就编译成功。 ![](https://i-blog.csdnimg.cn/direct/0b93cc1e3182445c9a3577b7df0ac024.png) 继续编译currency项目,在链接阶段报错 ![](https://i-blog.csdnimg.cn/direct/d88fc95caaec46218346c9389ab36fe1.png) 这个问题怎么排查呢? 先找链接字符串在哪个文件中出现 ![](https://i-blog.csdnimg.cn/direct/eea396fd666b432ba6c22cb929037781.png)这个错误原因就很明显了,操作系统没有安装opentelemetry,默认库目录下当然找不到库,那么 -lopentelemetry 开头的配置是怎么生成的呢? 答案是cmakelists.txt的target_link_libraries写了链接的库,将opentelemetry开头的链接项删除就可以了 ![](https://i-blog.csdnimg.cn/direct/0354056599574be0855c3e86dc7dacce.png) 继续build项目 ![](https://i-blog.csdnimg.cn/direct/7f04ac7e24d54c099400604a6a788728.png) ## **bingo! you make it!** **总结** **vcpkg在跨平台c++开发中是非常有效的包管理工具,不同linux自带的包管理器安装包时会遇到各种各样的问题,比如不支持cmake构建环境,比如原生包管理器不支持包,比如包版本不兼容并且包管理器没有匹配的版本。vcpkg是非常棒的fallback选择。**

相关推荐
jojo_zjx2 小时前
GESP 23年6月2级 找素数
c++
闻缺陷则喜何志丹2 小时前
【动态规划】P9980 [USACO23DEC] Flight Routes G|普及+
c++·算法·动态规划·洛谷
橘颂TA2 小时前
【剑斩OFFER】算法的暴力美学——力扣 433 题:最小基因变化
数据结构·c++·算法·哈希算法
移幻漂流2 小时前
C/C++内存掌控之道:从内存泄漏到零开销抽象的进阶之路
java·c语言·c++
橘颂TA2 小时前
【剑斩OFFER】算法的暴力美学——力扣 1926 题:迷宫中离入口最近的出口
c++·算法·结构与算法
余衫马2 小时前
Qt for Python:PySide6 入门指南(下篇)
c++·python·qt
HalvmånEver2 小时前
Linux:信号初识上(信号一)
linux·运维·服务器·c++·系统架构·信号
HellowAmy2 小时前
我的C++规范 - 请转移到文件
开发语言·c++·代码规范
strive-debug2 小时前
cpp篇~~类和对象
开发语言·c++