全部產品
Search
文件中心

Simple Log Service:快速入門:接入Log ServiceSDK上報日誌並分析

更新時間:Aug 27, 2025

Log ServiceSDK支援通過介面手動上傳日誌。本文介紹使用Python語言SDK上報日誌至Logstore,結合控制台進行可視化分析、配置日誌異常警示等步驟,協助您快速上手使用Log Service。

前提條件

  • 已有可用的ECS。更多資訊,請參見Elastic Compute Service快速入門

  • 已開通Log Service。具體操作,請參見開通Log Service

  • 已安裝Python和Python開發環境(例如PyCharm)。

    Log ServicePython SDK支援以下Python版本。

    • Python2:2.7及以上版本。

    • Python3:3.7及以上版本。

    • Pypy2:2.7及以上版本。

    • Pypy3:3.7及以上版本。

方案概覽

閱讀本文您可以學習:

  • 建立Project(資源嵌入式管理單元)和Logstore(日誌儲存單元)。

  • 使用Python SDK上傳日誌到Logstore進行儲存、建立索引以及查詢和分析。

  • 將分析結果通過儀錶盤轉換為可視化圖形。

  • 通過配置警示規則實現警示監控。

  • 如何清理不再需要的資源以免產生額外費用。

1. 建立Project和Logstore

1.1 建立Project

登入Log Service控制台在Project列表地區,單擊建立Project,在建立Project面板中,選擇所屬地區,輸入Project名稱。本文以華東1(杭州)地區,名稱為aliyun-test-project的Project為例,其餘參數保持預設。

image

1.2 建立Logstore

建立Project完成後,系統會提示您建立一個Logstore。在Logstore面板中,輸入Logstore名稱,其餘參數保持預設。

image

2. 安裝SDK

  1. 在命令列工具中,以管理員身份執行如下命令安裝Python SDK。更多版本資訊,請參見Aliyun Log Python Release

    pip install -U aliyun-log-python-sdk
  2. 安裝SDK後,執行以下命令,驗證已安裝的Log Service Python SDK。

    pip show aliyun-log-python-sdk

    返回以下資訊,代表安裝成功。

    Name: aliyun-log-python-sdk
    Version: 0.9.12
    Summary: Aliyun log service Python client SDK
    Home-page: https://github.com/aliyun/aliyun-log-python-sdk
    Author: Aliyun

3. 初始化用戶端

LogClient是Log Service的用戶端,提供建立Project和Logstore、寫入日誌、讀取日誌等一系列方法。使用AK初始化(V1簽名)方法需要以下步驟:

  1. 擷取AccessKey:在阿里雲控制台建立AccessKey,擷取access_key_idaccess_key_secret

  2. 配置環境變數:根據作業系統(Linux/macOS/Windows)將密鑰配置為環境變數(例如ALIBABA_CLOUD_ACCESS_KEY_IDALIBABA_CLOUD_ACCESS_KEY_SECRET)。

  3. 設定Endpoint:本文以華東1(杭州)地區為例,endpoint配置為 cn-hangzhou.log.aliyuncs.com(其他地區需替換為對應的Endpoint)。

# 引入sls包。
from aliyun.log import *

# 通過環境變數擷取AccessKey時需要引入。
import os

# 從環境變數中擷取 AccessKey ID 和 AccessKey Secret
access_key_id = os.environ.get('ALIBABA_CLOUD_ACCESS_KEY_ID', '')
access_key_secret = os.environ.get('ALIBABA_CLOUD_ACCESS_KEY_SECRET', '')

# Log Service的服務存取點
endpoint = "cn-hangzhou.log.aliyuncs.com"

# 建立 LogClient 執行個體
client = LogClient(endpoint, access_key_id, access_key_secret)

4. 上報日誌

本樣本中,通過調用put_logs介面主動上報日誌資料。原始日誌如下:

10.0.*.1 - - [14/Jul/2025:12:00:03 +0000] "POST /login HTTP/1.1" 302 0 "http://example.com/login.html" "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/100.0.4896.88 Safari/537.36"  

通過put_logs介面上傳時,為了方便後續分析日誌,建議您按欄位設定日誌內容並上傳。

# Project名稱。
project_name = "aliyun-test-project"
# Logstore名稱
logstore_name = "aliyun-test-logstore"

