All Products
Search
Document Center

Simple Log Service:Collect client-side logs with WebTracking

Last Updated:Jun 02, 2026

WebTracking captures user behavior in a browser—page views, purchases, session duration—and streams it to Simple Log Service (SLS) for analysis with minimal code changes.

WebTracking supports two ingestion methods. Authenticated ingestion is recommended.

  • Authenticated ingestion (recommended)
    The frontend obtains a temporary STS token from your backend. This token provides time-limited, least-privilege credentials (AccessKey + SecurityToken) for signed log requests to SLS, preventing forgery and data contamination. Ideal for production.



  • Unauthenticated ingestion
    The frontend writes logs directly to a public WebTracking endpoint without credentials. Simple to configure, but requires anonymous write permission. If Project or Logstore information leaks, data contamination is possible. Recommended for testing only.



Prepare cloud resources

Create the cloud resources required for log storage.

Step 1: Create a project

A project is the primary resource management unit in SLS that isolates resources for different applications.

Procedure: Log on to the Log Service console and click Create Project.

Parameters:

  • Region: Select a region based on the location of your log sources. You cannot change this setting after the project is created.

  • Project Name: Enter a name that is globally unique within Alibaba Cloud. You cannot change this name after the project is created.

  • Leave the other settings at their default values and click Create.

Step 2: Create a logstore

A Logstore stores the collected frontend logs.

Procedure: Navigate to the target project. In the navigation pane, choose Log Storageimage, and click +.

Parameters:

  • Logstore Name: Enter a name that is unique within the project. This name cannot be changed later. For example, web-tracking-logstore.

  • Logstore Type: Select Standard or Query based on your requirements.

  • Billing Mode:

    • Pay-by-feature: Suitable for scenarios with low log volumes or for development and testing.

    • Pay-by-ingested-data: Suitable for scenarios with stable log volumes that require long-term analysis.

  • Data Retention Period: The default is 30 days. The supported range is 1 to 3,650 days.

  • Leave the other settings at their default values and click OK.

STS authentication mode (Recommended)

This method uses a backend credential service to avoid exposing frontend keys. Recommended for production.

How it works

The frontend requests a temporary credential from an STS service on your application server. The WebTracking SDK uses this credential to upload logs. Credentials expire after 60 minutes by default.

image
  1. The frontend application requests a temporary security credential from the application server to upload logs.

  2. After validating the request, the application server uses a preconfigured RAM user to call the Alibaba Cloud STS AssumeRole API and assume a RAM role with write permissions for SLS.

  3. STS validates the role's permissions and issues a temporary security credential that contains an AccessKey ID, AccessKey Secret, and a security token.

  4. The application server returns the temporary security credential to the frontend application.

  5. The frontend application uses the temporary security credential with the WebTracking SDK to upload logs to the specified logstore.

Step 1: Configure RAM permissions

Create least-privilege identities for the backend credential service and the frontend SDK.

1. Create a RAM role for the frontend

This virtual identity has no long-term keys. The frontend assumes it temporarily to write logs.

1.1 Create a RAM role

Procedure: Log on to the RAM console. In the left-side navigation pane, choose Identities > Role, and then click Create Role.

Configuration:

  • Principal Type: Select Alibaba Cloud Account.

  • Principal Name: Select the current cloud account or specify another cloud account.

  • Click OK and enter the role name sls-web-tracking.

1.2 Create a log write policy

This policy restricts the role to writing logs to the specified Logstore only.

Procedure: In the left-side navigation pane, choose Permission Management > Policy, and then click Create Policy.

Configuration:

  • Use the JSON editor to paste the following script. Replace <ProjectName> and <LogstoreName> with your actual project and logstore names.

    {
      "Version":"1",
      "Statement":[
        {
          "Effect":"Allow",
          "Action":[
            "log:PostLogStoreLogs",
            "log:PutLogs"
          ],
          "Resource":[
            "acs:log:*:*:project/<ProjectName>/logstore/<LogstoreName>"
          ]
        }
      ]
    }
  • Click OK, and then enter post-logs-policy as the Policy Name to create the policy.

1.3 Grant log write permissions to the role

Attach the write policy from the previous step to the frontend role.

Procedure: In the left-side navigation pane, choose Identities > Role. Click the name of the target role to go to its details page. In the Permission Management tab, click Create Authorization.

Configuration:

  • In the Add Permissions panel, search for and select the custom policy created in the previous step (post-logs-policy).

  • Click Authorize to attach the policy.

2. Create a RAM user for the backend

