{"id":13387648,"url":"https://github.com/meitu/mthawkeye","last_synced_at":"2025-05-15T14:05:00.687Z","repository":{"id":34688535,"uuid":"173854041","full_name":"meitu/MTHawkeye","owner":"meitu","description":"Profiling / Debugging assist tools for iOS. (Memory Leak, OOM, ANR, Hard Stalling, Network, OpenGL, Time Profile ...)","archived":false,"fork":false,"pushed_at":"2023-11-17T08:43:58.000Z","size":20990,"stargazers_count":1495,"open_issues_count":8,"forks_count":185,"subscribers_count":37,"default_branch":"develop","last_synced_at":"2025-05-15T14:04:53.954Z","etag":null,"topics":["anr","apm","assistant","autotesting","debugging","ios","memory-leak-detection","monitor","network","network-monitor","oom","opengl-debugger","performance-analysis","performance-monitoring","profiling","time-profile","tool"],"latest_commit_sha":null,"homepage":"","language":"Objective-C","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/meitu.png","metadata":{"files":{"readme":"Readme-cn.md","changelog":"Changelog.md","contributing":"Contributing.md","funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null}},"created_at":"2019-03-05T02:00:46.000Z","updated_at":"2025-04-29T04:46:18.000Z","dependencies_parsed_at":"2022-09-04T09:51:12.995Z","dependency_job_id":"3962e77b-0953-4ce9-9f8b-90cae3e55e39","html_url":"https://github.com/meitu/MTHawkeye","commit_stats":{"total_commits":259,"total_committers":17,"mean_commits":"15.235294117647058","dds":0.444015444015444,"last_synced_commit":"4e2af4d66f71255594fc31e13f845099ee5b468a"},"previous_names":[],"tags_count":16,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/meitu%2FMTHawkeye","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/meitu%2FMTHawkeye/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/meitu%2FMTHawkeye/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/meitu%2FMTHawkeye/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/meitu","download_url":"https://codeload.github.com/meitu/MTHawkeye/tar.gz/refs/heads/develop","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":254355334,"owners_count":22057354,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["anr","apm","assistant","autotesting","debugging","ios","memory-leak-detection","monitor","network","network-monitor","oom","opengl-debugger","performance-analysis","performance-monitoring","profiling","time-profile","tool"],"created_at":"2024-07-30T12:01:25.855Z","updated_at":"2025-05-15T14:04:55.666Z","avatar_url":"https://github.com/meitu.png","language":"Objective-C","funding_links":[],"categories":["\u003ca id=\"58cd9084afafd3cd293564c1d615dd7f\"\u003e\u003c/a\u003e工具"],"sub_categories":["\u003ca id=\"d0108e91e6863289f89084ff09df39d0\"\u003e\u003c/a\u003e新添加的"],"readme":"# MTHawkeye\n\n[![Platform](https://img.shields.io/cocoapods/p/MTHawkeye.svg?style=flat)](http://cocoapods.org/pods/MTHawkeye) \n[![License](https://img.shields.io/github/license/meitu/MTHawkeye.svg?style=flat)](https://github.com/meitu/MTHawkeye/blob/master/LICENSE) \n[![PRs Welcome](https://img.shields.io/badge/PRs-welcome-brightgreen.svg)](https://github.com/meitu/MTHawkeye/pulls) \n[![Version](https://img.shields.io/cocoapods/v/MTHawkeye.svg?style=flat)](http://cocoapods.org/pods/MTHawkeye)\n\nMTHawkeye 是 iOS 下的调试优化辅助工具集，旨在帮助 iOS 开发者提升开发效率、辅助优化性能体验。\n\n在产品开发周期内，我们引入 MTHawkeye 来帮助我们更快的发现、查找、分析、定位、解决问题：\n\n- 开发阶段，侧重于开发调试辅助，及时侦测问题，并在必要时提示开发者及时处理\n- 测试阶段，侧重于根据测试场景，收集尽可能多的数据，用于自动化测试分析报告\n- 线上阶段，侧重补充传统 APM 组件缺失，但自身业务需要收集的一些性能数据\n\nMTHawkeye 内置了一些常用的性能侦测相关插件，也引入并改进了 FLEX 作为调试辅助的一个插件，应用接入 MTHawkeye 时可自定义增改自己需要的插件。\n\n以下为一些内置插件的 demo 演示图，分别用于`查看主线程耗时方法`，`查看 App 内存分配详情`，`查看网络请求详情记录`。更多插件及说明见后文。\n\n\u003cimg src=\"./doc/images/ui-time-profiler-demo-flow.gif\" width=285\u003e \u003cimg src=\"./doc/images/memory-allocations-demo-flow.gif\" width=285\u003e \u003cimg src=\"./doc/images/network-monitor-demo-flow.gif\" width=285\u003e\n\n## 0x00 功能简介\n\nMTHawkeye 简单可分为上中下三层，除了最下面的`基础层`外，中间为`UI 基础层`，最上层的各个插件内部根据不同场景做了职责拆分，应用可根据自己的需要接入。整体结构如下：\n\n![MTHawkeye overall structure](./doc/images/hawkeye-arch.png)\n\n### 基础功能\n\n`基础层`主要提供了插件管理能力，[存储能力](./doc/hawkeye-storage-cn.md)和一些基础工具类。\n`UI基础层` 则提供了开发、测试阶段使用的界面交互框架，包含了悬浮窗、主界面框架和设置面板，插件可以集成到其中。\n\n### 内置的可选插件\n\n内置的插件根据关注点分成了 `Memory`, `TimeConsuming`, `Energy`, `Network`, `Graphics`, `Storage`, `Utility` 几个类别。\n\n#### Memory\n\n##### # [LivingObjectSniffer](./doc/memory/unexpected-living-objects-sniffer-cn.md)\n\n`LivingObjectSniffer` 主要用于跟踪观察 ViewController 直接或间接持有的对象，以及自定义 View 对象，侦测他们是否异常存活，比如内存泄露、未及时释放或者不必要的内存缓存。\n\n在开发、测试阶段，侦测到的异常情况可以以浮窗警告、Toast 的形式提示开发、测试人员。自动化测试时也可以直接提取记录的存活对象做进一步的分析判断。\n\n##### # [Allocations](./doc/memory/allocations-cn.md)\n  \n`Allocations` 类同于 Instrument 的 Allocations 功能，跟踪应用实际分配的内存详情，在应用内存使用异常（异常上升、OOM 退出）时可以通过记录的内存使用详情数据，来排查内存使用问题。\n\n#### TimeConsuming\n\n##### # [UITimeProfiler](./doc/time-consuming/ui-time-profiler-cn.md)\n\n`UITimeProfiler` 用于辅助主线程耗时任务的优化。\n\n数据采集部分主要包含 VC Life Trace 和 ObjC CallTrace 两个组件。VC Life Trace 用于跟踪 ViewController 打开各个阶段的具体时间点，ObjC CallTrace在开启后，则可跟踪耗时大于指定阈值的 Objective-C 方法。\n\n界面层部分将两部分的数据合并展示，便于开发者更便捷的找出关注流程的耗时信息。示例图如前文的动图，更详细的说明见插件说明文档。\n\n自动化测试、线上阶段接入后，无需埋点或插入其他代码，即可持续的跟踪启动耗时、页面打开耗时和其他关键流程耗时。\n\n##### # [ANRTrace](./doc/time-consuming/anr-tracer-cn.md)\n\n`ANRTrace` 用于捕获卡顿事件，同时采样卡顿发生时的主线程调用栈。\n\n##### # [FPSTrace](./doc/time-consuming/fps-tracer.md)\n\n`FPSTrace` 用于跟踪界面 FPS 以及 OpenGL 刷新绘制 FPS，并在浮窗上显示当前值。\n\n#### Energy\n\n##### # [CPUTrace](./doc/energy/cpu-trace-cn.md)\n\n`CPUTrace` 用于跟踪 CPU 持续高使用率，同时记录高使用率期间主要调用了哪些方法。\n\n##### # [BackgroundTask Trace](./doc/energy/background-task-trace-cn.md)\n\n`BackgoundTask trace`插件将跟踪UIBackgroundTaskIdentifier的开始/结束，在尝试查找崩溃0xbada5e47的原因时将很有用。 （直接参见使用代码）\n\n#### Network\n\n##### # [NetworkMonitor](./doc/network/network-monitor-cn.md)\n\n`NetworkMonitor` 监听记录 App 内 HTTP(S) 网络请求的各个阶段耗时，并提供内置的记录查看界面，便于开发者排查优化网络问题。\n\n1. 继承 FLEX 的网络请求记录，过滤搜索裸机价。同时优化了监听初始化逻辑，大幅减少对启动时间的影响\n2. 针对 iOS 9 后的 NSURLSession 的请求，增加记录 URLSessionTaskMetrics 方便查看请求各个阶段的时间\n3. 基于 URLSessionTaskMetrics 增加类似 Chrome 网络调试的 waterfall 视图，方便查看网络请求的队列和并发情况\n4. 增加重复网络请求的侦测\n5. 增强搜索栏，支持多条件搜索（域名筛选、重复请求、url 过滤、status 过滤）\n6. 记录展示完整的网络请求记录（增加 request headers, request body, response body 记录）\n\n##### # [NetworkInspect](./doc/network/network-inspect-cn.md)\n\n`NetworkInspect` 插件基于 Network Monitor，根据记录的网络请求实际情况，侦测是否有可改进优化的项，上层可以自定义自己的规则。\n\n#### Graphics\n\n##### # [OpenGLTrace](./doc/graphics/opengl-trace-cn.md)\n\n`OpengGLTrace` 用于跟踪 OpenGL 资源内存占用情况，辅助发现 OpenGL API 错误调用、异常参数传递。\n\n#### Storage\n\n##### # [DirectoryWatcher](./doc/storage/directory-watcher-cn.md)\n\n`DirectoryWatcher` 主要用于沙盒文件夹的大小跟踪，便于开发测试过程中发现异常的文件管理问题。同时也集成了 FLEX 的沙盒文件查看。\n\n#### Utility\n\n##### # [FLEX](https://github.com/Flipboard/FLEX)\n\nMTHawkeye 插件扩展支持了沙盒文件的 AirDrop 功能。\n\n### 桌面扩展\n\n如果需要将插件扩展到桌面端，如在桌面上查看处理插件收集到的信息，可基于各插件提供的接口获取数据，然后桥接到第三方桌面端提供的协议。如\n\n- [Facebook Flipper](https://github.com/facebook/flipper)\n- [Woodpecker](http://www.woodpeck.cn/)\n\n## 0x01 接入\n\n### 开发阶段接入\n\n首先，以 pod 的形式，在项目 podfile 文件中加入 MTHawkeye 引用：\n\n```ruby\n  #\u003c Only used during Debug\n  #\u003c Since the podfile dependency doesn't support environment configuration, \n  #\u003c the dependent pods also need to be explicitly configured as Debug.\n  \n  def hawkeye\n    pod 'MTHawkeye', :configurations =\u003e 'Debug'\n\n    pod 'FLEX', :configurations =\u003e ['Debug']\n    pod 'FBRetainCycleDetector', :configurations =\u003e ['Debug']\n    pod 'fishhook', :configurations =\u003e ['Debug']\n    pod 'CocoaLumberjack', \n    '3.6.0', :configurations =\u003e ['Debug'] # CocoaLumberjack is optional, change to `MTHawkeye/DefaultPluginsWithoutLog` if don't need.\n    # pod 'MTGLDebug', :configurations =\u003e ['Debug'] # MTGLDebug is exclude by default, change `MTHawkeye` to `MTHawkeye/DefaultPlugins` to include.\n\n    pod 'MTAppenderFile', :configurations =\u003e ['Debug']\n  end\n\n  target \"YourProject\" do\n    hawkeye\n\n    # ...\n  end\n```\n注意：`CocoaLumberjack`这个依赖库需要使用\u003c~3.6.0版本。\n然后，在应用启动时开启 MTHawkeye 服务。可以使用默认集成的所有插件，或者选择自己需要的插件启动。\n\nA: 快速集成默认的所有插件:\n\n```objc\n#ifdef DEBUG\n  #import \u003cMTHawkeye/MTRunHawkeyeInOneLine.h\u003e\n#endif\n\n- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {\n#ifdef DEBUG\n  [MTRunHawkeyeInOneLine start];\n#endif\n  // ...\n}\n```\n\n\u003cdetails\u003e\n\u003csummary\u003e B: 选择需要的插件、插入外部新的插件: \u003c/summary\u003e\n\n```objc\n- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {\n  [self startCustomHawkeye];\n  // ...\n}\n\n- (void)startCustomHawkeye {\n#ifdef DEBUG\n  [[MTHawkeyeClient shared]\n    setPluginsSetupHandler:^(NSMutableArray\u003cid\u003cMTHawkeyePlugin\u003e\u003e *_Nonnull plugins) {\n      [MTHawkeyeDefaultPlugins addDefaultClientPluginsInto:plugins];\n\n      // add your additional plugins here.\n    }\n    pluginsCleanHandler:^(NSMutableArray\u003cid\u003cMTHawkeyePlugin\u003e\u003e *_Nonnull plugins) {\n      // if you don't want to free plugins memory, remove this line.\n      [MTHawkeyeDefaultPlugins cleanDefaultClientPluginsFrom:plugins];\n\n      // clean your additional plugins if need.\n    }];\n\n  [[MTHawkeyeClient shared] startServer];\n\n  [[MTHawkeyeUIClient shared]\n    setPluginsSetupHandler:^(NSMutableArray\u003cid\u003cMTHawkeyeMainPanelPlugin\u003e\u003e *_Nonnull mainPanelPlugins, NSMutableArray\u003cid\u003cMTHawkeyeFloatingWidgetPlugin\u003e\u003e *_Nonnull floatingWidgetPlugins, NSMutableArray\u003cid\u003cMTHawkeyeSettingUIPlugin\u003e\u003e *_Nonnull defaultSettingUIPluginsInto) {\n      [MTHawkeyeDefaultPlugins addDefaultUIClientMainPanelPluginsInto:mainPanelPlugins\n                                    defaultFloatingWidgetsPluginsInto:floatingWidgetPlugins\n                                          defaultSettingUIPluginsInto:defaultSettingUIPluginsInto];\n\n\n        // add your additional plugins here.\n    }\n    pluginsCleanHandler:^(NSMutableArray\u003cid\u003cMTHawkeyeMainPanelPlugin\u003e\u003e *_Nonnull mainPanelPlugins, NSMutableArray\u003cid\u003cMTHawkeyeFloatingWidgetPlugin\u003e\u003e *_Nonnull floatingWidgetPlugins,NSMutableArray\u003cid\u003cMTHawkeyeSettingUIPlugin\u003e\u003e *_Nonnull defaultSettingUIPluginsInto) {\n      // if you don't want to free plugins memory, remove this line.\n      [MTHawkeyeDefaultPlugins cleanDefaultUIClientMainPanelPluginsFrom:mainPanelPlugins\n                                      defaultFloatingWidgetsPluginsFrom:floatingWidgetPlugins\n                                            defaultSettingUIPluginsFrom:defaultSettingUIPluginsInto];\n\n      // clean your additional plugins if need.\n    }];\n\n  dispatch_async(dispatch_get_main_queue(), ^(void) {\n    [[MTHawkeyeUIClient shared] startServer];\n  });\n#endif\n}\n```\n\n\u003c/details\u003e\n\n### 测试、线上阶段接入\n\n测试阶段时可能有特殊的需求，而线上阶段可能不需要保留界面部分的代码。这个时候你可以根据工程的需要创建一个新的 `podspec`, 在 podspec 里引入在测试、线上阶段要引入的 MTHawkeye subspec, 然后在 podfile 内引入\n\n```ruby\n  pod 'YourOnlineHawkeye', :podspec =\u003e 'xxx/yourOwnHawkeyeOnline.podspec', :configurations =\u003e 'Release'\n```\n\n然后在初始化内根据自己的需要加载插件，配置插件是否启动（默认不启动），如\n\n```objc\n#ifdef Release\n  [MTHawkeyeUserDefaults shared].allocationsTraceOn = YES; // 根据需要开启插件、配置插件\n\n  [[MTHawkeyeClient shared]\n    setPluginsSetupHandler:^(NSMutableArray\u003cid\u003cMTHawkeyePlugin\u003e\u003e *_Nonnull plugins) {\n      [plugins addObject:[MTHAllocationsHawkeyeAdaptor new]];\n\n      // add your additional plugins here.\n    }\n    pluginsCleanHandler:^(NSMutableArray\u003cid\u003cMTHawkeyePlugin\u003e\u003e *_Nonnull plugins) {\n\n    }];\n\n  [[MTHawkeyeClient shared] startServer];\n#endif\n```\n\n## 0x02 交互说明\n\n基础操作说明：\n\n- 悬浮窗\n  - 展示、隐藏悬浮窗：使用三指长按两秒手势或者三指左滑手势\n  - 显示、隐藏悬浮窗插件：进入设置界面，进入 Floating Window，显隐插件  \n- 进入主面板：点击浮窗直接查看最近一次查看的面板\n- 设置界面：进入主面板，点击标题呼出模块切换界面，点击右上角 `Setting` 进入设置界面\n\n各插件的界面交互文档：[详见上文链接](#内置的可选插件)\n\n## 0x03 开发自己的插件\n\n如果有一个模块在开发过程中需要避开很多坑，或者开发过程中调试/优化相关的日志代码很多，可以考虑编写一个调试辅助组件，然后基于 Hawkeye 基础框架 API，可将这个组件接入到 Hawkeye 框架中使用，以便统一交互和接口。\n\n如果你关注的性能指标在自动化测试时无法持续跟踪，考虑编写一个性能分析插件用于抓取性能数据。\n\n详见：[MTHawkeye 插件开发说明文档](./doc/hawkeye-plugin-dev-guide-cn.md)\n\n## 0x04 Contribute to MTHawkeye\n\nFor more information about contributing issues or pull requests, see [MTHawkeye Contributing Guide](./Contributing.md)。\n\n## 0x05 Thanks\n\n- [FLEX](https://github.com/Flipboard/FLEX)\n- [Tencent Mars](https://github.com/Tencent/mars)\n- [PLeakSniffer](https://github.com/music4kid/PLeakSniffer)\n- [FBRetainCycleDetector](https://github.com/facebook/FBRetainCycleDetector)\n- [iOS 微信内存监控](https://wetest.qq.com/lab/view/367.html)\n- [深入剖析 iOS 性能优化](http://www.jianshu.com/p/c58001ae3da5)\n- [RSSwizzle](https://github.com/rabovik/RSSwizzle)\n- [fishhook](https://github.com/facebook/fishhook)\n- [CocoaLumberjack](https://github.com/CocoaLumberjack/CocoaLumberjack)\n\n## 0x06 License\n\nMTHawkeye 使用 MIT 协议，详情请参考 [LICENSE](./LICENSE)。\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmeitu%2Fmthawkeye","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fmeitu%2Fmthawkeye","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmeitu%2Fmthawkeye/lists"}