天天看點

精通日志查詢: 如何翻頁擷取日志和計算結果精通日志查詢: 如何翻頁擷取日志和計算結果查詢翻頁使用案例

精通日志查詢: 如何翻頁擷取日志和計算結果

日志服務提供一站式的日志采集、存儲、查詢、計算功能。互動式的日志采集體驗,釋放使用者的運維壓力,解放使用者的雙手; 互動式的查詢分析體驗,讓使用者自由的建構資料模型、探索式分析挖掘資料深層。

精通日志查詢: 如何翻頁擷取日志和計算結果精通日志查詢: 如何翻頁擷取日志和計算結果查詢翻頁使用案例

使用者使用日志服務的查詢分析能力,不僅可以在控制台互動式查詢,也可以使用SDK,在程式中使用查詢分析。 當計算結果比較大時,怎麼把全量結果讀取到本地,是一個比較比較頭疼的問題。幸好,日志服務提供了翻頁的功能,不僅可以翻頁讀取原始日志内容,也可以把SQL的計算結果翻頁讀取到本地。開發者可以通過日志服務提供的SDK,或者Cli,通過讀資料接口翻頁讀取日志。

查詢和分析使用不同的分頁方式

精通日志查詢: 如何翻頁擷取日志和計算結果精通日志查詢: 如何翻頁擷取日志和計算結果查詢翻頁使用案例

日志服務提供一個統一的查詢日志入口:GetLogstoreLogs,既可以根據關鍵字查詢日志原始内容,也可以送出SQL計算,擷取計算結果。

查詢翻頁使用案例

在GetLogStoreLogs api中,包含offset和lines兩個參數

  • 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 翻頁讀取樣例

更詳細案例參考

文檔

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()  # 這裡處理結果           

Java 翻頁讀取樣例

更詳細的案例參考

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分析結果翻頁讀取

在SQL分析中,GetLogStoreLogs API 參數中的offset 和lines是無效的,填寫。也就是說,如果按照上文翻頁讀取原始内容的方式,周遊offset翻頁,那麼每次SQL執行的結果都是一樣的。理論上,我們可以在一次調用中,擷取全部的計算結果,但是如果結果集太大,可能會産生以下問題:

  • 網絡上傳輸大量資料延時比較高。
  • 用戶端的記憶體要儲存大量的結果,供進一步處理。

為了解決SQL翻頁的問題,我們提供了标準SQL的limit翻頁文法

limit Offset, Line           
  • Offset表示從第幾行開始讀取結果
  • Line表示讀取多少行,Line沒有大小限制;但是如果一次讀取太多,會影響網絡延時和用戶端的處理。

一個典型案例,假如以下SQL共産生2000條日志

* | 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           

SQL翻頁樣例

在程式中,SQL翻頁的僞代碼這樣寫:

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行           

Python程式樣例:

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()  # 這裡處理結果           

Java程式樣例:

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;
            }
            
        }
                   
精通日志查詢: 如何翻頁擷取日志和計算結果精通日志查詢: 如何翻頁擷取日志和計算結果查詢翻頁使用案例

延伸資料

日志服務使用者手冊,最完整的資料 日志服分析Demo,Nginx日志、CDN日志、DDOS日志、SLB日志Demo,grafana、Datav大屏Demo 5分鐘搭建網站實時分析:Grafana+日志服務實戰