This RAM user provides the long-term AccessKey pair your backend uses to call STS and assume the role.

2.1 Create a RAM user

Procedure:  Log on to the RAM console. In the left-side navigation pane, choose Identities > Users, and then click Create User.

Configuration:

  • Logon Name: Enter a name that contains only letters, digits, periods (.), hyphens (-), and underscores (_). The name can be up to 64 characters long. Example: sls-token-service.

  • Access Method: Select Using permanent AccessKey to access.

  • Leave the other settings at their default values, click OK to create the user, and then save the AccessKey ID and AccessKey Secret.

    The AccessKey Secret is displayed only once upon creation and cannot be retrieved later. Make sure to save it to a secure location immediately.
2.2 Grant permission to assume a role

Procedure: Click the name of the target user to go to the user details page. Switch to the Permission Management tab, and then click Create Authorization.

Configuration:

  • In the Policy section, select the AliyunSTSAssumeRoleAccess policy.

  • Leave the other settings at their default values and click OK.

Summary: The backend service uses the RAM user's AccessKey pair to assume the sls-web-tracking RAM role. This process generates a temporary security credential and returns it to the frontend application. The WebTracking SDK then uses this temporary credential to securely upload logs.

Step 2: Build a backend STS service

You must build a backend API endpoint that receives credential requests from the frontend and returns an STS temporary security credential. The following example uses Python and Flask.

Java, Node.js, PHP, and Ruby examples are available in Appendix 1: STS examples in multiple languages.

1. Prepare the server environment

Integrate the STS credential API into your existing application server or deploy it standalone. Requirements:

  • The frontend application can access the server over HTTP or HTTPS.

  • Python 3 is installed. Version 3.8 or later is recommended.

Run the following commands to install the required libraries:

# Install the Flask web framework and related Alibaba Cloud SDK libraries
pip3 install Flask==3.1.2
pip3 install aiohttp==3.8.4
pip3 install alibabacloud-credentials==0.3.2
pip3 install alibabacloud-sts20150401==1.1.3
pip3 install alibabacloud-tea==0.3.2
pip3 install alibabacloud-tea-openapi==0.3.7
pip3 install alibabacloud-tea-util==0.3.8
pip3 install alibabacloud-tea-xml==0.0.2

2. Write the backend STS service code

Create an HTTP endpoint /get_sts_token to generate and return an STS temporary security credential.

2.1 Create the project directory and file
# Create and enter the project directory
mkdir my_web_sample
cd my_web_sample
touch main.py
2.2 Edit the main.py file

Paste the following code into the main.py file. Replace <YOUR_ROLE_ARN> with the ARN of the sls-web-tracking RAM role and replace <YOUR_ROLE_SESSION_NAME> with a custom session name, such as role_session_test.

import json
from flask import Flask, render_template
from alibabacloud_tea_openapi.models import Config
from alibabacloud_sts20150401.client import Client as Sts20150401Client
from alibabacloud_sts20150401 import models as sts_20150401_models
from alibabacloud_credentials.client import Client as CredentialClient

app = Flask(__name__)

# ================== User Configuration ==================
# Replace with your RAM role ARN. Format: acs:ram::${accountId}:role/${roleName}
role_arn_for_sls_upload = '<YOUR_ROLE_ARN>'

# Set the role session name. We recommend using a unique identifier for the request source.
role_session_name = '<YOUR_ROLE_SESSION_NAME>'  # e.g., sls-web-session-001

# The region of the STS service, such as cn-hangzhou.
region_id = 'cn-hangzhou'
# ==============================================

@app.route("/")
def hello_world():
    return render_template('index.html')

@app.route('/get_sts_token', methods=['GET'])
def get_sts_token():
    """
    Endpoint: /get_sts_token
    Method: GET
    Function: Call the STS AssumeRole API to obtain a temporary security token.
    Returns: A Credentials object in JSON format.
    """
    # If you do not specify parameters when initializing CredentialClient, the default credential chain is used.
    # When running the program locally, specify the AccessKey pair by using the ALIBABA_CLOUD_ACCESS_KEY_ID and ALIBABA_CLOUD_ACCESS_KEY_SECRET environment variables.
    # When running on ECS, ECI, or Container Service, specify the instance RAM role by using the ALIBABA_CLOUD_ECS_METADATA environment variable. The SDK automatically obtains the STS temporary credential.
    config = Config(
        region_id=region_id,
        credential=CredentialClient()
    )
    sts_client = Sts20150401Client(config=config)

    # Construct the AssumeRole request
    assume_role_request = sts_20150401_models.AssumeRoleRequest(
        role_arn=role_arn_for_sls_upload,
        role_session_name=role_session_name,
    )
      
    # Call STS to obtain a temporary credential
    response = sts_client.assume_role(assume_role_request)
    
    token = json.dumps(response.body.credentials.to_map())
    return token


