【android bluetooth 框架分析 02】【Module详解 13】【CounterMetrics 模块介绍】

1. CounterMetrics 介绍

CounterMetrics 模块代码很少, 我简单介绍一下。

// system/gd/metrics/counter_metrics.cc
#define LOG_TAG "BluetoothCounterMetrics"#include "metrics/counter_metrics.h"#include "common/bind.h"
#include "os/log.h"
#include "os/metrics.h"namespace bluetooth {
namespace metrics {const int COUNTER_METRICS_PERDIOD_MINUTES = 360; // Drain counters every 6 hoursconst ModuleFactory CounterMetrics::Factory = ModuleFactory([]() { return new CounterMetrics(); });void CounterMetrics::ListDependencies(ModuleList* list) const {
}void CounterMetrics::Start() {alarm_ = std::make_unique<os::RepeatingAlarm>(GetHandler());alarm_->Schedule(common::Bind(&CounterMetrics::DrainBufferedCounters,bluetooth::common::Unretained(this)),std::chrono::minutes(COUNTER_METRICS_PERDIOD_MINUTES));LOG_INFO("Counter metrics initialized");initialized_ = true;
}void CounterMetrics::Stop() {DrainBufferedCounters();initialized_ = false;alarm_->Cancel();alarm_.reset();LOG_INFO("Counter metrics canceled");
}bool CounterMetrics::CacheCount(int32_t key, int64_t count) {if (!IsInitialized()) {LOG_WARN("Counter metrics isn't initialized");return false;}if (count <= 0) {LOG_WARN("count is not larger than 0. count: %s, key: %d", std::to_string(count).c_str(), key);return false;}int64_t total = 0;std::lock_guard<std::mutex> lock(mutex_);if (counters_.find(key) != counters_.end()) {total = counters_[key];}if (LLONG_MAX - total < count) {LOG_WARN("Counter metric overflows. count %s current total: %s key: %d",std::to_string(count).c_str(), std::to_string(total).c_str(), key);counters_[key] = LLONG_MAX;return false;}counters_[key] = total + count;return true;
}bool CounterMetrics::Count(int32_t key, int64_t count) {if (!IsInitialized()) {LOG_WARN("Counter metrics isn't initialized");return false;}if (count <= 0) {LOG_WARN("count is not larger than 0. count: %s, key: %d", std::to_string(count).c_str(), key);return false;}os::LogMetricBluetoothCodePathCounterMetrics(key, count);return true;
}void CounterMetrics::DrainBufferedCounters() {if (!IsInitialized()) {LOG_WARN("Counter metrics isn't initialized");return ;}std::lock_guard<std::mutex> lock(mutex_);LOG_INFO("Draining buffered counters");for (auto const& pair : counters_) {Count(pair.first, pair.second);}counters_.clear();
}}  // namespace metrics
}  // namespace bluetooth

如果你 看过我之前其他模块的介绍。应该很容易看明白, CounterMetrics 模块对应函数的触发流程。 我这里简单的介绍一下。CounterMetrics模块的作用。

2. CounterMetrics 的功能作用是什么?

该模块主要用于 收集并定期上报蓝牙栈内部的计数型指标(Counter Metrics),其核心职责包括:

功能点解析:

  1. 缓存统计项

    • 使用 CacheCount(int32_t key, int64_t count) 将特定的计数项临时缓存在内存中(如某类事件的触发次数)。
  2. 定时上报

    • 通过 os::RepeatingAlarm 每 6 小时调用 DrainBufferedCounters(),将缓存中的计数上报给系统的 metrics 框架(如 statsd)。
  3. 线程安全

    • 内部通过 std::mutex 锁保护 counters_ map,保证并发场景下的正确性。
  4. 溢出保护

    • 如果某个计数项的总值超出 LLONG_MAX,将其钳制为 LLONG_MAX 并发出警告。

3. 设计该模块的目的是什么?

背后的设计理念:

设计需求说明
低频统计上传某些蓝牙事件(如连接失败次数、重连次数、A2DP 播放错误等)不适合立即上报或日志输出。
延迟处理,降低性能影响延迟上报避免频繁调用 I/O 操作(如写文件、上报 statsd)。
可扩展性强只需新增对应的 key,即可添加新的统计项,无需修改上层逻辑。
帮助调优与问题排查比如分析 Bluetooth 启动失败次数、配对错误数,辅助 Google 收集大数据做产品改进。

4. 如果去掉这个模块会怎样?

  1. 无法延迟上报

    • 每次计数都需要即时上报,性能开销显著增加。
  2. 缺失统计数据

    • 某些只有内部记录但未及时上报的数据将无法收集,影响用户反馈分析与 QA 问题定位。
  3. 不利于数据分析平台接入

    • Google 的 statsd、OEM 的大数据平台等依赖此模块的统一接口上传蓝牙计数指标。

