Trying Out Amazon CloudWatch Logs' New "Managed Syslog Ingestion" Feature to Ingest Syslog Directly from Within a VPC Without an Agent
This page has been translated by machine translation. View original
Introduction
On June 23, 2026, a managed syslog ingestion feature was added to Amazon CloudWatch Logs.
Just by sending syslog messages to a VPC endpoint (AWS PrivateLink), they are ingested into CloudWatch Logs.
Previously you needed the CloudWatch Agent or Fluent Bit, but with this feature you can ingest syslog directly.
| Aspect | Conventional method (Agent) | Managed syslog ingestion |
|---|---|---|
| Agent | Required (CloudWatch Agent / Fluent Bit, etc.) | Not required |
| Syslog parsing configuration | Manual (defined in configuration files) | Automatic (supports RFC 5424 / 3164 / Cisco) |
| Communication path | Agent → CloudWatch Logs API (HTTPS) | syslog → VPC endpoint (PrivateLink) |
| Setup effort | Agent installation + distributing configuration files | Create VPC endpoint + Syslog Configuration |
The supported protocols are as follows.
| Protocol | Port | Notes |
|---|---|---|
| TCP + TLS | 6514 | Encrypted. Recommended when you have compliance requirements |
| TCP plaintext | 1514 | Network-isolated via PrivateLink |
| UDP | 514 | Best-effort delivery |
The supported syslog formats are RFC 5424, RFC 3164, and Cisco FTD/ASA.
Setup Procedure
The environment used in this article is as follows.
- Region: ap-northeast-1 (Tokyo)
- VPC: Default VPC
- EC2: t3.micro, Amazon Linux 2023, SSM connection
- VPC endpoint:
com.amazonaws.ap-northeast-1.syslog-logs(Interface type)
This feature requires creating a VPC endpoint (Interface type). No public endpoint is provided.
Create the resources in the following order.
Creating the Security Group
Create a security group to associate with the VPC endpoint. Allow inbound TCP 1514 and UDP 514 from the syslog sources.
aws ec2 create-security-group \
--group-name syslog-vpce-sg \
--description "Security group for syslog VPC endpoint" \
--vpc-id <VPC_ID>
# Allow TCP 1514
aws ec2 authorize-security-group-ingress \
--group-id <SG_ID> \
--protocol tcp \
--port 1514 \
--cidr 172.31.0.0/16
# Allow UDP 514
aws ec2 authorize-security-group-ingress \
--group-id <SG_ID> \
--protocol udp \
--port 514 \
--cidr 172.31.0.0/16
Creating the VPC Endpoint
aws ec2 create-vpc-endpoint \
--vpc-endpoint-type Interface \
--service-name com.amazonaws.ap-northeast-1.syslog-logs \
--vpc-id <VPC_ID> \
--subnet-ids <SUBNET_ID> \
--security-group-ids <SG_ID>
After creation, check the DNS name of the endpoint.
aws ec2 describe-vpc-endpoints \
--vpc-endpoint-ids <VPCE_ID> \
--query 'VpcEndpoints[0].DnsEntries[0].DnsName' \
--output text
Example output:
vpce-0123456789abcdef0-abcdefgh.syslog-logs.ap-northeast-1.vpce.amazonaws.com
This DNS name is the destination for syslog.
Creating the Log Group
Create a log group to store the syslog messages.
aws logs create-log-group --log-group-name /syslog/test
aws logs put-retention-policy \
--log-group-name /syslog/test \
--retention-in-days 7
Configuring the Resource Policy
Grant write permissions to the log group for the CloudWatch Logs syslog service principal.
aws logs put-resource-policy \
--policy-name syslog-ingestion \
--policy-document '{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Principal": {
"Service": "syslog.logs.amazonaws.com"
},
"Action": [
"logs:PutLogEvents",
"logs:CreateLogStream"
],
"Resource": "arn:aws:logs:ap-northeast-1:<ACCOUNT_ID>:log-group:/syslog/test:*"
}
]
}'
Creating the Syslog Configuration
Create a Syslog Configuration that links the log group and the VPC endpoint.
aws logs create-syslog-delivery \
--log-group-name /syslog/test \
--vpc-endpoint-id <VPCE_ID>
This completes the setup. The log stream is created automatically when a syslog message is received. The naming convention is {VPCE_ID}_Syslog_{Region}.
Verification: Sending Messages over TCP
Send an RFC 5424-format syslog message from the EC2 instance over TCP (port 1514).
Since nc (netcat) is not installed by default on Amazon Linux 2023, we use bash's /dev/tcp. Because the echo command appends a newline, the message is sent with newline-terminated framing (non-transparent framing).
exec 3<>/dev/tcp/<VPCE_DNS>/1514 && \
echo '<134>1 2026-06-24T07:38:00Z syslog-test myapp 1234 - - Hello from syslog ingestion test' >&3 && \
exec 3>&-
Fields of the RFC 5424 message
<134>: PRI value. facility=16 (local0), severity=6 (info)1: Version2026-06-24T07:38:00Z: Timestampsyslog-test: Hostnamemyapp: Application name1234: Process ID-: Message ID (none)-: Structured data (none)Hello from syslog ingestion test: Message body
After 10 to 20 seconds, the event is recorded in CloudWatch Logs.
aws logs get-log-events \
--log-group-name /syslog/test \
--log-stream-name <VPCE_ID>_Syslog_ap-northeast-1
This is the response from the get-log-events API.
{
"timestamp": 1782286680000,
"message": "<134>1 2026-06-24T07:38:00Z syslog-test myapp 1234 - - Hello from syslog ingestion test",
"ingestionTime": 1782286667881
}
The timestamp (1782286680000 = 2026-06-24T07:38:00Z) uses the timestamp inside the syslog message, and differs from ingestionTime (1782286667881 = 07:37:47Z).
At least for messages that contain a parsable timestamp, such as the RFC 5424 format, the syslog timestamp is used as the event timestamp.
Automatic Extraction of Structured Fields
When you query with CloudWatch Logs Insights, you can reference structured fields automatically extracted from the syslog header.
fields @timestamp, facility, severity, hostname, appName, procId, message
| sort @timestamp desc
| limit 10
Extraction results:
| Field | Value |
|---|---|
| facility | local0 |
| severity | info |
| hostname | syslog-test |
| appName | myapp |
| procId | 1234 |
| message | Hello from syslog ingestion test |
The message extracted field that you can reference in Logs Insights contains only the syslog message body. On the other hand, @message stores the entire original syslog message (including the header).
Extraction from Messages with Structured Data
I also sent a message containing RFC 5424 structured data and checked it.
exec 3<>/dev/tcp/<VPCE_DNS>/1514 && \
echo '<165>1 2026-06-24T08:50:00Z syslog-test myapp 9999 ID001 [exampleSDID@32473 iut="3" eventSource="Application" eventID="1011"] Structured data test message' >&3 && \
exec 3>&-
Extraction results:
| Field | Value |
|---|---|
| facility | local4 |
| severity | notice |
| hostname | syslog-test |
| appName | myapp |
| procId | 9999 |
| msgId | ID001 |
| structuredData | [exampleSDID@32473 iut="3" eventSource="Application" eventID="1011"] |
| message | Structured data test message |
msgId and structuredData were also extracted as individual fields. The contents of the structured data (key-value pairs) are not automatically broken down into individual fields, and are stored as-is as a string.
Verification: Sending Messages over UDP
Send in the same way over UDP (port 514).
echo '<134>1 2026-06-24T07:41:00Z syslog-test myapp 5678 - - Hello from UDP syslog test' > \
/dev/udp/<VPCE_DNS>/514
Event recorded in CloudWatch Logs:
{
"timestamp": 1782286860000,
"message": "<134>1 2026-06-24T07:41:00Z syslog-test myapp 5678 - - Hello from UDP syslog test\n"
}
Over UDP, as with TCP, the structured fields (facility, severity, hostname, appName, procId) are extracted. A trailing newline is appended by echo, but in this verification the extracted message field could be referenced as a value without the trailing newline.
Deleting Resources
These are the steps to delete the resources created for the verification.
# Delete the Syslog Configuration
aws logs delete-syslog-delivery \
--log-group-name /syslog/test \
--vpc-endpoint-id <VPCE_ID>
# Delete the VPC endpoint
aws ec2 delete-vpc-endpoints --vpc-endpoint-ids <VPCE_ID>
# Delete the log group
aws logs delete-log-group --log-group-name /syslog/test
# Delete the resource policy
aws logs delete-resource-policy --policy-name syslog-ingestion
# Delete the security group
aws ec2 delete-security-group --group-id <SG_ID>
Choosing Between Protocols
| Aspect | TCP (1514 / 6514) | UDP (514) |
|---|---|---|
| Error notification | Some errors are visible to the sender as connection resets | None (best effort) |
| Backpressure | Yes. May be visible as a connection reset on errors | None |
| Encryption | TLS supported (6514) | Not supported |
| Use cases | Security audits, compliance requirements | Large numbers of network devices, when you want to minimize the impact on senders |
With TCP, if a delivery error or an unable-to-accept state occurs on the CloudWatch Logs side, it may be visible to the sender as a connection reset. However, it is not a protocol that confirms, per message, that persistence to CloudWatch Logs has completed.
UDP is best effort. Even if messages are discarded due to network congestion or capacity constraints on the service side, there is no feedback to the sender. To check for drops observed on the service side, you can use the CloudWatch metric SyslogMessagesDropped.
This verification was performed with TCP plaintext (1514) and UDP (514). In production environments, consider using TLS (6514) according to your compliance requirements.
Cost
Standard Interface Endpoint pricing applies to the VPC endpoint (at the time of writing, Tokyo region $0.014/ENI/hour). For the latest pricing, see the AWS PrivateLink pricing page.
| Number of AZs | Hourly rate | Monthly (730h) |
|---|---|---|
| 1 AZ | $0.014 | $10.22 |
| 2 AZs | $0.028 | $20.44 |
| 3 AZs | $0.042 | $30.66 |
The data processing fee is $0.01/GB. Syslog messages are generally a few hundred bytes, so even 100,000 messages per day (average 200 B) amount to about 0.6 GB per month ($0.006), which is small as a PrivateLink data processing fee.
Separately from this, CloudWatch Logs ingestion fees (at the time of writing, Tokyo region $0.76/GB) and storage fees ($0.033/GB/month) are incurred. For the latest pricing, see the CloudWatch pricing page.
Summary
Using the managed syslog ingestion feature of Amazon CloudWatch Logs, I sent syslog messages over TCP and UDP from EC2 in a VPC and confirmed they were ingested into CloudWatch Logs.
In addition to the syslog header's facility, severity, hostname, and so on, RFC 5424's msgId and structured data are also automatically extracted.
For the RFC 5424 format checked here, the timestamp inside the syslog message was used as the event timestamp.
In Logs Insights, you can both run structured queries using the extracted fields and refer to the original text via @message.
For configurations that previously built a syslog server on EC2 or prepared a syslog receiving platform with EC2 and an NLB, this is worth considering as a managed syslog destination. Once you prepare a VPC endpoint and a Syslog Configuration, syslog can be ingested directly from the senders into CloudWatch Logs, which may reduce the operational burden of receiving servers.
However, a VPC endpoint is required, and you need to verify how to replace the monitoring, alerting, and downstream integrations that were handled by your existing syslog server with CloudWatch Logs. When migrating from an existing environment, we recommend a thorough evaluation, including the protocols and formats supported by the senders, the extracted fields, and the impact on monitoring flows.
Reference Links
