Log Forwarding log-forwarding

NOTE
A beta for mutual TLS (mTLS) authentication is available for Splunk, Elasticsearch/OpenSearch, and HTTPS destinations, for AEM logs (including Apache/Dispatcher) and CDN logs. To join, email aemcs-logforwarding-beta@adobe.com with your program ID and environment IDs. See Mutual TLS (mTLS) authentication.
NOTE
Log Forwarding is now configured in self-serve way, different from the legacy method, which required submitting an Adobe Support ticket. See the Migrating section if your log forwarding was setup by Adobe.

Customers with a license with a logging vendor or who host a logging product can have AEM logs (including Apache/Dispatcher) and CDN logs forwarded to the associated logging destination. AEM as a Cloud Service supports the following logging destinations:

Log Technnology
AEM
Dispatcher
CDN
mTLS
Amazon S3
Yes
Yes
Future
No
Azure Blob Storage
Yes
Yes
Yes
No
DataDog
Yes
Yes
Yes
No
Dynatrace
Yes
Yes
Future
No
ElasticSearch
OpenSearch
Yes
Yes
Yes
Beta
HTTPS
Yes
Yes
Yes
Beta
New Relic
Yes
Yes
Future
No
Splunk
Yes
Yes
Yes
Beta
Sumo Logic
Yes
Yes
Yes
No
NOTE
For upcoming CDN Log Technologies planned for the future, please email aemcs-logforwarding-beta@adobe.com to register interest.
Log Technologies marked Beta in the mTLS column support client certificate authentication (mutual TLS) for AEM, Dispatcher, and CDN logs. mTLS is in beta; to request access, email aemcs-logforwarding-beta@adobe.com with your program ID and environment IDs. See Mutual TLS (mTLS) authentication.

Log forwarding is configured in a self-service manner by declaring a configuration in Git, and can be deployed via Cloud Manager config pipelines to dev, stage, and production environment types. The configuration file can be deployed to Rapid Development Environments (RDEs) using command line tooling.

There is an option for the AEM and Apache/Dispatcher logs to be routed through AEM’s advanced networking infrastructure, such as dedicated egress IP.

Note that the network bandwidth associated with logs sent to the logging destination are considered part of your organization’s Network I/O usage.

How This Article is Organized how-organized

This article is organized in the following way:

  • Setup - common for all logging destinations
  • Transport & Advanced Networking - consideration should be given to network setup before creating logging configuration
  • Mutual TLS (mTLS) authentication - authenticating to Splunk, Elasticsearch/OpenSearch, and HTTPS destinations with a client certificate (beta)
  • Logging destination configurations - each destination has a slightly different format
  • Log Entry Formats - information about the log entry formats
  • Migrating from legacy log forwarding - how to move from log forwarding previously setup by Adobe to the self-serve approach

Setup setup

  1. Create a file named logForwarding.yaml. It should contain metadata, as described in the Configuration Pipeline article (kind should be set to LogForwarding and version set to “1”), with a configuration similar to the following (we use Splunk as an example).

    code language-yaml
    kind: "LogForwarding"
    version: "1"
    data:
      splunk:
        default:
          enabled: true
          host: "splunk-host.example.com"
          token: "${{SPLUNK_TOKEN}}"
          index: "AEMaaCS"
    
  2. Place the file somewhere under a top level folder named config or similar, as described in Using Config Pipelines.

  3. For environment types other than RDE (which uses command line tooling), create a targeted deployment config pipeline in Cloud Manager, as referenced by this section; note that Full Stack pipelines and Web Tier pipelines do not deploy the configuration file.

  4. Deploy the configuration.

Tokens in the configuration (such as ${{SPLUNK_TOKEN}}) represent secrets, which should not be stored in Git. Instead, declare them as Cloud Manager Secret Environment Variables. Make sure to select All as the dropdown value for the Service Applied field, so logs can be forwarded to author, publish, and preview tiers.

