QT 应用中集成 Sentry

news2024/12/23 8:26:39

QT 应用中集成 Sentry

  • QT应用中集成 Sentry
    • Sentry SDK for C/C++
    • 注册 Sentry 账号
    • QT 应用中集成 Sentry
    • 触发 Crash 上报

QT应用中集成 Sentry

Sentry 是一个开源的错误监控和日志记录平台,旨在帮助开发团队实时捕获、跟踪和解决软件应用程序中的错误和异常。它提供了强大的错误监控和日志记录工具,使开发团队能够快速定位并解决生产环境中的问题。

在现代软件开发中,错误和异常是不可避免的。良好的错误监控和日志记录系统可以帮助开发团队快速响应和解决问题,提高软件的可靠性和稳定性。通过及时发现和修复问题,可以降低用户遭遇错误的概率,提升用户体验,同时也有助于保护品牌声誉。

本文将介绍如何集成 Sentry 到 QT应用程序,实现一个完善的错误监控和日志记录功能,解决 C 端产品因为用户环境等原因导致的难于定位、难于收集有效信息的痛点。

Sentry SDK for C/C++

第一步,前往 https://github.com/getsentry/sentry-native 下载 Sentry Native SDK。Sentry Native SDK 是一个针对本机应用程序的错误和崩溃报告客户端,针对 C 和 C++ 进行了优化,支持Sentry 20.6.0及更高版本。截止本文撰写的时间,最新版本是 0.7.0,直接下载 sentry-native.zip 这个包。
在这里插入图片描述
解压 sentry-native.zip 压缩包:

unzip sentry-native.zip -d sentry-native

第二步,编译 Sentry Native SDK。

$ cd sentry-native/
$ cmake -B build -D SENTRY_BACKEND=crashpad -D SENTRY_INTEGRATION_QT=YES
$ cmake --build build --parallel
# 将头文件和库文件等安装到 install 目录
$ cmake --install build --prefix install --config RelWithDebInfo
# 查看 install 下的目录结构,如果系统没有 tree 命令,使用 sudo apt install tree 安装
$ tree install
install
├── bin
│   └── crashpad_handler
├── include
│   └── sentry.h
└── lib
    ├── cmake
    │   └── sentry
    │       ├── sentry-config.cmake
    │       ├── sentry-config-version.cmake
    │       ├── sentry_crashpad-targets.cmake
    │       ├── sentry_crashpad-targets-relwithdebinfo.cmake
    │       ├── sentry-targets.cmake
    │       └── sentry-targets-relwithdebinfo.cmake
    └── libsentry.so

如果出现如下错误:

CMake Error at /home/alex/.local/lib/python3.8/site-packages/cmake/data/share/cmake-3.27/Modules/FindCURL.cmake:176 (message):
  CURL: Required feature AsynchDNS is not found
Call Stack (most recent call first):
  CMakeLists.txt:278 (find_package)

解决方法:

$ sudo apt install libcurl4-openssl-dev

可以看到,编译出来的 Sentry Native SDK 包含头文件、库文件,还有一个 crashpad_handler,需要注意的是,crashpad_handler 这个文件需要放到应用程序所在的目录下。

注册 Sentry 账号

Sentry 服务可以本地部署,也可以直接使用 Sentry 提供的免费服务。对于个人开发者来说,Sentry 提供的免费服务够用,没有必要自行去折腾。

访问 https://sentry.io 网站,首先注册一个账号,这个过程和大多数注册过程相同,按照提示进行即可,这里就不赘述。

注册完成后,出现如下界面:
在这里插入图片描述
点击上面的那个Start按钮,会一步步直到你配置项目。
在这里插入图片描述
先点上面的 Desktop,就会出现桌面项目,然后点 QT,最后点击右下角的 Configure SDK。出现针对 QT 的集成代码示例,参照代码示例就可以完成在 QT 项目中集成 Sentry SDK。
在这里插入图片描述
点击右下角的 View Sample Error,系统会生成一个 Error 示例,在 Sentry 控制台可以看到:
在这里插入图片描述
上图展现了一个 Sentry 上报事件的详细信息。

