Giter Club home page Giter Club logo

aliyun-log-ios-sdk's Introduction

log service ios producer

功能特点

  • 异步
    • 异步写入,客户端线程无阻塞
  • 聚合&压缩 上传
    • 支持按超时时间、日志数、日志size聚合数据发送
    • 支持lz4压缩
  • 多客户端
    • 可同时配置多个客户端,每个客户端可独立配置采集优先级、缓存上限、目的project/logstore、聚合参数等 (多客户端,断点续传文件路径不能相同)
  • 缓存
    • 支持缓存上限可设置
    • 超过上限后日志写入失败
  • 自定义标识
    • 支持设置自定义tag、topic
  • 断点续传功能
    • 每次发送前会把日志保存到本地的binlog文件,只有发送成功才会删除,保证日志上传At Least Once

image.png

性能测试

  • 开启断点续传
发送 条/每秒 cpu占用 内存占用(MB) 上传速(MB/min)
1 <1% 14.2 0.046
10 1% 14.5 0.435
100 6% 14.5 4.31
300 11% 14.7 12.80
  • 不开启断点续
发送 条/每秒 cpu占用 内存占用(MB) 上传速(MB/min)
1 <1% 14 0.046
10 1% 14 0.437
100 6% 14.1 4.50
300 9% 14.4 13.47

Podfile

pod 'AliyunLogProducer', '~> 2.2.25'

swift 配置说明

import

import AliyunLogProducer

创建config

https://help.aliyun.com/document_detail/29064.html

// endpoint前需要加 https://
let endpoint = "project's_endpoint";
let project = "project_name";
let logstore = "logstore_name";
let accesskeyid = "your_accesskey_id";
let accesskeysecret = "your_accesskey_secret";

let config = LogProducerConfig(endpoint:endpoint, project:project, logstore:logstore, accessKeyID:accesskeyid, accessKeySecret:accesskeysecret)!
// 指定sts token 创建config,过期之前调用ResetSecurityToken重置token
// let config = LogProducerConfig(endpoint:endpoint, project:project, logstore:logstore, accessKeyID:accesskeyid, accessKeySecret:accesskeysecret, securityToken:securityToken)

配置config & 创建client

// 设置主题
config.setTopic("test_topic")
// 设置tag信息,此tag会附加在每条日志上
config.addTag("test", value:"test_tag")
// 每个缓存的日志包的大小上限,取值为1~5242880,单位为字节。默认为1024 * 1024
config.setPacketLogBytes(1024*1024)
// 每个缓存的日志包中包含日志数量的最大值,取值为1~4096,默认为1024
config.setPacketLogCount(1024)
// 被缓存日志的发送超时时间,如果缓存超时,则会被立即发送,单位为毫秒,默认为3000
config.setPacketTimeout(3000)
// 单个Producer Client实例可以使用的内存的上限,超出缓存时add_log接口会立即返回失败
// 默认为64 * 1024 * 1024
config.setMaxBufferLimit(64*1024*1024)
// 发送线程数,默认为1,不建议修改此配置
// 开启断点续传功能后,sendThreadCount强制为1
config.setSendThreadCount(1)

// 1 开启断点续传功能, 0 关闭
// 每次发送前会把日志保存到本地的binlog文件,只有发送成功才会删除,保证日志上传At Least Once
config.setPersistent(1)
// 持久化的文件名,需要保证文件所在的文件夹已创建。
let file = NSSearchPathForDirectoriesInDomains(FileManager.SearchPathDirectory.documentDirectory, FileManager.SearchPathDomainMask.userDomainMask, true).first
let path = file! + "/log.dat"
config.setPersistentFilePath(path)
// 是否每次AddLog强制刷新,高可靠性场景建议打开
config.setPersistentForceFlush(1)
// 持久化文件滚动个数,建议设置成10。
config.setPersistentMaxFileCount(10)
// 每个持久化文件的大小,建议设置成1-10M
config.setPersistentMaxFileSize(1024*1024)
// 本地最多缓存的日志数,不建议超过1M,通常设置为65536即可
config.setPersistentMaxLogCount(65536)
config.setGetTimeUnixFunc({ () -> UInt32 in
    let time = Date().timeIntervalSince1970
    return UInt32(time);
})
let callbackFunc: on_log_producer_send_done_function = {config_name,result,log_bytes,compressed_bytes,req_id,error_message,raw_buffer,user_param in
          let res = LogProducerResult(rawValue: Int(result))
//            print(res!)
//            let req = String(cString: req_id!)
//            print(req)
//            print(log_bytes)
//            print(compressed_bytes)
}
client = LogProducerClient(logProducerConfig:config, callback:callbackFunc)
//        client = LogProducerClient(logProducerConfig:config)

