flutter 客户端日志上传定位错误信息

背景

flutter 开发的app 安装到真机上 无法定位报错信息,只能使用usb连接电脑 使用adb logcat来查看日志效率低下。

想法

如果将flutter 开发的app 运行的时候 将日志写进一个日志文件里面去,然后给flutter app搭建一个http服务器,后端知道对应app的ip后,直连对应app 获取日志文件。

效果如下

第一步

获取本机的ip地址 放在个人中心里面

如:

flutter 获取本机ip

方式一:缺点(模拟器获取有时会获取不到) 不推荐 但是必须使用

  for (var interface in await NetworkInterface.list()) {for (var addr in interface.addresses) {if (addr.type == InternetAddressType.IPv4) {address = addr.address.toString();print('IPv4 地址: ${addr.address}');}// else if (addr.type == InternetAddressType.IPv6) {//   print('IPv6 地址: ${addr.address}');//   // address = addr.address.toString();// }}}

方式二:

dart_ipify dart_ipify | Dart Package 这里是外网的IP(不适用)

import 'package:dart_ipify/dart_ipify.dart';final ipv4 = await Ipify.ipv4();print(ipv4); // 98.207.254.136

这里声明一下  客户端日志上传只限于局域网  如果是外网 手机的网络ip app 内部是局域网 是访问不到的 

如果是外网 采用用户 手动触发一些列操作  如 去个人中心 点击上报日志 (这个功能需要实现)

第二步

利用shelf  flutter 的插件搭建 app内的服务器

shelf | Dart PackageA model for web server middleware that encourages composition and easy reuse.icon-default.png?t=N7T8https://pub-web.flutter-io.cn/packages/shelf注意端口不能为 80

import 'package:LS/common/extension/custom_ext.dart';
import 'package:LS/common/utils/log.dart';
import 'package:dart_ipify/dart_ipify.dart';
import 'package:flutter/foundation.dart';
import 'package:shelf/shelf.dart';
import 'package:shelf/shelf_io.dart' as shelf_io;class Server {static String address = "";static init() async {if (kIsWeb) {return;}for (var interface in await NetworkInterface.list()) {for (var addr in interface.addresses) {if (addr.type == InternetAddressType.IPv4) {address = addr.address.toString();print('IPv4 地址: ${addr.address}');}// else if (addr.type == InternetAddressType.IPv6) {//   print('IPv6 地址: ${addr.address}');//   // address = addr.address.toString();// }}}// String ipv4 = await Ipify.ipv4();"当前ip i $address".w();// address = ipv4;var handler =const Pipeline().addMiddleware(logRequests()).addHandler(_echoRequest);var server = await shelf_io.serve(handler, address, 8080);// Enable content compressionserver.autoCompress = true;print('Serving at http://${server.address.host}:${server.port}');}static Future<Response> _echoRequest(Request request) async {switch (request.requestedUri.path) {case '/':return Response.ok('Hello, World!');case "/log":var headers = {'content-type': 'text/plain','content-disposition': 'attachment; filename="log.txt"'};String log = await Console.getLogLocalFile();return Response.ok(log, headers: headers);}return Response.ok('Request for "${request.url}"');}
}

核心代码就是

import 'package:shelf/shelf.dart';
import 'package:shelf/shelf_io.dart' as shelf_io;void main() async {var handler =const Pipeline().addMiddleware(logRequests()).addHandler(_echoRequest);var server = await shelf_io.serve(handler, 'localhost', 8080);// Enable content compressionserver.autoCompress = true;print('Serving at http://${server.address.host}:${server.port}');
}Response _echoRequest(Request request) =>Response.ok('Request for "${request.url}"');

 main中 运行服务器

  if (kDebugMode) {Server.init();}

日志是 再打印的时候 就会自动进行写入

日志输出 同时写入app文件夹制定文件里面

///输出日志工具类
class Console {static const bool _isLog = true; // 是否输出日志标识static const bool _isDebug = kDebugMode; // 是否为debug模式static const String _logFlag = "app输出日志"; // 输出日志前缀///日志输出,仅dubug模式下生效static void d(Object? object) {if (_isLog && _isDebug) {// print("$_logFlag | $object");// developer.log();Global.logger.i("$_logFlag | $object");if (!kIsWeb) {writeLogsToFile("$_logFlag | $object");}}}static log(List args) {if (_isLog && _isDebug) {// print("$_logFlag | ${args.toString()}");// developer.log("$_logFlag | ${args.toString()}");Global.logger.i("$_logFlag | ${args.toString()}");if (!kIsWeb) {writeLogsToFile("$_logFlag | ${args.toString()}");}}}// 只写日志 不输出static void staticWriteLogsToFile(String logs, String type) async {writeLogsToFile("$type | ${DateTime.now().toLocal()} | $logs}");}static Future<String> getLogsDirectory() async {Directory appDocDir = await getApplicationDocumentsDirectory();print("appDocDir==> $appDocDir");String logsDirectory = '${appDocDir.path}/log/api';Directory(logsDirectory).createSync(recursive: true);return logsDirectory;}static Future<void> writeLogsToFile(String logMessage) async {String logsDirectory = await getLogsDirectory();File logFile = File('$logsDirectory/app_logs.txt');await logFile.writeAsString('$logMessage\n', mode: FileMode.append);}static Future getLogLocalFile() async {String logsDirectory = await getLogsDirectory();File logFile = File('$logsDirectory/app_logs.txt');String log = await logFile.readAsString();return log;}
}

为字符串扩展 方法进行 打印  

extension LogExt on String {log() {Global.logger.d(this);Console.staticWriteLogsToFile(this, "log");}t() {Global.logger.t(this);Console.staticWriteLogsToFile(this, "stackTrace");}info() {Global.logger.i(this);Console.staticWriteLogsToFile(this, "info");}errorLog() {Global.logger.e("Error", error: this);Console.staticWriteLogsToFile(this, "error");}w() {Global.logger.w(this);Console.staticWriteLogsToFile(this, "warning");}
}

使用如:

"日志 啊啊啊".w();

获取日志

任何可以发送请求的 工具 ,我使用浏览器

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

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

相关文章

如何使用VNC实现Win系统远程桌面Ubuntu图形化界面【内网穿透】

文章目录 推荐前言1. ubuntu安装VNC2. 设置vnc开机启动3. windows 安装VNC viewer连接工具4. 内网穿透4.1 安装cpolar【支持使用一键脚本命令安装】4.2 创建隧道映射4.3 测试公网远程访问 5. 配置固定TCP地址5.1 保留一个固定的公网TCP端口地址5.2 配置固定公网TCP端口地址5.3 …

vue:处理base64格式文件pdf、图片预览

一、需求&#xff1a;后端返回是base64数据&#xff0c;需要前端处理来展示文件。 二、实现方法&#xff1a; 解释一下这段代码的功能&#xff1a; &#xff09;preview(item) 是一个函数&#xff0c;接受一个参数 item&#xff0c;其中包含了文件的相关信息。 &#xff09;首…

HTML5+CSS3+JS小实例:实时给中文添加拼音

实例:实时给中文添加拼音 技术栈:HTML+CSS+JS 效果: 源码: 【HTML】 <!DOCTYPE html> <html lang="zh-CN"> <head><meta charset="UTF-8"><meta http-equiv="X-UA-Compatible" content="IE=edge"&…

使用freessl为网站获取https证书及配置详细步骤

文章目录 一、进入freessl网站二、修改域名解析记录三、创建证书四、配置证书五、服务启动 一、进入freessl网站 首先进入freessl网站&#xff0c;需要注册一个账号 freessl网站 进入网站后填写自己的域名 接下来要求进行DCV配置 二、修改域名解析记录 到域名管理处编辑域名…

智慧水务管理的发展历史有哪些阶段呢

随着科技的飞速发展&#xff0c;智慧水务管理已经成为了城市基础设施的重要组成部分。从传统的人工管理到现代的智能化管理&#xff0c;智慧水务经历了多个阶段的发展历程。本文将带您了解智慧水务管理的历史演变。 一、初级阶段&#xff1a;人工管理 在智慧水务管理发展的初期…

MS2358——96KHz、24bit 音频 ADC

产品简述 MS2358 是带有采样速率 8kHz-96kHz 的立体声音频模数 转换器&#xff0c;适合于面向消费者的专业音频系统。 MS2358 通过使用增强型双位 Δ - ∑ 技术来实现其高精度 的特点。 MS2358 支持单端的模拟输入&#xff0c;所以不需要外部器 件&#xff0c;非常适…

maven环境搭建(打包项目)

Maven:直观来讲就是打包写好的代码封装 Apahche 软件基金会&#xff08;非营业的组织&#xff0c;把一些开源软件维护管理起来&#xff09; maven apahce的一个开宇拿项目&#xff0c;是一个优秀的项目构建&#xff08;管理工具&#xff09; maven 管理项目的jar 以及jar与j…

[C++]:12:模拟实现list

[C]:12:模拟实现list 一.看一看SGI的stl_list的源码&#xff1a;1.基础结构构造函数1.节点结构&#xff1a;2.节点构造函数&#xff1a;3.链表结构&#xff1a;4.链表的构造函数&#xff1a; 2.析构1.节点析构&#xff1a;2.链表的析构&#xff1a; 3.迭代器 二.模拟实现list1.…

py的函数多返回值

前言:之前我们学过了py中函数&#xff0c;这一章我们来学习它的进阶版 目录 一.函数的多返回值 1.1关于函数的多返回值 1.2举例 二.函数多种传参方式 2.1关于多种传参方式 2.2关键字参数 2.2缺省参数 2.3不定长参数 2.4小结 三.匿名函数 3.1关于函数如何作为参数进行…

android 自定义八边形进度条

自定义八边形动画效果图如下 绘制步骤&#xff1a; 1.先绘制橙色底部八边形实心 2.黑色画笔绘制第二层&#xff0c;让最外层显示一条线条宽度即可 3.再用黄色画笔绘制黄色部分 4.使用渐变画笔根据当前进度绘制覆盖黄色部分 5.使用黑色画笔根据当前进度绘制刻度条 6.黑色画笔绘制…

使用Sqoop的并行处理:扩展数据传输

使用Sqoop的并行处理是在大数据环境中高效传输数据的关键。它可以显著减少数据传输的时间&#xff0c;并充分利用集群资源。本文将深入探讨Sqoop的并行处理能力&#xff0c;提供详细的示例代码&#xff0c;以帮助大家更全面地了解和应用这一技术。 Sqoop的并行处理 在开始介绍…

Java网络编程:概述--快速入门

I. 介绍 1.1 什么是网络编程 - 网络编程是指通过计算机网络实现程序之间的通信。在Java中&#xff0c;网络编程通常涉及到数据的传输、通信协议的使用以及与网络相关的各种操作。 1.2. 为什么学习Java网络编程 - Java网络编程是Java开发者重要的技能之一&#xff0c;因为它允许…

mybatis----小细节

1、起别名 在MyBatis中&#xff0c;<typeAliases>元素用于定义类型别名&#xff0c;它可以将Java类名映射为一个更简短的别名&#xff0c;这样在映射文件中可以直接使用别名而不需要完整的类名。 下面是一个示例&#xff1a; 在mybatis核心配置文件中配置typeAliases标…

SSH隧道技术

SSH隧道 简介 SSH隧道是一种通过SSH协议在两个网络节点之间建立安全通信的技术。它可以用于多种用途&#xff0c;包括加密和保护敏感数据传输、绕过防火墙限制、远程访问内部服务等。 应用&#xff1a; 端口转发&#xff1a;SSH隧道可以将本地端口转发到远程主机上&#xf…

合并K个升序链表(LeetCode 23)

文章目录 1.问题描述2.难度等级3.热门指数4.解题思路方法一&#xff1a;顺序合并方法二&#xff1a;分治合并方法三&#xff1a;使用优先队列合并 参考文献 1.问题描述 给你一个链表数组&#xff0c;每个链表都已经按升序排列。 请你将所有链表合并到一个升序链表中&#xff…

Python——基本语法(二)

一、while 循环 语法&#xff1a; while 条件表达式:条件表达示为真&#xff0c;就执⾏这⾥的代码&#xff0c;必须缩进 4 个空格多⾏代码保持缩进⼀致 条件表达式可以是: True # 布尔值的 True 1 < 10 # 凡是在 if 语句中使⽤的判断表达示&#xff0c;这⾥都可以使…

【Java实战项目】基于ssm的流浪动物领养系统网站

&#x1f64a;作者简介&#xff1a;多年一线开发工作经验&#xff0c;分享技术代码帮助学生学习&#xff0c;独立完成自己的项目或者毕业设计。 代码可以私聊博主获取。&#x1f339;赠送计算机毕业设计600个选题excel文件&#xff0c;帮助大学选题。赠送开题报告模板&#xff…

【音视频原理】图像相关概念 ② ( 帧率 | 常见帧率标准 | 码率 | 码率单位 )

文章目录 一、帧率1、帧率简介2、常见帧率标准3、帧率 刷新率 二、码率1、码率简介2、码率单位 一、帧率 1、帧率简介 帧率 Frame Rate , 帧 指的是 是 画面帧 , 帧率 是 画面帧 的 速率 ; 帧率 的 单位是 FPS , Frames Per Second , 是 每秒钟 的 画面帧 个数 ; 帧率 是 动画…

漫漫数学之旅006

文章目录 经典格言数学习题古今评注名人小传 - 格洛里亚斯泰纳姆经典格言 数学上有才华的人没有在历史或英语上有才华的人那么多。——格洛里亚斯泰纳姆(Gloria Steinem) 数学习题 求阴影部分的面积。 古今评注 查尔斯巴贝奇,这位19世纪的英国数学家、发明家和机械工程…

相机内外参标定综合

相机内外参标定 内外参标定常用的工具相机成像原理内外参标定数学原理1&#xff09;求解内参矩阵与外参矩阵的积2&#xff09;求解内参矩阵3&#xff09;求解外参矩阵 内外参标定常用的工具 如图所示&#xff0c;棋盘格是很常见使用的标定工具 左下角写着棋盘格的参数&#xf…