全部产品
Search
文档中心

日志服务:分页显示查询分析结果

更新时间:Sep 03, 2024

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

分页方式

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

  • 查询语句:使用关键字查询,获取原始日志内容。您可以通过GetLogs API中的offsetline参数实现分页。更多信息,请参见查询概述

  • 分析语句:使用SQL对查询结果进行分析,获取统计结果。您可以通过SQL中的LIMIT语法实现分页。更多信息,请参见分析概述LIMIT子句

查询结果分页

GetLogs API中的offsetline参数说明如下:

  • offset:指定从某一行开始读取查询结果。

  • line:指定当前请求读取的行数,最大值为100。如果大于100,则仍然返回100行。

在分页读取时,不停地增大offset的值,直到读取到某个offset值后,获取的结果行数为0,并且结果的progress为complete状态,则表示读取了所有数据。

  • 分页的示例代码逻辑

    offset = 0                           #从第0行开始读取。
    line = 100                          #每次读取100行。
    query = "status:200"                 #查询status字段是200的所有日志。
    while True:
         response = get_logstore_logs(query, offset, line) #执行读取请求。
         process (response)                                 #调用自定义逻辑,处理返回结果。
         如果 response.get_count() == 0 && response.is_complete()   
             则读取结束,跳出当前循环
         否则
            offset += 100                          # offset增加到100,读取下一个100行。
  • Python代码示例

    更多信息,请参见Python SDK概述

    # 日志服务的服务接入点。
    endpoint = '' 
    # 本示例从环境变量中获取AccessKey ID和AccessKey Secret。
    accessKeyId = os.environ.get('ALIBABA_CLOUD_ACCESS_KEY_ID', '')
    accessKey = os.environ.get('ALIBABA_CLOUD_ACCESS_KEY_SECRET', '')
    # Project名称。
    project = ''     
    # Logstore名称。
    logstore = ''  
    client = LogClient(endpoint, accessKeyId, accessKey)
    topic = ""
    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=topic, line=log_line, offset=offset)
            res4 = client.get_logs(req4)
            if res4 is not None and res4.is_completed():
                break
            time.sleep(1)
         offset += 100 
         if res4.is_completed() and res4.get_count() == 0:
             break;
         if res4 is not None:
             # 处理结果。
            res4.log_print() 
  • Java示例

    更多信息,请参见Java SDK概述

    int log_offset = 0;
    int log_line = 100;   //log_line的最大值为100,每次获取100行数据。若需要读取更多数据,请使用offset分页。offset和line只对关键字查询有效,若使用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:指定从某一行开始读取分析结果。

  • line:指定当前请求读取的行数,最大值为1,000,000。如果一次读取太多,会影响网络延时和客户端的处理速度。

例如,通过* | select count(1) , url group by url 语句进行查询分析,指定返回2000行日志。您可以通过分页指定每次读取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行开始读取。
    line = 500    //每次读取500行。
    query = "* | select count(1) , url  group by url  limit "
    while True:
    real_query = query + offset + "," +  line
    response = get_logstore_logs(real_query) //执行读取请求。
    process (response)                       //调用自定义逻辑,处理返回的结果。
    如果 response.get_count() == 0   
        则读取结束,跳出当前循环
    否则
        offset += 500                        //offset增加到500,读取下一个500行。
  • Python代码示例

    更多信息,请参见Python SDK概述

    # 日志服务的服务接入点
    endpoint = '' 
    # 本示例从环境变量中获取AccessKey ID和AccessKey Secret。
    accessKeyId = os.environ.get('ALIBABA_CLOUD_ACCESS_KEY_ID', '')
    accessKey = os.environ.get('ALIBABA_CLOUD_ACCESS_KEY_SECRET', '')
    # Project名称。
    project = ''     
    # Logstore名称。
    logstore = ''  
    client = LogClient(endpoint, accessKeyId, accessKey)
    topic = ""
    origin_query = "* | select *  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=topic, query=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() and res4.get_count() == 0:
            break;
        if res4 is not None:
        # 处理结果。
            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;
                }
    }