# 向Logstore寫入資料。
def put_logs():
    print("ready to put logs for %s" % logstore_name)
    log_group = []
    for i in range(0, 100):
        log_item = LogItem()
        # 按欄位設定日誌內容
        contents = [
            ('remote_addr', '192.168.0.%d' % (i % 255)),
            ('remote_user', 'user%d' % i),
            ('time_local', time.strftime('%d/%b/%Y:%H:%M:%S +0000', time.gmtime())),
            ('request_method', 'GET' if i % 2 == 0 else 'POST'),
            ('request_uri', '/index.html' if i % 3 == 0 else '/api/data'),
            ('status', str(200 + (i % 100))),  # 狀態代碼在200-299之間
            ('body_bytes_sent', str(1024 + i)),
            ('http_referer', 'http://example.com/page%d' % (i // 10)),
            ('http_user_agent',
             'Mozilla/5.0 AppleWebKit/537.36 (KHTML, like Gecko) Chrome/90.0.%d Safari/537.36' % (i * 10))
        ]
        log_item.set_contents(contents)
        log_group.append(log_item)
    request = PutLogsRequest(project_name, logstore_name, "", "", log_group, compress=False)
    client.put_logs(request)
    print("put logs for %s success " % logstore_name)
    time.sleep(60)

5. 建立索引

上傳的日誌需要配置索引才能進行查詢。設定remote_addrremote_usertime_localrequest_methodrequest_uristatusbody_bytes_senthttp_refererhttp_user_agent作為索引欄位。

# Project名稱。
project_name = "aliyun-test-project"
# Logstore名稱
logstore_name = "aliyun-test-logstore"
# 索引。
logstore_index = {'line': {
    'token': [',', ' ', "'", '"', ';', '=', '(', ')', '[', ']', '{', '}', '?', '@', '&', '<', '>', '/', ':', '\n', '\t',
              '\r'], 'caseSensitive': False, 'chn': False},
    'keys': {'remote_addr': {'type': 'text', 'token': [',', ' ', "'", '"', ';', '=', '(', ')', '[', ']', '{', '}', '?', '@', '&', '<', '>', '/', ':', '\n', '\t', '\r'], 'caseSensitive': False, 'alias': 'remote_addr', 'doc_value': True, 'chn': False},
            'remote_user': {'type': 'text', 'token': [',', ' ', "'", '"', ';', '=', '(', ')', '[', ']', '{', '}', '?', '@', '&', '<', '>', '/', ':', '\n', '\t', '\r'], 'caseSensitive': False, 'alias': 'remote_user', 'doc_value': True, 'chn': False},
            'time_local': {'type': 'text', 'token': [',', ' ', "'", '"', ';', '=', '(', ')', '[', ']', '{', '}', '?', '@', '&', '<', '>', '/', ':', '\n', '\t', '\r'], 'caseSensitive': False, 'alias': 'time_local', 'doc_value': True, 'chn': False},
            'request_method': {'type': 'text', 'token': [',', ' ', "'", '"', ';', '=', '(', ')', '[', ']', '{', '}', '?', '@', '&', '<', '>', '/', ':', '\n', '\t', '\r'], 'caseSensitive': False, 'alias': 'request_method', 'doc_value': True, 'chn': False},
            'request_uri': {'type': 'text', 'token': [',', ' ', "'", '"', ';', '=', '(', ')', '[', ']', '{', '}', '?', '@', '&', '<', '>', '/', ':', '\n', '\t', '\r'], 'caseSensitive': False, 'alias': 'request_uri', 'doc_value': True, 'chn': False},
            'status': {'type': 'long', 'alias': 'status', 'doc_value': True},
            'body_bytes_sent': {'type': 'long', 'alias': 'body_bytes_sent', 'doc_value': True},
            'http_referer': {'type': 'text', 'token': [',', ' ', "'", '"', ';', '=', '(', ')', '[', ']', '{', '}', '?', '@', '&', '<', '>', '/', ':', '\n', '\t', '\r'], 'caseSensitive': False, 'alias': 'http_referer', 'doc_value': True, 'chn': False},
            'http_user_agent': {'type': 'text', 'token': [',', ' ', "'", '"', ';', '=', '(', ')', '[', ']', '{', '}', '?', '@', '&', '<', '>', '/', ':', '\n', '\t', '\r'], 'caseSensitive': False, 'alias': 'http_user_agent', 'doc_value': True, 'chn': False}}}

# 建立索引。
def create_index():
    print("ready to create index for %s" % logstore_name)
    index_config = IndexConfig()
    index_config.from_json(logstore_index)
    client.create_index(project_name, logstore_name, index_config)
    print("create index for %s success " % logstore_name)
    time.sleep(60 * 2)

索引建立成功之後,查詢日誌結果如下:

image

6. 查詢與分析日誌

手動上報日誌,保證有新日誌產生。配置*| select request_method,status from aliyun-test-logstore查詢分析語句來檢索日誌。查詢與分析功能,請參考索引模式查詢與分析進行學習。

# Project名稱。
project_name = "aliyun-test-project"
# Logstore名稱
logstore_name = "aliyun-test-logstore"
# 查詢語句。
query = "*| select request_method,status from " + logstore_name
# from_time和to_time表示查詢日誌的時間範圍,Unix時間戳記格式。
from_time = int(time.time()) - 3600
to_time = time.time() + 3600

# 通過SQL查詢日誌。
def get_logs():
    print("ready to query logs from logstore %s" % logstore_name)
    request = GetLogsRequest(project_name, logstore_name, from_time, to_time, query=query)
    response = client.get_logs(request)
    for log in response.get_logs():
        for k, v in log.contents.items():
            print("%s : %s" % (k, v))
        print("*********************")

響應結果如下:

ready to query logs from logstore aliyun-test-logstore
request_method : GET
status : 200
*********************
request_method : POST
status : 201
*********************
request_method : GET
status : 202
*********************
request_method : POST
status : 203
*********************
Process finished with exit code 0

7. 儀錶盤可視化資料

  1. 在Project頁面左側導覽列中找到儀錶盤下的儀錶盤列表,單擊添加儀錶盤

    image

  2. 添加到儀錶盤對話方塊,選擇您希望的儀錶盤配置模式,預設使用網格布局,填寫儀錶盤名稱後單擊確認

    image

  3. 在新產生的儀錶盤中點擊添加新圖表後進入圖表建立頁面。

    image

  4. 在編輯圖表頁面中,左下角查詢分析面板處下拉選擇Logstore(SQL),然後下拉選擇對應的Logstore,輸入* | SELECT request_method,status,COUNT(*) AS request_count GROUP BY request_method,status ORDER BY request_count DESC LIMIT 10;,表示統計某段時間內各方法和狀態代碼的請求次數(TOP 10)。由於樣本是統計欄位,因此在右側圖表類型中選擇表格Pro,然後點擊應用,即可展現下圖效果。如果視覺效果符合預期,單擊確定,然後在儀錶盤頁面中單擊右上方的儲存。儀錶盤支援多種圖表類型,支援資料篩選過濾與對接第三方工具,更多使用請參考可視化概述學習。

    image

8. 警示與監控

8.1 建立行動策略

  1. 在Project左側導覽列中找到警示,單擊通知策略 > 行動策略下的建立

    image

  2. 添加行動策略彈框,建立一個標識符test-action-policy名稱新警示規則-我的行動策略test的警示策略,當警示觸發時,使用DingTalk通知,行動組具體配置如下:

    • 渠道:通過DingTalk-自訂進行警示。

    • 請求地址:設定具體的DingTalk機器人Webhook,比如https://oapi.dingtalk.com/robot/send?access_token=4dff******6bfe

    • 提醒方式:DingTalk群收到警示時不提醒使用者。

    • 內容範本:警示內容通過SLS內建內容範本進行展示。

    • 發送時段任意時間段發生警示通知。

    image

Log Service提供系統管理使用者、系統管理使用者組、管理Webhook整合、管理行動策略、管理警示策略和管理內容範本SDK介面,更多資訊,請參見管理警示資源資料

8.2 建立警示規則

  1. 在Project左側導覽列中找到警示,單擊警示規則下的建立警示

    image

  2. 在建立警示頁面,配置警示規則。當Log Service監測到有資料時,每隔15分鐘觸發DingTalk警示通知,具體配置如下:

    • 規則名稱新警示規則

    • 檢查頻率固定間隔15分鐘

    • 查詢統計

      • 類型日誌庫

      • 地區華東1(杭州)

      • 專案aliyun-test-project

      • 日誌庫aliyun-test-logstore

      • 查詢語句* | select *

      • 查詢區間今天

    • 分組評估不分組

    • 觸發條件:當有資料時,嚴重度的警示資訊。

    • 添加標註:key分別為titledesc,描述均為${alert_name}警示觸發

    • 輸出目標:SLS通知,行動策略配置為建立的test-action-policy

    image

  3. 單擊建立的警示規則,在警示歷史地區中發現警示資訊如下。在儀錶盤可視化中統計資料是5,但是警示配置後第一次並未觸發,手動在access.log中添加兩條背景資訊中的日誌範例後,統計資料為7並觸發了警示。原因是檢查頻率與查詢統計的查詢區間均設定15分鐘,造成只有增量日誌時才觸發警示的表象,您可以通過修改時間範圍調整。如果您想深入瞭解警示功能,請參考警示概述以及快速設定日誌警示進行學習。image

9. 刪除日誌資源

在您完成以上快速入門教程後,此時您可能不再需要新手教程中建立的資源,但保留這些資源將會產生計費。因為只要Logstore存在,無論是否使用都會產生活躍Shard租用費用。因此,您需要手動刪除資源。執行如下代碼,通過刪除Project來刪除Project的所有資源。

# Project名稱。
project_name = "aliyun-test-project"

# 刪除指定project
def main():
    try:
        response = client.delete_project(project_name)
        response.log_print()
    except Exception as error:
        print(error)

附錄:完整範例程式碼

from aliyun.log import LogClient, PutLogsRequest, LogItem, GetLogsRequest, IndexConfig
import time
import os

# 本樣本從環境變數中擷取AccessKey ID和AccessKey Secret。
accessKeyId = os.environ.get('ALIBABA_CLOUD_ACCESS_KEY_ID', '')
accessKey = os.environ.get('ALIBABA_CLOUD_ACCESS_KEY_SECRET', '')
# Log Service的服務存取點。此處以杭州為例,其它地區請根據實際情況填寫。
endpoint = "cn-hangzhou.log.aliyuncs.com"

# 建立Log ServiceClient。
client = LogClient(endpoint, accessKeyId, accessKey)

# Project名稱。
project_name = "aliyun-test-project"
# Logstore名稱
logstore_name = "aliyun-test-logstore"
# 查詢語句。
query = "*| select request_method,status from " + logstore_name
# from_time和to_time表示查詢日誌的時間範圍,Unix時間戳記格式。
from_time = int(time.time()) - 3600
to_time = time.time() + 3600
# 索引。
logstore_index = {'line': {
    'token': [',', ' ', "'", '"', ';', '=', '(', ')', '[', ']', '{', '}', '?', '@', '&', '<', '>', '/', ':', '\n', '\t',
              '\r'], 'caseSensitive': False, 'chn': False},
    'keys': {'remote_addr': {'type': 'text', 'token': [',', ' ', "'", '"', ';', '=', '(', ')', '[', ']', '{', '}', '?', '@', '&', '<', '>', '/', ':', '\n', '\t', '\r'], 'caseSensitive': False, 'alias': 'remote_addr', 'doc_value': True, 'chn': False},
            'remote_user': {'type': 'text', 'token': [',', ' ', "'", '"', ';', '=', '(', ')', '[', ']', '{', '}', '?', '@', '&', '<', '>', '/', ':', '\n', '\t', '\r'], 'caseSensitive': False, 'alias': 'remote_user', 'doc_value': True, 'chn': False},
            'time_local': {'type': 'text', 'token': [',', ' ', "'", '"', ';', '=', '(', ')', '[', ']', '{', '}', '?', '@', '&', '<', '>', '/', ':', '\n', '\t', '\r'], 'caseSensitive': False, 'alias': 'time_local', 'doc_value': True, 'chn': False},
            'request_method': {'type': 'text', 'token': [',', ' ', "'", '"', ';', '=', '(', ')', '[', ']', '{', '}', '?', '@', '&', '<', '>', '/', ':', '\n', '\t', '\r'], 'caseSensitive': False, 'alias': 'request_method', 'doc_value': True, 'chn': False},
            'request_uri': {'type': 'text', 'token': [',', ' ', "'", '"', ';', '=', '(', ')', '[', ']', '{', '}', '?', '@', '&', '<', '>', '/', ':', '\n', '\t', '\r'], 'caseSensitive': False, 'alias': 'request_uri', 'doc_value': True, 'chn': False},
            'status': {'type': 'long', 'alias': 'status', 'doc_value': True},
            'body_bytes_sent': {'type': 'long', 'alias': 'body_bytes_sent', 'doc_value': True},
            'http_referer': {'type': 'text', 'token': [',', ' ', "'", '"', ';', '=', '(', ')', '[', ']', '{', '}', '?', '@', '&', '<', '>', '/', ':', '\n', '\t', '\r'], 'caseSensitive': False, 'alias': 'http_referer', 'doc_value': True, 'chn': False},
            'http_user_agent': {'type': 'text', 'token': [',', ' ', "'", '"', ';', '=', '(', ')', '[', ']', '{', '}', '?', '@', '&', '<', '>', '/', ':', '\n', '\t', '\r'], 'caseSensitive': False, 'alias': 'http_user_agent', 'doc_value': True, 'chn': False}}}

# 建立索引。
def create_index():
    print("ready to create index for %s" % logstore_name)
    index_config = IndexConfig()
    index_config.from_json(logstore_index)
    client.create_index(project_name, logstore_name, index_config)
    print("create index for %s success " % logstore_name)
    time.sleep(60 * 2)


# 向Logstore寫入資料。
def put_logs():
    print("ready to put logs for %s" % logstore_name)
    log_group = []
    for i in range(0, 100):
        log_item = LogItem()
        # 按欄位設定日誌內容
        contents = [
            ('remote_addr', '192.168.0.%d' % (i % 255)),
            ('remote_user', 'user%d' % i),
            ('time_local', time.strftime('%d/%b/%Y:%H:%M:%S +0000', time.gmtime())),
            ('request_method', 'GET' if i % 2 == 0 else 'POST'),
            ('request_uri', '/index.html' if i % 3 == 0 else '/api/data'),
            ('status', str(200 + (i % 100))),  # 狀態代碼在200-299之間
            ('body_bytes_sent', str(1024 + i)),
            ('http_referer', 'http://example.com/page%d' % (i // 10)),
            ('http_user_agent',
             'Mozilla/5.0 AppleWebKit/537.36 (KHTML, like Gecko) Chrome/90.0.%d Safari/537.36' % (i * 10))
        ]
        log_item.set_contents(contents)
        log_group.append(log_item)
    request = PutLogsRequest(project_name, logstore_name, "", "", log_group, compress=False)
    client.put_logs(request)
    print("put logs for %s success " % logstore_name)
    time.sleep(60)


# 通過SQL查詢日誌。
def get_logs():
    print("ready to query logs from logstore %s" % logstore_name)
    request = GetLogsRequest(project_name, logstore_name, from_time, to_time, query=query)
    response = client.get_logs(request)
    for log in response.get_logs():
        for k, v in log.contents.items():
            print("%s : %s" % (k, v))
        print("*********************")


if __name__ == '__main__':
    # 建立索引。
    create_index()
    # 向Logstore寫入資料。
    put_logs()
    # 通過SQL查詢日誌。
    get_logs()

擴充情境

  • Log Service支援多種語言的SDK日誌採集,具體請參考SDK參考概述

  • 阿里雲OpenAPI開發人員門戶提供調試、SDK、樣本和配套文檔。通過OpenAPI,您無需手動封裝請求和簽名操作,就可以快速對Log ServiceAPI進行調試。更多資訊,請參見OpenAPI開發人員門戶

  • 為滿足越來越多的自動化Log Service配置需求,Log Service提供命令列工具CLI。更多資訊,請參見CLI概述

  • 使用SDK、OpenAPI開發人員門戶和Log ServiceCLI產生的費用和使用控制台產生的費用一致。更多資訊,請參見計費概述

常見問題

Log ServiceSDK都支援哪些功能?

Log ServiceSDK已經實現Log Service大部分功能,包括日誌採集、建立索引、查詢和分析、資料加工、日誌消費、日誌投遞管理、警示、定時SQL等。若您在SDK調試中發現未實現功能,建議您升級到最新版本SDK重試或關注後續SDK版本更新。

使用Log ServiceSDK的基本流程是什嗎?

Log ServiceSDK提供全流程的日誌管理,其使用流程和控制台使用流程基本相似。其使用基本流程大致如下:

  1. 開通Log Service。

  2. 擷取存取金鑰。

  3. 建立專案Project和日誌庫Logstore。

  4. 日誌採集並儲存至Logstore。

  5. 為日誌建立索引。

  6. 查詢和分析日誌,可視化展示。

  7. 對日誌資料進行加工、投遞和警示等操作。

Log Service提供介面化Operations 主控台,操作更簡單。更多資訊,請參考Log Service快速入門

SDK調試常見報錯如何處理?

Log ServiceSDK提供錯誤處理邏輯。SDK可能出現的異常錯誤可以分成如下幾類:

  • 由Log Service端返回的錯誤。這類錯誤由Log Service端返回並由SDK處理。關於這類錯誤的詳細資料可以參見具體的API介面說明、API錯誤碼。關於錯誤碼的更多資訊,請參見錯誤碼

  • 由SDK在向服務端發出請求時出現的網路錯誤。這類錯誤包括網路連接不通,服務端返回逾時等。

  • 由SDK自身產生的、與平台及語言相關的錯誤,如記憶體溢出等。

更多資訊,請參見錯誤處理

在使用Log ServiceSDK過程中,您可能遇到日誌採集、索引、查詢和分析、加工等各類報錯,您可以參考Log Service常見問題進行處理。更多資訊,請參見常見問題

使用Log ServiceSDK是否存在限制?

Log Service對基礎資源(例如Project個數、Logstore個數、Shard個數、LogItem大小)設定了合理的限制。建議您在使用前閱讀使用限制文檔,瞭解基礎資源的使用限制。更多資訊,請參見基礎資源使用限制