5. 实际应用场景举例(车机)

场景CounterMetrics 的作用
A2DP 播放中断记录播放异常次数,辅助分析车机蓝牙不稳定问题
HFP 通话失败统计通话连接失败次数,用于判断兼容性问题
蓝牙重启频率如果蓝牙频繁崩溃,CounterMetrics 可以记录频率帮助开发定位根因
配对异常统计不同品牌手机配对失败的频率,为白名单机制提供数据

6. 总结

项目内容
模块名称CounterMetrics
主要功能缓存并定期上报蓝牙内部计数数据
设计意义降低性能开销、支持延迟上报、提高调试能力
可否去除不能,否则将严重影响日志分析、问题定位及大数据支持能力

PS:
车机/手机 中 如果要对蓝牙服务 埋点, 诊断等。 其实可以结合这个模块来添加。

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

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

相关文章

QMK键盘固件配置详解

QMK键盘固件配置详解 前言 大家好&#xff01;今天给大家带来QMK键盘固件配置的详细指南。如果你正在DIY机械键盘或者想要给自己的键盘刷固件&#xff0c;这篇文章绝对不容错过。QMK是目前最流行的开源键盘固件框架之一&#xff0c;它允许我们对键盘进行高度自定义。接下来&a…

基于STM32、HAL库的DPS368XTSA1气压传感器 驱动程序设计

一、简介: DPS368XTSA1 是 InvenSense(TDK 集团旗下公司)生产的一款高精度数字气压传感器,专为需要精确测量气压和温度的应用场景设计。它具有超低功耗、高精度、快速响应等特点,非常适合物联网、可穿戴设备和无人机等应用。 二、硬件接口: DPS368XTSA1 引脚STM32L4XX 引…

因子分析——数学原理及R语言代码

正交因子分析 目的数学原理参数估计方法主成分法主因子法极大似然法 因子旋转模型检验因子得分加权最小二乘法回归法 代码实现注意事项例子 Reference 目的 FactorAnalysis的目的是从多个高度相关的观测变量中提取出少数几个LatentFactor&#xff0c;这些因子代表了变量背后的…

ACL访问控制列表:access-list 10 permit 192.168.10.1

ACL访问控制列表 标准ACL语法 1. 创建ACL access-list <编号> <动作> <源IP> <通配符掩码> // 编号范围 1-99 // 动作&#xff1a;permit 允许 、 deny 拒绝2. 示例 //允许192.168.1.0/24g整个网络,0.0.0.255 反掩码 access-list 10 permit 192.1…

解决社区录音应用横屏状态下,录音后无法播放的bug

最近看到社区有小伙伴反映&#xff0c;社区录音应用横屏时&#xff0c;录音后无法播放的问题。现分享解决办法。 社区录音应用的来源&#xff1a;https://gitee.com/openharmony/applications_app_samples/tree/OpenHarmony-5.0.2-Release/code/SystemFeature/Media/Recorder …

每周靶点分享:Angptl3、IgE、ADAM9及文献分享:抗体的多样性和特异性以及结构的新见解

本期精选了《脂质代谢的关键调控者Angptl3》《T细胞活化抑制因子VISTA靶点》《文献分享&#xff1a;双特异性抗体重轻链配对设计》三篇文章。以下为各研究内容的概述&#xff1a; 1. 脂质代谢的关键调控者Angptl3 血管生成素相关蛋白3&#xff08;Angptl3&#xff09;是血管生…

保持Word中插入图片的清晰度

大家有没有遇到这个问题&#xff0c;原本绘制的高清晰度图片&#xff0c;插入word后就变模糊了。先说原因&#xff0c;word默认启动了自动压缩图片功能&#xff0c;分享一下如何关闭这项功能&#xff0c;保持Word中插入图片的清晰度。 ①在Word文档中&#xff0c;点击左上角的…

Datawhale AI春训营 day