写数据

let log = Log()
let logTime = Date().timeIntervalSince1970
//不设置默认当前时间
log.setTime(useconds_t(logTime))
log.putContent("k1", value:"v1")
log.putContent("k2", value:"v2")

// addLog第二个参数flush,是否立即发送,1代表立即发送,不设置时默认为0
let res = client?.add(log, flush:0)

oc 配置说明

import

#import "AliyunLogProducer/AliyunLogProducer.h"

创建config

https://help.aliyun.com/document_detail/29064.html

// endpoint前需要加 https://
NSString* endpoint = @"project's_endpoint";
NSString* project = @"project_name";
NSString* logstore = @"logstore_name";
NSString* accesskeyid = @"your_accesskey_id";
NSString* accesskeysecret = @"your_accesskey_secret";

LogProducerConfig* config = [[LogProducerConfig alloc] initWithEndpoint:endpoint project:project logstore:logstore accessKeyID:accesskeyid accessKeySecret:accesskeysecret];
// 指定sts token 创建config,过期之前调用ResetSecurityToken重置token
// LogProducerConfig* config = [[LogProducerConfig alloc] initWithEndpoint:endpoint project:project logstore:logstore accessKeyID:accesskeyid accessKeySecret:accesskeysecret securityToken:securityToken];

配置config & 创建client

// 设置主题
[config SetTopic:@"test_topic"];
// 设置tag信息,此tag会附加在每条日志上
[config AddTag:@"test" value:@"test_tag"];
// 每个缓存的日志包的大小上限,取值为1~5242880,单位为字节。默认为1024 * 1024
[config SetPacketLogBytes:1024*1024];
// 每个缓存的日志包中包含日志数量的最大值,取值为1~4096,默认为1024
[config SetPacketLogCount:1024];
// 被缓存日志的发送超时时间,如果缓存超时,则会被立即发送,单位为毫秒,默认为3000
[config SetPacketTimeout:3000];
// 单个Producer Client实例可以使用的内存的上限,超出缓存时add_log接口会立即返回失败
// 默认为64 * 1024 * 1024
[config SetMaxBufferLimit:64*1024*1024];
// 发送线程数,默认为1,不建议修改此配置
// 开启断点续传功能后,sendThreadCount强制为1
[config SetSendThreadCount:1];
     
// 1 开启断点续传功能, 0 关闭
// 每次发送前会把日志保存到本地的binlog文件,只有发送成功才会删除,保证日志上传At Least Once
[config SetPersistent:1];
// 持久化的文件名,需要保证文件所在的文件夹已创建。
[config SetPersistentFilePath:Path];
// 是否每次AddLog强制刷新,高可靠性场景建议打开
[config SetPersistentForceFlush:1];
// 持久化文件滚动个数,建议设置成10。
[config SetPersistentMaxFileCount:10];
// 每个持久化文件的大小,建议设置成1-10M
[config SetPersistentMaxFileSize:1024*1024];
// 本地最多缓存的日志数,不建议超过1M,通常设置为65536即可
[config SetPersistentMaxLogCount:65536];

// 注册 获取服务器时间 的函数
[config SetGetTimeUnixFunc:time];

//创建client
client = [[LogProducerClient alloc] initWithLogProducerConfig:config];

写数据

Log* log = [[Log alloc] init];
int logTime = [[NSDate date] timeIntervalSince1970];
//不设置默认当前时间
[log SetTime:logTime];
[log PutContent:@"k1" value:@"v1"];
[log PutContent:@"k2" value:@"v2"];

// addLog第二个参数flush,是否立即发送,1代表立即发送,不设置时默认为0
LogProducerResult res = [client AddLog:log flush:0];

config其他参数说明

