This AWS Lambda function serves as an HTTPS logging endpoint for Fastly and forwards received logs to Logz.io. It handles both Fastly's health check mechanism and log forwarding functionality, with configuration managed via URL query parameters.
Before creating your Fastly endpoint, review the URL Parameters Reference section below to understand the required and optional parameters you'll need to include in your endpoint URL.
- Log into your Fastly account and select your service
- Go to Logging → Create a new endpoint → HTTPS
- Configure the following settings:
| Setting | Value |
|---|---|
| Name | Logz.io Logs (or any name you prefer) |
| URL | https://fastly.listener-logz.io/?service_id=YOUR_SERVICE_ID&token=YOUR_LOGZIO_TOKEN&host=YOUR_LOGZIO_HOST |
| Method | POST |
| Format Version | 2 |
| Response Condition | Leave empty |
| Content Type | application/json |
| Maximum Batch Size | 0 (no limit) or your preferred size |
| JSON log entry format | Use newline-delimited JSON |
| Request Compression | Gzip (optional but recommended) |
The Lambda function is format-agnostic. Below is an example of a comprehensive log format that includes common fields, but you can customize it based on your needs:
{"@timestamp":"%{begin:%Y-%m-%dT%H:%M:%SZ}t","time_elapsed_msec":"%{time.elapsed.msec}V","is_tls":"%{if(req.is_ssl, \"true\", \"false\")}V","client_ip":"%h","message":"%m %U returned %>s for %h on %v in %{time.elapsed.msec}Vms (UA: %{User-Agent}i, Cache: %{fastly_info.state}V)" ,"client_geo_city":"%{client.geo.city}V","client_geo_country_code":"%{client.geo.country_code}V","client_geo_continent_code":"%{client.geo.continent_code}V","client_geo_region":"%{client.geo.region}V","http_host":"%v","http_method":"%m","http_url":"%U","http_protocol":"%H","http_status_code":"%>s","http_referer":"%{Referer}i","http_user_agent":"%{User-Agent}i","bytes_received_from_client":"%I","bytes_sent_to_client":"%O","resp_content_type":"%{Content-Type}o","fastly_service_id":"%{req.service_id}V","fastly_service_version":"%{req.vcl.version}V","fastly_pop":"%{server.identity}V","fastly_region":"%{server.region}V","fastly_cache_status":"%{fastly_info.state}V","fastly_is_h2":"%{if(fastly_info.is_h2, \"true\", \"false\")}V","fastly_is_h3":"%{if(fastly_info.is_h3, \"true\", \"false\")}V","tls_client_protocol":"%{tls.client.protocol}V","tls_client_cipher":"%{tls.client.cipher}V","tls_client_ciphers_sha":"%{tls.client.ciphers_sha}V","tls_client_iana_chosen_cipher_id":"%{tls.client.iana_chosen_cipher_id}V","fastly_error_details":"%{fastly.error}V"}You can customize the log format to include only the fields you need. The Lambda function will forward whatever JSON structure you define. Here are some tips for customization:
-
Required Fields for Logz.io:
@timestamp- Required for proper log indexing, must be in ISO 8601 format (e.g.,%{begin:%Y-%m-%dT%H:%M:%SZ}t)message- A human-readable log message (recommended for better log readability)
-
Important Note About Service ID:
- While you provide the
service_idas a URL parameter, this is only used by the Lambda for processing - The service ID is NOT automatically added to the logs sent to Logz.io
- If you want to see or filter by service ID in Logz.io, you must include it in your Fastly log format (e.g.,
%{req.service_id}V)
- While you provide the
-
Optional Fastly Fields to Consider:
fastly_service_id- For service identification in Logz.io (%{req.service_id}V)fastly_service_version- For version tracking (%{req.vcl.version}V)fastly_pop- Point of Presence information (%{server.identity}V)fastly_region- Geographic region information (%{server.region}V)fastly_cache_status- Cache hit/miss status (%{fastly_info.state}V)
-
Common Fields to Consider:
- HTTP method, URL, and status code
- Client IP and geo information
- Response time
- Error details if applicable
-
Format Options:
- Use Fastly's VCL variables (prefixed with
%{...}V) - Include request headers (prefixed with
%{...}i) - Add response headers (prefixed with
%{...}o) - Use standard format specifiers (like
%hfor client IP) - Use consistent field names across your logging
- Use Fastly's VCL variables (prefixed with
For more information about available Fastly logging variables, refer to the Fastly VCL Variables documentation.
Your URL should include the following required parameters:
https://fastly.listener-logz.io/?service_id=YOUR_SERVICE_ID&token=YOUR_LOGZIO_TOKEN&host=YOUR_LOGZIO_HOST
Replace:
YOUR_SERVICE_IDwith your Fastly Service IDYOUR_LOGZIO_TOKENwith your Logz.io shipping tokenYOUR_LOGZIO_HOSTwith your Logz.io listener host (e.g.,listener.logz.ioor region-specific host)
For region-specific listener hosts, refer to the Logz.io Regions documentation.
After configuring the endpoint:
- Generate some traffic to your Fastly service
- Wait a few moments (typically less than 1 minute) for logs to appear
- Log into your Logz.io account
- Go to the Logs tab
- Search for
type:fastly-logsto see your Fastly logs (ortype:YOUR_CUSTOM_TYPEif you specified a custom type using thetypeparameter)
| Parameter | Required | Description | Example |
|---|---|---|---|
service_id |
Yes | Your Fastly Service ID | service_id=YOUR_SERVICE_ID |
token |
Yes | Your Logz.io logs shipping token | token=YOUR_LOGZIO_TOKEN |
host |
Yes | The Logz.io listener host address (may vary by region) | host=listener.logz.io or host=listener-eu.logz.io |
type |
No | Custom log type to be assigned in Logz.io (default: fastly-logs) |
type=my-custom-logs |
debug |
No | Set to true to enable debug logging (default: false) |
debug=true |
This implementation follows this flow:
- Request Handling: AWS API Gateway receives requests from Fastly
- Lambda Processing:
- Validates query parameters
- Handles health checks (required by Fastly)
- Processes incoming log data
- Forwards logs to Logz.io
- Response: Returns appropriate responses to Fastly
The Lambda function handles two types of requests:
-
Health Check Requests: Fastly periodically sends requests to
/.well-known/fastly/logging/challengeto verify the endpoint is working- The function calculates a SHA256 hash of the service_id and returns it as plain text
- This is required by Fastly to validate the endpoint
-
Log Forwarding Requests: Fastly sends log data via POST to the configured endpoint
- The function extracts the log data from the request body
- Handles base64 encoding and gzip compression
- Forwards the logs to Logz.io using the provided token and host
- The function implements a retry mechanism for transient failures
- All errors are logged to CloudWatch for monitoring
- Even on downstream errors, the function returns 200 to Fastly to prevent retry storms
This project uses GitHub Actions to automate the release process. When a new release is published on GitHub, the Lambda function is automatically deployed to AWS.
- Create a new release on GitHub with a version number tag (e.g., "1.0.1")
- The release workflow will automatically:
- Update the version.py file with the release tag version
- Package the Lambda function
- Deploy it to AWS Lambda
- Update the function configuration
The following secrets need to be configured in your GitHub repository:
AWS_ACCESS_KEY_ID: AWS access key with permissions to update LambdaAWS_SECRET_ACCESS_KEY: AWS secret key
The following variables need to be configured in your GitHub repository:
AWS_REGION: AWS region where your Lambda is deployedAWS_LAMBDA_FUNCTION_NAME: Name of your Lambda function
- Create a new Python 3.11+ Lambda function
- Upload the
lambda_function.pyandversion.pyfiles - No environment variables required as all configuration is via query parameters
- Set the Lambda timeout to at least 30 seconds
- Set the memory allocation based on your log volume (128MB is usually sufficient)
- Create a new HTTP API in API Gateway
- Create the following routes:
GET /.well-known/fastly/logging/challenge→ Lambda integrationPOST /logs→ Lambda integration
- Ensure query string parameters are passed to the Lambda
- Deploy the API to a stage (e.g.,
prod)
The Lambda function requires an IAM role with the following policies:
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": [
"logs:CreateLogGroup",
"logs:CreateLogStream",
"logs:PutLogEvents"
],
"Resource": "arn:aws:logs:*:*:*"
}
]
}- Monitor the Lambda function's CloudWatch Logs for execution details and errors
- Debug Mode: To enable detailed debug logging, add
debug=trueto your query parameters - Setting
debug=truechanges the logger level to DEBUG, showing more detailed logs - Logs include the service ID for easy filtering
- Check CloudWatch Metrics for Lambda execution time, memory usage, and error rates
To run tests locally:
python -m venv venv
source venv/bin/activate
pip install -r requirements.txt
pytest
pytest --cov=. --cov-report=term
deactivate- 1.0.0
- Initial release
- Support for Fastly health check mechanism
- Log forwarding to Logz.io
- Support for gzipped and uncompressed logs
- Debug mode
- Retry mechanism for transient failures