All Products
Search
Document Center

Simple Log Service:Quickstart: Upload and analyze logs with the SLS SDK

Last Updated:Jul 10, 2026

Upload logs with the Simple Log Service (SLS) Python SDK, visualize analysis results in the console, and configure alerts for anomalies.

Prerequisites

  • You have an available ECS instance. For more information, see ECS Quick Start.

  • You have activated Simple Log Service. For more information, see Activate Simple Log Service.

  • Python and a Python development environment, such as PyCharm, are installed.

    The SLS Python SDK supports the following versions:

    • Python 2: 2.7 and later

    • Python 3: 3.7 and later

    • PyPy 2: 2.7 and later

    • PyPy 3: 3.7 and later

Solution overview

image

In this quickstart, you learn to:

  • Create a project (a resource management unit) and a logstore (a log storage unit).

  • Use the Python SDK to upload logs to a logstore, create an index, and then query and analyze the logs.

  • Visualize analysis results as charts on a dashboard.

  • Configure alert rules for monitoring.

  • Clean up unneeded resources to avoid charges.

1. Create a project and a logstore

1.1 Create a project

Log on to the Simple Log Service console. In the Projects section, click Create Project. In the Create Project panel, select a Region and enter a Project Name. This document uses a project named aliyun-test-project in the China (Hangzhou) region as an example. Keep the default values for other parameters.

1.2 Create a logstore

2. Install the SDK

  1. In the command-line interface (CLI), run the following command as an administrator to install the Python SDK. For more information about versions, see Aliyun Log Python Release.

    pip install -U aliyun-log-python-sdk
  2. After installing the SDK, run the following command to verify:

    pip show aliyun-log-python-sdk

    The following output confirms a successful installation:

    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. Initialize the client

LogClient manages projects, logstores, and log data. To initialize the client with an AccessKey pair (V1 signature):

  1. Obtain an AccessKey pair. In the Alibaba Cloud console, create an AccessKey to obtain an access_key_id and an access_key_secret.

  2. Configure the keys as environment variables, such as ALIBABA_CLOUD_ACCESS_KEY_ID and ALIBABA_CLOUD_ACCESS_KEY_SECRET, based on your operating system (Linux, macOS, or Windows).

  3. Set the endpoint. This document uses the China (Hangzhou) region as an example. The endpoint is set to cn-hangzhou.log.aliyuncs.com. For other regions, replace the value with the corresponding endpoint.

# Import the SLS package.
from aliyun.log import *
# Import this module to get the AccessKey pair from environment variables.
import os
# Obtain the AccessKey ID and AccessKey secret from environment variables.
access_key_id = os.environ.get('ALIBABA_CLOUD_ACCESS_KEY_ID', '')
access_key_secret = os.environ.get('ALIBABA_CLOUD_ACCESS_KEY_SECRET', '')
# The endpoint of Simple Log Service.
endpoint = "cn-hangzhou.log.aliyuncs.com"
# Create a LogClient instance.
client = LogClient(endpoint, access_key_id, access_key_secret)

4. Upload logs

Call put_logs to upload log data. The following is an example raw log:

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"  

Structure the log content by field when calling put_logs to simplify subsequent analysis.

# The name of the project.
project_name = "aliyun-test-project"
# The name of the logstore.
logstore_name = "aliyun-test-logstore"
# Write data to the logstore.
def put_logs():
    print("ready to put logs for %s" % logstore_name)
    log_group = []
    for i in range(0, 100):
        log_item = LogItem()
        # Set the log content by field.
        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))),  # Status codes are between 200 and 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. Create an index

You must configure an index before you can query logs. Set remote_addr, remote_user, time_local, request_method, request_uri, status, body_bytes_sent, http_referer, and http_user_agent as index fields.

# The name of the project.
project_name = "aliyun-test-project"
# The name of the logstore.
logstore_name = "aliyun-test-logstore"
# The index.
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}}}
# Create an index.
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)

After the index is created, you can query the logs.

On the Raw Logs page in the SLS console, 100 logs are returned with indexed fields and values such as body_bytes_sent:1024, remote_addr:192.168.0.1, request_method:GET, request_uri:/index.html, status:200, and http_referer:http://example.com/page0. This confirms the index is working and the log data is queryable.

6. Query and analyze logs

Upload logs to generate new data, then run the query *| select request_method,status from aliyun-test-logstore to retrieve them. For more information, see Index-based query and analysis.

# The name of the project.
project_name = "aliyun-test-project"
# The name of the logstore.
logstore_name = "aliyun-test-logstore"
# The query statement.
query = "*| select request_method,status from " + logstore_name
# from_time and to_time specify the time range for the query, in UNIX timestamp format.
from_time = int(time.time()) - 3600
to_time = time.time() + 3600
# Query logs by using 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("*********************")

The following response is returned:

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. Visualize data

  1. On the chart editing page, select Logstore (SQL) from the dropdown list in the Query and Analysis panel. Then, select the corresponding logstore and enter * | SELECT request_method,status,COUNT(*) AS request_count GROUP BY request_method,status ORDER BY request_count DESC LIMIT 10;. This query calculates the top 10 request counts for each method and status code. Because this example counts fields, select Table Pro from the chart types on the right, and then click Apply to display the result. If the visualization meets your requirements, click OK, and then click Save in the upper-right corner of the dashboard page. Dashboards support various chart types, data filtering, and integration with third-party tools. For more information, see Visualization overview.

8. Alerting and monitoring

