126 lines
3.9 KiB
Dart
126 lines
3.9 KiB
Dart
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;
|
||
|
||
TraceDio(Logger logger)
|
||
: _dio = Dio(),
|
||
_logger = logger {
|
||
// 配置 Dio
|
||
// 设置连接超时
|
||
_dio.options.connectTimeout = Duration(seconds: 5);
|
||
// 设置接收超时
|
||
_dio.options.receiveTimeout = Duration(seconds: 5);
|
||
//保留原始大小写
|
||
_dio.options.preserveHeaderCase = true;
|
||
|
||
// 设置拦截器,自动添加 traceId 和 spanId,并记录日志
|
||
_dio.interceptors.add(InterceptorsWrapper(
|
||
onRequest: (options, handler) {
|
||
// 获取请求中的 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('Sending request: ${options.method} ${options.uri}',
|
||
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 received: ${response.statusCode} ${response.statusMessage}',
|
||
tag: "DIO",
|
||
traceId: traceId,
|
||
spanId: spanId);
|
||
return handler.next(response); // 继续处理响应
|
||
},
|
||
onError: (DioException e, handler) {
|
||
// 记录错误日志
|
||
String? traceId = e.response?.headers.value('X-Trace-ID');
|
||
String? spanId = e.response?.headers.value('X-Span-ID');
|
||
_logger.error('Request failed: ${e.message}',
|
||
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}) {
|
||
if (request != null) {
|
||
return {
|
||
"X-Trace-ID": request.context['request_trace_id'] as String,
|
||
"X-Span-ID": request.context['request_span_id'] as String
|
||
};
|
||
}
|
||
return null;
|
||
}
|
||
|
||
// 发起 GET 请求
|
||
Future<Response> get(String url,
|
||
{Map<String, dynamic>? queryParameters, sf.Request? request}) async {
|
||
return await _dio.get(url,
|
||
queryParameters: queryParameters,
|
||
options: Options(headers: getHeader(request: request)));
|
||
}
|
||
|
||
// 发起 POST 请求
|
||
Future<Response> post(String url,
|
||
{Object? data,
|
||
Map<String, dynamic>? queryParameters,
|
||
sf.Request? request}) async {
|
||
return await _dio.post(url,
|
||
data: data,
|
||
queryParameters: queryParameters,
|
||
options: Options(headers: getHeader(request: request)));
|
||
}
|
||
|
||
// 发起 PUT 请求
|
||
Future<Response> put(String url,
|
||
{Object? data,
|
||
Map<String, dynamic>? queryParameters,
|
||
sf.Request? request}) async {
|
||
return await _dio.put(url,
|
||
data: data,
|
||
queryParameters: queryParameters,
|
||
options: Options(headers: getHeader(request: request)));
|
||
}
|
||
|
||
// 发起 DELETE 请求
|
||
Future<Response> delete(String url,
|
||
{Object? data,
|
||
Map<String, dynamic>? queryParameters,
|
||
sf.Request? request}) async {
|
||
return await _dio.delete(
|
||
url,
|
||
data: data,
|
||
queryParameters: queryParameters,
|
||
options: Options(headers: getHeader(request: request)),
|
||
);
|
||
}
|
||
}
|