Syslog is a widely used log transport protocol. Most security information and event management (SIEM) platforms use syslog to receive logs, such as IBM QRadar and HP ArcSight. This topic describes how to use Function Compute to ship logs from Simple Log Service to an SIEM platform over the syslog protocol.
Background information
Syslog is defined in RFC 5424 and RFC 3164. RFC 3164 was published in 2001, and RFC 5424 is an upgraded version published in 2009. We recommend that you use RFC 5424 because this version is compatible with RFC 3164 and resolves more issues than RFC 3164. For more information, see RFC 5424 and RFC 3164.
Syslog over TCP/TLS: Syslog only defines the standard format of log messages. Syslog supports TCP and UDP to ensure the stability of data transmission. RFC 5425 defines the use of Transport Layer Security (TLS) as the transport-layer protocol for log messages. If your SIEM platform supports TCP or TLS, we recommend that you use TCP or TLS instead of UDP. For more information, see RFC 5425.
Simple Log Service: Simple Log Service is a cloud-native monitoring and analysis platform that provides large-scale, low-cost, and real-time services to process logs, metrics, and traces. Simple Log Service allows you to collect, query, analyze, transform, visualize, consume, and ship data. Simple Log Service also allows you to configure alerts.
Function Compute: Alibaba Cloud Function Compute is a fully managed, event-driven computing service. Function Compute allows you to write and upload code without the need to manage infrastructure resources such as servers. Function Compute allocates computing resources, runs code in an elastic and reliable manner, and provides features such as log query, performance monitoring, and alerting.
Simple Log Service trigger: An extract, transform, and load (ETL) job corresponds to a Simple Log Service trigger in Function Compute and is used to invoke a function. After you create an ETL job for a Logstore in Simple Log Service, a timer is started to poll data from the shards of the Logstore based on the job configurations. If data is written to the Logstore, a triple data record in the
<shard_id,begin_cursor,end_cursor >format is generated as a function event. Then, the associated ETL function is invoked.
Shipping process
We recommend that you write a program based on consumer groups in Simple Log Service to consume data in real time. You can manage the consumer groups in Function Compute. Then, you can configure a Simple Log Service trigger to ship logs to an SIEM platform by using syslog over TCP/TLS.

Shipping example
In the following example, a Simple Log Service Logstore is used as the data source, and Function Compute is used to ship logs to an SIEM platform over the syslog protocol.
This topic is based on Simple Log Service triggers.
In this topic, Function Compute 2.0 is used.
Prerequisites
Simple Log Service is activated. For more information, see Activate Simple Log Service.
A project and a Logstore are created. For more information, see Create a project and Create a Logstore.
Procedure
Step 1: Create a function in Function Compute
Log on to the Function Compute console. Click Back to Function Compute 2.0 in the upper-right corner.

In the left-side navigation pane, click Services & Functions.
In the top navigation bar, select a region. On the Services page, click Create Service.
Configure the Name and Service Role parameters. If you create a role to manage Simple Log Service resources, grant the role the permissions to consume data in Logstores. For other parameters, retain the default settings. You can click Show Advanced Options to find the Service Role parameter. For more information, see Grant Function Compute permissions to access other Alibaba Cloud services and Examples of using custom policies to grant permissions to a RAM user.
After the service is created, click Create Function on the Functions page.

Perform the following steps to configure the function:
Select Use Built-in Runtime to create a function.
Click Create.

