Android 日志打印频率过高排查的一些技巧

最近项目快到 sop 阶段了,看到最近的一个新的任务,提示应用打印频率每秒超过 100 行/秒,需要优化一下。

那这样看起来需要删减一点日志,是不是先要找一下我们的应用打印了多少。

当然如果项目是自己维护的,那肯定是知道哪个地方调用高,打印的日志,那如果需要处理多个模块,不是自己的,那只能分析日志了不是。

所以我们应该有几个步骤要走:


  1. 找到应用的对应进程。
  2. 过滤出对应进程的所有日志。
  3. 统计每秒的日志打印数是否满足。
  4. 针对性的考虑是否需要删除或者保留。

一、找到应用的对应进程。

拿到所有的日志文件,考虑到应用有可能有异常的情况会重启,我们在通过应用名过滤包名的时候需要看下是否在所有的时候对应 pid 都是一个。

可以用命令行,先用 grep 过滤关键包名,再用含有 pid 的输出作为第二次过滤。

因为我们系统会隔段时间 dumpCpu, 这里会打印出应用和 pid 信息,这里就用的 pid ,如果不是的话,可以先不第二次过滤,看看搜索结果中有没有含 pid 的关键字再进行过滤。

因为一般开发都是使用 Linux 或者 Mac ,这里命令应该是一样的,如果是 Windows 的话可以转成对应的命令。

在日志目录中开启命令行。

# package 和 pid 需要换成对应的关键字
grep -rn "<package>" | grep <pid>

-r 代表遍历文件

-n 代表显示行数

| 为管道,代表将搜索结果转给下一个命令使用

比如我处理的第一个应用是行车记录仪,一般名字是 dvr。

那我就可以用

grep -rn "com.xxx.dvr" | grep pid

这样从结果中大致看看是否是相同 pid ,如果是那该日志期间是没有重启过,如果是多个的话,说明应用可能有点不稳定呀,可以选取时间长的几个 pid 进行处理。


二、过滤出对应进程的所有日志。

找到了 pid ,那我们过滤下 pid 日志导出,这里需要看每个系统中关于日志打印的格式,我们是这样的。

