本文共 6094 字,大约阅读时间需要 20 分钟。
日志服务提供一站式的日志采集、存储、查询、计算功能。交互式的日志采集体验,释放用户的运维压力,解放用户的双手; 交互式的查询分析体验,让用户自由的构建数据模型、探索式分析挖掘数据深层。
用户使用日志服务的查询分析能力,不仅可以在控制台交互式查询,也可以使用SDK,在程序中使用查询分析。 当计算结果比较大时,怎么把全量结果读取到本地,是一个比较比较头疼的问题。幸好,日志服务提供了翻页的功能,不仅可以翻页读取原始日志内容,也可以把SQL的计算结果翻页读取到本地。开发者可以通过日志服务提供的SDK,或者Cli,通过读数据接口翻页读取日志。
日志服务提供一个统一的查询日志入口:GetLogstoreLogs,既可以根据关键字查询日志原始内容,也可以提交SQL计算,获取计算结果。
在翻页读取时,不停的增大offset,知道读取到某个offset后,获取的结果行数为0,并且结果的progress为complete状态,则认为读取到了全部数据,可以结束了。
offset = 0 // 从第0行开始读取lines = 100 //每次读取100行query = "status:200" //查询status字段包含200的所有日志while True: response = get_logstore_logs(query, offset, lines) // 执行读取请求 process (response) //调用自定义逻辑,处理返回的结果 如果 response.get_count() == 0 && response.is_complete() 则读取结束,跳出当前循环 否则 offset += 100 offset增加100,读取下一个100行
更详细案例参考:
endpoint = '' # 选择与上面步骤创建Project所属区域匹配的Endpoint accessKeyId = '' # 使用您的阿里云访问密钥AccessKeyId accessKey = '' # 使用您的阿里云访问密钥AccessKeySecret project = '' # 上面步骤创建的项目名称 logstore = '' # 上面步骤创建的日志库名称 client = LogClient(endpoint, accessKeyId, accessKey) topic = "" query = "index" From = int(time.time()) - 600 To = int(time.time()) log_line = 100 offset = 0 while True: res4 = None for retry_time in range(0, 3): req4 = GetLogsRequest(project, logstore, From, To, topic, query, log_line, offset, False) res4 = client.get_logs(req4) if res4 is not None and res4.is_completed(): break time.sleep(1) offset += 100 if res4.is_completed() && res4.get_count() == 0: break; if res4 is not None: res4.log_print() # 这里处理结果
更详细的案例参考
int log_offset = 0; int log_line = 100;//log_line 最大值为100,每次获取100行数据。若需要读取更多数据,请使用offset翻页。offset和lines只对关键字查询有效,若使用SQL查询,则无效。在SQL查询中返回更多数据,请使用limit语法。 while (true) { GetLogsResponse res4 = null; // 对于每个 log offset,一次读取 10 行 log,如果读取失败,最多重复读取 3 次。 for (int retry_time = 0; retry_time < 3; retry_time++) { GetLogsRequest req4 = new GetLogsRequest(project, logstore, from, to, topic, query, log_offset, log_line, false); res4 = client.GetLogs(req4); if (res4 != null && res4.IsCompleted()) { break; } Thread.sleep(200); } System.out.println("Read log count:" + String.valueOf(res4.GetCount())); log_offset += log_line; if (res4.IsCompleted() && res4.GetCount() == 0) { break; } }
在SQL分析中,GetLogStoreLogs API 参数中的offset 和lines是无效的,填写。也就是说,如果按照上文翻页读取原始内容的方式,遍历offset翻页,那么每次SQL执行的结果都是一样的。理论上,我们可以在一次调用中,获取全部的计算结果,但是如果结果集太大,可能会产生以下问题:
limit Offset, Line
* | select count(1) , url group by url
那么可以翻页,每次读取500行,共4次读取完成:
* | select count(1) , url group by url limit 0, 500* | select count(1) , url group by url limit 500, 500* | select count(1) , url group by url limit 1000, 500* | select count(1) , url group by url limit 1500, 500
offset = 0 // 从第0行开始读取lines = 500 //每次读取500行query = "* | select count(1) , url group by url limit " while True: real_query = query + offset + "," + lines response = get_logstore_logs(real_query) // 执行读取请求 process (response) //调用自定义逻辑,处理返回的结果 如果 response.get_count() == 0 则读取结束,跳出当前循环 否则 offset += 500 offset增加100,读取下一个500行
endpoint = '' # 选择与上面步骤创建Project所属区域匹配的Endpoint accessKeyId = '' # 使用您的阿里云访问密钥AccessKeyId accessKey = '' # 使用您的阿里云访问密钥AccessKeySecret project = '' # 上面步骤创建的项目名称 logstore = '' # 上面步骤创建的日志库名称 client = LogClient(endpoint, accessKeyId, accessKey) topic = "" origin_query = "* | select count(1) , url group by url limit " From = int(time.time()) - 600 To = int(time.time()) log_line = 100 offset = 0 while True: res4 = None query = origin_query + str(offset) + " , " + str(log_line) for retry_time in range(0, 3): req4 = GetLogsRequest(project, logstore, From, To, topic, query) res4 = client.get_logs(req4) if res4 is not None and res4.is_completed(): break time.sleep(1) offset += 100 if res4.is_completed() && res4.get_count() == 0: break; if res4 is not None: res4.log_print() # 这里处理结果
int log_offset = 0; int log_line = 500; String origin_query = "* | select count(1) , url group by url limit " while (true) { GetLogsResponse res4 = null; // 对于每个 log offset,一次读取 500 行 log,如果读取失败,最多重复读取 3 次。 query = origin_query + log_offset + "," + log_line; for (int retry_time = 0; retry_time < 3; retry_time++) { GetLogsRequest req4 = new GetLogsRequest(project, logstore, from, to, topic, query); res4 = client.GetLogs(req4); if (res4 != null && res4.IsCompleted()) { break; } Thread.sleep(200); } System.out.println("Read log count:" + String.valueOf(res4.GetCount())); log_offset += log_line; if (res4.GetCount() == 0) { break; } }
转载地址:http://eghbm.baihongyu.com/