查询分析日志时,查询分析结果内容过多会影响显示速度和查询体验。日志服务提供分页功能,可控制每次返回的日志数量。本文介绍查询结果和分析结果的分页方法。

分页方式

日志服务查询和分析功能支持在查询分析语句中同时实现关键字查询和查询结果的SQL分析。您可以调用GetLogs API,根据关键字查询日志原始内容,也可以进行查询结果的SQL计算,获取分析结果。查询结果和分析结果使用不同的分页方法。
  • 查询语句:使用关键字查询,获取原始日志内容。您可以通过GetLogstoreLogs API中的offsetlines参数实现分页。
  • 分析语句:使用SQL对查询结果进行分析,获取统计结果。您可以通过SQL中的LIMIT语法实现分页。更多信息,请参见LIMIT语法

查询结果分页

GetLogstoreLogs API中的offsetlines参数说明如下:
  • offset:指定从某一行开始读取查询结果。
  • lines:指定当前请求读取的行数,最大值为100。如果大于100,则仍然返回100行。

在分页读取时,不停地增大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行。
  • Python代码示例
    更多信息,请参见Python SDK
        endpoint = ''      //日志服务的域名。更多信息,请参见服务入口。
        accessKeyId = ''   //阿里云访问密钥AccessKey ID。更多信息,请参见访问密钥。阿里云主账号AccessKey拥有所有API的访问权限,风险很高。强烈建议您创建并使用RAM账号进行API访问或日常运维。
        accessKey = ''     //阿里云访问密钥AccessKey Secret。
        project = ''       //Project项目名称。
        logstore = ''      //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 = Nonefor 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 isnotNoneand res4.is_completed():
                    break
                time.sleep(1)
            offset += 100if res4.is_completed() && res4.get_count() == 0:
                  break;
            if res4 isnotNone:
                res4.   log_print()  //处理结果。
  • Java示例

    更多信息,请参见Java SDK

            int log_offset = 0;
            int log_line = 100;   //log_line的最大值为100,每次获取100行数据。若需要读取更多数据,请使用offset分页。offset和lines只对关键字查询有效,若使用SQL查询,则无效。在SQL查询中返回更多数据,请使用limit语法。
            while (true) {
                GetLogsResponse res4 = null;
                //对于每个Offset,一次读取100行日志,如果读取失败,最多重复读取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中的Limit语法实现分析结果分析显示,示例如下所示:
limit Offset, Line

参数说明如下所示:

  • offset:指定从某一行开始读取分析结果。
  • lines:指定当前请求读取的行数,无大小限制,但是如果一次读取太多,会影响网络延时和客户端的处理速度。

例如,通过* | selectcount(1) , url group by url 语句进行查询分析,指定返回2000条日志。您可以通过分页指定每次读取500行,共4次读取完成,示例如下:

* | selectcount(1) , url  group by url  limit 0, 500
* | selectcount(1) , url  group by url  limit 500, 500
* | selectcount(1) , url  group by url  limit 1000, 500
* | selectcount(1) , url  group by url  limit 1500, 500
  • 分析结果分页的示例代码
        offset = 0     //从第0行开始读取。
        lines = 500    //每次读取500行。
        query = "* | select count(1) , url  group by url  limit "whileTrue:
        real_query = query + offset + "," +  lines
        response = get_logstore_logs(real_query) //执行读取请求。
        process (response)                       //调用自定义逻辑,处理返回的结果。
        如果 response.get_count() == 0   
             则读取结束,跳出当前循环
        否则
            offset += 500                        //offset增加到500,读取下一个500行。
  • Python代码示例

    更多信息,请参见Python SDK

        endpoint = ''      //日志服务的域名。更多信息,请参见服务入口。 
        accessKeyId = ''   //阿里云访问密钥AccessKey ID。更多信息,请参见访问密钥。阿里云主账号AccessKey拥有所有API的访问权限,风险很高。强烈建议您创建并使用RAM账号进行API访问或日常运维。
        accessKey = ''     //阿里云访问密钥AccessKey Secret。
        project = ''       //Project名称。
        logstore = ''      //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 isnotNoneand res4.is_completed():
                    break
                time.sleep(1)
            offset += 100if res4.is_completed() && res4.get_count() == 0:
                  break;
            if res4 isnotNone:
                res4.log_print()  //处理结果。
  • Java代码示例

    更多信息,请参见Java SDK

            int log_offset = 0;
            int log_line = 500;
            String origin_query = "* | select count(1) , url  group by url  limit "while (true) {
                GetLogsResponse res4 = null;
                //对于每个Offset,一次读取500行日志。如果读取失败,最多重复读取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;
                }
    
            }