09-30 15:12:55.895790  3142  3142 E DvrApplication: [ (DvrApplication.java:282)#onVolumeStateChanged ]vol: VolumeInfo{public:8,17}:

所以过滤的话,就用 grep 过滤出 3142 就行。

因为我们日志会打印的秒后面位数比较多,所以可能出现秒也有 3142 的情况,grep 时可以在前后带一个空格。

grep -rn " 3142 " > filterLogs.lg

> 为重定向符号,这里的意思就是,把过滤出的内容原本应该在命令行打印出的信息导出到一个新的文件。

filterLogs.lg 日志文件名,自己可以取一个简单的。

这样我们就拿到了一个过滤 pid 后的文件内容,但是当我打开的时候发现,grep 之后的内容有点问题。

  • 第一是有文件名,这样后续不太方便统计时间戳。
  • 第二是时间, -rn 是乱序遍历的。

那首先是解决第一个问题,这个简单,搜了一下 grep 的用法,使用 -h 可以隐藏文件名,Easy。

第二个问题,我发现日志文件是有序的,但是遍历了不行,这里我开始先想的是不是要排序一下,但是问了下 chagpt 怎么顺序遍历,让我 ls 给 grep 过滤,我一试,发现真是个天才。ls 默认升序排列。

改良版的命令。

grep -h " 3142 " $(ls) > filterLogs.lg

-h 代表隐藏文件名

$(ls) 代表执行 ls 命令,这里是作为了输出文件名给 ls 使用。可以理解为 shell 中的函数执行格式。

可有的那个有朋友会问了,那这里是一个 pid ,如果是多个怎么办,你说有没有一种可能 grep 支持正则,这里就作为小作业啦。


三、统计每秒的日志打印数是否满足。

既然拿到了过滤好的日志,那是不是可以看看哪些时候在一秒内打印频率比较高。

当然有些是肉眼比较好看出来的,有些就不太好看,那怎么能够统一下这个数据呢,你应该想到了,可以问问 chatGPT,当然我已经帮你问了。

awk '{print substr($0, 1, 18)}' filterLogs.log | sort | uniq -c > nums.log

awk 为文字处理工具。

substr($0, 1, 18) 为处理当前行,提取前 18 个字符

sort 就是对结果排序

uniq -c 统计相同的时间,然后 +1.

虽然这个答案很完美,但是当我把一行日志给了 chatGPT 时,还给我说前 18 个字符,手动改了一下只需要前 14 个字符就可以了。

当然每家的日志格式不一样,这里就需要单独处理一下,拿到的结果就像这样,很完美。

      4 09-30 15:14:53.4 09-30 15:15:03.4 09-30 15:15:13.3 09-30 15:15:19.4 09-30 15:15:23.37 09-30 15:15:32.31 09-30 15:15:33.4 09-30 15:15:43.1 09-30 15:15:47.1 09-30 15:15:48.3 09-30 15:15:49.4 09-30 15:15:53.

这里一下就清晰看到有没有问题,如果不符合,你也有依据给该任务关一个无效。

如果有问题,可以通过对应的时间很快定位到需要处理的时间,排查该时间段是因为什么原因在一秒内打印了很多日志。

当你用了几次脚本后发现好用是好用,但是如果日志少,一两眼就能看到哪一秒超过100。

但是如果日志很长,随眼一晃,发现没有,但是又不放心,搜索吧,不好搜 > 100 这个条件,自己检查,那眼睛都要看瞎,所以还是需要加一个标记。

awk '{print substr($0, 1, 14)}' <logPath> | sort | uniq -c | awk '{if ($1 > 100) {print $0, " <-- more than 100"} else {print $0}}' > nums.log

前面部分是一样的,logPath 换成自己的日志路径。

后面部分代表对比对一列是否大于 100 ,大于在最后输出一个标记,这样结果输出我们可以直接搜索这个关键字。


四、针对性的考虑是否需要删除或者保留。

到了这里接下来就是排查自己的代码,哪些日志需要留下来分析,那些需要删除。肯定是自己项目的分析了,这里记一下我这里碰到一个例子。

用这个方法处理了几个应用,以为顺顺利利就可以完成的时候,还是出了意外,发现了一个目标。

请添加图片描述

顺着时间看过去。

在这里插入图片描述

发现是项目用了 FFmpeg 代码。

再定位到代码中的使用场景,原来是用它来抽取封面。

    private static int extractFrames(String videoPath, String outputDirectory) {//"1"表示第一帧String[] cmd = new String[]{"-y", "-i", videoPath,"-vframes", "1", "-s", "244x184", outputDirectory};int returnCode = FFmpeg.execute(cmd);MLog.e(TAG, "returnCode: " + returnCode);return returnCode;}

那这个这么减少日志呢,我先是搜了下 FFmpeg 这个类有没有对应的方法,搜了一圈源码没有看到。

在网上搜了下呢,有答案,但是这个 jar 包里面没有对应的方法,看了下版本,有点小差异,但是按理说不应该有这儿大的差异。

我又找有没有 Config 之类的配置类,有,但是没有直接调用的,连构造函数都是 private 。

在这里插入图片描述

就当我还在想要 FFmpeg 是怎么用这个 Config 类时,我才注意到,原来这个方法就是执行 FFmpeg 命令。

熟悉 Linux 一些工具的对应命令就知道,很多都会有 -q 的设置,代表安静,不输出内容。

FFmpeg 这么流行的框架,那肯定也有会对应的方法。

果然有个 -loglevel 可以调整输出日志的等级,那我直接加在 extractFrames 中就可以了,稍微改下,这里的话问了下 gpt 的顺序,有些参数的执行还是有顺序的匹配问题。

    private static int extractFrames(String videoPath, String outputDirectory) {//"1"表示第一帧String[] cmd = new String[]{"-y", "-loglevel", "error", "-i", videoPath,"-vframes", "1", "-s", "244x184", outputDirectory};int returnCode = FFmpeg.execute(cmd);MLog.e(TAG, "returnCode: " + returnCode);return returnCode;}

重新运行应用,验证 OK。


是不是觉得 Linux 这些命令还挺好用的呢。

在这里插入图片描述

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

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

相关文章

java中创建不可变集合

一.应用场景 二.创建不可变集合的书写格式&#xff08;List&#xff0c;Set&#xff0c;Map) List集合 package com.njau.d9_immutable;import java.util.Iterator; import java.util.List;/*** 创建不可变集合:List.of()方法* "张三","李四","王五…

Let‘s Encrypt 的几个常用命令

Lets Encrypt 是免费的 ssl 证书提供商&#xff0c;在当前纷纷收费的形式下&#xff0c;这是一个良心厂家&#xff0c;虽然使用起来略微繁琐。坚决抵制某 cxxn 站&#xff0c;竟然开始有辣么多收费的东西。这里记录几个常用的命令&#xff08;使用环境Ubuntu 24&#xff09;&am…

MySQL高阶2041-面试中被录取的候选人

目录 题目 准备数据 分析数据 总结 题目 编写解决方案&#xff0c;找出 至少有两年 工作经验、且面试分数之和 严格大于 15 的候选人的 ID 。 可以以 任何顺序 返回结果表。 准备数据 Create table If Not Exists Candidates (candidate_id int, name varchar(30), yea…

给大家提个醒!!!

前些天在某鱼买了一个KNX路由器&#xff0c;外观看起没什么问题&#xff0c;但内部就大跌眼镜了。 话不多说&#xff0c;直接上图 拿到手&#xff0c;外壳看起来没有什么问题 . 上电只亮灯 之后插网线&#xff0c;路由器上找不到设备 开壳&#xff0c;惊掉下巴 加个PHY…

利用自动化工具增强防火墙管理

在选择下一代防火墙以平衡安全需求和网络性能时&#xff0c;组织应优先考虑哪些因素&#xff1f; 最重要的部分——安全需求、可用性和网络性能必须保持平衡&#xff0c;而找到共同点并不总是那么容易。 选择防火墙时&#xff0c;组织必须采取的第一步是深入了解现有网络基础…

广联达 Linkworks办公OA Service.asmx接口存在信息泄露漏洞

漏洞描述 广联达科技股份有限公司以建设工程领域专业应用为核心基础支撑&#xff0c;提供一百余款基于“端云大数据”产品/服务&#xff0c;提供产业大数据、产业新金融等增值服务的数字建筑平台服务商。广联达OA存在信息泄露漏洞&#xff0c;由于某些接口没有鉴权&#xff0c…

基于 STM32F407 的串口 IAP

目录 一、概述二、IAP 实现三、IAP 程序1、串口部分2、iap 程序3、内部 flash 读写4、main 程序 IAP&#xff08;In Application Programming&#xff0c;在应用编程&#xff09;是用户自己的程序在运行过程中对 User Flash 的部分区域进行烧写。简单来说&#xff0c;就是开发者…

红外画面空中目标检测系统源码分享

红外画面空中目标检测检测系统源码分享 [一条龙教学YOLOV8标注好的数据集一键训练_70全套改进创新点发刊_Web前端展示] 1.研究背景与意义 项目参考AAAI Association for the Advancement of Artificial Intelligence 项目来源AACV Association for the Advancement of Comp…

Spring Boot助力IT领域交流平台开发

2 系统关键技术 2.1 JAVA技术 Java是一种非常常用的编程语言&#xff0c;在全球编程语言排行版上总是前三。在方兴未艾的计算机技术发展历程中&#xff0c;Java的身影无处不在&#xff0c;并且拥有旺盛的生命力。Java的跨平台能力十分强大&#xff0c;只需一次编译&#xff0c;…

vmvare虚拟机centos 忘记超级管理员密码怎么办?

vmvare虚拟机centos 忘记超级管理员密码怎么办?如何重置密码呢? 一、前置操作 重启vmvare虚拟机的过程中,长按住Shift键 选择第一个的时候,按下按键 e 进入编辑状态。 然后就会进入到类似这个界面中。 在下方界面 添加 init=/bin/sh,然后按下Ctrl+x进行保存退出。 init=/bi…

开放式耳机的优缺点?哪个品牌专业?好用的开放式蓝牙耳机分享

我相信很多想入手的开放式耳机的家人都想知道开放式耳机是什么&#xff0c;开放式耳机有什么优缺点&#xff0c;开放式耳机是不是智商税、值不值得购买以及如果要购买的话&#xff0c;有什么专业的开放式耳机品牌推荐。因为我毕竟是测评过三十多款开放式耳机的数码博主&#xf…

mdm监管锁系统功能说明

普通用户后台功能说明 设备管理 设备列表 添加的设备列表 点击序列号可以进入设备详细信息 可以修改设备使用人的姓名 手机号 分组等 还可以导出报表 设备信息 展示了一些设备信息和可以下发指令 指令说明 指令分为异步和非异步 下发指令是和手机设备有交互&#xff0c;一…

使用默认不可变的Rust变量会踩什么坑

讲动人的故事&#xff0c;写懂人的代码 Rust的变量真的是名不副实。名字中明明有个“变”字&#xff0c;却默认不可变。还美其名曰“不可变变量”。要想让变量名副其实&#xff0c;还必须费心额外加个mut关键字&#xff0c;并必须称其为“可变变量”&#xff0c;才能与前者区分…

【AI人工智能】文心智能体,陪爸妈去旅游,国庆假期不容错过,旅游搭子首选

文章目录 背景创作灵感陪爸妈去旅游简介角色与目标思考路径个性化开场白调优 智能体体验总结和感受 背景 文心智能体平台&#xff0c;开启新一轮活动&#xff0c;超级创造营持续百日活动。 在AI 浪潮席卷的今天&#xff0c;如雨后春笋般丛生的 AI 应用&#xff0c;昭告着时代风…

MySQL优化实战 解决CPU100%

问题表象 在24年初有一个日经问题困扰着我们&#xff0c;每到正点03分DB的CPU开始打满&#xff0c;持续1分钟又恢复正常水平。但由于日常业务交付压力较大且权限限制没有登录DB主机的权限&#xff0c;大家也就得过且过一直没有去认真排查。直到某天我来兴趣了也有时间了&#…

基于51单片机的家用防火防盗控制系统设计

本设计基于51单片机的家用防火防盗控制系统&#xff0c;该系统通过模块间的协同作用实现了对烟雾与天然气浓度的监测、温度监测、人体红外监测、通信传输、声光报警等功能。利用按键模块设置报警的阈值&#xff0c;将处理后的信息与阈值进行对比。判断气体浓度和温度是否超过阈…

酒店智能门锁SDK接口pro[V10] 门锁校验C#-SAAS本地化-未来之窗行业应用跨平台架构

一、代码 int 酒店标识_int Convert.ToInt32(酒店标识);StringBuilder 锁号2024 new StringBuilder(8);//信息 "未知返回值&#xff1a;" bufCard_原始;GetGuestLockNoByCardDataStr_原始(酒店标识_int, bufCard_原始.ToString(), 锁号2024);StringBuilder 退…

C++语言学习(4): identifier 的概念

1. 什么是 identifier identifier 中文意思是标识符&#xff0c;在 cppreference 中明确提到&#xff0c;identifier 是任意长度的数字、下划线、大写字母、小写字母、unicode 字符 的序列&#xff1a; An identifier is an arbitrarily long sequence of digits, underscores…

nginx打包部署前端vue项目全过程【保姆级教程】

&#x1f939;‍♀️潜意识起点&#xff1a;个人主页 &#x1f399;座右铭&#xff1a;得之坦然&#xff0c;失之淡然。 &#x1f48e;擅长领域&#xff1a;前端 是的&#xff0c;我需要您的&#xff1a; &#x1f9e1;点赞❤️关注&#x1f499;收藏&#x1f49b; 是我持…