app.run(host="0.0.0.0", port=80)

3. Start the backend service

Run the following command to start the service with the AccessKey pair of the RAM user created in Step 1:

ALIBABA_CLOUD_ACCESS_KEY_ID=<YOUR_AK_ID> 
ALIBABA_CLOUD_ACCESS_KEY_SECRET=<YOUR_AK_SECRET> 
python3 main.py

4. Verify the endpoint

Send a test request:

curl http://<your_instance_public_ip_address>/get_sts_token

Sample success response:

{
  "AccessKeyId": "STS.L4xxxxxx",
  "AccessKeySecret": "Dcyyyyyyyy",
  "Expiration": "2025-04-05T10:30:00Z",
  "SecurityToken": "CAISzxxxxxxxxxxx..."
}

Verification points:

  • The response contains the AccessKeyIdAccessKeySecret, and SecurityToken fields.

  • The AccessKeyId starts with STS., indicating that it is a temporary credential.

  • The Expiration field indicates the expiration time and should be within a reasonable range.

Step 3: Integrate the WebTracking SDK

Integrate the SDK into your frontend application and configure the STS plugin for secure log uploads. A complete working example is in Appendix 2: Sample frontend application project.

1. Install SDK dependencies

Use npm to install the WebTracking SDK and its STS plugin:

npm install --save @aliyun-sls/web-track-browser
npm install --save @aliyun-sls/web-sts-plugin

2. Initialize the SDK and configure STS

Create a JavaScript file (for example, index.js) to initialize the SlsTracker instance and configure the STS plugin.

2.1 Import core modules
import SlsTracker from "@aliyun-sls/web-track-browser";
import createStsPlugin from "@aliyun-sls/web-sts-plugin";
2.2 Configure SLS information

Specify the following parameters based on your actual resource information:

const opts = {
  host: "${endpoint}", // The endpoint for your region. Example: cn-hangzhou.log.aliyuncs.com
  project: "${project}", // Your project name.
  logstore: "${logstore}", // Your logstore name.
  time: 10, // The time interval for sending logs, in seconds. Default: 10.
  count: 10, // The number of logs to send in a batch. Default: 10.
  topic: "topic", // A custom log topic.
  source: "source",
  tags: {
    tags: "tags",
  },
};
2.3 Configure the STS plugin

The frontend should not store long-term AccessKey pairs. Use the STS plugin to fetch and auto-refresh temporary tokens from your backend.

const stsOpt = {
  accessKeyId: "",
  accessKeySecret: "",
  securityToken: "",
  
  // An asynchronous function to refresh the STS token.
  refreshSTSToken: () =>
    new Promise((resolve, reject) => {
      const xhr = new window.XMLHttpRequest();
      xhr.open("GET", "http://<your_instance_public_ip_address>/get_sts_token", true);
      xhr.send();
      
      xhr.onreadystatechange = () => {
        if (xhr.readyState === 4) {
          if (xhr.status === 200) {
            let credential = JSON.parse(xhr.response);
            // Update the temporary credential.
            stsOpt.accessKeyId = credential.AccessKeyId;
            stsOpt.accessKeySecret = credential.AccessKeySecret;
            stsOpt.securityToken = credential.SecurityToken;
            resolve();
          } else {
            reject("Wrong status code.");
          }
        }
      };
    }),
   // (Optional) A custom refresh interval. Default: 5 minutes (300,000 ms).
  // refreshSTSTokenInterval: 300000,
  
  // (Optional) The period before token expiration to trigger a refresh, in milliseconds.
  // stsTokenFreshTime: undefined,
};
2.4 Initialize the tracker and enable the STS plugin
// Create a tracker instance.
const tracker = new SlsTracker(opts);

// Create and register the STS plugin.
const stsPlugin = createStsPlugin(stsOpt);
tracker.useStsPlugin(stsPlugin);

3. Report logs

On your web page, use standard DOM event binding to capture user actions and call the tracker.send() method to send custom logs.

3.1 Listen for user interactions

Example: Track a user login event.

document.getElementById("loginButton").addEventListener("click", () => {
  const username = document.getElementById("username").value;
  
  tracker.send({
    eventType: "login",
    username: username,
  });
  
  console.log("Login event tracked for:", username);
});
3.2 Reference the script

