全部產品
Search
文件中心

Simple Log Service:分頁顯示查詢分析結果

更新時間:Jun 30, 2024

查詢分析日誌時,查詢分析結果內容過多會影響顯示速度和查詢體驗。Log Service提供分頁功能,可控制每次返回的日誌數量。本文介紹查詢結果和分析結果的分頁方法。

分頁方式

Log Service查詢和分析功能支援在查詢分析語句中同時實現關鍵字查詢和查詢結果的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概述

    # Log Service的服務存取點。
    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概述

    # Log Service的服務存取點
    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;
                }
    }