It is possible to set different values between CDN logs and AEM logs (including Apache/Dispatcher), by including an additional cdn and/or aem block after the default block, where properties can override those defined in the default block; only the enabled property is required. A possible use case could be to use a different Splunk index for CDN logs, as the example below illustrates.

   kind: "LogForwarding"
   version: "1"
   data:
     splunk:
       default:
         enabled: true
         host: "splunk-host.example.com"
         token: "${{SPLUNK_TOKEN}}"
         index: "AEMaaCS"
       cdn:
         enabled: true
         token: "${{SPLUNK_TOKEN_CDN}}"
         index: "AEMaaCS_CDN"

Another scenario is to disable either forwarding of the CDN logs or AEM logs (including Apache/Dispatcher). For example, to only forward the CDN logs, one can configure the following:

   kind: "LogForwarding"
   version: "1"
   data:
     splunk:
       default:
         enabled: true
         host: "splunk-host.example.com"
         token: "${{SPLUNK_TOKEN}}"
         index: "AEMaaCS"
       aem:
         enabled: false

Transport & Advanced Networking transport-advancednetworking

Some organizations choose to restrict which traffic can be received by the logging destinations, others may require to use ports other than HTTPS (443). If so Advanced Networking will need to be configured before deploying log forwarding configuration.

Use the table below to see what the requirements are for Advanced Networking and Logging configuration based on whether you are using port 443 or not, and whether or not you need your logs to appear from a fixed IP address.

Destination Port
Requirement for Logs to appear from Fixed IP?
Advanced Networking Needed
LogForwarding.yaml Port Definition Needed
HTTPS (443)
No
No
No
Yes
Yes, Dedicated Egress
No
Non standard port (e.g 8088)
No
Yes, Flexible Egress
Yes
Yes
Yes, Dedicated Egress
Yes
NOTE
Whether your logs appear from a single IP address is determined by your choice of Advanced Networking configuration. Dedicated Egress must be used to facilitate this.
Advanced Networking configuration is a two-step process requiring enablement at program and environment level.
Per note below it is not possible to use Log Forwarding with Advanced Networking VPN connections.

For AEM logs (including Apache/Dispatcher), if you have configured Advanced Networking, you can use the aem.advancedNetworking property to forward them from a Dedicated Egress IP address.

The example below shows how to configure logging on a standard HTTPS port with Advanced Networking.

kind: "LogForwarding"
version: "1"
data:
  splunk:
    default:
      enabled: true
      host: "splunk-host.example.com"
      port: 443
      token: "${{SPLUNK_TOKEN}}"
      index: "aemaacs"
    aem:
      advancedNetworking: true

For CDN logs, you can allow-list the IP addresses, as described in Fastly documentation - Public IP List. If that list of shared IP addresses is too large, consider sending traffic to an https server or (non-Adobe) Azure Blob Store where logic can be written to send the logs out of a known IP to their ultimate destination.

NOTE
It is not possible for CDN logs to appear from the same IP address that your AEM logs appear from, this is because logs are sent directly from Fastly and not AEM Cloud Service.
For this reason it is not possible to use Log Forwarding with Advanced Networking VPN configurations.

Mutual TLS (mTLS) authentication mtls

NOTE
mTLS for Log Forwarding is a beta feature. To use it, email aemcs-logforwarding-beta@adobe.com with your program ID and environment IDs.

Splunk, Elasticsearch/OpenSearch, and HTTPS destinations support mutual TLS (mTLS). With mTLS, AEM as a Cloud Service presents a client certificate when it connects to your logging destination, so the destination can verify that the logs come from your environment. mTLS applies to AEM logs (including Apache/Dispatcher) and to CDN logs.

mTLS works alongside the destination’s existing authentication. Keep the destination’s existing authentication properties, such as token (Splunk) or user and password (Elasticsearch/OpenSearch). For HTTPS destinations that forward CDN logs, authHeaderName and authHeaderValue are required.

Configuration mtls-configuration

Add an mtls block alongside the destination’s other properties:

  • cert - required. The client certificate, in PEM format. It can be followed by intermediate CA certificates, with the client certificate first.
  • key - required. The private key for the client certificate, in PEM format. RSA and EC keys are supported, unencrypted or encrypted. See Supported key formats.
  • ca - optional. The CA certificate, in PEM format, used to verify your destination’s server certificate. It can contain more than one certificate, such as a certificate chain. Set it when the server certificate is issued by a private CA.
  • keyPasswd - optional. The password for the private key. Set it only if the key is encrypted.

