You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何将Dio请求日志整合成单个Sentry面包屑上报

解决方案

首先明确:你没遗漏现有库的配置——pretty_dio_logger确实没有内置合并日志行的选项,sentry_dio默认也只上报请求性能与基础参数,无法直接上报响应体。下面是几个可行的解决思路:

方案一:自定义Dio拦截器(最推荐)

放弃pretty_dio_logger,自己写一个拦截器,将完整的请求/响应日志组装成单条字符串,一次性提交给Sentry作为单个面包屑。示例代码:

class CustomDioLoggerInterceptor extends Interceptor {
  @override
  void onRequest(RequestOptions options, RequestInterceptorHandler handler) {
    // 组装请求日志
    final requestLog = '''
请求方法: ${options.method}
请求URL: ${options.uri}
请求头: ${options.headers.toString()}
请求参数: ${options.data.toString()}
''';
    // 添加到Sentry面包屑
    Sentry.addBreadcrumb(
      Breadcrumb(
        message: requestLog,
        category: 'http.request',
        level: SentryLevel.info,
      ),
    );
    super.onRequest(options, handler);
  }

  @override
  void onResponse(Response response, ResponseInterceptorHandler handler) {
    // 组装响应日志
    final responseLog = '''
响应状态: ${response.statusCode} ${response.statusMessage}
响应URL: ${response.requestOptions.uri}
响应体: ${response.data.toString()}
''';
    // 添加到Sentry面包屑
    Sentry.addBreadcrumb(
      Breadcrumb(
        message: responseLog,
        category: 'http.response',
        level: SentryLevel.info,
      ),
    );
    super.onResponse(response, handler);
  }

  @override
  void onError(DioException err, ErrorInterceptorHandler handler) {
    // 组装错误日志
    final errorLog = '''
请求错误: ${err.message}
请求URL: ${err.requestOptions.uri}
错误栈: ${err.stackTrace.toString()}
''';
    Sentry.addBreadcrumb(
      Breadcrumb(
        message: errorLog,
        category: 'http.error',
        level: SentryLevel.error,
      ),
    );
    super.onError(err, handler);
  }
}

// 使用方式
dio.interceptors.add(CustomDioLoggerInterceptor());

方案二:改造pretty_dio_logger的输出逻辑

如果不想放弃pretty_dio_logger的格式化能力,可以重写它的logPrint方法,将所有日志行先拼接成单条字符串再打印,这样Sentry只会捕获一条面包屑:

final logger = PrettyDioLogger(
  logPrint: (message) {
    // 统一拼接成单条日志
    final fullLog = message is List ? message.join('\n') : message.toString();
    // 直接打印(Sentry会捕获这条打印作为单个面包屑)
    print(fullLog);
    // 也可以直接调用Sentry添加面包屑,跳过系统打印
    // Sentry.addBreadcrumb(Breadcrumb(message: fullLog, category: 'http'));
  },
);
dio.interceptors.add(logger);

如果上述方式不生效(比如pretty_dio_logger内部仍逐行调用logPrint),那就只能fork库,修改其内部日志输出逻辑,把循环逐行打印改成一次性输出完整日志。

方案三:扩展SentryDioInterceptor上报响应体

你提到的sentry_dio其实可以通过自定义回调补充响应体数据,同时保留它的性能监控能力:

final sentryDioInterceptor = SentryDioInterceptor(
  dio: dio,
  onResponse: (response, hub) {
    // 在响应完成后,添加包含响应体的面包屑
    hub.addBreadcrumb(
      Breadcrumb(
        message: '响应体: ${response.data.toString()}',
        category: 'http.response.body',
        level: SentryLevel.info,
      ),
    );
  },
);
dio.interceptors.add(sentryDioInterceptor);

内容的提问来源于stack exchange,提问作者sharbel okzan

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.12 05:52:59