Sources/NetworkDiagnosis/SLSNetworkDiagnosisFeature.m (764 lines of code) (raw):
//
// SLSNetworkDiagnosisFeature.m
// AliyunLogProducer
//
// Created by gordon on 2022/8/10.
//
#import "SLSProducer.h"
#import "SLSNetworkDiagnosisFeature.h"
#import "SLSUtdid.h"
#import "NSString+SLS.h"
#import "SLSNetworkDiagnosis.h"
#import "TimeUtils.h"
#import "SLSSdkSender.h"
#import "SLSCredentials.h"
#import "AliNetworkDiagnosis/AliDns.h"
#import "AliNetworkDiagnosis/AliHttpPing.h"
#import "AliNetworkDiagnosis/AliMTR.h"
#import "AliNetworkDiagnosis/AliPing.h"
#import "AliNetworkDiagnosis/AliTcpPing.h"
#import "AliNetworkDiagnosis/AliNetworkDiagnosis.h"
#import "SLSHttpHeader.h"
#import "SLSDiagnosisProtocol.h"
// for better compatibility, use __has_include instead of preprocessor
// in AliyunLogNetworkDiagnosis-NoSwift target, there is no .swift files
#if __has_include("AliyunLogNetworkDiagnosis/AliyunLogNetworkDiagnosis-Swift.h")
#define SLS_NETWORK_SWIFT_FEATURE
#import "AliyunLogNetworkDiagnosis/AliyunLogNetworkDiagnosis-Swift.h"
#endif
static int DEFAULT_PING_SIZE = 64;
static int DEFAULT_TIMEOUT = 2 * 1000;
static int DEFAULT_MAX_TIMES = 10;
static int DEFAULT_MAX_COUNT = 10;
static int DEFAULT_MAX_INTERVAL = 200;
static int DEFAULT_MTR_MAX_TTL = 30;
static int DEFAULT_MTR_MAX_PATH = 1;
static int DEFAULT_INVALID = -1;
static BOOL DEFAULT_HTTP_HEADER_ONLY = NO;
static int DEFAULT_HTTP_DOWNLOAD_BYTES_LIMIT = 64 * 1024; // 64KB
static NSString *DNS_TYPE_IPv4 = @"A";
static NSString *DNS_TYPE_IPv6 = @"AAAA";
@class SLSNetworkDiagnosisSender;
#pragma mark -- network diagnosis sender
@interface SLSNetworkDiagnosisSender : SLSSdkSender<AliNetworkDiagnosisDelegate>
- (instancetype) initWithFeature: (SLSSdkFeature *) feature;
- (void) registerCallback: (nullable Callback2) callback;
+ (instancetype) sender: (SLSCredentials *) credentials feature: (SLSSdkFeature *) feature;
@end
#pragma mark -- internal credential delegate
@interface InternalHttpCredentialDelegate : NSObject<AliHttpCredentialDelegate>
@property(nonatomic, copy) CredentialDelegate delegate;
+ (instancetype) delegate: (CredentialDelegate) delegate;
@end
#pragma mark -- network diagnosis feature extension
@interface SLSNetworkDiagnosisFeature ()
@property(nonatomic, strong) SLSNetworkDiagnosisSender *sender;
@property(nonatomic, strong) NSString *idPrefix;
@property(nonatomic, assign) long index;
@property(nonatomic, strong) NSLock *lock;
@property(nonatomic, assign) BOOL enableMultiplePortsDetect;
@property(nonatomic, strong) id<SLSDiagnosisProtocol> diagnosis;
- (NSString *) getIPAIdBySecretKey: (NSString *) secretKey;
- (NSString *) generateId;
@end
#pragma mark -- request & response
@implementation SLSRequest
@end
@implementation SLSHttpRequest
- (instancetype)init
{
self = [super init];
if (self) {
_headerOnly = DEFAULT_HTTP_HEADER_ONLY;
_downloadBytesLimit = DEFAULT_HTTP_DOWNLOAD_BYTES_LIMIT;
}
return self;
}
@end
@implementation SLSPingRequest
- (instancetype)init
{
self = [super init];
if (self) {
_size = DEFAULT_PING_SIZE;
_maxTimes = DEFAULT_MAX_TIMES;
_timeout = DEFAULT_TIMEOUT;
_parallel = NO;
}
return self;
}
@end
@implementation SLSTcpPingRequest
- (instancetype)init
{
self = [super init];
if (self) {
_port = DEFAULT_INVALID;
}
return self;
}
@end
@implementation SLSMtrRequest
- (instancetype)init
{
self = [super init];
if (self) {
_maxTTL = DEFAULT_MTR_MAX_TTL;
_maxPaths = DEFAULT_MTR_MAX_PATH;
_protocol = SLS_MTR_PROROCOL_ALL;
}
return self;
}
@end
@implementation SLSDnsRequest
- (instancetype)init
{
self = [super init];
if (self) {
_type = DNS_TYPE_IPv4;
}
return self;
}
@end
@interface SLSResponse ()
+ (instancetype) response: context type: (NSString *)type content: (NSString *)content;
+ (instancetype) error: (NSString *)content;
@end
@implementation SLSResponse
- (instancetype)initWithContext: context type: (NSString *)type content: (NSString *)content error: (NSString *)error {
self = [super init];
if (self) {
_context = context;
_type = type;
_content = content;
_error = error;
}
return self;
}
+ (instancetype) response: context type: (NSString *)type content: (NSString *)content {
return [[SLSResponse alloc] initWithContext:context type:type content:content error:nil];
}
+ (instancetype) error: (NSString *)error {
return [[SLSResponse alloc] initWithContext:nil type:nil content:nil error:error];
}
@end
#pragma mark -- feature
@implementation SLSNetworkDiagnosisFeature
#pragma mark - init
- (instancetype)init {
if (self = [super init]) {
_idPrefix = [NSString stringWithFormat:@"%ld", (long) [TimeUtils getTimeInMilliis]];
_lock = [[NSLock alloc] init];
_enableMultiplePortsDetect = NO;
_diagnosis = [[NetSpeedDiagnosis alloc] init];
}
return self;
}
- (NSString *)name {
return @"network_diagnosis";
}
- (void)setDiagnosis:(id<SLSDiagnosisProtocol>)diagnosis {
_diagnosis = diagnosis;
}
- (SLSSpanBuilder *) newSpanBuilder: (NSString *)spanName provider: (id<SLSSpanProviderProtocol>) provider processor: (id<SLSSpanProcessorProtocol>) processor {
return [[SLSSpanBuilder builder] initWithName:spanName
provider:self.configuration.spanProvider
processor:(id<SLSSpanProcessorProtocol>)_sender
];
}
- (void)onPreInit:(SLSCredentials *)credentials configuration:(SLSConfiguration *)configuration {
[super onPreInit:credentials configuration:configuration];
SLSNetworkDiagnosisCredentials *networkCredentials = credentials.networkDiagnosisCredentials;
if (!networkCredentials) {
SLSLog(@"SLSNetworkDiagnosisCredentials must not be null.");
return;
}
if (networkCredentials.secretKey.length > 0) {
networkCredentials.instanceId = [self getIPAIdBySecretKey:networkCredentials.secretKey];
}
#ifdef SLS_NETWORK_SWIFT_FEATURE
[NetworkDiagnosisHelper updateWorkspace:networkCredentials.endpoint
project:networkCredentials.project
logstore:networkCredentials.instanceId
];
#endif
_sender = [SLSNetworkDiagnosisSender sender:credentials feature:self];
[_diagnosis preInit:networkCredentials.secretKey
deviceId:[[SLSUtdid getUtdid] copy]
siteId:networkCredentials.siteId
extension:networkCredentials.extension
];
#ifdef DEBUG
[_diagnosis enableDebug:self.configuration.debuggable];
#else
[_diagnosis enableDebug:NO];
#endif
[_diagnosis registerDelegate:_sender];
[[SLSNetworkDiagnosis sharedInstance] setNetworkDiagnosisFeature:self];
}
- (void)onInitialize:(SLSCredentials *)credentials configuration:(SLSConfiguration *)configuration {
[super onInitialize:credentials configuration:configuration];
SLSNetworkDiagnosisCredentials *networkCredentials = credentials.networkDiagnosisCredentials;
if (!networkCredentials) {
SLSLog(@"SLSNetworkDiagnosisCredentials must not be null.");
return;
}
if (networkCredentials.secretKey.length > 0) {
networkCredentials.instanceId = [self getIPAIdBySecretKey:networkCredentials.secretKey];
}
[_diagnosis init:networkCredentials.secretKey
deviceId:[[SLSUtdid getUtdid] copy]
siteId:networkCredentials.siteId
extension:networkCredentials.extension];
}
- (void)setCredentials:(SLSCredentials *)credentials {
if (nil == credentials.networkDiagnosisCredentials) {
[credentials createNetworkDiagnosisCredentials];
}
[_sender setCredentials:credentials];
}
- (void)setCallback:(CredentialsCallback)callback {
[super setCallback:callback];
if (_sender) {
[_sender setCallback:callback];
}
}
- (NSString *) getIPAIdBySecretKey: (NSString *) secretKey {
NSString *decode = [secretKey base64Decode];
if (!decode) {
return @"";
}
NSDictionary *dict = [decode toDictionary];
if (!dict || ![dict objectForKey:@"ipa_app_id"]) {
return @"";
}
return [[dict objectForKey:@"ipa_app_id"] lowercaseString];
}
- (NSString *)generateId {
[_lock lock];
_index += 1;
NSString *traceId = [NSString stringWithFormat:@"%@_%ld", _idPrefix, _index];
[_lock unlock];
return traceId;
}
- (void) disableExNetworkInfo {
[_diagnosis disableExNetInfo];
}
- (void) setPolicyDomain: (NSString *) policyDomain {
[_diagnosis setPolicyDomain:policyDomain];
}
- (void) setMultiplePortsDetect: (BOOL) enable {
_enableMultiplePortsDetect = enable;
}
- (void) registerCallback:(Callback)callback {
[self registerCallback2:^(SLSResponse * _Nonnull response) {
if (callback) {
callback([response.content copy]);
}
}];
}
- (void)registerCallback2:(nullable Callback2) callback {
if (!_sender) {
return;
}
[_sender registerCallback:callback];
}
- (void) updateExtensions: (NSDictionary *) extension {
[_diagnosis updateExtension: [extension copy]];
}
- (void) registerHttpCredentialDelegate: (nullable CredentialDelegate) delegate {
[_diagnosis registerHttpCredentialDelegate:[InternalHttpCredentialDelegate delegate:delegate]];
}
#pragma mark - dns
- (void)dns:(nonnull NSString *)domain {
[self dns:domain callback:nil];
}
- (void)dns:(nonnull NSString *)domain callback:(nullable Callback)callback {
[self dns:@"" domain:domain callback:callback];
}
- (void)dns:(nonnull NSString *)nameServer domain:(nonnull NSString *)domain callback:(nullable Callback)callback {
[self dns:nameServer domain:domain type:DNS_TYPE_IPv4 callback:callback];
}
- (void)dns:(nonnull NSString *)nameServer domain:(nonnull NSString *)domain type:(nonnull NSString *)type callback:(nullable Callback)callback {
[self dns:nameServer domain:domain type:type timeout:DEFAULT_TIMEOUT callback:callback];
}
- (void)dns:(nonnull NSString *)nameServer domain:(nonnull NSString *)domain type:(nonnull NSString *)type timeout:(int)timeout callback:(nullable Callback)callback {
SLSDnsRequest *request = [[SLSDnsRequest alloc] init];
request.nameServer = nameServer;
request.domain = domain;
request.type = type;
request.timeout = timeout;
[self dns2:request callback:^(SLSResponse * _Nonnull response) {
if (callback) {
callback([response.content copy]);
}
}];
}
- (void)dns2:(SLSDnsRequest *)request {
[self dns2:request callback:nil];
}
- (void)dns2:(SLSDnsRequest *)request callback:(Callback2)callback {
if (nil == request || request.domain.length < 1) {
if (callback) {
callback([SLSResponse error:@"SLSDnsRequest is null or domain is empty."]);
}
return;
}
#ifdef SLS_NETWORK_SWIFT_FEATURE
TraceNode *node = [TraceNode traceNode:@"dns" request:request];
#endif
AliDnsConfig *dnsConfig = [[AliDnsConfig alloc] init:request.domain
nameServer:request.nameServer
type:request.type
timeout:request.timeout
interfaceType:(_enableMultiplePortsDetect ? AliNetDiagNetworkInterfaceDefault : AliNetDiagNetworkInterfaceCurrent)
traceID:[self generateId]
complete:^(id context, NSString *traceID, AliDnsResult *result) {
if (callback) {
callback([SLSResponse response:context type:@"dns" content:[result.content copy]]);
}
#ifdef SLS_NETWORK_SWIFT_FEATURE
[node end];
#endif
}
context:request.context
];
#ifdef SLS_NETWORK_SWIFT_FEATURE
[node setDetectConfig:dnsConfig];
#endif
if (request.extention) {
dnsConfig.detectExtension = [NSMutableDictionary dictionaryWithDictionary:request.extention];
}
[_diagnosis dns: dnsConfig];
}
#pragma mark - http
- (void)http:(nonnull NSString *)url {
[self http:url callback:nil];
}
- (void)http:(nonnull NSString *)url callback:(nullable Callback)callback {
[self http:url callback:callback credential:nil];
}
- (void)http:(nonnull NSString *)url callback:(nullable Callback)callback credential: (nullable CredentialDelegate)credential {
SLSHttpRequest *request = [[SLSHttpRequest alloc] init];
request.domain = url;
request.credential = credential;
request.context = self;
[self http2:request callback:^(SLSResponse * _Nonnull response) {
if (callback) {
callback([response.content copy]);
}
}];
}
- (void)http2:(SLSHttpRequest *)request {
[self http2:request callback:nil];
}
- (void)http2:(SLSHttpRequest *)request callback:(Callback2)callback {
if (nil == request || request.domain.length < 1) {
callback([SLSResponse error:@"SLSHttpRequest is null or domain is empty."]);
return;
}
InternalHttpCredentialDelegate *delegate = [InternalHttpCredentialDelegate delegate:request.credential];
AliHttpCredential *httpCredential = [delegate getHttpCredential:request.domain context:request.context];
#ifdef SLS_NETWORK_SWIFT_FEATURE
TraceNode *node = [TraceNode traceNode:@"http" request:request];
#endif
AliHttpPingConfig *config = [[AliHttpPingConfig alloc] init:request.domain
traceId:[self generateId]
clientCredential:(nil != httpCredential ? httpCredential.clientCredential : nil)
serverCredential:nil
timeout:request.timeout
limit:request.downloadBytesLimit
headerOnly:request.headerOnly
context:request.context
complete:^(id context, NSString *traceID, AliHttpPingResult *result) {
if (callback) {
callback([SLSResponse response:context type:@"http" content:[result.content copy]]);
}
#ifdef SLS_NETWORK_SWIFT_FEATURE
[node end];
#endif
}
];
if (request.extention) {
config.detectExtension = [NSMutableDictionary dictionaryWithDictionary:request.extention];
}
#ifdef SLS_NETWORK_SWIFT_FEATURE
[node setDetectConfig:config];
#endif
[_diagnosis http:config];
}
#pragma mark - mtr
- (void)mtr:(nonnull NSString *)domain {
[self mtr:domain callback:nil];
}
- (void)mtr:(nonnull NSString *)domain callback:(nullable Callback)callback {
[self mtr:domain maxTTL:DEFAULT_MTR_MAX_TTL callback:callback];
}
- (void)mtr:(nonnull NSString *)domain maxTTL:(int)maxTTL callback:(nullable Callback)callback {
[self mtr:domain maxTTL:maxTTL maxPaths:DEFAULT_MTR_MAX_PATH callback:callback];
}
- (void)mtr:(nonnull NSString *)domain maxTTL:(int)maxTTL maxPaths:(int)maxPaths callback:(nullable Callback)callback {
[self mtr:domain maxTTL:maxTTL maxPaths:maxPaths maxTimes:DEFAULT_MAX_TIMES callback:callback];
}
- (void)mtr:(nonnull NSString *)domain maxTTL:(int)maxTTL maxPaths:(int)maxPaths maxTimes:(int)maxTimes callback:(nullable Callback)callback {
[self mtr:domain maxTTL:maxTTL maxPaths:maxPaths maxTimes:maxTimes timeout:DEFAULT_TIMEOUT callback:callback];
}
- (void)mtr:(nonnull NSString *)domain maxTTL:(int)maxTTL maxPaths:(int)maxPaths maxTimes:(int)maxTimes timeout:(int)timeout callback:(nullable Callback)callback {
SLSMtrRequest *request = [[SLSMtrRequest alloc] init];
request.domain = domain;
request.maxTTL = maxTTL;
request.maxPaths = maxPaths;
request.maxTimes = maxTimes;
request.timeout = timeout;
[self mtr2:request callback:^(SLSResponse * _Nonnull response) {
if (callback) {
callback([response.content copy]);
}
}];
}
- (void)mtr2:(SLSMtrRequest *)request {
[self mtr2:request callback:nil];
}
- (void)mtr2:(SLSMtrRequest *)request callback:(Callback2)callback {
if (nil == request || request.domain.length < 1) {
if (callback) {
callback([SLSResponse error:@"SLSMtrRequest is null or domain is empty."]);
}
return;
}
#ifdef SLS_NETWORK_SWIFT_FEATURE
TraceNode *node = [TraceNode traceNode:@"mtr" request:request];
#endif
AliMTRConfig *config = [[AliMTRConfig alloc] init:request.domain
maxTtl:request.maxTTL
maxPaths:request.maxPaths
maxTimeEachIP:request.maxTimes
timeout:request.timeout
interfaceType:(_enableMultiplePortsDetect ? AliNetDiagNetworkInterfaceDefault : AliNetDiagNetworkInterfaceCurrent)
prefer:0
context:request.context
traceID:[self generateId]
complete:^(id context, NSString *traceID, AliMTRResult *result) {
if (callback && result) {
callback([SLSResponse response:context type:@"mtr" content:[result.content copy]]);
}
#ifdef SLS_NETWORK_SWIFT_FEATURE
[node end];
#endif
}
combineComplete:nil
];
if (request.extention) {
config.detectExtension = [NSMutableDictionary dictionaryWithDictionary:request.extention];
}
config.protocol = request.protocol;
config.parallel = request.parallel;
#ifdef SLS_NETWORK_SWIFT_FEATURE
[node setDetectConfig:config];
#endif
[_diagnosis mtr:config];
// [AliMTR start:request.domain
// maxTtl:request.maxTTL
// interfaceType:(_enableMultiplePortsDetect ? AliNetDiagNetworkInterfaceDefault : AliNetDiagNetworkInterfaceCurrent)
// maxPaths:request.maxPaths
// maxTimesEachIP:request.maxTimes
// timeout:request.timeout
// context:request.context
// traceID:[self generateId]
// output:nil
// complete:^(id context, NSString *traceID, AliMTRResult *result) {
// if (callback && result) {
// callback([SLSResponse response:context type:@"mtr" content:[result.content copy]]);
// }
// }
// ];
}
#pragma mark - ping
- (void)ping:(nonnull NSString *)domain {
[self ping:domain callback:nil];
}
- (void)ping:(nonnull NSString *)domain callback:(nullable Callback)callback {
[self ping:domain maxTimes:DEFAULT_MAX_TIMES timeout:DEFAULT_TIMEOUT callback:callback];
}
- (void)ping:(nonnull NSString *)domain maxTimes:(int)maxTimes timeout:(int)timeout callback:(nullable Callback)callback {
[self ping:domain size:DEFAULT_PING_SIZE maxTimes:maxTimes timeout:timeout callback:callback];
}
- (void)ping:(nonnull NSString *)domain size:(int)size callback:(nullable Callback)callback {
[self ping:domain size:size maxTimes:DEFAULT_MAX_TIMES timeout:DEFAULT_TIMEOUT callback:callback];
}
- (void)ping:(nonnull NSString *)domain size:(int)size maxTimes:(int)maxTimes timeout:(int)timeout callback:(nullable Callback)callback {
SLSPingRequest *request = [[SLSPingRequest alloc] init];
request.domain = domain;
request.size = size;
request.maxTimes = maxTimes;
request.timeout = timeout;
request.context = self;
[self ping2:request callback:^(SLSResponse * _Nonnull response) {
if (callback) {
callback([response.content copy]);
}
}];
}
- (void)ping2:(SLSPingRequest *)request {
[self ping2:request callback:nil];
}
- (void)ping2:(SLSPingRequest *)request callback:(Callback2)callback {
if (nil == request || request.domain.length < 1) {
if (callback) {
callback([SLSResponse error:@"SLSPingRequest is null or domain is empty."]);
}
return;
}
#ifdef SLS_NETWORK_SWIFT_FEATURE
TraceNode *node = [TraceNode traceNode:@"ping" request:request];
#endif
AliPingConfig *config = [[AliPingConfig alloc] init:request.domain
timeout:request.timeout
interfaceType:(_enableMultiplePortsDetect ? AliNetDiagNetworkInterfaceDefault : AliNetDiagNetworkInterfaceCurrent)
prefer:0
context:request.context
traceID:[self generateId]
size:request.size
count:DEFAULT_MAX_COUNT
interval:DEFAULT_MAX_INTERVAL
complete:^(id context, NSString *traceID, AliPingResult *result) {
if (callback) {
callback([SLSResponse response:context type:@"ping" content:[result.content copy]]);
}
#ifdef SLS_NETWORK_SWIFT_FEATURE
[node end];
#endif
}
combineComplete:nil
];
config.parallel = request.parallel;
if (request.extention) {
config.detectExtension = [NSMutableDictionary dictionaryWithDictionary:request.extention];
}
#ifdef SLS_NETWORK_SWIFT_FEATURE
[node setDetectConfig:config];
#endif
[_diagnosis ping: config];
}
#pragma mark - tcpping
- (void)tcpPing:(nonnull NSString *)domain port:(int)port {
[self tcpPing:domain port:port callback:nil];
}
- (void)tcpPing:(nonnull NSString *)domain port:(int)port callback:(nullable Callback)callback {
[self tcpPing:domain port:port maxTimes:DEFAULT_MAX_TIMES callback:callback];
}
- (void)tcpPing:(nonnull NSString *)domain port:(int)port maxTimes:(int)maxTimes callback:(nullable Callback)callback {
[self tcpPing:domain port:port maxTimes:maxTimes timeout:DEFAULT_TIMEOUT callback:callback];
}
- (void)tcpPing:(nonnull NSString *)domain port:(int)port maxTimes:(int)maxTimes timeout:(int)timeout callback:(nullable Callback)callback {
SLSTcpPingRequest *request = [[SLSTcpPingRequest alloc] init];
request.domain = domain;
request.port = port;
request.maxTimes = maxTimes;
request.timeout = timeout;
request.context = self;
[self tcpPing2:request callback:^(SLSResponse * _Nonnull response) {
if (callback) {
callback([response.content copy]);
}
}];
}
- (void)tcpPing2:(SLSTcpPingRequest *)request {
[self tcpPing2:request callback:nil];
}
- (void)tcpPing2:(SLSTcpPingRequest *)request callback:(Callback2)callback {
if (nil == request || request.domain.length < 1) {
if (callback) {
callback([SLSResponse error:@"SLSTcpPingRequest is null or domain is empty."]);
}
return;
}
#ifdef SLS_NETWORK_SWIFT_FEATURE
TraceNode *node = [TraceNode traceNode:@"tcpping" request:request];
#endif
AliTcpPingConfig *config = [[AliTcpPingConfig alloc] init:request.domain
timeout:request.timeout
interfaceType:(_enableMultiplePortsDetect ? AliNetDiagNetworkInterfaceDefault : AliNetDiagNetworkInterfaceCurrent)
prefer:0
context:request.context
traceID:[self generateId]
port:request.port
count:request.maxTimes
interval:DEFAULT_MAX_INTERVAL
complete:^(id context, NSString *traceID, AliTcpPingResult *result) {
if (callback) {
callback([SLSResponse response:context type:@"tcpping" content:[result.content copy]]);
}
#ifdef SLS_NETWORK_SWIFT_FEATURE
[node end];
#endif
}
combineComplete:nil
];
if (request.extention) {
config.detectExtension = [NSMutableDictionary dictionaryWithDictionary:request.extention];
}
#ifdef SLS_NETWORK_SWIFT_FEATURE
[node setDetectConfig:config];
#endif
[_diagnosis tcpPing: config];
}
@end
#pragma mark - network diagnosis sender
@interface SLSNetworkDiagnosisSender ()
@property(nonatomic, strong) SLSSdkFeature *feature;
@property(nonatomic, strong, readonly) Callback2 globalCallback;
@end
@implementation SLSNetworkDiagnosisSender
+ (instancetype) sender: (SLSCredentials *) credentials feature: (SLSSdkFeature *) feature {
SLSNetworkDiagnosisSender *sender = [[SLSNetworkDiagnosisSender alloc] initWithFeature:feature];
[sender initialize:credentials];
return sender;;
}
- (void) registerCallback: (nullable Callback2) callback {
_globalCallback = callback;
}
- (instancetype) initWithFeature: (SLSSdkFeature *) feature {
if (self = [super init]) {
_feature = feature;
}
return self;
}
- (NSString *)provideFeatureName {
return [_feature name];
}
- (NSString *)provideLogFileName:(SLSCredentials *)credentials {
return @"net_d";
}
- (NSString *)provideEndpoint:(SLSCredentials *)credentials {
if (nil != credentials.networkDiagnosisCredentials && credentials.networkDiagnosisCredentials.endpoint.length > 0) {
return credentials.networkDiagnosisCredentials.endpoint;
}
return [super provideEndpoint:credentials];
}
- (NSString *)provideProjectName:(SLSCredentials *)credentials {
if (nil != credentials.networkDiagnosisCredentials && credentials.networkDiagnosisCredentials.project.length > 0) {
return credentials.networkDiagnosisCredentials.project;
}
return [super provideProjectName:credentials];
}
- (NSString *)provideLogstoreName:(SLSCredentials *)credentials {
if (nil != credentials.networkDiagnosisCredentials && credentials.networkDiagnosisCredentials.instanceId.length > 0) {
return [NSString stringWithFormat:@"ipa-%@-raw", credentials.networkDiagnosisCredentials.instanceId];
} else {
if (credentials.instanceId.length > 0) {
return [NSString stringWithFormat:@"ipa-%@-raw", credentials.instanceId];
}
return nil;
}
}
- (NSString *)provideAccessKeyId:(SLSCredentials *)credentials {
if (nil != credentials.networkDiagnosisCredentials && credentials.networkDiagnosisCredentials.accessKeyId.length > 0) {
return credentials.networkDiagnosisCredentials.accessKeyId;
}
return [super provideAccessKeyId:credentials];
}
- (NSString *)provideAccessKeySecret:(SLSCredentials *)credentials {
if (nil != credentials.networkDiagnosisCredentials && credentials.networkDiagnosisCredentials.accessKeySecret.length > 0) {
return credentials.networkDiagnosisCredentials.accessKeySecret;
}
return [super provideAccessKeySecret:credentials];
}
- (NSString *)provideSecurityToken:(SLSCredentials *)credentials {
if (nil != credentials.networkDiagnosisCredentials && credentials.networkDiagnosisCredentials.securityToken.length > 0) {
return credentials.networkDiagnosisCredentials.securityToken;
}
return [super provideSecurityToken:credentials];
}
- (void) provideLogProducerConfig: (id) config {
[config setHttpHeaderInjector:^NSArray<NSString *> *(NSArray<NSString *> *srcHeaders) {
return [SLSHttpHeader getHeaders:srcHeaders, [NSString stringWithFormat:@"%@/%@", [self->_feature name], [self->_feature version]], nil];
}];
}
- (void)log:(NSString *)content level:(AliNetDiagLogLevel)level context:(id)context {
if (level <= AliNetDiagLogLevelInfo) {
SLSLogV(@"network_diagnosis, %@", content);
} else {
SLSLog(@"network_diagnosis, %@", content);
}
}
- (void)report:(NSString *)content level:(AliNetDiagLogLevel)level context:(id)context {
if (!content) {
SLSLog(@"network_diagnosis, content is empty.");
return;
}
NSString *finalContent = [content mutableCopy];
NSData *data = [finalContent dataUsingEncoding:NSUTF8StringEncoding];
NSError *error;
NSDictionary *dict = [NSJSONSerialization JSONObjectWithData:data
options:kNilOptions
error:&error
];
if (error) {
SLSLog(@"network_diagnosis, content is not valid json. content: %@", finalContent);
return;
}
NSString *method = [dict objectForKey:@"method"];
if (!method) {
SLSLog(@"network_diagnosis, method is empty.");
return;
}
SLSSpanBuilder *builder = [_feature newSpanBuilder:@"network_diagnosis"];
[builder addAttribute:
[SLSAttribute of:@"t" value:@"net_d"],
[SLSAttribute of:@"net.type" value:method],
[SLSAttribute of:@"net.origin" dictValue:dict],
nil
];
[builder setGlobal:NO];
[[builder build] end];
if (_globalCallback) {
_globalCallback([SLSResponse response:context type:method content:[content copy]]);
}
}
@end
#pragma mark internal ali http credential delegate
@implementation InternalHttpCredentialDelegate
+ (instancetype) delegate: (CredentialDelegate) delegate {
InternalHttpCredentialDelegate *instance = [[self alloc] init];
instance.delegate = delegate;
return instance;
}
- (AliHttpCredential *)getHttpCredential:(NSString *)url context:(id)context {
if (nil == _delegate) {
return nil;
}
NSURLCredential *credential = _delegate(url);
if (nil != credential) {
AliHttpCredential *httpCredential = [[AliHttpCredential alloc] init];
httpCredential.clientCredential = credential;
return httpCredential;
}
return nil;
}
@end
#pragma mark -- NetSpeed Diagnosis
@implementation NetSpeedDiagnosis
- (void)dns:(nonnull AliDnsConfig *)config {
[AliDns execute: config];
}
- (void)http:(nonnull AliHttpPingConfig *)config {
[AliHttpPing execute: config];
}
- (void)mtr:(nonnull AliMTRConfig *)config {
[AliMTR execute: config];
}
- (void)ping:(nonnull AliPingConfig *)config {
[AliPing execute: config];
}
- (void)tcpPing:(nonnull AliTcpPingConfig *)config {
[AliTcpPing execute:config];
}
- (void)disableExNetInfo {
[AliNetworkDiagnosis disableExNetInfo];
}
- (void)enableDebug:(BOOL)debug {
[AliNetworkDiagnosis enableDebug:debug];
}
- (void)executeOncePolicy:(nonnull NSString *)policy {
[AliNetworkDiagnosis executeOncePolicy:policy];
}
- (void)preInit:(NSString*)secretKey deviceId:(NSString*)deviceId siteId:(NSString*)siteId extension:(NSDictionary*)extension {
[AliNetworkDiagnosis preInit:secretKey deviceId:deviceId siteId:siteId extension:extension];
}
- (void)init:(nonnull NSString *)secretKey deviceId:(nonnull NSString *)deviceId siteId:(nonnull NSString *)siteId extension:(nonnull NSDictionary *)extension {
[AliNetworkDiagnosis init:secretKey deviceId:deviceId siteId:siteId extension:extension];
}
- (void)refreshSecretKey:(nonnull NSString *)secretKey {
[AliNetworkDiagnosis refreshSecretKey:secretKey];
}
- (void)registerDelegate:(nonnull id<AliNetworkDiagnosisDelegate>)delegate {
[AliNetworkDiagnosis registerDelegate:delegate];
}
- (void)registerHttpCredentialDelegate:(nonnull id<AliHttpCredentialDelegate>)delegate {
[AliNetworkDiagnosis registerHttpCredentialDelegate:delegate];
}
- (void)setPolicyDomain:(nonnull NSString *)domain {
[AliNetworkDiagnosis setPolicyDomain:domain];
}
- (void)updateExtension:(nonnull NSDictionary *)extension {
[AliNetworkDiagnosis updateExtension:extension];
}
@end