QNUploadRequestMetrics.m 7.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272
  1. //
  2. // QNUploadRequestMetrics.m
  3. // QiniuSDK
  4. //
  5. // Created by yangsen on 2020/4/29.
  6. // Copyright © 2020 Qiniu. All rights reserved.
  7. //
  8. #import "QNUploadRequestMetrics.h"
  9. #import "NSURLRequest+QNRequest.h"
  10. #import "QNZoneInfo.h"
  11. @interface QNUploadSingleRequestMetrics()
  12. @end
  13. @implementation QNUploadSingleRequestMetrics
  14. + (instancetype)emptyMetrics{
  15. QNUploadSingleRequestMetrics *metrics = [[QNUploadSingleRequestMetrics alloc] init];
  16. return metrics;
  17. }
  18. - (instancetype)init{
  19. if (self = [super init]) {
  20. [self initData];
  21. }
  22. return self;
  23. }
  24. - (void)initData{
  25. _countOfRequestHeaderBytesSent = 0;
  26. _countOfRequestBodyBytesSent = 0;
  27. _countOfResponseHeaderBytesReceived = 0;
  28. _countOfResponseBodyBytesReceived = 0;
  29. }
  30. - (void)setRequest:(NSURLRequest *)request{
  31. NSMutableURLRequest *newRequest = [NSMutableURLRequest requestWithURL:request.URL
  32. cachePolicy:request.cachePolicy
  33. timeoutInterval:request.timeoutInterval];
  34. newRequest.allHTTPHeaderFields = request.allHTTPHeaderFields;
  35. NSInteger headerLength = [NSString stringWithFormat:@"%@", request.allHTTPHeaderFields].length;
  36. NSInteger bodyLength = [request.qn_getHttpBody length];
  37. _totalBytes = @(headerLength + bodyLength);
  38. _request = [newRequest copy];
  39. }
  40. - (NSNumber *)totalElapsedTime{
  41. return [self timeFromStartDate:self.startDate
  42. toEndDate:self.endDate];
  43. }
  44. - (NSNumber *)totalDnsTime{
  45. return [self timeFromStartDate:self.domainLookupStartDate
  46. toEndDate:self.domainLookupEndDate];
  47. }
  48. - (NSNumber *)totalConnectTime{
  49. return [self timeFromStartDate:self.connectStartDate
  50. toEndDate:self.connectEndDate];
  51. }
  52. - (NSNumber *)totalSecureConnectTime{
  53. return [self timeFromStartDate:self.secureConnectionStartDate
  54. toEndDate:self.secureConnectionEndDate];
  55. }
  56. - (NSNumber *)totalRequestTime{
  57. return [self timeFromStartDate:self.requestStartDate
  58. toEndDate:self.requestEndDate];
  59. }
  60. - (NSNumber *)totalWaitTime{
  61. return [self timeFromStartDate:self.requestEndDate
  62. toEndDate:self.responseStartDate];
  63. }
  64. - (NSNumber *)totalResponseTime{
  65. return [self timeFromStartDate:self.responseStartDate
  66. toEndDate:self.responseEndDate];
  67. }
  68. - (NSNumber *)bytesSend{
  69. int64_t totalBytes = [self totalBytes].integerValue;
  70. int64_t senderBytes = self.countOfRequestBodyBytesSent + self.countOfRequestHeaderBytesSent;
  71. int64_t bytes = MIN(totalBytes, senderBytes);
  72. return @(bytes);
  73. }
  74. - (NSNumber *)timeFromStartDate:(NSDate *)startDate toEndDate:(NSDate *)endDate{
  75. if (startDate && endDate) {
  76. double time = [endDate timeIntervalSinceDate:startDate] * 1000;
  77. return @(time);
  78. } else {
  79. return nil;
  80. }
  81. }
  82. @end
  83. @interface QNUploadRegionRequestMetrics()
  84. @property (nonatomic, strong) id <QNUploadRegion> region;
  85. @property (nonatomic, copy) NSMutableArray<QNUploadSingleRequestMetrics *> *metricsListInter;
  86. @end
  87. @implementation QNUploadRegionRequestMetrics
  88. + (instancetype)emptyMetrics{
  89. QNUploadRegionRequestMetrics *metrics = [[QNUploadRegionRequestMetrics alloc] init];
  90. return metrics;
  91. }
  92. - (instancetype)initWithRegion:(id<QNUploadRegion>)region{
  93. if (self = [super init]) {
  94. _region = region;
  95. _metricsListInter = [NSMutableArray array];
  96. }
  97. return self;
  98. }
  99. - (NSNumber *)totalElapsedTime{
  100. if (self.metricsList) {
  101. double time = 0;
  102. for (QNUploadSingleRequestMetrics *metrics in self.metricsList) {
  103. time += metrics.totalElapsedTime.doubleValue;
  104. }
  105. return time > 0 ? @(time) : nil;
  106. } else {
  107. return nil;
  108. }
  109. }
  110. - (NSNumber *)requestCount{
  111. if (self.metricsList) {
  112. return @(self.metricsList.count);
  113. } else {
  114. return @(0);
  115. }
  116. }
  117. - (NSNumber *)bytesSend{
  118. if (self.metricsList) {
  119. long long bytes = 0;
  120. for (QNUploadSingleRequestMetrics *metrics in self.metricsList) {
  121. bytes += metrics.bytesSend.longLongValue;
  122. }
  123. return @(bytes);
  124. } else {
  125. return @(0);
  126. }
  127. }
  128. - (void)addMetricsList:(NSArray<QNUploadSingleRequestMetrics *> *)metricsList{
  129. @synchronized (self) {
  130. [_metricsListInter addObjectsFromArray:metricsList];
  131. }
  132. }
  133. - (void)addMetrics:(QNUploadRegionRequestMetrics*)metrics{
  134. if ([metrics.region.zoneInfo.regionId isEqualToString:self.region.zoneInfo.regionId]) {
  135. @synchronized (self) {
  136. [_metricsListInter addObjectsFromArray:metrics.metricsListInter];
  137. }
  138. }
  139. }
  140. - (NSArray<QNUploadSingleRequestMetrics *> *)metricsList{
  141. @synchronized (self) {
  142. return [_metricsListInter copy];
  143. }
  144. }
  145. @end
  146. @interface QNUploadTaskMetrics()
  147. @property (nonatomic, copy) NSMutableDictionary<NSString *, QNUploadRegionRequestMetrics *> *metricsInfo;
  148. @end
  149. @implementation QNUploadTaskMetrics
  150. + (instancetype)emptyMetrics{
  151. QNUploadTaskMetrics *metrics = [[QNUploadTaskMetrics alloc] init];
  152. return metrics;
  153. }
  154. - (instancetype)init{
  155. if (self = [super init]) {
  156. _metricsInfo = [NSMutableDictionary dictionary];
  157. }
  158. return self;
  159. }
  160. - (NSNumber *)totalElapsedTime{
  161. NSDictionary *metricsInfo = [self syncCopyMetricsInfo];
  162. if (metricsInfo) {
  163. double time = 0;
  164. for (QNUploadRegionRequestMetrics *metrics in metricsInfo.allValues) {
  165. time += metrics.totalElapsedTime.doubleValue;
  166. }
  167. return time > 0 ? @(time) : nil;
  168. } else {
  169. return nil;
  170. }
  171. }
  172. - (NSNumber *)requestCount{
  173. NSDictionary *metricsInfo = [self syncCopyMetricsInfo];
  174. if (metricsInfo) {
  175. NSInteger count = 0;
  176. for (QNUploadRegionRequestMetrics *metrics in metricsInfo.allValues) {
  177. count += metrics.requestCount.integerValue;
  178. }
  179. return @(count);
  180. } else {
  181. return @(0);
  182. }
  183. }
  184. - (NSNumber *)bytesSend{
  185. NSDictionary *metricsInfo = [self syncCopyMetricsInfo];
  186. if (metricsInfo) {
  187. long long bytes = 0;
  188. for (QNUploadRegionRequestMetrics *metrics in metricsInfo.allValues) {
  189. bytes += metrics.bytesSend.longLongValue;
  190. }
  191. return @(bytes);
  192. } else {
  193. return @(0);
  194. }
  195. }
  196. - (NSNumber *)regionCount{
  197. NSDictionary *metricsInfo = [self syncCopyMetricsInfo];
  198. if (metricsInfo) {
  199. int count = 0;
  200. for (QNUploadRegionRequestMetrics *metrics in metricsInfo.allValues) {
  201. if (![metrics.region.zoneInfo.regionId isEqualToString:QNZoneInfoEmptyRegionId]) {
  202. count += 1;
  203. }
  204. }
  205. return @(count);
  206. } else {
  207. return @(0);
  208. }
  209. }
  210. - (void)addMetrics:(QNUploadRegionRequestMetrics *)metrics{
  211. NSString *regionId = metrics.region.zoneInfo.regionId;
  212. if (!regionId) {
  213. return;
  214. }
  215. @synchronized (self) {
  216. QNUploadRegionRequestMetrics *metricsOld = self.metricsInfo[regionId];
  217. if (metricsOld) {
  218. [metricsOld addMetrics:metrics];
  219. } else {
  220. self.metricsInfo[regionId] = metrics;
  221. }
  222. }
  223. }
  224. - (NSDictionary<NSString *, QNUploadRegionRequestMetrics *> *)syncCopyMetricsInfo {
  225. @synchronized (self) {
  226. return [_metricsInfo copy];
  227. }
  228. }
  229. @end