参数 说明 取值
connect_timeout_sec 网络连接超时时间 整数,单位秒,默认为10
send_timeout_sec 日志发送超时时间 整数,单位秒,默认为15
destroy_flusher_wait_sec flusher线程销毁最大等待时间 整数,单位秒,默认为1
destroy_sender_wait_sec sender线程池销毁最大等待时间 整数,单位秒,默认为1
compress_type 数据上传时的压缩类型,默认为LZ4压缩 0 不压缩,1 LZ4压缩, 默认为1
ntp_time_offset 设备时间与标准时间之差,值为标准时间-设备时间,一般此种情况用户客户端设备时间不同步的场景 整数,单位秒,默认为0;比如当前设备时间为1607064208, 标准时间为1607064308,则值设置为 1607064308 - 1607064208 = 100
max_log_delay_time 日志时间与本机时间之差,超过该大小后会根据 drop_delay_log 选项进行处理。一般此种情况只会在设置persistent的情况下出现,即设备下线后,超过几天/数月启动,发送退出前未发出的日志 整数,单位秒,默认为7243600,即7天
drop_delay_log 对于超过 max_log_delay_time 日志的处理策略 0 不丢弃,把日志时间修改为当前时间; 1 丢弃,默认为 1 (丢弃)
drop_unauthorized_log 是否丢弃鉴权失败的日志,0 不丢弃,1丢弃 整数,默认为 0,即不丢弃

aliyun-log-ios-sdk's People

Contributors

1019272778 avatar chaolee50 avatar cnbleu avatar duan007a avatar lujiajing1126 avatar sandbeach avatar sdlcdhc avatar wangjwchn avatar zzboy avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

aliyun-log-ios-sdk's Issues

多个统计行为同时进行,后台出现窜表的问题

logstore要传不同的行为名称,按照demo中的方式进行配置上传,导致后台统计出现窜表,一个统计行为跑到另一个统计行为的表里。
猜测出现问题的原因:项目里有很多行为可能同时上报,导致初始化完client后,还没统计上,下一个行为的client就被创建了。

因为client里要用logstore字段,没法用单例的模式。

怎么解决???

pod install报错,下载不了

linkcircle@linkcircledeMBP LogDemo % pod install
Analyzing dependencies
Downloading dependencies
Installing AliyunLogProducer (2.1.0)

[!] Error installing AliyunLogProducer
[!] /usr/bin/git clone https://github.com/aliyun/aliyun-log-ios-sdk.git /var/folders/2q/kf6k0z916s3gkzqnwxgbwty00000gn/T/d20201027-2004-1khewp0 --template= --single-branch --depth 1 --branch 2.1.0

Cloning into '/var/folders/2q/kf6k0z916s3gkzqnwxgbwty00000gn/T/d20201027-2004-1khewp0'...
error: RPC failed; curl 18 transfer closed with outstanding read data remaining
fatal: the remote end hung up unexpectedly
fatal: early EOF
fatal: index-pack failed

集成AliyunLOGiOS.framework后,方法走不通啊, xcode 9.2

2018-06-14 10:33:00.934198+0800 AliYunLogsTest[22758:680818] Fatal error: 'try!' expression unexpectedly raised an error: Error Domain=NSCocoaErrorDomain Code=3840 "JSON text did not start with array or object and option to allow fragments not set." UserInfo={NSDebugDescription=JSON text did not start with array or object and option to allow fragments not set.}: file /BuildRoot/Library/Caches/com.apple.xbs/Sources/swiftlang/swiftlang-900.0.74.1/src/swift/stdlib/public/core/ErrorType.swift, line 181

你们自己demo都跑不通啊

1、下载demo
2、编译framework
3、打开demo工程,编译demo
4、提示 找不到module:No such module 'AliyunLOGiOS'

然后我自己的工程拖入你们的framework,编译能通过,但是里面的类全都不能用
环境xcode9.2,swift3.2

升级Xcode10 SDK报错Symbol not found: __T0BOWV

dyld: Symbol not found: __T0BOWV
Referenced from: /Users/apple10/Library/Developer/CoreSimulator/Devices/9E85D055-4FDB-4DEE-AE35-75396B3ACE4C/data/Containers/Bundle/Application/CF6C3F15-CA79-4AEB-8FBC-20BE4FBC2C8E/GameDemo.app/Frameworks/AliyunLOGiOS.framework/AliyunLOGiOS
Expected in: /Users/apple10/Library/Developer/CoreSimulator/Devices/9E85D055-4FDB-4DEE-AE35-75396B3ACE4C/data/Containers/Bundle/Application/CF6C3F15-CA79-4AEB-8FBC-20BE4FBC2C8E/GameDemo.app/Frameworks/libswiftCore.dylib
in /Users/apple10/Library/Developer/CoreSimulator/Devices/9E85D055-4FDB-4DEE-AE35-75396B3ACE4C/data/Containers/Bundle/Application/CF6C3F15-CA79-4AEB-8FBC-20BE4FBC2C8E/GameDemo.app/Frameworks/AliyunLOGiOS.framework/AliyunLOGiOS

-[LogProducerClient convertToChar:] 会crash