QT 应用中集成 Sentry

借助于 Sentry native SDK,我们很容易集成 Sentry。下面用一个简单的示例程序进行说明,为了简单起见,我们创建一个控制台程序,项目起名为 SentryDemo。
在这里插入图片描述
按照前面 Qt SDK 配置提示的那样,在 main.cpp 中加入 sentry 初始化代码:

    sentry_options_t *options = sentry_options_new();
    sentry_options_set_dsn(options, "https://47e01ddf9ed4e2ce58914c67cd315d07@o4506677667561472.ingest.sentry.io/4506683131428864");
    // This is also the default-path. For further information and recommendations:
    // https://docs.sentry.io/platforms/native/configuration/options/#database-path
    sentry_options_set_database_path(options, ".sentry-native");
    sentry_options_set_release(options, "my-project-name@2.3.12");
    sentry_options_set_debug(options, 1);
    sentry_init(options);

其中第二行代码要换成你的 Sentry 项目的 DSN,这个值可以在 sentry.io 的项目设置中查到。
在这里插入图片描述
接下来加入一个简单的事件捕获代码:

    sentry_capture_event(sentry_value_new_message_event(
      /*   level */ SENTRY_LEVEL_INFO,
      /*  logger */ "custom",
      /* message */ "It works!"
    ));

为了使得代码编译通过,还得修改项目工程 pro 文件,加入:

INCLUDEPATH += $${PWD}/../thirdparty/sentry-native/install/include
LIBS += -L$${PWD}/../thirdparty/sentry-native/install/lib -lsentry

这样就得到了 SentryDemo 可执行程序,需要注意的是,在运行 SentryDemo 前,需要将前一步编译 Sentry Native SDK 得到的 libsentry.so 和 crashpad_handler 复制到和可执行程序相同的目录。执行结果如下:

