Files
easy_dart_module/lib/base/http/TraceDio.dart

167 lines
5.3 KiB
Dart
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
import 'dart:convert';
import 'package:EasyDartModule/base/logger/Logger.dart';
import 'package:dio/dio.dart';
import 'package:shelf/shelf.dart' as sf;
import 'package:uuid/uuid.dart';
class TraceDio {
final Dio _dio;
final Logger? _logger;
final Uuid uuid = Uuid();
static late TraceDio _traceDio;
//token
String? token;
//自定义查询条件
Map<String, String> queryParameters = {};
TraceDio(Logger? logger)
: _dio = Dio(),
_logger = logger {
// 配置 Dio
// 设置连接超时
_dio.options.connectTimeout = Duration(seconds: 60);
// 设置接收超时
_dio.options.receiveTimeout = Duration(seconds: 5 * 60);
//保留原始大小写
_dio.options.preserveHeaderCase = true;
// 设置拦截器,自动添加 traceId 和 spanId并记录日志
_dio.interceptors.add(InterceptorsWrapper(
onRequest: (options, handler) {
//动态添加请求参数
options.queryParameters.addAll(queryParameters);
// 获取请求中的 traceId如果没有则生成
String? traceId = options.headers['X-Trace-ID'];
String? spanId = options.headers['X-Span-ID'];
if (traceId == null) {
// 在请求头中添加 traceId 和 spanId
traceId = uuid.v4();
spanId = uuid.v4();
options.headers['X-Trace-ID'] = traceId;
options.headers['X-Span-ID'] = spanId;
}
// 记录请求日志
_logger?.info(
'发送请求: ${options.method} ${options.uri} ${options.data != null ? jsonEncode(options.data) : ""}',
tag: "DIO",
traceId: traceId,
spanId: spanId);
return handler.next(options); // 继续请求
},
onResponse: (response, handler) {
// 记录响应日志
String? traceId = response.headers.value('X-Trace-ID');
String? spanId = response.headers.value('X-Span-ID');
_logger?.info('接收数据: ${response.statusCode} ${response.statusMessage}',
tag: "DIO", traceId: traceId, spanId: spanId);
//自动更新token
if (response.headers["token"] != null) {
token = response.headers["token"]?[0];
}
return handler.next(response); // 继续处理响应
},
onError: (DioException e, handler) {
// 记录错误日志
String? traceId = e.requestOptions.headers['X-Trace-ID'];
String? spanId = e.requestOptions.headers['X-Span-ID'];
String errMsg;
if (e.response != null) {
errMsg =
"请求错误: url:${e.requestOptions.path} 请求方法:${e.requestOptions.method} 请求数据:${e.requestOptions.data} 响应代码:${e.response?.statusCode} 响应消息:${e.response?.statusMessage} 响应内容:${e.response?.data}";
} else {
errMsg =
"请求错误: url:${e.requestOptions.path} 请求方法:${e.requestOptions.method} 请求数据:${e.requestOptions.data} 错误消息:${e.message ?? e.error}";
}
print(errMsg);
_logger?.error(errMsg, tag: "DIO", traceId: traceId, spanId: spanId);
return handler.next(e); // 继续处理错误
},
));
}
static TraceDio getInstance() {
return _traceDio;
}
static void setInstance(TraceDio traceDio) {
_traceDio = traceDio;
}
Map<String, dynamic>? getHeader(
{Map<String, dynamic>? headers, sf.Request? request}) {
headers ??= {};
if (token != null) {
headers["token"] = token;
}
if (request != null) {
return {
...headers,
"X-Trace-ID": request.context['request_trace_id'] as String,
"X-Span-ID": request.context['request_span_id'] as String
};
}
return headers;
}
// 发起 GET 请求
Future<Response> get(String url,
{Map<String, dynamic>? queryParameters,
sf.Request? request,
ResponseType? responseType,
Duration? receiveTimeout}) async {
return await _dio.get(url,
queryParameters: queryParameters,
options: Options(
receiveTimeout: receiveTimeout,
headers: getHeader(request: request),
responseType: responseType));
}
// 发起 POST 请求
Future<Response> post(String url,
{Object? data,
Map<String, dynamic>? queryParameters,
sf.Request? request,
Duration? receiveTimeout}) async {
return await _dio.post(url,
data: data,
queryParameters: queryParameters,
options: Options(
receiveTimeout: receiveTimeout,
headers: getHeader(request: request)));
}
// 发起 PUT 请求
Future<Response> put(String url,
{Object? data,
Map<String, dynamic>? queryParameters,
sf.Request? request,
Duration? receiveTimeout}) async {
return await _dio.put(url,
data: data,
queryParameters: queryParameters,
options: Options(
receiveTimeout: receiveTimeout,
headers: getHeader(request: request)));
}
// 发起 DELETE 请求
Future<Response> delete(String url,
{Object? data,
Map<String, dynamic>? queryParameters,
sf.Request? request,
Duration? receiveTimeout}) async {
return await _dio.delete(
url,
data: data,
queryParameters: queryParameters,
options: Options(
receiveTimeout: receiveTimeout, headers: getHeader(request: request)),
);
}
}