版本:3.1.16
测试代码:
`

  • (void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event {
    [super touchesBegan:touches withEvent:event];

    // 模拟栈被占用很多的情况
    char cStr [100000];

    NSMutableString *str = [NSMutableString new];
    for (NSInteger i = 0; i < 1000000 - 1; i ++) {
    [str appendString:@"1"];
    }

    [self convertToChar:str];
    }

/// 从LogProducerClient源码复制出来的
-(char*)convertToChar:(NSString*)strtemp
{
NSUInteger len = [strtemp lengthOfBytesUsingEncoding:NSUTF8StringEncoding] + 1;
if (len > 1000000) return strdup([strtemp UTF8String]);
char cStr [len];
[strtemp getCString:cStr maxLength:len encoding:NSUTF8StringEncoding];
return strdup(cStr);
}

`
crash信息:Thread 1: EXC_BAD_ACCESS (code=1, address=0x16f5b0bf0)

当栈被占用很多的时候,
[strtemp getCString:cStr maxLength:len encoding:NSUTF8StringEncoding];
这行代码会造成坏内存访问,可能是StackOverflow了

如何知道每一个log是否上传成功呢?

只有初始化client的时候有一个on_log_producer_send_done_function的回调,在这个回调里也无法区分是哪一个log,
请问如何知道每一个log是否上传成功呢?

LogClient初始化bug

现象:LogClient使用便利方法生成对象和使用初始化方法生成对象,进行postLog时结果不同。通过便利方法生成的对象进行postLog时,请求回报错。

初步判断:LogClient的便利构造方法的token在初始化的时候会解包为空字符串而不是nil~
但在postLog方法中拼接header的时候,token的拼接是对token参数判空而不是判断字符串长度。最终导致了请求header中的字段不对。

沙盒里找不到对应的sqlite文件。

请问,2.2.4版本
LogProducerResult res = [client AddLog:log flush:0];
NSLog(@"res %ld", res);
打印为res 0,
但是在沙盒里 找不到对应的sqlite文件。只有 .idx 和_000 结尾的两个文件。
请问哪里出错了吗?
还是不会生成sqlite文件?
是按照介绍里,初始化的SDK和config。

swift 3 完全编不过

完全编不过呀,为何这样的代码还打了 release 了。完全是半残品啊。

Is Api Frozen?

The documents I saw this morning and evening are totally different.

So I wonder whether the api has been frozen or will change in the future?

I hope it could comply with the rule of semver

dyld: Library not loaded: @rpath/libswiftCore.dylib

XCode 10.0
OC代码集成报错dyld: Library not loaded: @rpath/libswiftCore.dylib
已按照要求确保General--Embedded Binaries中含有AliyunLOGiOS.framework以及依赖的FMDB.framework
确保Build Settings--Search Paths--Framework Search Paths中有AliyunLOGiOS.framework,FMDB.framework的文件路径
可以编译成功,运行起来就报错

value传字典crash

NSMutableDictionary *dic = [log getContent];
[dic setValue:@{@"cookie_id":@"",@"session_id":@"",@"uid":[UserService sharedService].userId} forKey:@"user"];

crash

2022-06-08 14:53:55.447649+0800xxx[10434:6860520] -[__NSDictionaryI lengthOfBytesUsingEncoding:]: unrecognized selector sent to instance 0x60000067ad00

如何修改Topic的值呢?

你好,请教个问题:项目中需要上传多个埋点(topic),看代码里topic是通过LogProducerConfig实例对象设置的,那岂不是一个topic对应一个client对象了?那有100个topic就需要创建100个不同的client对象保存在一个Dictionary里,这个内存会不会太大了,有什么建议吗?

AliyunLogProducer -[LogProducerClient AddLog:flush:] + 456 偶先 Crash

image

您好 我目前遇到的问题是 AddLog的时候崩溃,目前崩溃率还挺高,猜测的原因是目前业务覆盖多个国家,Client存在切换国家 再次new赋值情况,是否需要保持多个client 还是一个来回切换赋值,使用DestroyLogProducer 方法先释放掉。
还有就是 [_logClient DestroyLogProducer]; 也会偶发Crash

发送日志报401错误,签名错误

版本号:sls-ios-sdk_v2.2.8
问题描述:发送日志失败,返回结果401,提示签名错误
hmac-sha.c文件中的hmac_sha1 函数出现问题,任何输入数据,
签名出来的数据hmac-sha1均为:\345m\241�}*F\306�$\213M\200|\355�Oe\246!R
base64后的结果为 5W2hFn0qRsYIJItNgHztEk9lpiE=
很令人费解,不知道是否是签名算法出现问题还是和别的函数、变量等有冲突。
敬请解答。