$ ./SentryDemo 
[sentry] INFO using database path "/work/mywork/qt-in-action/source/build-SentryDemo-Desktop_Qt_5_15_2_GCC_64bit-Debug/.sentry-native"
[sentry] DEBUG starting transport
[sentry] DEBUG starting background worker thread
[sentry] DEBUG starting backend
[sentry] DEBUG starting crashpad backend with handler "/work/mywork/qt-in-action/source/build-SentryDemo-Desktop_Qt_5_15_2_GCC_64bit-Debug/crashpad_handler"
[sentry] DEBUG background worker thread started
[sentry] DEBUG using minidump URL "https://o4506677667561472.ingest.sentry.io:443/api/4506683131428864/minidump/?sentry_client=sentry.native/0.7.0&sentry_key=47e01ddf9ed4e2ce58914c67cd315d07"
[sentry] INFO started crashpad client handler
[sentry] DEBUG setting up Qt integration
[sentry] DEBUG processing and pruning old runs
[sentry] DEBUG merging scope into event
[sentry] DEBUG trying to read modules from /proc/self/maps
[sentry] DEBUG read 57 modules from /proc/self/maps
[sentry] DEBUG adding attachments to envelope
[sentry] DEBUG sending envelope
[sentry] DEBUG submitting task to background worker thread
[sentry] DEBUG executing task on worker thread
*   Trying 34.120.195.249:443...
* TCP_NODELAY set
* Connected to o4506677667561472.ingest.sentry.io (34.120.195.249) port 443 (#0)
* ALPN, offering h2
* ALPN, offering http/1.1
* successfully set certificate verify locations:
*   CAfile: /etc/ssl/certs/ca-certificates.crt
  CApath: /etc/ssl/certs
* SSL connection using TLSv1.3 / TLS_AES_256_GCM_SHA384
* ALPN, server accepted to use h2
* Server certificate:
*  subject: C=US; ST=California; L=San Francisco; O=Sentry; CN=ingest.sentry.io
*  start date: Nov  2 00:00:00 2023 GMT
*  expire date: Dec  2 23:59:59 2024 GMT
*  subjectAltName: host "o4506677667561472.ingest.sentry.io" matched cert's "*.ingest.sentry.io"
*  issuer: C=US; O=DigiCert Inc; CN=DigiCert Global G2 TLS RSA SHA256 2020 CA1
*  SSL certificate verify ok.
* Using HTTP2, server supports multi-use
* Connection state changed (HTTP/2 confirmed)
* Copying HTTP/2 data in stream buffer to connection buffer after upgrade: len=0
* Using Stream ID: 1 (easy handle 0x55ad8d179b20)
> POST /api/4506683131428864/envelope/ HTTP/2
Host: o4506677667561472.ingest.sentry.io
user-agent: sentry.native/0.7.0
accept: */*
x-sentry-auth:Sentry sentry_key=47e01ddf9ed4e2ce58914c67cd315d07, sentry_version=7, sentry_client=sentry.native/0.7.0
content-type:application/x-sentry-envelope
content-length:13896

* We are completely uploaded and fine
* old SSL session ID is stale, removing
* Connection state changed (MAX_CONCURRENT_STREAMS == 100)!
< HTTP/2 200 
< server: nginx
< date: Sat, 03 Feb 2024 13:54:11 GMT
< content-type: application/json
< content-length: 41
< access-control-allow-origin: *
< vary: origin,access-control-request-method,access-control-request-headers
< access-control-expose-headers: x-sentry-error,x-sentry-rate-limits,retry-after
< cross-origin-resource-policy: cross-origin
< x-envoy-upstream-service-time: 0
< strict-transport-security: max-age=31536000; includeSubDomains; preload
< via: 1.1 google
< alt-svc: h3=":443"; ma=2592000,h3-29=":443"; ma=2592000
< 
{"id":"8a84cd16adab42f49611bb32adfe72f0"}* Connection #0 to host o4506677667561472.ingest.sentry.io left intact

前往 sentry.io,可以看到我们收到如下消息上报:
在这里插入图片描述
点开,可以查看事件的详细信息。
在这里插入图片描述
可以看到,详细信息中包含操作系统版本、程序发布版本等等。

看到这里,你可能觉得,这不就是一个日志系统吗?

当然,你的确可以把 Sentry 当做一个在线日志系统,还是加强版本的。事件消息可以分级(level),还可以自定义类别(logger),还可以分版本(release)。

不过这样做,就有点暴殄天物了,因为 Sentry 还可以收集 crash 日志。

触发 Crash 上报

在程序中加入一段能引发内存访问错误的代码,模拟程序崩溃,看看会发生什么。

static void *invalid_mem = (void *)1;

static void
trigger_crash()
{
    memset((char *)invalid_mem, 1, 100);
}

在 main 函数中调用 trigger_crash,运行之后,在 sentry.io 管理端就可以看到有新的 crash 报告上来:
在这里插入图片描述
点开可以查看详情:
在这里插入图片描述
这样,我们在程序崩溃时,就得到了错误上报,还包含了 crash 堆栈,通过调试符号,我们可以根据偏移地址,找到对应的源码行。

Sentry 的强大在于,我们可以上传调试符号文件,Sentry 自动分析符号文件,直接定位到源代码行,省去了我们使用 addr2line 之类的工具。

如何生成调试符号文件,如何上传调试符号文件,咱们在下一章再见。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1432066.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

qml中布局属性讲解

1.行布局&列布局:RowLayout&ColumnLayout RowLayout {id: layoutanchors.fill: parentspacing: 6Rectangle {color: tealLayout.fillWidth: trueLayout.minimumWidth: 50Layout.preferredWidth: 100Layout.maximumWidth: 300Layout.minimumHeight: 150Text {anchors.c…

基于nginx的虚拟主机配置

目录 一.基于不同ip的虚拟主机 二.基于不同端口的虚拟主机 三.基于不同域名的虚拟主机 一.基于不同ip的虚拟主机 1.关闭 SELinux和防火墙 2.在/data目录中创建三个目录&#xff0c;分别为nginx1、nginx2 和nginx3,具体名为: 3.分别在三个目录中创建index.html,并输入内容“…

C++程序在开机自启和定时器执行时遇到的问题和解决方法

遇到的错误如下&#xff1a; Camera is created.load vfvlog.[dll/so] failed for dll[/vfvlog.so] unexistedLoadDbgConfig, LoadFile fail, err:-3, errno: No such file or directoryqt.qpa.xcb: could not connect to displayqt.qpa.plugin: Could not load the Qt platfo…

XSS haozi靶场通关笔记

XSS靶场地址&#xff1a;alert(1) 靶场的要求是输出一个内容为1的弹窗&#xff1b;这个靶场限制了输入位置只能是input code&#xff1b;而且浏览器发送内容时会自动进行url编码&#xff1b;所以重点考察的是代码的分析和基础payload构造&#xff1b;一切完成在当前页面&#…

毫米波雷达在汽车领域的原理、优势和未来趋势

1 毫米波雷达的原理 汽车引入毫米波雷达最初主要是为了实现盲点监测和定距巡航。毫米波实质上是电磁波&#xff0c;其频段位于无线电和可见光、红外线之间&#xff0c;频率范围为10GHz-200GHz。工作原理类似一般雷达&#xff0c;通过发射无线电波并接收回波&#xff0c;利用障…

Dynamo根据几何相交对墙体进行分组——群问题整理002

你好&#xff0c;这里是 BIM 的乐趣&#xff0c;我是九哥~ 近期给大家分享一些短平快的小教程&#xff0c;基本都是来自群里面常问的问题&#xff0c;不做过多的介绍了&#xff0c;直接上截图和代码。 问题&#xff1a;002 - 根据几何相交对墙体进行分组 今天分享的&#xff0…

C++后端开发之Sylar学习二:配置VSCode远程连接Ubuntu开发

C后端开发之Sylar学习二&#xff1a;配置VSCode远程连接Ubuntu开发 没错&#xff0c;我不能像大佬那样直接在Ubuntu上面用Vim手搓代码&#xff0c;只能在本地配置一下VSCode远程连接Ubuntu进行开发咯&#xff01; 本篇主要是讲解了VSCode如何配置ssh连接Ubuntu&#xff0c;还有…

【文件增量备份系统】前端项目构建

文章目录 创建项目安装项目依赖引入element plus组件下载组件在main.js中使用组件测试 整合路由router下载组件创建路由管理器index.js使用路由App.vue上面使用 <router-view />测试 整合axios下载组件工具类axiosRequest.js工具类使用 创建项目 damwangrunqindeMBP dev…

PyTorch 2.2 中文官方教程(十四)

参数化教程 原文&#xff1a; 译者&#xff1a;飞龙 协议&#xff1a;CC BY-NC-SA 4.0 作者&#xff1a;Mario Lezcano 注意 点击这里下载完整示例代码 在本教程中&#xff0c;您将学习如何实现并使用此模式来对模型进行约束。这样做就像编写自己的nn.Module一样容易。 对深…

Mybatis基础教程及使用细节

本篇主要对Mybatis基础使用进行总结&#xff0c;包括Mybatis的基础操作&#xff0c;使用注解进行增删改查的练习&#xff1b;详细介绍xml映射文件配置过程并且使用xml映射文件进行动态sql语句进行条件查询&#xff1b;为了简化java开发提高效率&#xff0c;介绍一下依赖&#x…

树莓派5一键安装C++版本OpenCV

安装环境 本人当前的安装环境&#xff1a; 树莓派5Raspberry Pi os (64-bit) Debian12 Bookworm 镜像下载地址 我这里是将镜像安装好后直接安装opencv&#xff0c;如果不是刚安装好的镜像需要注意是否有openCV的python之类的安装过&#xff0c;不然可能出现编译错误 一、扩展内…

vue3+threejs+koa可视化项目——模型文件上传(第四步)

文章目录 ⭐前言&#x1f496;往期node系列文章&#x1f496;threejs系列相关文章&#x1f496;vue3threejs系列 ⭐koa后端文件上传(koa-body)&#x1f496;自动创建目录&#x1f496;自定义目录上传&#x1f496;apifox自测上传接口 ⭐vue3前端上传模型文件&#x1f496; axio…

echarts使用之饼图(四)

1 基本使用 <!DOCTYPE html> <html lang"en"><head><meta charset"UTF-8"><meta name"viewport" content"widthdevice-width, initial-scale1.0"><meta http-equiv"X-UA-Compatible" cont…

latex multirow学习

今天搞了一晚上的这个multirow&#xff0c;总算弄出来了几个比较好的例子&#xff0c;主要是这个multirow的语法我没看懂&#xff0c;这个逻辑我是没理解&#xff0c;就很尴尬&#xff0c;一改就报错&#xff0c;只能先弄几个例子&#xff0c;自己慢慢试 \documentclass{artic…

k8s学习-Kubernetes的网络

Kubernetes作为编排引擎管理着分布在不同节点上的容器和Pod。Pod、Service、外部组件之间需要⼀种可靠的方找到彼此并进行通信&#xff0c;Kubernetes网络则负责提供这个保障。1.1 Kubernetes网络模型 Container-to-Container的网络 当Pod被调度到某个节点&#xff0c;Pod中的…

【Python】【完整代码】解析Excel 文件中的内容并检查是否包含某字符串,并返回判断结果

示例&#xff1a; 开发需求&#xff1a;解析Excel 文件中的内容并检查是否包含 "Fail" 字符&#xff0c;若没有则返回True&#xff0c;若有则返回False 实现代码&#xff1a; #!/usr/bin/env python3 # -*- encoding: utf-8 -*-File : check_excel_for_fail.py Ti…

后端程序员入门react笔记——react的生命周期(二)

React常用的钩子函数 constructor 这个函数我们太常见了&#xff0c;在初始化类的state的时候&#xff0c;或者初始化类的props的时候都会用到&#xff0c;就是一个类的构造函数。对后端人员来说很熟悉 constructor() {super();this.state {age: 18}}getDerivedStateFromPro…

【C++入门学习指南】:函数重载提升代码清晰度与灵活性

&#x1f3a5; 屿小夏 &#xff1a; 个人主页 &#x1f525;个人专栏 &#xff1a; C入门到进阶 &#x1f304; 莫道桑榆晚&#xff0c;为霞尚满天&#xff01; 文章目录 &#x1f4d1;前言一、函数重载1.1 函数重载的概念1.2 函数重载的作用1.3 C支持函数重载的原理1.4 扩展 &…

如何写好论文——(15)如何写研究目标之实例讲解

写好研究目标一要有方向、二要有边界。 定边界的时候要有方法和结论。 下面的例子为目标的两种写法&#xff0c;第二种提供了更明确可以测量的目标。 下面的第二个例子更有方向性。第一个例子的本质是去验证一种假说&#xff0c;这种假说如果成立完全可以支撑第二种写法中的目…

【C/C++ 08】简单计算器

一、题目 输入算术表达式&#xff0c;可包含空格&#xff0c;检查算术表达式的合法性&#xff0c;若算术表达式不合法&#xff0c;打印错误类型&#xff0c;若合法&#xff0c;则进行运算&#xff0c;打印计算结果。 二、算法 1. 将输入的算术表达式字符串去除空格。 2. 检查…