待补充 2025星火杯应用赛入门应用 创空间 魔搭社区 {"default": {"system": "你是星火大模型&#xff0c;一个由科大讯飞研发的人工智能助手。请用简洁、专业、友好的方式回答问题。","description": "默认系统提示词"}…

项目全栈实战-基于智能体、工作流、API模块化Docker集成的创业分析平台

目录 思维导图 前置知识 Docker是什么&#xff1f; Docker的核心概念&#xff1a; Docker在本项目中的作用 1. 环境隔离与一致性 2. 简化部署流程 3. 资源管理与扩展性 4. 服务整合与通信 5. 版本控制和回滚 6. 开发与生产环境一致性 总结 前端 1.小程序 2.web …

正则表达式实用指南:原理、场景、优化与引擎对比

正则表达式实用指南&#xff1a;原理、场景、优化与引擎对比 正则表达式&#xff08;Regular Expression&#xff0c;简称 regex 或 regexp&#xff09;是程序员处理文本数据时不可或缺的“瑞士军刀”。无论是表单校验、日志分析、数据清洗&#xff0c;还是敏感信息脱敏&#…

OSCP - Hack The Box - Sau

主要知识点 CVE-2023-27163漏洞利用systemd提权 具体步骤 执行nmap扫描&#xff0c;可以先看一下55555端口 Nmap scan report for 10.10.11.224 Host is up (0.58s latency). Not shown: 65531 closed tcp ports (reset) PORT STATE SERVICE VERSION 22/tcp o…

5.1.1 WPF中Command使用介绍

WPF 的命令系统是一种强大的输入处理机制,它比传统的事件处理更加灵活和可重用,特别适合 MVVM (Model, View, ViewModel)模式开发。 一、命令系统核心概念 1.命令系统基本元素: 命令(Command): 即ICommand类,使用最多的是RoutedCommand,也可以自己继承ICommand使用自定…

Dagster Pipes系列-2:增强外部脚本与Dagster的交互能力

在现代数据工程中&#xff0c;自动化和监控是确保数据管道高效运行的关键因素。Dagster作为一款强大的数据编排工具&#xff0c;提供了多种方式来实现这些目标。本文将深入探讨如何使用Dagster Pipes修改外部代码&#xff0c;以实现日志记录、结构化元数据报告以及资产检查等功…

C++类和对象进阶 —— 与数据结构的结合

&#x1f381;个人主页&#xff1a;工藤新一 &#x1f50d;系列专栏&#xff1a;C面向对象&#xff08;类和对象篇&#xff09; &#x1f31f;心中的天空之城&#xff0c;终会照亮我前方的路 &#x1f389;欢迎大家点赞&#x1f44d;评论&#x1f4dd;收藏⭐文章 文章目录 […

Java中进阶并发编程

第一章、并发编程的挑战 并发和并行&#xff1a;指多线程或多进程 线程的本质&#xff1a;操作系统能够进行运算调度的最小单位&#xff0c;是进程&#xff08;Process&#xff09;中的实际工作单元 进程的本质&#xff1a;操作系统进行资源分配和调度的基本单位&#xff0c…

《 指针变量类型与内存访问:揭秘背后的奥秘》

&#x1f680;个人主页&#xff1a;BabyZZの秘密日记 &#x1f4d6;收入专栏&#xff1a;C语言 &#x1f30d;文章目入 一、指针变量类型的基本概念二、指针类型与内存访问字节数的关系&#xff08;一&#xff09;整型指针&#xff08;二&#xff09;字符型指针&#xff08;三&…

mapbox进阶,使用mapbox-plugins插件加载饼状图

👨‍⚕️ 主页: gis分享者 👨‍⚕️ 感谢各位大佬 点赞👍 收藏⭐ 留言📝 加关注✅! 👨‍⚕️ 收录于专栏:mapbox 从入门到精通 文章目录 一、🍀前言1.1 ☘️mapboxgl.Map 地图对象1.1 ☘️mapboxgl.Map style属性二、🍀使用mapbox-plugins插件加载饼状图1. ☘…

GraphicLayer与BusineDataLayer层级控制

补充说明&#xff1a; 当参与层级控制的元素是点型元素时&#xff0c;是无法参与ZIndex层级控制的&#xff0c;此时可以换个解决方案 1.给不同的高度值实现&#xff0c;元素间的层级控制覆盖 import * as mars3d from "mars3d"export let map // mars3d.Map三维地…

uniapp 百家云直播插件打包失败

打包错误日志 Android自有证书 打包失败 错误日志: https://app.liuyingyong.cn/build/errorLog/cf41a610-effe-11ef-88db-05262d4c3e5d原因&#xff1a;需要导入插件依赖 依赖地址&#xff1a;https://ext.dcloud.net.cn/plugin?id16289 百家云直播插件地址 直播插…

【C++】”如虎添翼“:模板初阶

泛型编程&#xff1a; C中一种使用模板来实现代码重用和类型安全的编程范式。它允许程序员编写与数据类型无关的代码&#xff0c;从而可以用相同的代码逻辑处理不同的数据类型。模板是泛型编程的基础 模板分为两类&#xff1a; 函数模板&#xff1a;代表了一个函数家族&#x…