8.1 Create an action policy

  1. In the left-side navigation pane, choose Alerts > Notification Policy > Action Policy, and then click Create.

  2. In the Add Action Policy dialog box, create an action policy with the Identifier set to test-action-policy and the Name set to New Alert Rule-My Action Policy test. This policy sends notifications by using DingTalk when an alert is triggered. The specific configurations of the action group are as follows:

    • Channel : Select DingTalk-Custom.

    • Request URL : Enter your DingTalk chatbot webhook, for example, https://oapi.dingtalk.com/robot/send?access_token=4dff******6bfe.

    • Reminder : Select No Reminder to prevent at-mentions in the DingTalk alert notification.

    • Content template : Select SLS Built-in Content Template.

    • Sending period : Select Any time to send alert notifications whenever an alert occurs.

Simple Log Service provides SDKs for managing users, user groups, webhook integrations, action policies, alert policies, and content templates. For more information, see Manage alert resource data.

8.2 Create an alert rule

  1. In the left-side navigation pane, choose Alerts > Alert Monitoring Rule, and then click Create Alert.

  2. On the Create Alert page, configure a rule to trigger a DingTalk alert notification every 15 minutes when data is detected. Configure the rule as follows:

    • Rule Name: New Alert Rule.

    • Check Frequency: Fixed interval of 15 minutes.

    • Query statistics:

      • Type: Logstore.

      • Region: China (Hangzhou).

      • Project: aliyun-test-project.

      • Logstore: aliyun-test-logstore.

      • Query: * | select *.

      • Query Time Range: Today.

    • Group evaluation: No grouping.

    • Trigger Condition: When there is data, an alert with a Severity of Medium is triggered.

    • Add Annotation: Set the keys to title and desc, and set the value for both to ${alert_name} alert is triggered.

    • Destination: For SLS notifications, set the action policy to the created test-action-policy.

    Also, enable the EventStore and CloudMonitor Event Center destinations. For the alert policy, select Normal Mode and set the repeat interval to 1 minute.

9. Clean up resources

Delete the resources created in this quickstart to avoid ongoing charges. Active shards incur costs as long as a logstore exists, even when unused. Run the following code to delete the project and all associated resources.

# The name of the project.
project_name = "aliyun-test-project"

# Delete the specified project.
def main():
    try:
        response = client.delete_project(project_name)
        response.log_print()
    except Exception as error:
        print(error)

Complete sample code

from aliyun.log import LogClient, PutLogsRequest, LogItem, GetLogsRequest, IndexConfig
import time
import os
# This example obtains the AccessKey ID and AccessKey secret from environment variables.
access_key_id = os.environ.get('ALIBABA_CLOUD_ACCESS_KEY_ID', '')
access_key_secret = os.environ.get('ALIBABA_CLOUD_ACCESS_KEY_SECRET', '')
# The endpoint of Simple Log Service. This example uses the China (Hangzhou) region. For other regions, specify the actual endpoint.
endpoint = "cn-hangzhou.log.aliyuncs.com"
# Create a Simple Log Service client.
client = LogClient(endpoint, access_key_id, access_key_secret)
# The name of the project.
project_name = "aliyun-test-project"
# The name of the logstore.
logstore_name = "aliyun-test-logstore"
# The query statement.
query = "*| select request_method,status from " + logstore_name
# from_time and to_time specify the time range for the query, in UNIX timestamp format.
from_time = int(time.time()) - 3600
to_time = time.time() + 3600
# The index.
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}}}
# Create an index.
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)
# Write data to the logstore.
def put_logs():
    print("ready to put logs for %s" % logstore_name)
    log_group = []
    for i in range(0, 100):
        log_item = LogItem()
        # Set the log content by field.
        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))),  # Status codes are between 200 and 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)
# Query logs by using 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 an index.
    create_index()
    # Write data to the logstore.
    put_logs()
    # Query logs by using SQL.
    get_logs()

Related topics

  • Simple Log Service provides SDKs for multiple programming languages. For more information, see SDK reference overview.

  • OpenAPI Explorer lets you debug SLS API operations without manually constructing requests or handling signatures. For more information, see OpenAPI Explorer.

  • SLS provides a command-line interface (CLI) for automated configuration. For more information, see CLI overview.

  • Using the SDK, OpenAPI Explorer, or the CLI incurs the same fees as using the console. For more information, see Billing overview.

FAQ

What features do the Simple Log Service SDKs support?

The SLS SDKs support most SLS features, including log collection, index creation, query and analysis, data transformation, log consumption, log delivery management, alerting, and scheduled SQL jobs. If a feature is unsupported, upgrade to the latest SDK version or check for updates in subsequent releases.

What is the basic procedure for using a Simple Log Service SDK?

Using an SDK follows a similar workflow to using the console:

  1. Activate Simple Log Service.

  2. Obtain an AccessKey pair.

  3. Create a project and a Logstore.

  4. Collect logs and store them in the Logstore.

  5. Create an index for the logs.

  6. Query and analyze logs, and visualize the results.

  7. Perform operations on log data, such as data transformation, delivery, and alerting.

For simpler operations, use the SLS console. Quick Start.

How do I handle common errors when I debug an SDK?

The SLS SDKs provide built-in error handling. Exceptions fall into the following categories:

  • Exceptions returned by Simple Log Service. The SDK handles these exceptions. For more information, see the API operation descriptions and Error codes.

  • Network exceptions that occur when the SDK sends requests, such as network disconnection and server response timeout.

  • Platform- and language-specific exceptions generated by the SDK, such as memory overflow.

Error handling.

For solutions to common errors related to log collection, indexing, query and analysis, and transformation, see the FAQ.

Are there limits on using the Simple Log Service SDKs?

SLS imposes limits on projects, Logstores, shards, and LogItem size. Review Limits on basic resources before using an SDK.