范文健康探索娱乐情感热点
投稿投诉
热点动态
科技财经
情感日志
励志美文
娱乐时尚
游戏搞笑
探索旅游
历史星座
健康养生
美丽育儿
范文作文
教案论文
国学影视

Rust语言的全链路追踪库tracing

  在一个应用程序或库的开发过程中,除了其本身的逻辑以外,开发人员还需要做很多额外的工作,以保证编写的代码可以正确的运行,或者在出错时可以快速定位到错误的位置以及原因,这就需要引入一些额外的工具,trace 就是其中特别好用的一种,下文我将会简单介绍 trace,并以 Rust 为例,演示 trace 在 Rust 中的使用方法。 可观测性
  Logs、Metrics 和 Traces 并称为可观测性三大支柱 ,通过分析它们输出的数据,开发人员能够更好的观测到系统的运行状况,更快的定位问题,从而提高系统的可靠性。
  日志(Logs)
  日志作为最常用的可观测性数据源之一,相信多数开发者都比较熟悉。其本质上就是一种带有时间戳的离散事件记录,通常用于记录系统的运行状态,日志的使用十分简单,只需要在代码中需要报告信息的点添加一行代码,就可以将这些信息输出到控制台或文件中,但是日志也有很大的缺点,它的输出是离散的,这意味着在记录的时候,无法将日志信息相互关联,也无法知道日志信息的上下文,尤其是在多线程的环境下,最终输出的信息比较混乱,不便于检索和分析。 指标(Metrics)
  指标是一种定量衡量,例如平均值、比率和百分比等。其值始终为数字而非文本,可以通过数学方法统计和分析,其主要用于描述系统运行状态的数据,比如 CPU 的使用率、内存的使用率、磁盘的使用率等,这些数据可以用来监控系统的运行状态,也可以用来预警。 追踪(Traces)
  追踪是一种用于记录系统中一次请求的完整生命周期的数据,它可以记录下一个请求从开始到结束的所有信息,包括请求的发起者、接收者、请求的路径、请求的状态、请求的耗时、请求的错误信息等,这些信息可以用来分析系统的性能瓶颈,也可以用来分析系统的错误。追踪本质上也是一种日志,他与日志的数据结构十分相似,但是它能够提供比日志更丰富的信息。特别是在分布式系统中,追踪能够跨越多个服务,汇总出一次请求的完整信息,让开发人员能够更方便的找到系统中的问题。
  Rust 中的 Trace
  Rust 社区中比较有名的 trace 实现有三个: tracing  由 tokio 团队维护,目前使用最广泛,生态也比较完善 rustracing  使用人数相对较少 minitrace tikv  团队打造,性能最好
  接下来就以 tracing 为例,介绍一下 trace 的核心概念以及使用方法 : Span
  Span 可以说是 trace 中最关键的概念之一,它表示的是一个过程,也就是一段时间内发生的所有事件的集合,其数据结构中包含着 Span 的开始时间和结束时间,在分析数据是可以借助工具直观的看到某次请求或操作的耗时情况。在同一个 trace 流程中的所有 Span 都共享这相同的 Trace Id ,每个 Span 也有着自己的 Span Id,并且 Span 还支持嵌套,嵌套的 Span 中也会保存着相应的父子关系,最终可以靠这些信息,将请求的完整生命周期串联起来,并且不会与相同时间段内的其他请求产生干扰。 use tracing::{span, Level};  fn main() {     let span = span!(Level::INFO, "span");     let _enter = span.enter();     // enter 后进入该 span 的上下文     // 可以记录信息到 span 中 } // 离开作用域后,_enter 被 drop,对应的 span 在此结束
  以上代码是创建并使用一个 Span 最简单的方式,除此以外还有几种不同的方式 #[instrument] // tracing 会为当前函数自动创建 span ,该 span 名与函数相同,并且整个函数都在该 span 的上下文内 fn do_something() {     // some event     let span = span!(Level::INFO, "external function");     span.in_scope(|| some_external_function()); //对于无法添加 #[instrument] 的外部函数,也可以使用 in_scope 方法让其在 span 的上下文中执行 }  #[instrument] // 此方法同样对异步函数适用 async fn do_something_async() {     let future = async {         // some async code     };     let span = span!(Level::INFO, "future");     future.instrument(span).await; // 也可以在 future .await 之前将 span 附加给 future }  // async 代码中要避免以下情况 async fn some_async_code() {     let span = span!(Level::INFO, "span");     let _enter = span.enter();     // 此处进入 span 的上下文,直到 _enter 被 drop 后才会结束     async_fn().await; // .await 时,task 可能会让出当前线程的执行权,而此时 _enter 还没有 drop,因此可能会错误的记录到其他 task 的 enent. }   Event
  Event 与日志类似,表示的是某一个时间点发生的事件,但与日志不同的是,Event 可以将信息记录到 Span 的上下文中,这样在分析数据时,可以直接查看 Span 中发生的所有事件。 use tracing::{event, info, span, Level};  fn main() {     event!(Level::INFO, "event"); // 在 span 的上下文之外记录一个 Leval 为 INFO 的 event      let span = span!(Level::INFO, "span");     let _enter = span.enter();      event!(Level::INFO, "event"); // 在 span 的上下文内记录 event      info!("something with info level"); // 也可以使用和 log 相同的形式记录 event } Collector
  以上的示例不会有任何可见的输出,因为我们还没有配置 Collector,tracing 中所有的 Span 和 Event 都是通过 Collector 来收集的,Collector 会将 Span 和 Event 以一定的格式输出到指定的地方,比如 stdout、stderr、文件、网络等。tracing-subscriber 的 fmt 模块提供了一个 Collector ,可以方便的输出事件信息。 use tracing::info; use tracing_subscriber;  fn main() {     // 初始化全局 Collector     tracing_subscriber::fmt::init();      info!("Hello, world!"); }
  运行上面这段代码,可以在终端中看到一条 INFO 级别的事件,如果需要将 Trace 信息发送到其他地方,就要用到其他的 Collector 实现,比如 tracing-appender 这个 crate,可以将 Trace 信息输出到文件中。 在 Rust 中使用
  tracing 的完整示例 use std::{thread::sleep, time::Duration};  use tracing::{debug, info, info_span, instrument};  #[instrument] fn expensive_work(secs: u64) {     debug!("doing expensive work");     sleep(Duration::from_secs(secs));     debug!("done with expensive work"); }  fn main() {     tracing_subscriber::fmt()         // enable everything         .with_max_level(tracing::Level::TRACE)         // sets this to be the default, global collector for this application.         .init();     let span = info_span!("root");     let _enter = span.enter();      info!("some info in the root span");      expensive_work(1); }
  运行以上代码将会的到以下输出 2022-12-01T02:50:59.425475Z  INFO root: tracing_example: some info in the root span 2022-12-01T02:50:59.425518Z DEBUG root:expensive_work{secs=1}: tracing_example: doing expensive work 2022-12-01T02:51:00.425722Z DEBUG root:expensive_work{secs=1}: tracing_example: done with expensive work
  每个事件都已相同的格式输出,此输出模式下,与 log 的输出十分相似,
  但 tracing 输出的内容多出了 Span 相关的信息。由 instrument 生成的 Span 还自动添加了函数的参数信息。下面介绍的 OpenTelemetry 和 Jaeger,还可以让我们更加直观的查看 Span 之间的时间关系。 Trace 的标准化
  想要让 Trace 跨越多个服务,集成到多种不同的语言,那就必须要规定大家相互调用的规范,要遵守一套相同的协议,才能让 Trace 的数据在不同的系统中都能够正常传递,Trace 早期诞生了两种规范,分别是 OpenTracing 和 OpenCensus,后来为了规范的统一,OpenTracing 和 OpenCensus 合并成了 OpenTelemetry,现在已经成为了 Trace 的事实标准。OpenTelemetry 提供了不同语言的 SDK,可以方便的集成到不同的系统中,对于 Rust ,它提供了一系列相关的 crate 用于集成。tracing 也提供了 tracing-OpenTelemetry 用来将其收集到的信息发送到兼容 OpenTelemetry 的分布式追踪系统中。 Trace 数据的可视化分析
  Jaeger 是受到 Dapper 和 OpenZipkin 启发的开源分布式跟踪系统,由 Uber 开发,现已捐赠给 CNCF。Jaeger 通过收集 Trace 数据,将其可视化展示,方便开发者分析系统的问题。下图为 Jaeger 部署的示例。
  要将 Trace 数据发送给 Jaeger,需要在我们的应用中添加 jaeger-client 。OpenTelemetry 提供的 crate 中,就包括了响应的 jaeger-clinet 实现: opentelemetry-jaeger。它会将 Span 信息以 UDP 包的形式发送到 jaeger-agent,jaeger-agent 将一段时间内的数据打包分批发送到 jaeger-collector,再由 jaeger-collector 把数据存入数据库内,我们在 jaeger 的 UI 中就可以查询到这些数据。
  OpenTelemetry 的仓库中也提供了以上流程的示例,我们可以直接运行这个示例,然后在 jaeger 的前端我们就可以得到下图的内容:
  有了这些数据,开发人员就能够快速定位到请求的主要耗时部分,也能够通过其中包含的事件获取到请求内的消息记录。
  总结
  对于大多数同步程序,用 Log 就能够满足需求,并且使用起来也足够简单,但是一旦涉及到异步程序或其他的一些复杂情况,Log 就会变得不那么好用了,一段时间内的 Log 信息可能来自于多个不同的处理流程,难以快速方便的获取我们需要的信息,而 Trace 则能够很好的解决这个问题。
  推荐阅读
  DatenLord|Rust程序性能分析

警惕旅游市场中的老年歧视丨九派时评九派新闻特约评论员梅明蕾作为投资主体,老年人每每被重视作为消费主体,他们又往往遭遇歧视。最近,一个年近七旬的朋友被几家保险公司的销售人员追逐,他们争相向他推销自己公司的一些保险产品疯狂一周!国际油价急挫,投资者措手不及!还会再跌吗?原油市场经历了极其疯狂的一周,短短4个交易日国际油价高点回落10美元,很多投资者没有为此做好准备。这是海通期货分析师杨安对本周国际油价走势的评价。换句话说,大家被暴跌的五年内每年予以财政奖励!海南明确5大类型总部企业可申请认定省商务厅近日印发海南省促进总部经济发展管理办法(以下简称办法),符合条件的企业可申请总部企业资格认定,涉及跨国公司区域总部大企业总部综合型总部功能型总部和高成长型总部等5大类型。为亿万资产家庭13万个,600万资产家庭518万户,贫富差距在拉大吗?2023年3月10日,根据胡润财富报告的数据显示,截止2023年1月1日。全国拥有600万人民币资产的富裕家庭数量,总计518万户。而拥有亿元人民币资产的用户总计13。8万个。而在老牛捉妖记0317中润资源超预期4连板,梯队完整,空间有限指数高开高走,本以为可以安心开心过个周末,没想到风云突变,帅不过三秒,没有惊喜只有惊吓。还是那个剧情,还是那个套路。10点半一到,准时跳水,上证指数在券商暴力护盘下勉强横盘,创业板外贸冲锋队成立!中山这家企业接力出海抢单一季度,我们计划参加2023年美国芝加哥家电及家庭用品展,筹备参加第133届广交会事宜。部署着周游全球的行程,广东思诺得环保科技有限公司(简称思诺得公司)总经理卢海洋信心满满。今年关注宝马集团2030年单车全周期碳排放降低402050年实现气候中和文懂车帝原创李德喆懂车帝原创行业懂车帝从宝马集团获悉,在日前举行的2023年宝马集团财报年会上,集团管理层重申对1。5摄氏度控温目标的承诺,在2050年前实现气候中和,尤其是实现温洞见丨网课爆破之后,教育隐私安全何解?当前,教育行业已经成为网络安全的重灾区之一。全球知名的网络安全技术公司CheckPoint发布的安全报告显示,2022年7月,全球范围的教育机构平均每周每家会被攻击2000次。这个好消息,今年多款完整L3级自动驾驶车型将上市,但也有隐忧!国家已经着手推进L3以上级别自动驾驶,造车新势力蔚来小鹏理想表现积极,但却喜忧参半。本文将从国家对自动驾驶的政策推进,目前自动驾驶渗透率,上市的自动驾驶车型自动驾驶主流芯片芯片应用任正非预言会有人求着我们买芯片,外媒如今真的成现实了任正非是华为的创始人和CEO,他曾经多次表示过华为在芯片领域的野心和战略布局。他曾在2019年底的采访中表示,华为预计到2021年将能够实现自己的芯片制造,而到2025年,华为的芯TikTokCEO周受资将在国会接受质询美国打压又来了!中国最成功的海外appTikTok正面临生死存亡!TikTokCEO周受资将于3月23日出席美国众议院能源和商业委员会举行的听证会。这是周受资自去年5月就任TikTokCEO以来首
140多名FF员工请愿罢免董事会主席,公司Q2净亏损增至1。42亿美元8月26日消息,据证券日报援引外媒报道称,近日,FaradayFuture(法拉第未来,下称FF)全球140多名员工集体实名,向FF董事会和全球股东发出请愿书,请愿罢免SueSwe杨开明杨开慧之弟,毛主席在传世名篇中不留情面地3次点名批评老覃在昨天写了毛主席真的是一支笔抵十万兵?来看蒋介石和日本侵略者的评价一文,文中提到,毛主席在主持召开延安文艺界座谈会期间,群伦咸服,一锤定音,俨然就是在文坛的执牛耳者。实际上,毛山西这十年山西省妇女事业高质量发展迈出新步伐9月7日,省委宣传部举行山西这十年系列主题新闻发布会的第十二场发布会,同时也是省总工会团省委省妇联专场新闻发布会。省妇联党组书记主席黄岑丽在会上介绍了党的十八大以来推动全省妇女事业银河系的旋臂不可思议地触发了地球大陆的形成研究人员报告说,在一个奇怪的命运地质扭曲中,我们人类称之为家的大陆很可能是40亿年前巨大地球撞击物的副产品,这些撞击物是通过银河系旋臂的通道不可思议地触发的。在刚刚发表在地质学杂志炎陵23个项目集中开竣工总投资38亿元华声在线8月25日讯(全媒体记者张咪通讯员张和生霍强)8月24日,炎陵县举行项目建设集中开竣工活动,23个项目集中开竣工,总投资38亿元。此次开竣工项目包括欧科亿数控刀具(株洲)产6亿光年外,一个极不寻常的星系,科学家研究多年,仍不清楚原理宇宙浩瀚得令人无法想象,人类对宇宙的认知,很可能连冰山一角都算不上,在过去的日子里,人们在宇宙深空中观测到了不少无法用现有理论解释的现象,比如说在大约6亿光年之外,就存在着一个极不一个请代驾不用,一个醉驾要求重罚,高新警方连查两名奇葩酒司机湖北日报客户端讯(全媒体见习记者刘远方通讯员刘晨光邹红)喝酒不开车,开车不喝酒,任何理由也无法成为酒驾的借口。近日,紫贞警务平台连查两名奇葩酒醉驾司机。9月2日凌晨,紫贞警务平台接2005年,福建发现孙悟空的墓穴和金箍棒,他真的存在过吗?2005年,孙悟空的墓穴在福建被发现,让人匪夷所思的是在这座古墓中,专家们还发现了孙悟空的如意金箍棒!孙悟空只是一个角色而已,怎么会有墓穴呢?这墓的来头可真是让专家们犯了难。西游记钟丽缇身价过亿,三婚下嫁软饭男张伦硕,52岁还想拼四胎身价不菲人鱼女神变人间阔太一身珠宝即京城一套房,钟丽缇到底有多富。光靠收北京房子的租金钟丽缇就能后生无忧,当张雨绮还嘲讽碎钻不值钱的时候,钟丽缇手上鸽子蛋一样大的钻戒啪啪打了她的脸熊猫奶爸的幸福生活组图来源新华网8月20日,在马来西亚吉隆坡附近的马来西亚国家动物园,大熊猫谊谊在大熊猫保护中心休息。阿克迈勒是马来西亚国家动物园的大熊猫饲养员。从2014年大熊猫兴兴和靓靓入住马来西亚玻璃陨石玻璃陨石为半透明的玻璃质体,有微弱磁性,颜色为墨绿色绿色,淡绿色,棕色,褐色,深褐色,还有少见的朱砂色。玻璃陨石是在高空高温高压和高速下形成的,通体布满致密的小气泡,外部有融壳,融