The following example forwards AEM and CDN logs to Splunk using mTLS:

kind: "LogForwarding"
version: "1"
data:
  splunk:
    default:
      enabled: true
      host: "splunk-host.example.com"
      token: "${{SPLUNK_TOKEN}}"
      index: "aemaacs"
      mtls:
        cert: "${{SPLUNK_MTLS_CERT}}"
        key: "${{SPLUNK_MTLS_KEY}}"
        ca: "${{SPLUNK_MTLS_CA}}"

The following rules apply:

  • cert and key must be provided together. An mtls block that contains only ca or keyPasswd is rejected.
  • Each mtls property must be a secret reference, such as ${{SPLUNK_MTLS_CERT}}, and nothing else. Certificate or key text placed directly in the file is rejected.
  • Declare each secret as a Cloud Manager Secret Environment Variable, as described in Setup. Paste the complete PEM text, including the -----BEGIN and -----END lines. If the line breaks are removed when you paste the value into Cloud Manager, they are restored automatically. To provide more than one certificate, paste them one after another in the same secret.
  • The client certificate is checked when you deploy. It must be valid PEM and within its validity period. If cert contains more than one certificate, the client certificate must come first and the certificates must form a valid chain. If a check fails, the deployment fails.

Supported key formats mtls-key-formats

The first line of the key’s PEM text shows its format:

Key format
First line of the PEM text
RSA, PKCS#1
-----BEGIN RSA PRIVATE KEY-----
EC, SEC1
-----BEGIN EC PRIVATE KEY-----
PKCS#8 (RSA or EC)
-----BEGIN PRIVATE KEY-----
Encrypted PKCS#8 (RSA or EC)
-----BEGIN ENCRYPTED PRIVATE KEY-----
Encrypted, older format (RSA or EC), with AES or Triple DES (DES-EDE3-CBC)
-----BEGIN RSA PRIVATE KEY----- or -----BEGIN EC PRIVATE KEY-----, followed by Proc-Type: 4,ENCRYPTED and DEK-Info lines

For an encrypted key, also set keyPasswd to its password.

Encrypted PKCS#8 is recommended for encrypted keys. To convert a key in the older format, use the following command, which asks for the current password and then for the password of the new key:

openssl pkcs8 -topk8 -v2 aes-256-cbc -in client.key -out client-pkcs8.key

Store the content of client-pkcs8.key in the secret referenced by key, and its password in the secret referenced by keyPasswd.

CDN logs mtls-cdn

Like other properties, an mtls block under default applies to both AEM logs and CDN logs. To use a different certificate for CDN logs, set the mtls properties in a cdn block. To use mTLS for only AEM logs or only CDN logs, place the mtls block in the aem or cdn block instead of default.

After you deploy a configuration that enables CDN log forwarding to a destination, it can take several minutes before the first CDN logs arrive. For HTTPS destinations, CDN log delivery also starts only after your server completes the one-time challenge described in HTTPS. The challenge request is sent with the same client certificate, so your server must accept that certificate on the challenge path too.

Certificate rotation and expiry mtls-rotation

To rotate a certificate, update the Cloud Manager secret environment variables that hold the certificate (and the key, if it changed), then re-run the config pipeline. If the log forwarding configuration file itself is unchanged, also make a change to it so that the configuration is applied again. For example, store the new values in new secret environment variables and reference those names in the mtls block.

You may also receive a proactive Actions Center notification about 21 days before a client certificate expires. Track certificate expiry dates yourself rather than relying on this notification.

Logging Destination Configuration logging-destinations

Configurations for the supported logging destinations are listed below, along with any specific considerations.

Amazon S3 amazons3

Log Forwarding to Amazon S3 supports AEM and Dispatcher logs, CDN logs are not yet supported.

NOTE
Logs written to S3 periodically, every 10 minutes for each log file type. This may result in an initial delay for logs being written to S3 once the feature is toggled. Further information on this behavior.
kind: "LogForwarding"
version: "1"
data:
  awsS3:
    default:
      enabled: true
      region: "your-bucket-region"
      bucket: "your_bucket_name"
      accessKey: "${{AWS_S3_ACCESS_KEY}}"
      secretAccessKey: "${{AWS_S3_SECRET_ACCESS_KEY}}"