Make sure that the JavaScript file is loaded correctly. We recommend importing it as a module:

<!DOCTYPE html>
<html lang="en-US">
<head>
  <meta charset="UTF-8" />
  <title>User Behavior Monitoring Example</title>
</head>
<body>
  <input type="text" id="username" placeholder="Enter username" />
  <button id="loginButton">Login</button>

  <!-- Use a modular script -->
  <script type="module" src="/static/js/index.js"></script>
</body>
</html>

4. Run and test

Start the frontend, access the page, and trigger user behavior events to verify that the SDK collects and uploads logs.

  1. Start the frontend service and access the frontend page at http://<your_instance_public_ip_address>.

  2. Simulate a user action, such as clicking the login button.

  3. Open the developer tools in your browser (F12):

    • On the Console tab, check whether the output displays Login event tracked for: xxx.

    • On the Network tab, check for a successful POST request to cn-xxx.log.aliyuncs.com.

5. Verify log ingestion

Confirm that frontend logs are written to the SLS Logstore.

  1. Log on to the SLS console.

  2. In the Projects list, click the target project.

  3. On the Logstores page, click image next to the name of the target logstore to expand it.

  4. Click image to go to the Search & Analyze page.

  5. Click Enable. In the panel that appears on the right, click Automatic Index Generation.

  6. The system automatically identifies the log structure and generates recommended field configurations. Review the configuration and click OK.

  7. After enabling indexing, wait about one minute for the index to take effect. You can then query the logs.

Unauthenticated ingestion

This method enables WebTracking on a Logstore to grant public write access. Clients upload logs directly without credentials via the SDK, HTTP requests, or HTML tags.

Important

After enabling WebTracking, log uploads require no authentication. If your project or logstore information is compromised, attackers can pollute your data. Use this feature in test environments only.

Step 1: Enable WebTracking

  1. Log on to the SLS console.

  2. In the Projects section, click the target project.

  3. On the Log Storage > Logstores tab, find the target logstore and choose icon > Modify.

  4. On the Logstore Attributes page, click Modify.

  5. Enable WebTracking and click Save.

Step 2: Configure unauthenticated ingestion and upload logs

SLS supports the following four integration methods:

  • Integrate the WebTracking SDK: Import the WebTracking SDK into your frontend code and call the send() method to send structured logs. This method is ideal for modern web and mini program applications.

  • HTTP GET request: Append log data to the URL parameters and upload it directly with a GET request. This method is simple to implement and ideal for debugging or lightweight collection of a small number of logs.

  • HTML tag (img): Use the <img> tag's src attribute to initiate a request, with log information encoded in the URL. This method requires no JavaScript, inherently supports cross-domain requests, and is ideal for static pages or email tracking.

  • OpenAPI batch write: Call the SLS OpenAPI by sending a POST request. This method is ideal for uploading large amounts of data from a server.

WebTracking SDK

In unauthenticated ingestion mode, you do not need to configure an STS plugin. You can initialize the SDK directly.

Install dependencies

# For browsers
npm install --save @aliyun-sls/web-track-browser

# For mini programs
npm install --save @aliyun-sls/web-track-mini

Configure basic SLS information

import SlsTracker from '@aliyun-sls/web-track-browser'

const opts = {
  host: '${host}', // The endpoint for SLS in your region. Example: cn-hangzhou.log.aliyuncs.com
  project: '${project}', // The project name.
  logstore: '${logstore}', // The logstore name.
  time: 10, // The time interval for sending logs, in seconds. Default value: 10.
  count: 10, // The number of logs to send in a batch. Default value: 10.
  topic: 'topic',// A custom log topic.
  source: 'source',
  tags: {
    tags: 'tags',
  },
}

const tracker = new SlsTracker(opts)  // Create an SlsTracker object

Upload logs

When you upload a single log, it is represented as a single object. When you upload multiple logs, the data structure is an array of objects.

Single log

tracker.send({
  eventType:'view_product',
  productName: 'Tablet',
  price: 500
})

Upload a single log immediately (the time and count parameters are ignored):

tracker.sendImmediate({
  eventType:'view_product',
  productName: 'Tablet',
  price: 500
})

Batch logs

tracker.sendBatchLogs([
  {
    eventType: 'view_product',
    productName: 'Tablet',
    price: 500
  },
  {
    eventType: 'view_product',
    productName: 'Laptop',
    price: 1200
  }
])

Upload a batch of logs immediately (the time and count parameters are ignored):