https

上传日志并没有使用https
LogClient.swift 75行

convertToChar: 字符串超500000崩溃问题

我们在测试过程发现一旦字符串超过500000就会蹦在这个方法里面,我们尝试的做法是把1000000改为500000就OK了,
-(char*)convertToChar:(NSString*)strtemp
{
NSUInteger len = [strtemp lengthOfBytesUsingEncoding:NSUTF8StringEncoding] + 1;
if (len > 500000) return strdup([strtemp UTF8String]);
char cStr [len];
[strtemp getCString:cStr maxLength:len encoding:NSUTF8StringEncoding];
return strdup(cStr);
}
这里的getCString是什么作用,能否修复一下?或者提供一个好的解决方案?谢谢

埋点报错

(lldb) po response
<NSHTTPURLResponse: 0x2838542a0> { URL: https://trace-logs.log-global.aliyuncs.com/logstores/prd-mobile/shards/lb } { Status Code: 400, Headers {
"Access-Control-Allow-Origin" = (
""
);
"Content-Length" = (
65
);
"Content-Type" = (
"application/json"
);
Date = (
"Fri, 15 Mar 2019 05:52:54 GMT"
);
Server = (
Tengine
);
Via = (
"cache13.l2nu20-1[44,0], cache7.cn1221[46,0]"
);
eagleid = (
77a7fa9b15526291743487054e
);
"timing-allow-origin" = (
"
"
);
"x-alicdn-da-ups-status" = (
"endOs,0,400"
);
"x-log-requestid" = (
5C8B3DB60216E61CF0E52807
);
} }

(lldb) po error
nil
(lldb)

日志重复上传多条 且 内容不对

版本:2.2.6
描述:开启断点续传功能后(SetPersistent:1),发现一个相同的topic被重复上传了多条,且对应的内容不是该topic存放的内容

下面为Xcode打印的日志:
image
下面为阿里云日志平台显示的结果:
image

如果关闭断点续传功能,
image
image

下面是代码截图:
上传日志方法只调用了一次
image

HTTPS 请求报错

error = Optional(Error Domain=NSURLErrorDomain Code=-1202 "The certificate for this server is invalid. You might be connecting to a server that is pretending to be “****-hangzhou.sls.aliyuncs.com” which could put your confidential information at risk." UserInfo={NSURLErrorFailingURLPeerTrustErrorKey=<SecTrustRef: 0x6000029d2760>, NSLocalizedRecoverySuggestion=Would you like to connect to the server anyway?, _kCFStreamErrorDomainKey=3, _kCFStreamErrorCodeKey=-9843, NSErrorPeerCertificateChainKey=(
"<cert(0x7f92c3055a00) s: .log.aliyuncs.com i: GlobalSign Organization Validation CA - SHA256 - G2>",
"<cert(0x7f92c2854000) s: GlobalSign Organization Validation CA - SHA256 - G2 i: GlobalSign Root CA>"
), NSUnderlyingError=0x6000015b42a0 {Error Domain=kCFErrorDomainCFNetwork Code=-1202 "(null)" UserInfo={_kCFStreamPropertySSLClientCertificateState=0, kCFStreamPropertySSLPeerTrust=<SecTrustRef: 0x6000029d2760>, _kCFNetwork36
36
3D
CFStreamSSLErrorOriginalValue=-9843, _kCFStreamErrorDomainKey=3, _kCFStreamErrorCodeKey=-9843, kCFStreamPropertySSLPeerCertificates=(
"<cert(0x7f92c3055a00) s: .log.aliyuncs.com i: GlobalSign Organization Validation CA - SHA256 - G2>",
"<cert(0x7f92c2854000) s: GlobalSign Organization Validation CA - SHA256 - G2 i: GlobalSign Root CA>"
)}}, NSLocalizedDescription=The certificate for this server is invalid. You might be connecting to a server that is pretending to be “
-hangzhou.sls.aliyuncs.com” which could put your confidential information at risk., NSErrorFailingURLKey=https://-hangzhou.sls.aliyuncs.com/logstores//shards/lb, NSErrorFailingURLStringKey=https://-hangzhou.sls.aliyuncs.com/logstores/*/shards/lb, NSErrorClientCertificateStateKey=0})

旧版本获取版本号

请问通过Framework的方式引用了旧版本SDK,是否提供了API获取该版本号,已尝试通过TCData sdk_version属性获取,不能获取版本号。

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.