In order to use the S3 Log Forwarder, you will need to preconfigure an AWS IAM user with appropriate policy for accessing your S3 bucket. See AWS IAM User Documentation for how to create IAM user credentials.

The IAM policy should allow the user to use s3:putObject. For example:

 {
    "Version": "2012-10-17",
    "Statement": [{
        "Effect": "Allow",
        "Action": [
            "s3:PutObject"
        ],
        "Resource": "arn:aws:s3:::your_bucket_name/*"
    }]
}

See AWS Bucket Policy Documentation for more information on how to implement.

NOTE
CDN Log support for AWS S3 is planned for the future. Please email aemcs-logforwarding-beta@adobe.com to register interest.

Azure Blob Storage azureblob

kind: "LogForwarding"
version: "1"
data:
  azureBlob:
    default:
      enabled: true
      storageAccountName: "example_acc"
      container: "aem_logs"
      sasToken: "${{AZURE_BLOB_SAS_TOKEN}}

A SAS token should be used for authentication. It should be created from the Shared access signature page, rather than on the Shared access token page, and should be configured with these settings:

  • Allowed services: Blob must be selected.
  • Allowed resources: Object and container must be selected.
  • Allowed permissions: Read, Write, Add, List, Create must be selected.
  • A valid Start and Expiry date/time.

Here is a screenshot of a sample SAS token configuration:

Azure Blob SAS token configuration

If logs have stopped being delivered after previously functioning correctly, check whether the SAS token you configured is still valid, as it may have expired.

Azure Blob Storage CDN logs azureblob-cdn

Each of the globally distributed logging servers will produce a new file every few seconds, under the aemcdn folder. Once created, the file will no longer be appended to. The filename format is YYYY-MM-DDThhss.sss-uniqueid.log. E.g., 2024-03-04T10:00:00.000-WnFWYN9BpOUs2aOVn4ee.log.

As an example, at some point in time:

aemcdn/
   2024-03-04T10:00:00.000-abc.log
   2024-03-04T10:00:00.000-def.log

And then 30 seconds later:

aemcdn/
   2024-03-04T10:00:00.000-abc.log
   2024-03-04T10:00:00.000-def.log
   2024-03-04T10:00:30.000-ghi.log
   2024-03-04T10:00:30.000-jkl.log
   2024-03-04T10:00:30.000-mno.log

Each file contains multiple json log entries, each on a separate line. The log entry formats are described under Logging for AEM as a Cloud Service, and each log entry also includes the additional properties mentioned in the Log Entry Formats section below.

Azure Blob Storage AEM logs azureblob-aem

AEM logs (including Apache/Dispatcher) appear below a folder with the following naming convention:

  • aemaccess
  • aemerror
  • aemrequest
  • aemdispatcher
  • aemhttpdaccess
  • aemhttpderror

Under each folder, a single file will be created and appended to. Customers are responsible for processing and managing this file so it does not grow too large.

See the log entry formats under Logging for AEM as a Cloud Service. The log entries will also include the additional properties mentioned in the Log Entry Formats section below.

Datadog datadog

kind: "LogForwarding"
version: "1"
data:
  datadog:
    default:
      enabled: true
      host: "http-intake.logs.datadoghq.eu"
      token: "${{DATADOG_API_KEY}}"
      tags:
         tag1: value1
         tag2: value2

Considerations

  • Create an API Key, without any integration with a specific cloud provider.
  • The tags property is optional
  • For AEM logs, the Datadog source tag is set to one of aemaccess, aemerror, aemrequest, aemdispatcher, aemhttpdaccess, or aemhttpderror
  • For CDN logs, the Datadog source tag is set to aemcdn
  • The Datadog service tag is set to adobeaemcloud, but you can overwrite it in the tags section
  • If your ingestion pipeline uses Datadog tags to determine the appropriate index for forwarding logs, verify that these tags are correctly configured in the Log Forwarding YAML file. Missing tags may prevent successful log ingestion if the pipeline depends on them.