Step 2: Configure function code
On the Code tab, replace index.py with the following code:
""" The sample code is used to implement the following features: * Parse the event parameter to obtain the trigger information of Simple Log Service events. * Initialize the Simple Log Service client based on the obtained information. * Obtain real-time logs from the source Logstore. * Ship the logs over syslog. This sample code is mainly doing the following things: * Get SLS processing related information from event * Initiate SLS client * Pull logs from source log store * Send logs with syslog """ # !/usr/bin/env python # -*- coding: utf-8 -*- import json from aliyun.log import LogClient import os import logging import six from datetime import datetime from aliyun.log import PullLogResponse from aliyun.log.ext import syslogclient from pysyslogclient import SyslogClientRFC5424 as SyslogClient logger = logging.getLogger() def get_syslog_config(): config = { 'host': os.environ.get('SYSLOG_HOST', ''), 'port': int(os.environ.get('SYSLOG_PORT', '514')), 'protocol': os.environ.get('SYSLOG_PROTOCOL', 'tcp'), "facility": syslogclient.FAC_USER, # Optional. You can refer to the values of other syslogclient.FAC_* parameters. "severity": syslogclient.SEV_INFO, # Optional. You can refer to the values of other syslogclient.SEV_* parameters. "hostname": "aliyun.example.com", # Optional. Specify a hostname. The default value is the hostname of the local host. "tag": "tag" # Optional. Specify a tag. The default value is a hyphen (-). } return config def init_syslog_client(config): client = SyslogClient(config.get('host'), config.get('port'), config.get('protocol')) return client def process(shard_id, log_groups, config): logs = PullLogResponse.loggroups_to_flattern_list(log_groups, time_as_str=True, decode_bytes=True) logger.info("Get data from shard {0}, log count: {1}".format(shard_id, len(logs))) try: client = init_syslog_client(config) for log in logs: # suppose we only care about audit log timestamp = datetime.fromtimestamp(int(log[u'__time__'])) del log['__time__'] io = six.StringIO() # Modify the content format based on your business requirements. In this example, data is transmitted by using key-value pairs that are separated by two consecutive vertical bars (||). for k, v in six.iteritems(log): io.write("{0}{1}={2}".format('||', k, v)) data = io.getvalue() # Modify the facility and severity parameters based on your business requirements. client.log(data, facility=config.get("facility", None), severity=config.get("severity", None), timestamp=timestamp, program=config.get("tag", None), hostname=config.get("hostname", None)) except Exception as err: logger.debug("Failed to connect to remote syslog server ({0}). Exception: {1}".format(config, err)) # Add code to handle errors. For example, you can add code to retry requests or report errors. raise err logger.info("Complete send data to remote") def handler(event, context): # Use context.credentials.to obtain information about keys. # Access keys can be fetched through context.credentials print("The content in context entity is: \n") print(context) creds = context.credentials access_key_id = creds.access_key_id access_key_secret = creds.access_key_secret security_token = creds.security_token # Parse the event parameter to the object data type. # parse event in object event_obj = json.loads(event.decode()) print("The content in event entity is: \n") print(event_obj) # Use event.source to obtain the following information: project name, Logstore name, Simple Log Service endpoint, start cursor, end cursor, and shard ID. # Get the name of log project, the name of log store, the endpoint of sls, begin cursor, end cursor and shardId from event.source source = event_obj['source'] log_project = source['projectName'] log_store = source['logstoreName'] endpoint = source['endpoint'] begin_cursor = source['beginCursor'] end_cursor = source['endCursor'] shard_id = source['shardId'] # Initialize the Simple Log Service client. # Initialize client of sls client = LogClient(endpoint=endpoint, accessKeyId=access_key_id, accessKey=access_key_secret, securityToken=security_token) syslog_config = get_syslog_config() # Read logs based on the start and end cursors in the source Logstore. In this example, the specified cursors cover all logs that trigger the invocation of the function. # Read data from source logstore within cursor: [begin_cursor, end_cursor) in the example, which contains all the logs trigger the invocation while True: response = client.pull_logs(project_name=log_project, logstore_name=log_store, shard_id=shard_id, cursor=begin_cursor, count=100, end_cursor=end_cursor, compress=False) log_group_cnt = response.get_loggroup_count() if log_group_cnt == 0: break logger.info("get %d log group from %s" % (log_group_cnt, log_store)) process(shard_id, response.get_loggroup_list(), syslog_config) begin_cursor = response.get_next_cursor() return 'success'
Step 3: Create a custom layer
In this topic, logs are shipped over the syslog protocol. Therefore, the dependency library of syslog is required. The following procedure describes how to create a custom layer to import the dependency library:
Click Edit Layer.
In the panel that appears, choose .
Click Create Custom Layer. Then, configure the following parameters.
Select Python 3.9 for Compatible Runtime.
Select Build Dependency Layer Online for Layer Upload Method.
Select Python 3.9 for Build Environment.
Enter
pysyslogclientin the requirements.txt File field.Click Create.
Return to the layer modification panel, select the custom layer that you created in 3 for Layer 1, and then click OK.
Step 4: Test the function and deploy code
Click Test Function. If success is returned, the log shipping is successful.

Click Deploy to deploy code.
FAQ
What do I do if the UnhandleInvocationError error is reported when I test my function?
If the error is reported because your service role does not have the required permissions, see Configure a role.
If the error is reported because the configured environment variables are invalid, see Configure environment variables.
If you have more questions, join the DingTalk group 11721331 to contact Function Compute engineers.
What to do next
Check whether logs are received on the syslog server.
View the trigger and invocation information of the function on the Logs tab.

References
If you use a Simple Log Service trigger, Simple Log Service consumers are used to consume logs. For more information about consumers, see Consume logs.
After you ship logs from Simple Log Service to an SIEM platform, you can use consumer groups of Simple Log Service to consume logs. For more information, see Ship logs to an SIEM system over HTTPS and Ship logs to an SIEM system over syslog.
For more information about consumer groups of Simple Log Service, see Use consumer groups to consume data.