tracker.sendBatchLogsImmediate([
  {
    eventType:'view_product',
    productName: 'Tablet',
    price: 500
  },
  {
    eventType:'view_product',
    productName: 'Laptop',
    price: 1200
  }
])

HTTP GET request

Send a GET request directly to the SLS ingestion endpoint with the log data encoded as URL parameters.

curl --request GET 'https://${project}.${host}/logstores/${logstore}/track?APIVersion=0.6.0&key1=val1&key2=val2'
  • host: The SLS endpoint for your region. Available endpoints are listed in Endpoints.

  • key1=val1&key2=val2: The field names and values (key-value pairs) to upload to SLS. You can set multiple fields. The total length must be less than 16 KB.

HTML tag (img)

Embed an invisible <img> tag on the frontend page. The browser automatically loads the image, which triggers the log upload.

<!-- Collect custom fields -->
<img src='https://${project}.${host}/logstores/${logstore}/track.gif?APIVersion=0.6.0&key1=val1&key2=val2'/>
<!-- Also collect User-Agent and Referer -->
<img src='https://${project}.${host}/logstores/${logstore}/track_ua.gif?APIVersion=0.6.0&key1=val1&key2=val2'/>
Note

Using track_ua.gif automatically collects User-Agent and Referer information. To prevent browser caching, add a timestamp parameter.

OpenAPI: Batch write

To upload large quantities of logs, call the PutWebtracking API.

Step 3: Verify log ingestion

Verify that frontend logs reach the SLS Logstore.

  1. Log on to the SLS console.

  2. In the Projects list, click the target project.

  3. On the logstore page, click image next to the name of the target logstore to expand it.

  4. Click image to go to the Search & Analyze page.

  5. Click Enable. In the panel that opens on the right, click Automatic Index Generation.

  6. The system automatically identifies the log structure and generates recommended field configurations. Confirm the configurations and click OK.

  7. After enabling indexing, wait about one minute to ensure the index takes effect. You can then query the logs.

Quotas and limits

To ensure service stability, SLS WebTracking applies the following quotas to log uploads from browsers:

  • Maximum data size per request: 3 MB

  • Maximum number of log entries per request: 4,096

Billing

The WebTracking feature is free, but log writing, storage, and query operations incur charges.

1. Billing modes

When you create a Logstore, you can choose a billing mode:

  • Pay-by-ingested-data: Suitable for complex use cases that require long-term log storage, analysis, processing, and consumption across multiple scenarios.

  • Pay-by-feature: Suitable for lightweight or phased use cases where flexible cost control is needed.

2. Core billable items

Pay-by-ingested-data

  • Ingested raw data volume: This is the primary charge, billed based on the uncompressed size (in GB) of your raw logs. This fee includes data writes, indexing, API calls, and the first month (30 days) of hot storage.

  • Storage fees: Storage beyond 30 days incurs additional fees.

Pay-by-feature

  • Index traffic: A one-time fee applies when data is written, based on the uncompressed size of the raw logs. This is a prerequisite for making logs searchable.

  • Storage fees: Billed from day one based on the size of your compressed data.

  • Read and write traffic, number of reads and writes, active Shards, and more.

FAQ

CDN import

Yes. This method is ideal for lightweight frontend projects, static pages, or quick validation scenarios without an npm build process.

Outdated version risk: The latest version available on the CDN is 0.3.5. This version may lack features available in the latest version on npm.

How to import:

  1. Add the following script reference to the <head> or <body> tag of your HTML file.

    <script src="https://g.alicdn.com/sls/sls-js-sdk/0.3.5/web-track-browser.js"></script>
  2. After the SDK loads, initialize the tracker instance with the global object window.SLS_Tracker:

    if (window.SLS_Tracker) {
      const tracker = new SLS_Tracker({
        host: 'your-project.cn-hangzhou.log.aliyuncs.com',
        project: 'your-project',
        logstore: 'your-logstore',
        time: 10,
        count: 10
      });
    }
    

Related documentation

Appendix 1: Multilingual STS examples

Alibaba Cloud provides open-source STS service examples in Java, Node.js, PHP, and Ruby. Each example calls the AssumeRole API to issue temporary credentials to a frontend application.

Example projects: Java, Node.js, PHP, Ruby

To use an example, modify the config.json file, then follow the instructions for your language to start the service.

Language

Port

Java

7080

Node.js

3000

PHP

8000

Ruby

4567

Appendix 2: Sample frontend project

Browser: simple-web-tracking-sts.zip.