Elasticsearch and OpenSearch elastic

kind: "LogForwarding"
version: "1"
data:
  elasticsearch:
    default:
      enabled: true
      host: "example.com"
      user: "${{ELASTICSEARCH_USER}}"
      password: "${{ELASTICSEARCH_PASSWORD}}"
      pipeline: "ingest pipeline name"

Considerations

  • by default, the port is 443. It can optionally be overridden with a property named port
  • For credentials, make sure to use use deployment credentials, rather than account credentials. These are the credentials that are generated in a screen that may resemble this image:

Elastic deployment credentials

  • For AEM logs, index is set to one of aemaccess, aemerror, aemrequest, aemdispatcher, aemhttpdaccess, or aemhttpderror
  • The optional pipeline property should be set to the name of the Elasticsearch or OpenSearch ingest pipeline, which can be configured to route the log entry to the appropriate index. The pipeline’s Processor type must be set to script and the script language should be set to painless. Here is a sample script snippet to route log entries into an index such as aemaccess_dev_26_06_2024:
def envType = ctx.aem_env_type != null ? ctx.aem_env_type : 'unknown';
def sourceType = ctx._index;
def date = new SimpleDateFormat('dd_MM_yyyy').format(new Date());
ctx._index = sourceType + "_" + envType + "_" + date;

HTTPS https

kind: "LogForwarding"
version: "1"
data:
  https:
    default:
      enabled: true
      url: "https://example.com/aem_logs/aem"
      authHeaderName: "X-AEMaaCS-Log-Forwarding-Token"
      authHeaderValue: "${{HTTPS_LOG_FORWARDING_TOKEN}}"

Considerations

  • The url string must include https:// or validation will fail.
  • The url may include a port. For example, https://example.com:8443/aem_logs/aem. If no port is included in the url string, port 443 (the default HTTPS port) is assumed.

HTTPS CDN logs https-cdn

Web requests (POSTs) will be sent continuously, with a json payload that is an array of log entries, with the log entry format described under Logging for AEM as a Cloud Service. Additional properties are mentioned in the Log Entry Formats section below.

There is also be a property named sourcetype, which is set to the value aemcdn.

NOTE
Before the first CDN log entry is sent, your HTTP server must successfully complete a one-time challenge: a request sent to the path /.well-known/fastly/logging/challenge must respond with an asterisk * in the body and 200 status code.

HTTPS AEM logs https-aem

For AEM logs (including apache/dispacher), web requests (POSTs) will be sent continuously, with a json payload that is an array of log entries, with the various log entry formats as described under Logging for AEM as a Cloud Service. Additional properties are mentioned in the Log Entry Formats section below.

There is also be a property named Source-Type, which is set to one of these values:

  • aemaccess
  • aemerror
  • aemrequest
  • aemdispatcher
  • aemhttpdaccess
  • aemhttpderror

New Relic Log API newrelic-https

Log Forwarding to New Relic leverages the New Relic HTTPS API for ingestion. Currently it only supports logs from AEM and Dispatcher; CDN logs are not yet supported.

  kind: "LogForwarding"
  version: "1"
  data:
    newRelic:
      default:
        enabled: true
        uri: "https://log-api.newrelic.com/log/v1"
        apiKey: "${{NR_API_KEY}}"
NOTE
Log forwarding to New Relic is only available to customer owned New Relic accounts.
CDN Log support for New Relic Log API is planned for the future. Please email aemcs-logforwarding-beta@adobe.com to register interest.
New Relic provides region specific endpoints based on where your New Relic account is provisioned. See New Relic documentation for further information.

Dynatrace Log API dynatrace-https

Log Forwarding to Dynatrace leverages the Dynatrace HTTPS API for ingestion. Currently it only supports logs from AEM and Dispatcher; CDN logs are not yet supported.

The “Ingest Logs” scope attribute is required for the Token.

  kind: "LogForwarding"
  version: "1"
  data:
    dynatrace:
      default:
        enabled: true
        environmentId: "${{DYNATRACE_ENVID}}"
        token: "${{DYNATRACE_TOKEN}}"
NOTE
CDN Log support for Dynatrace Log API is planned for the future. Please email aemcs-logforwarding-beta@adobe.com to register interest.

Splunk splunk

kind: "LogForwarding"
version: "1"
data:
  splunk:
    default:
      enabled: true
      host: "splunk-host.example.com"
      token: "${{SPLUNK_TOKEN}}"
      index: "aemaacs"

Considerations

  • By default, the port is 443. It can optionally be overridden with a property named port.
  • The sourcetype field will have one of the following values, depending on the specific log: aemaccess, aemerror,
    aemrequest, aemdispatcher, aemhttpdaccess, aemhttpderror, aemcdn
  • If the required IPs have been allowlisted and logs are still not being delivered, verify that there are no firewall rules enforcing Splunk token validation. Fastly performs an initial validation step where an invalid Splunk token is intentionally sent. If your firewall is set to terminate connections with invalid Splunk tokens, the validation process will fail, preventing Fastly from delivering logs to your Splunk instance.
NOTE
If migrating from legacy Log Forwarding to this self-serve model, the sourcetype field’s values sent to your Splunk index may have changed, so adjust accordingly.

Sumo Logic sumologic

When configuring Sumo Logic for data ingestion you will be presented with an “HTTP Source Address” which provides the host, receiverURI and the private key in a single string. For example:

https://collectors.de.sumologic.com/receiver/v1/http/ZaVnC...

You will need to copy the last section of the URL (without the preceeding /) and add that as a CloudManager Secret Environment Variable as described in the Setup section above, then reference that variable in your configuration. An example is provided below.

kind: "LogForwarding"
version: "1"
data:
  sumoLogic:
    default:
      enabled: true
      collectorURL: "https://collectors.de.sumologic.com/receiver/v1/http"
      privateKey: "${{SUMOLOGIC_PRIVATE_KEY}}"
      index: "aem-logs"
NOTE
The index field behavior depends on the log type:
  • AEM logs (including Apache/Dispatcher): routed to the partition specified by index, provided you have a Sumo Logic Enterprise subscription. Non-Enterprise subscriptions route to the sumologic_default partition instead.
  • CDN logs: the index field is ignored, as indexing is not technically supported for CDN logs forwarded to Sumo Logic. CDN logs are always routed to the sumologic_default partition.
See the Sumo Logic Partitioning Documentation for more information.

Log Entry Formats log-formats

See Logging for AEM as a Cloud Service for the format of each respective log type (CDN logs, and AEM logs including Apache/Dispatcher).

Since logs from multiple programs and environments may be forwarded to the same logging destination, in addition to the output described in the logging article, the following properties will be included in each log entry:

  • aem_env_id
  • aem_env_type
  • aem_program_id
  • aem_tier

As an example, the properties could have the following values:

aem_env_id: 1242
aem_env_type: dev
aem_program_id: 12314
aem_tier: author

Migrating from Legacy Log Forwarding legacy-migration

Before Log Forwarding configuration was achieved through a self-serve model, customers were requested to open support tickets, where Adobe would initiate the integration.

Customers who had been setup in that manner by Adobe are welcome to adapt to the self-serve model at their convenience. There are several reason to make this transition:

  • A new environment (e.g., a new dev env or RDE) has been provisioned.
  • Changes to your existing Splunk endpoint or credentials.
  • Adobe had setup your log forwarding before CDN logs were available and you would like to receive CDN logs.
  • A conscious decision to proactively adapt to the self-serve model so your organization has the knowledge even before a time-sensitive change is necessary.

When ready to migrate, simply configure the YAML file as described in the preceding sections. Use the Cloud Manager config pipeline to deploy to each of the environments where the configuration should be applied.

It is recommended, but not required, that a configuration is deployed to all environments so they are all under self-serve control. If not, you may forget which environments have been configured by Adobe versus those configured in a self-serve way.

NOTE
The sourcetype field’s values sent to your Splunk index may have changed, so adjust accordingly.
When Log Forwarding is deployed to an environment previously configured by Adobe support, you may receive duplicate logs for up to a few hours. This will eventually auto-resolve.
recommendation-more-help
experience-manager-cloud-service-help-main-toc