Chapter 2. Configuring log forwarding
Implement a tailored log routing pipeline to deliver the right data to the right stakeholders. By configuring log forwarding, you can bridge the gap between raw cluster telemetry and the specific needs of site reliability engineers (SREs), security officers, and developers, ensuring high-signal logs reach your external destinations while managing storage costs and compliance requirements.
2.1. About log forwarding Copy linkLink copied to clipboard!
You can design a log routing pipeline that connects raw cluster telemetry to the specific needs of your organization. A managed data service can help you balance deep operational visibility for site reliability engineers (SREs) with strict long-term retention requirements for security and compliance officers.
In a complex OpenShift Container Platform environment, a one-size-fits-all approach to logging is often too expensive or legally insufficient. Log forwarding helps you do the following:
- Reduce costs: Use filters to drop "noisy" debug logs or rate-limit high-volume applications before they hit expensive storage.
- Ensure compliance: Isolate sensitive audit trails and route them to immutable "cold storage" for long-term legal retention.
- Empower teams: Deliver application-specific logs directly to tools such as LokiStack, Splunk, or Datadog, allowing developers to use familiar platforms they already know.
By orchestrating multiple log routing pipelines, you can resolve the natural tensions between different log consumers:
- Cost versus visibility: Provide SREs with high-volume logs for short-term troubleshooting without incurring the costs of long-term storage on high-performance systems.
- Compliance versus accessibility: Create a dedicated audit log routing pipeline that bypasses standard developer tools to ship raw data directly to an immutable security archive.
- Data sovereignty: Ensure that filters prune specific fields or logs from sensitive namespaces before they leave the cluster for a third-party SaaS provider.
2.2. How log forwarding works Copy linkLink copied to clipboard!
Log forwarding is powered by a collector that runs as a DaemonSet on every node in your cluster. To manage how this collector handles data, you define a ClusterLogForwarder custom resource (CR) that routes logs through three distinct functional areas:
- Inputs
Inputs define the source of your telemetry. The collector recognizes three reserved, high-level input types:
- Application: Application logs provide telemetry for user-deployed workloads.
- Infrastructure: Infrastructure logs provide telemetry for the node operating system and OpenShift Container Platform components.
Audit: Audit logs provide telemetry for sensitive security and API server records.
In addition to these default input types, you can configure receiver inputs that allow the collector to listen for incoming log data from external sources. Receiver inputs enable the collector to act as a server that accepts logs over HTTP or syslog protocols. This is useful when logs originate from Red Hat-supported products installed on the same cluster, such as Red Hat OpenStack Services on OpenShift (RHOSO) or OpenShift Virtualization, or when logging is installed on hosted control planes.
TipYou can also define custom inputs to target specific namespaces or pods using label selectors, which can isolate data for specific application teams.
- Filters
-
Filters serve as the logic gates where you enforce data policies. You use filters to refine the stream before it leaves the cluster. This includes using a
prunefilter to remove specific metadata or JSON fields containing personally identifiable information (PII), and adropfilter to discard records based on regular expressions or severity levels. The collector also supports rate limiting to prevent a single high-volume application from overwhelming your storage infrastructure. - Outputs
- Outputs specify the final destination for the telemetry. You can configure multiple outputs to satisfy different consumers simultaneously. Supported destinations include internal stores like LokiStack, external providers like Splunk, Datadog, or Amazon CloudWatch, and standard protocols like Kafka, Syslog, or S3-compatible object storage.
Log routing pipelines act as the central orchestrator of the entire log routing process. A pipeline is not a step in the sequence, but the configuration logic that binds inputs and filters to specific outputs. By defining multiple pipelines within a single ClusterLogForwarder CR, you can split a single source into different paths. For example, one log routing pipeline can send raw audit logs to an S3 bucket for compliance, while a second pipeline filters those same logs for errors and sends them to a site reliability engineer (SRE) alerting dashboard.
Service account permissions ensure the collector has the necessary authority to gather logs. The collector uses a specific service account, identified in the spec.serviceAccount.name field of the CR. You must provide this service account with the appropriate ClusterRoleBinding permissions for each log type that you intend to collect.
2.3. About collector permissions and identity Copy linkLink copied to clipboard!
The Red Hat OpenShift Logging Operator uses a collector to gather logs from across your cluster. For the collector to access these logs, it must have a distinct role and explicit permission to read specific types of log data from the nodes and the API.
- Service account
-
When you configure log forwarding, you must first create a
ServiceAccountin theopenshift-loggingnamespace. This service account acts as the identity for the collector pods. You must reference this account by name when you create yourClusterLogForwardercustom resource (CR). - Log types and cluster roles
OpenShift Container Platform protects log data using role-based access control (RBAC). To allow the collector to "see" logs, you must create
ClusterRoleBindingsthat connect your service account to the following predefined roles:-
collect-application-logs: Grants access to logs from user-defined projects. -
collect-infrastructure-logs: Grants access to logs from the nodes and system projects such asopenshift-*andkube-*. -
collect-audit-logs: Grants access to the sensitive audit logs that the API server and OAuth server generate.
-
Sequence is critical. You must grant these permissions before you include the corresponding log types in your ClusterLogForwarder configuration.
If the ClusterLogForwarder CR requests a log type that the collector’s service account is not authorized to access, the Operator enters a protective failure state. To prevent an insecure or partial configuration, the Operator removes the entire collector DaemonSet, which stops all log collection for the cluster.
2.4. Granting collector permissions Copy linkLink copied to clipboard!
You must grant explicit permissions to the collector service account before the ClusterLogForwarder can collect logs. Each log type requires a separate ClusterRoleBinding.
Avoid a service outage: Always create the required ClusterRoleBinding before you add a new log type to the ClusterLogForwarder custom resource (CR).
If you add a log type to your pipeline without the corresponding permissions, the Operator removes the entire collector DaemonSet. This stops all log collection for the entire cluster.
Prerequisites
- You have installed the Red Hat OpenShift Logging Operator.
-
You have
cluster-adminpermissions.
Procedure
Create a service account for the collector. This example creates the service account in the
openshift-loggingnamespace, but you can deploy the collector in any namespace by running the following command:$ oc create sa collector -n openshift-loggingGrant the service account permission to collect application logs by running the following command:
$ oc adm policy add-cluster-role-to-user collect-application-logs \ system:serviceaccount:openshift-logging:collectorGrant the service account permission to collect infrastructure logs by running the following command:
$ oc adm policy add-cluster-role-to-user collect-infrastructure-logs \ system:serviceaccount:openshift-logging:collectorOptional: Grant the service account permission to collect audit logs by running the following command:
$ oc adm policy add-cluster-role-to-user collect-audit-logs \ system:serviceaccount:openshift-logging:collectorNoteYou can add audit log collection later. If you do, grant this
ClusterRoleBindingbefore you addauditto theinputRefslist in yourClusterLogForwarderCR.Considerations for audit logs:
- Volume and Cost: Audit logs are significantly more voluminous than application or infrastructure logs. In cloud environments, this can lead to unexpected storage and data transfer costs.
-
Sensitivity: Audit logs contain a detailed record of API activity. To protect sensitive metadata and manage data volume, consider implementing
prunefilters to remove specific fields before the logs are forwarded to their destination.
Verification
Verify that the
ClusterRoleBindingsexist for your service account by running the following command:$ oc get clusterrolebinding -o wide | grep collectThe output shows a binding for each log type that you granted:
Example output
collect-application-logs ClusterRole/collect-application-logs 11m system:serviceaccount:openshift-logging:collector collect-infrastructure-logs ClusterRole/collect-infrastructure-logs 11m system:serviceaccount:openshift-logging:collector
2.5. Creating the log forwarder Copy linkLink copied to clipboard!
Create a ClusterLogForwarder custom resource (CR) to define your log forwarding pipeline. This CR links the collector’s service account to specific log sources, optional filters, and your chosen destination.
Prerequisites
-
You have
cluster-adminpermissions. -
You have installed the Red Hat OpenShift Logging Operator in the
openshift-loggingnamespace. -
You have created a collector service account and granted the required
ClusterRoleBindings. See "Granting collector permissions for log collection." -
You have installed the Loki Operator and a
LokiStackinstance namedlogging-lokiexists in theopenshift-loggingnamespace if you are forwarding logs to LokiStack.
Prerequisite Check: You must have already created the collector service account and granted it the required permissions. If you reference a service account or log source without the proper ClusterRoleBinding, the Operator will shut down all log collection for the cluster.
Procedure
Define the
ClusterLogForwarderCR. Use the following example to forward application and infrastructure logs to an in-clusterLokiStack.apiVersion: observability.openshift.io/v1 kind: ClusterLogForwarder metadata: name: instance namespace: openshift-logging spec: serviceAccount: name: collector outputs: - name: default-lokistack type: lokiStack lokiStack: authentication: token: from: serviceAccount target: name: logging-loki namespace: openshift-logging tls: ca: configMapName: logging-loki-gateway-ca-bundle key: service-ca.crt pipelines: - name: default-logstore inputRefs: - application - infrastructure outputRefs: - default-lokistackmetadata.name-
The
namemust beinstance. It is a singleton. spec.serviceAccount.name-
The service account that the collector uses to authenticate. This service account must have
ClusterRoleBindingsfor each log type listed ininputRefs. spec.outputs[].type-
Set to
lokiStackfor the in-clusterLokiStack. This type uses theLokiStackgateway for authentication and multi-tenancy. spec.outputs[].lokiStack.target.name-
The name of your
LokiStackCR. This value must strictly match the name of theLokiStackyou want to forward logs to, and is not bound to a specific default. spec.outputs[].tls.ca.configMapName-
The
ConfigMapthat has the certificate authority (CA) bundle for theLokiStackgateway. Uselogging-loki-gateway-ca-bundle. spec.outputs[].tls.ca.keyThe key in the
ConfigMapthat has the CA certificate. For the service-signed certificate, useservice-ca.crt.NoteYou must include the
tls.cablock in the output configuration when forwarding to LokiStack. Without it, the collector cannot verify theLokiStackgateway certificate. TheClusterLogForwarderreportsReady, but the collector fails silently and no logs reachLokiStack.spec.pipelines[].inputRefs-
The log types to collect. Add only log types for which the service account has
ClusterRoleBindings.
Apply the
ClusterLogForwarderCR by running the following command:$ oc apply -f <filename>.yamlVerify that the
ClusterLogForwarderstatus showsReadyby running the following command:$ oc get clusterlogforwarder instance -n openshift-logging \ -o jsonpath='{.status.conditions[?(@.type=="Ready")].status}'The output should show
True. If the output showsFalse, check thestatus.conditionsfor error messages:$ oc get clusterlogforwarder instance -n openshift-logging \ -o jsonpath='{.status.conditions}' | python3 -m json.tool
2.5.1. Checking status conditions Copy linkLink copied to clipboard!
You can view the ClusterLogForwarder status conditions to verify that the CR is valid and the collector is running.
Procedure
View the
ClusterLogForwarderstatus by running the following command:$ oc get clusterlogforwarder instance -n openshift-logging \ -o jsonpath='{.status.conditions}' | python3 -m json.toolExample output
[ { "type": "observability.openshift.io/Authorized", "status": "True", "message": "permitted to collect log types: [application audit infrastructure]" }, { "type": "observability.openshift.io/Valid", "status": "True", "message": "" }, { "type": "Ready", "status": "True", "message": "" } ]
2.5.2. About status conditions Copy linkLink copied to clipboard!
The ClusterLogForwarder reports its state through status.conditions. Use these conditions to verify that the CR is valid and the collector is running:
| Condition | Expected | Description |
|---|---|---|
|
|
|
The collector service account has |
|
|
| The CR passes schema and semantic validation. |
|
|
| The Operator reconciled the CR without error or validation failures, and can create resources to support a collector deployment. |
If Authorized shows False, the collector service account lacks a required ClusterRoleBinding. The Operator removes the collector DaemonSet until you grant the missing binding.
If Valid shows False, the CR has a structural or semantic error. Check the message field for details.
2.5.3. Verifying that log collection is working Copy linkLink copied to clipboard!
After you create the ClusterLogForwarder custom resource (CR), verify that the collector is running and that logs are flowing to your destination. This verification step is critical for all stakeholders: developers need to confirm that their application logs are accessible, site reliability engineers need operational visibility, and security officers must ensure that audit logs are being captured for compliance.
Prerequisites
-
You have created a
ClusterLogForwarderCR. - You have access to the OpenShift Container Platform web console.
Procedure
Verify that the
ClusterLogForwarderstatus conditions all showTrueby running the following command:$ oc get clusterlogforwarder instance -n openshift-logging \ -o jsonpath='{.status.conditions}' | python3 -m json.toolConfirm the following conditions:
-
observability.openshift.io/AuthorizedisTrueand the message lists the log types that the collector can collect. -
observability.openshift.io/ValidisTrue. -
ReadyisTrue.
If
AuthorizedshowsFalse, the collector service account lacks a requiredClusterRoleBinding. See "Granting collector permissions for log collection."-
Verify that a collector pod is running by running the following command:
$ oc get pods -n openshift-logging -l app.kubernetes.io/component=collectorExample output
NAME READY STATUS RESTARTS AGE instance-jlhjw 1/1 Running 0 5m- In the OpenShift Container Platform web console, go to Observe > Logs.
- Select a log type from the drop-down menu, such as infrastructure, and verify that log entries appear.
Optional: Check the collector logs for errors by running the following command:
$ oc logs -n openshift-logging -l app.kubernetes.io/component=collector --tail=20
Troubleshooting
-
429 Too Many Requests: This status code can occur during initial log collection. The collector flushes a backlog of accumulated logs to the
LokiStack. The error typically resolves within several minutes. -
certificate verify failed: self-signed certificate in certificate chain: The
tls.cablock is missing or incorrect in theClusterLogForwarderoutput configuration. TheClusterLogForwarderstill reportsReady, but the collector cannot deliver logs. See "Creating aClusterLogForwarderforLokiStack`" for the required `tls.caconfiguration. -
Collector pod not found: If no collector pod exists, check the
ClusterLogForwarderstatus conditions. A common cause is a missingClusterRoleBindingfor one of the log types ininputRefs. See "Granting collector permissions for log collection."
2.6. Configuring inputs Copy linkLink copied to clipboard!
2.6.1. ClusterLogForwarder input types Copy linkLink copied to clipboard!
Input types define the source of log data for the collector to gather and forward. You can configure inputs to select specific log streams from different parts of your cluster.
applicationSelects logs from user-deployed application containers. This input type excludes logs from infrastructure namespaces. You can further customize which application logs to collect by specifying namespace and pod label selectors.
Use case: Developers need access to their application logs for debugging and troubleshooting. Use custom inputs with label selectors to route logs from specific applications to dedicated outputs that development teams can access.
The
applicationinput type can be configured with the following:-
selector: A label selector to collect logs only from pods with matching labels -
includes: A list of namespaces and container patterns to include -
excludes: A list of namespaces and container patterns to exclude -
tuning: Configuration for rate limiting per container and maximum message size
-
infrastructureSelects logs from infrastructure components and system services. This includes logs from two sources:
-
container: Container logs from workloads deployed in namespaces with thedefault,kube*, oropenshift*prefix -
node: Journal logs from the cluster nodes
If you do not specify sources, the collector gathers logs from both container and node sources.
Use case: Site reliability engineers need infrastructure logs for troubleshooting cluster issues, analyzing node performance, and monitoring Red Hat OpenShift Logging component health.
-
auditSelects audit logs that track security-relevant events in the cluster. Audit logs are sourced from multiple components:
-
kubeAPI: Kubernetes API server audit logs -
openshiftAPI: Red Hat OpenShift Logging API server audit logs -
auditd: Node audit daemon logs -
ovn: Open Virtual Network audit logs
If you do not specify sources, the collector gathers logs from all audit sources.
Use case: Security officers require audit logs for compliance, security investigations, and maintaining an immutable record of API activity. Audit logs are typically more voluminous and require careful consideration of storage costs and retention policies.
-
receiverCreates a network listener that receives logs from sources outside the cluster. This input type can accept logs from remote systems or applications that cannot use the standard collector deployment.
Supported receiver types include:
-
http: Receives logs over HTTP (currently supports Kubernetes audit logs only) -
syslog: Receives logs using the syslog protocol (currently supports infrastructure logs only)
Each receiver requires a port number between 1024 and 65535. The operator can request TLS certificates from the cluster certificate signing service or you can provide your own certificates.
-
2.6.2. Filtering application logs at input by including or excluding the namespace or container name Copy linkLink copied to clipboard!
You can include or exclude the application logs based on the namespace and container name by using the input selector.
Procedure
Add a configuration to include or exclude the namespace and container names in the
ClusterLogForwarderCR.apiVersion: observability.openshift.io/v1 kind: ClusterLogForwarder # ... spec: serviceAccount: name: <service_account_name> inputs: - name: mylogs application: includes: - namespace: "my-project" container: "my-container" excludes: - container: "other-container*" namespace: "other-namespace" type: application # ...includes.namespace- Specifies that the logs are only collected from these namespaces.
includes.container- Specifies that the logs are only collected from these containers.
excludes.namespace- Specifies the pattern of namespaces to ignore when collecting the logs.
excludes.containerSpecifies the set of containers to ignore when collecting the logs.
NoteThe
excludesfield takes precedence over theincludesfield.
Apply the
ClusterLogForwarderCR by running the following command:$ oc apply -f <filename>.yaml
2.6.3. Filtering application logs at input by including the label expressions or a matching label key and values Copy linkLink copied to clipboard!
You can include the application logs based on the label expressions or a matching label key and its values by using the input selector.
Procedure
Add a configuration for a filter to the
inputspec in theClusterLogForwarderCR.apiVersion: observability.openshift.io/v1 kind: ClusterLogForwarder # ... spec: serviceAccount: name: <service_account_name> inputs: - name: mylogs application: selector: matchExpressions: - key: env operator: In values: ["prod", "qa"] - key: zone operator: NotIn values: ["east", "west"] matchLabels: app: one name: app1 type: application # ...matchExpressions.key- Specifies the label key to match.
matchExpressions.operator-
Specifies the operator. Valid values include:
In,NotIn,Exists, andDoesNotExist. matchExpressions.values-
Specifies an array of string values. If the
operatorvalue is eitherExistsorDoesNotExist, the value array must be empty. matchLabels- Specifies an exact key and value mapping.
Apply the
ClusterLogForwarderCR by running the following command:$ oc apply -f <filename>.yaml
2.6.4. Filtering the audit and infrastructure log inputs by source Copy linkLink copied to clipboard!
You can define the list of audit and infrastructure sources to collect the logs by using the input selector.
Procedure
Add a configuration to define the
auditandinfrastructuresources in theClusterLogForwarderCR.apiVersion: observability.openshift.io/v1 kind: ClusterLogForwarder # ... spec: serviceAccount: name: <service_account_name> inputs: - name: mylogs1 type: infrastructure infrastructure: sources: - node - name: mylogs2 type: audit audit: sources: - kubeAPI - openshiftAPI - ovn # ...infrastructure.sourcesSpecifies the list of infrastructure sources to collect. The valid sources include:
-
node: Journal log from the node -
container: Logs from the workloads deployed in the namespaces
-
audit.sourcesSpecifies the list of audit sources to collect. The valid sources include:
-
kubeAPI: Logs from the Kubernetes API servers -
openshiftAPI: Logs from the OpenShift API servers -
auditd: Logs from a node auditd service -
ovn: Logs from an open virtual network service
-
Apply the
ClusterLogForwarderCR by running the following command:$ oc apply -f <filename>.yaml
2.6.5. Adding audit log collection Copy linkLink copied to clipboard!
To add audit log collection to an existing pipeline, you must explicitly grant the collect-audit-logs permission to the collector service account. You must complete this step before updating your ClusterLogForwarder custom resource (CR). Failure to grant this permission before adding the audit log type will trigger a protective shutdown of the entire collector DaemonSet, stopping all log collection across the cluster.
If you add audit to the inputRefs list of the ClusterLogForwarder`CR without first granting the `collect-audit-logs permission to the ClusterRoleBinding, the Operator removes the entire collector DaemonSet. All log collection stops until you grant the missing permission.
Logging is not a Security Information and Event Monitoring (SIEM) system and does not provide secure storage for audit logs. Audit logs are not stored by default. You must configure a ClusterLogForwarder CR to forward audit logs to a storage solution. For more information about Logging capabilities and limitations, see "OpenShift Logging support".
Procedure
Grant the collector service account permission to collect audit logs:
$ oc adm policy add-cluster-role-to-user collect-audit-logs \ system:serviceaccount:<namespace>:<service_account_name>Replace
<namespace>with the namespace where yourClusterLogForwarderCR is deployed and<service_account_name>with the name you specified in theClusterLogForwarderCRspec.serviceAccount.namefield.Add
auditto theinputRefslist in yourClusterLogForwarderpipeline by editing the CR:$ oc edit clusterlogforwarder <clusterlogforwarder_name> -n <namespace>Replace
<clusterlogforwarder_name>with the name of yourClusterLogForwarderCR and<namespace>with the namespace where it is deployed.NoteIn Logging versions before 5.9, the
ClusterLogForwarderCR was a singleton namedinstancein theopenshift-loggingnamespace. Starting in Logging 5.9, you can create multipleClusterLogForwarderCRs with different names in different namespaces.Example configuration
spec: # ... other configuration outputs: - name: default-loki # ... output configuration pipelines: - name: my-pipeline inputRefs: - application - infrastructure - audit outputRefs: - default-lokiVerify that the
ClusterLogForwarderstill showsReadyby running the following command:$ oc get clusterlogforwarder <clusterlogforwarder_name> -n <namespace> \ -o jsonpath='{.status.conditions[?(@.type=="Ready")].status}'Replace
<clusterlogforwarder_name>with the name of yourClusterLogForwarderCR and<namespace>with the namespace where it is deployed.The output should show
True.Verify that the
Authorizedcondition listsauditby running the following command:$ oc get clusterlogforwarder <clusterlogforwarder_name> -n <namespace> \ -o jsonpath='{.status.conditions[?(@.type=~"Authorized")].message}'Example output
permitted to collect log types: [application audit infrastructure]
2.7. Configuring filters Copy linkLink copied to clipboard!
2.7.1. ClusterLogForwarder filter types Copy linkLink copied to clipboard!
Filter types transform or drop log records as they flow through a pipeline. Filters are applied sequentially in the order specified in the pipeline configuration. A log record dropped by an earlier filter does not reach subsequent filters.
detectMultilineException- Enables multi-line error detection for container logs. This filter recognizes stack traces and exception messages that span multiple lines and combines them into a single log record. No additional configuration is required.
dropDrops entire log records based on conditional tests. A drop filter contains one or more tests, where each test contains multiple conditions. If all conditions in a test are true, the log record is dropped. This filter is useful for reducing log volume by excluding known noisy or irrelevant messages.
Use case: Site reliability engineers can reduce storage costs by dropping debug-level logs or messages from non-critical namespaces before they reach expensive long-term storage.
Each condition specifies:
-
A field path in the log record (for example,
.kubernetes.namespace_name) - A regular expression that the field value either matches or does not match
The collector applies tests in sequence and drops the record if any test passes.
-
A field path in the log record (for example,
kubeAPIAuditRemoves unwanted Kubernetes API audit events and reduces event size to create a manageable audit trail. This filter allows you to exclude audit events based on omit stages, omit response codes, and other criteria. Configure this filter to reduce storage costs while maintaining compliance requirements for audit log retention.
Use case: Security officers can filter out low-value audit events while retaining critical security-relevant records, balancing compliance requirements with storage costs.
openshiftLabels-
Adds custom labels to log records passing through the pipeline. These labels appear in the
openshift.labelsmap in the log record and can be used for routing decisions in downstream systems. Use this filter to tag logs with environment identifiers, team ownership, or compliance classifications. parse-
Parses log entries into structured log records. This filter attempts to parse the message field as JSON and adds the parsed message to the top level
structuredfield of the log record. No additional configuration is required. Parsing is best-effort; if the message cannot be parsed, it is left unchanged. pruneRemoves specific fields from log records to reduce the size of logs flowing into the log store. This filter is essential for managing storage costs and ensuring compliance with data privacy requirements.
The prune filter supports two modes:
-
in: Specifies field paths to remove from the log record -
notIn: Specifies field paths to keep (all other fields are removed)
Use case: Security officers must prune personally identifiable information (PII) from logs before forwarding them to third-party SaaS providers to ensure data sovereignty and compliance with privacy regulations.
ImportantYou cannot prune the following required fields:
.log_type,.log_source,.message,.kubernetes.namespace_name,.kubernetes.pod_name,.kubernetes.container_name, and.level. If you try to prune these required fields, the Operator accepts the CR but sets the validation condition toFalse.Additional pruning restrictions apply for specific output types:
-
For
googleCloudLoggingoutput:.hostnamecannot be pruned. -
For
lokiStackoutput: See the LokiStack output documentation for additional fields that cannot be pruned.
-
2.7.2. API audit filter overview Copy linkLink copied to clipboard!
OpenShift API servers generate audit events for every API call. These events include details about the request, the response, and the identity of the requester. This can lead to large volumes of data.
The API audit filter helps manage the audit trail by using rules to exclude non-essential events and to reduce the event size. Rules are checked in order, and checking stops at the first match. The amount of data in an event depends on the value of the level field:
-
None: The event is dropped. -
Metadata: The event includes audit metadata and excludes request and response bodies. -
Request: The event includes audit metadata and the request body, and excludes the response body. -
RequestResponse: The event includes all data: metadata, request body and response body. The response body can be very large. For example,oc get pods -Agenerates a response body containing the YAML description of every pod in the cluster.
You can only use the API audit filter feature if the Vector collector is set up in your logging deployment.
The ClusterLogForwarder custom resource (CR) uses the same format as the standard Kubernetes audit policy. The ClusterLogForwarder CR provides the following additional functions:
- Wildcards
-
Names of users, groups, namespaces, and resources can have a leading or trailing
*asterisk character. For example, theopenshift-\*namespace matchesopenshift-apiserveroropenshift-authenticationnamespaces. The\*/statusresource matchesPod/statusorDeployment/statusresources. - Default Rules
Events that do not match any rule in the policy are filtered as follows:
-
Read-only system events such as
get,list, andwatchare dropped. - Service account write events that occur within the same namespace as the service account are dropped.
- All other events are forwarded, subject to any configured rate limits.
To disable these defaults, either end your rules list with a rule that has only a
levelfield or add an empty rule.-
Read-only system events such as
- Omit Response Codes
-
A list of integer status codes to omit. You can drop events based on the HTTP status code in the response by using the
OmitResponseCodesfield, which lists HTTP status codes for which no events are created. The default value is[404, 409, 422, 429]. If the value is an empty list,[], no status codes are omitted.
The ClusterLogForwarder CR audit policy acts in addition to the OpenShift Container Platform audit policy. The ClusterLogForwarder CR audit filter changes what the log collector forwards, and provides the ability to filter by verb, user, group, namespace, or resource. You can create multiple filters to send different summaries of the same audit stream to different places. For example, you can send a detailed stream to the local cluster log store, and a less detailed stream to a remote site.
-
You must have the
collect-audit-logscluster role to collect the audit logs. - The following example provided is intended to illustrate the range of rules possible in an audit policy and is not a recommended configuration.
Example audit policy
apiVersion: observability.openshift.io/v1
kind: ClusterLogForwarder
metadata:
name: instance
namespace: openshift-logging
spec:
serviceAccount:
name: example-service-account
pipelines:
- name: my-pipeline
inputRefs:
- audit
filterRefs:
- my-policy
outputRefs:
- my-output
filters:
- name: my-policy
type: kubeAPIAudit
kubeAPIAudit:
# Don't generate audit events for all requests in RequestReceived stage.
omitStages:
- "RequestReceived"
rules:
# Log pod changes at RequestResponse level
- level: RequestResponse
resources:
- group: ""
resources: ["pods"]
# Log "pods/log", "pods/status" at Metadata level
- level: Metadata
resources:
- group: ""
resources: ["pods/log", "pods/status"]
# Don't log requests to a configmap called "controller-leader"
- level: None
resources:
- group: ""
resources: ["configmaps"]
resourceNames: ["controller-leader"]
# Don't log watch requests by the "system:kube-proxy" on endpoints or services
- level: None
users: ["system:kube-proxy"]
verbs: ["watch"]
resources:
- group: "" # core API group
resources: ["endpoints", "services"]
# Don't log authenticated requests to certain non-resource URL paths.
- level: None
userGroups: ["system:authenticated"]
nonResourceURLs:
- "/api*" # Wildcard matching.
- "/version"
# Log the request body of configmap changes in kube-system.
- level: Request
resources:
- group: "" # core API group
resources: ["configmaps"]
# This rule only applies to resources in the "kube-system" namespace.
# The empty string "" can be used to select non-namespaced resources.
namespaces: ["kube-system"]
# Log configmap and secret changes in all other namespaces at the Metadata level.
- level: Metadata
resources:
- group: "" # core API group
resources: ["secrets", "configmaps"]
# Log all other resources in core and extensions at the Request level.
- level: Request
resources:
- group: "" # core API group
- group: "extensions" # Version of group should NOT be included.
# A catch-all rule to log all other requests at the Metadata level.
- level: Metadata
+ inputRefs:: The collected log types. The value for this field can be audit for audit logs, application for application logs, infrastructure for infrastructure logs, or a named input that is defined for your application.
+ filterRefs:: The name of your audit policy.
2.7.3. Filtering collected logs Copy linkLink copied to clipboard!
You can add filters to a ClusterLogForwarder pipeline to drop, prune, or label log records before the collector sends them to an output. Filters reduce storage costs and remove noise from your log data.
For complete information about all available filter types and their capabilities, see "ClusterLogForwarder filter types" in the Additional resources section.
The following table shows the filter type to use for common tasks:
| Goal | Filter type | Example |
|---|---|---|
| Drop all logs from a specific namespace |
|
Drop logs where |
| Drop logs that match a field value |
|
Drop logs where |
| Remove specific fields from log records |
|
Remove |
| Keep only specific fields in log records |
|
Keep only |
To collect application logs only from certain namespaces, use a custom input instead of a filter. For more information, see "Filtering application logs at input by including or excluding the namespace or container name" in the Additional resources section.
2.7.3.1. Adding a drop filter Copy linkLink copied to clipboard!
Use a drop filter to exclude entire log records based on field values. The filter uses tests that evaluate log fields. Site reliability engineers use drop filters to reduce storage costs by excluding debug-level logs or noisy messages from non-critical namespaces before they reach long-term storage.
Procedure
Add a filter to the
spec.filtersarray and reference it from a pipeline:apiVersion: observability.openshift.io/v1 kind: ClusterLogForwarder metadata: name: instance namespace: openshift-logging spec: serviceAccount: name: collector filters: - name: drop-marketplace type: drop drop: - test: - field: .kubernetes.namespace_name matches: openshift-marketplace outputs: # ... your output configuration pipelines: - name: default-logstore inputRefs: - application - infrastructure outputRefs: - <output_name> filterRefs: - drop-marketplacespec.filters[].name-
A unique name for the filter. Reference this name in a pipeline
filterRefslist. spec.filters[].type-
Set to
dropto exclude matching records. spec.filters[].drop[].test[]-
An array of field tests. All tests within a single
testarray must match for the collector to drop the record (ANDlogic). If you specify severaltestarrays in thedroplist, the collector drops the record when anytestarray matches (ORlogic). spec.filters[].drop[].test[].field-
The dot-delimited path to a field in the log record. Each path segment can contain alphanumeric characters and underscores,
a-z,A-Z,0-9,_, for example,.kubernetes.namespace_name. If segments contain different characters, the segment must be in quotes, for example,.kubernetes.labels."app.version-1.2/beta". spec.filters[].drop[].test[].matches-
The value to match against. Supports exact strings and regular expressions. If the field value matches this regular expression, the condition evaluates to
True. spec.filters[].drop[].test[].notMatchesThe value to not match against. Supports exact strings and regular expressions. If the field value does not match this regular expression, the condition evaluates to
True.NoteYou can set either
matchesornotMatchesfor a single field, but not both. If a field referenced in a test does not exist in the log record, that condition evaluates toFalse.
Example: Keep only high-priority log records
+
spec: filters: - name: important type: drop drop: - test: - field: .message notMatches: "(?i)critical|error" - field: .level matches: "info|warning"+ This filter drops records where the message does not contain "critical" or "error" and the level is "info" or "warning".
+ Example: Multiple test conditions (OR logic)
+
spec: filters: - name: drop-noisy-logs type: drop drop: - test: - field: .kubernetes.namespace_name matches: "openshift.*" - test: - field: .log_type matches: "application" - field: .kubernetes.pod_name notMatches: "my-pod"+ This filter drops logs that either come from a namespace starting with
openshift(first test), or are application logs that do not havemy-podin the pod name (second test).Apply the updated
ClusterLogForwarderCR by running the following command:$ oc apply -f <filename>.yaml
Verification
Verify that the collector pods restarted by running the following command:
$ oc get pods -n <namespace> -l app.kubernetes.io/component=collectorReplace
<namespace>with the namespace where yourClusterLogForwarderCR is deployed. The pod age should show a recent restart.NoteIf multiple
ClusterLogForwarderCRs exist in the same namespace, this command lists all collector pods. To list only the pods for a specificClusterLogForwarderCR, add the label-l app.kubernetes.io/instance=<clusterlogforwarder_name>to the command.
2.7.3.2. Adding a prune filter Copy linkLink copied to clipboard!
Use a prune filter to remove or keep specific fields in log records. This reduces the size of each record and hides sensitive metadata without dropping the entire log record. This is particularly useful for managing the high volume and sensitivity of audit logs. Security officers commonly use prune filters to remove personally identifiable information (PII) from logs before forwarding them to third-party systems, ensuring data sovereignty and compliance with privacy regulations.
Procedure
Add a
prunefilter to thespec.filtersarray:spec: filters: - name: prune-audit-logs type: prune prune: in: [.audit.requestObject, .audit.responseObject, .audit.managedFields]prune.in-
Fields to remove from the log record. The collector keeps all other fields. Use dot notation to specify fields for removal. For audit logs,
requestObjectandresponseObjectoften contain the most data and sensitive information. prune.notInFields to keep. The collector removes all other fields.
ImportantYou cannot prune the following required fields:
.log_type,.log_source,.message,.kubernetes.namespace_name,.kubernetes.pod_name,.kubernetes.container_name, and.level. If you try to prune these required fields, the Operator accepts the CR but sets the validation condition toFalse.Additional pruning restrictions:
-
If you specify both
inandnotIn, thenotInarray takes precedence overinduring pruning. The collector processesnotInfirst to find the fields to keep, and then processesinto remove additional fields from the remaining set. -
If you use the
googleCloudLoggingoutput, you cannot prune.hostname, otherwise the collector cannot forward logs to Google Cloud Logging. -
If you use the
lokiStackoutput, see the LokiStack output documentation for additional fields that cannot be pruned.
-
If you specify both
Reference the filter in a pipeline:
spec: pipelines: - name: default-logstore filterRefs: - prune-audit-logsApply the updated
ClusterLogForwarderCR by running the following command:$ oc apply -f <filename>.yaml
Verification
Verify that the collector pods restarted by running the following command:
$ oc get pods -n <namespace> -l app.kubernetes.io/component=collectorReplace
<namespace>with the namespace where yourClusterLogForwarderCR is deployed. The pod age should show a recent restart.NoteIf multiple
ClusterLogForwarderCRs exist in the same namespace, this command lists all collector pods. To list only the pods for a specificClusterLogForwarderCR, add the label-l app.kubernetes.io/instance=<clusterlogforwarder_name>to the command.
2.7.4. About multi-line exception detection Copy linkLink copied to clipboard!
When log messages appear as a consecutive sequence forming an exception stack trace, the collector combines them into a single, unified log record. The collector replaces the first log message’s content with the concatenated content of all the message fields in the sequence.
The collector supports the following languages:
- Java
- JS
- Ruby
- Python
- Golang
- PHP
- Dart
Example java exception
java.lang.NullPointerException: Cannot invoke "String.toString()" because "<param1>" is null
at testjava.Main.handle(Main.java:47)
at testjava.Main.printMe(Main.java:19)
at testjava.Main.main(Main.java:10)
2.7.5. Enabling multi-line exception detection Copy linkLink copied to clipboard!
You can enable multi-line error detection of container logs to combine exception stack traces into a single log record.
Enabling this feature could have performance implications and might require additional computing resources or alternate logging solutions.
Procedure
To enable logging to detect multi-line exceptions and reassemble them into a single log entry, ensure that the
ClusterLogForwarderCustom Resource (CR) has adetectMultilineErrorsfield under the.spec.filters.Example
ClusterLogForwarderCRapiVersion: "observability.openshift.io/v1" kind: ClusterLogForwarder metadata: name: <log_forwarder_name> namespace: <log_forwarder_namespace> spec: serviceAccount: name: <service_account_name> filters: - name: <name> type: detectMultilineException pipelines: - inputRefs: - <input_name> name: <pipeline_name> filterRefs: - <filter_name> outputRefs: - <output_name>
2.8. Configuring outputs Copy linkLink copied to clipboard!
2.8.1. ClusterLogForwarder output types Copy linkLink copied to clipboard!
Output types define the destination where the collector forwards log records. Each output type has specific configuration requirements for authentication, connection parameters, and data formatting.
azureMonitorForwards logs to Azure Monitor Logs service. This output requires a customer ID and shared key for authentication. You can specify a custom log type and associate logs with a specific Azure resource ID.
WarningThe
azureMonitoroutput type is deprecated and will be removed in a future release. This output type will become obsolete in September 2026.cloudwatch- Forwards logs to Amazon CloudWatch. This output supports two authentication methods: AWS access keys or IAM roles with Security Token Service (STS). You must specify the AWS region and a group name pattern for organizing log streams. CloudWatch outputs support cross-account log forwarding using the AssumeRole feature.
elasticsearch- Forwards logs to an external Elasticsearch cluster. This output is tested with Elasticsearch versions 6, 7, and 8. You must specify the cluster URL, version, and index pattern. Elasticsearch outputs support Basic authentication with username and password, and custom headers for advanced configurations.
googleCloudLogging- Forwards logs to Google Cloud Logging (formerly Stackdriver). This output requires a service account credentials file and supports organization, folder, project, or billing account scopes. You must specify a log ID pattern to identify the log stream.
http- Forwards logs to a generic HTTP endpoint. This output sends logs as JSON or newline-delimited JSON (NDJSON) to any HTTP or HTTPS URL. It supports bearer token and Basic authentication, custom headers, and configurable HTTP methods. Use this output for custom log aggregators or webhook-based integrations.
kafka- Forwards logs to Apache Kafka topics. This output supports Kafka protocol version 0.11 and later. You can specify multiple broker endpoints and configure SASL authentication. The topic name supports template syntax for dynamic per-event routing.
loki- Forwards logs to a Loki aggregation system. This output is suitable for external Loki deployments outside of Red Hat OpenShift Logging. It supports custom label keys for stream identification and tenant keys for multitenant Loki deployments.
lokiStackForwards logs to a Red Hat managed LokiStack deployment by using the Red Hat OpenShift Logging tenancy model. This output integrates with Red Hat OpenShift Logging authentication and enforces multitenancy through the LokiStack gateway proxy. The collector automatically discovers the LokiStack service based on the namespace and name you specify.
Use case: Site reliability engineers and developers benefit from LokiStack for short-term troubleshooting and performance analysis. The built-in multitenancy ensures that developers can only access logs from their own namespaces.
ImportantThe following fields are required as default stream labels for LokiStack and cannot be pruned:
-
.kubernetes.container_name -
.kubernetes.namespace_name -
.kubernetes.pod_name
If these fields are not present in the log record, they will be set to the empty string.
-
otlpForwards logs by using the OpenTelemetry Protocol (OTLP) with Red Hat OpenShift Logging semantic conventions. This output sends logs in OTLP format over HTTP or HTTPS to OpenTelemetry collectors and observability backends that support OTLP ingestion.
Use case: Platform teams can forward logs to any observability platform that supports the OTLP protocol. Organizations can also use OpenTelemetry Collector as a central gateway to aggregate logs from multiple clusters before routing to final destinations. This approach provides vendor-neutral log forwarding and simplified multi-destination routing.
NoteThe
otlpoutput uses the OpenTelemetry data model, which differs from the ViaQ data model used by other output types. Field names and structure vary between these models.s3Forwards logs to Amazon S3 or S3-compatible object storage. This output supports the same authentication methods as CloudWatch (AWS access keys or IAM roles). You must specify the AWS region, bucket name, and key prefix pattern for organizing log objects. Use this output for long-term archival, compliance retention, or integration with data lake pipelines.
Use case: Security officers use S3 for immutable long-term retention of audit logs to meet compliance requirements. S3 bucket lifecycle policies can automatically move logs to cheaper storage tiers while maintaining the required retention period.
splunkForwards logs to Splunk HTTP Event Collector (HEC). This output requires a Splunk HEC token for authentication. You can configure custom index, source, and indexed fields to optimize Splunk search performance.
Use case: Developers and site reliability engineers often prefer Splunk because it is a familiar platform with powerful search and visualization capabilities. Organizations can route application and infrastructure logs to Splunk for operational analysis.
syslog- Forwards logs to an external syslog receiver by using RFC3164 or RFC5424 format. This output supports TCP, TLS, and UDP transports. You can customize facility, severity, application name, process ID, and message ID fields by using template syntax.
2.9. Configuring pipelines Copy linkLink copied to clipboard!
2.9.1. ClusterLogForwarder pipelines Copy linkLink copied to clipboard!
Pipelines define the routing logic that connects log sources to destinations. A pipeline binds one or more inputs to one or more outputs, with optional filters applied in between. Pipelines are the central orchestration mechanism that determines which logs flow where and how they are transformed along the way.
name-
A unique identifier for the pipeline. Use descriptive names that indicate the pipeline’s purpose, such as
app-logs-to-splunkoraudit-to-s3. inputRefsA list of input names to include in this pipeline. You can reference the built-in inputs (
application,infrastructure,audit) or custom inputs you have defined in thespec.inputssection. The collector gathers logs from all referenced inputs and sends them through this pipeline.ImportantYou can only reference inputs for log types that the collector service account is authorized to access through
ClusterRoleBindings. If you reference an unauthorized log type, the Operator removes the collectorDaemonSetand stops all log collection.outputRefsA list of output names where the pipeline sends logs. You can send logs to multiple destinations simultaneously by listing multiple outputs. The collector duplicates the log stream and forwards a copy to each output.
NoteIf you send the same log record to multiple outputs and one output fails, the collector continues forwarding to other outputs. Each output operates independently.
filterRefsAn optional list of filter names to apply to log records passing through this pipeline. Filters are applied sequentially in the order you specify. If a filter drops a log record, subsequent filters in the list do not process that record.
Common filter ordering patterns:
-
Drop before prune: Apply
dropfilters first to remove unwanted log records, then applyprunefilters to remove fields from the remaining records. This reduces processing work. -
Parse before filter: Apply
parsefilters early to convert JSON strings into structured fields, then applydroporprunefilters that operate on those structured fields. -
Label last: Apply
openshiftLabelsfilters after other transformations to add routing metadata that downstream systems can use.
-
Drop before prune: Apply
2.9.1.1. Pipeline examples Copy linkLink copied to clipboard!
The following examples demonstrate common pipeline patterns tailored to the needs of different stakeholders: developers who need application-specific log access, site reliability engineers (SREs) who need operational visibility, and security officers who need compliance and audit trails.
- Developer use case - Application logs to familiar tools
Developers need quick access to their application logs in tools they already know. This pipeline forwards application logs to a Splunk instance where development teams can troubleshoot issues:
pipelines: - name: apps-to-splunk inputRefs: - application outputRefs: - splunk-prod- SRE use case - Operational visibility
Site reliability engineers need comprehensive operational visibility across application and infrastructure components. This pipeline forwards both log types to a single LokiStack for short-term troubleshooting and performance monitoring:
pipelines: - name: all-logs-to-loki inputRefs: - application - infrastructure outputRefs: - default-lokistack- Security officer use case - Compliance and real-time monitoring
Security officers must balance compliance requirements with operational needs. This pipeline sends audit logs to both an S3 bucket for long-term immutable retention and CloudWatch for real-time security alerting:
pipelines: - name: audit-to-archive-and-monitor inputRefs: - audit outputRefs: - s3-compliance - cloudwatch-alerts- Security officer use case - Data sovereignty and PII protection
Security officers must ensure personally identifiable information (PII) does not leave the cluster for third-party SaaS providers. This pipeline drops noisy logs and prunes sensitive fields before forwarding to an external system:
pipelines: - name: filtered-apps inputRefs: - application filterRefs: - drop-marketplace-logs - prune-annotations outputRefs: - external-aggregator- Multi-stakeholder use case - Serving developers, SREs, and security officers
Organizations typically need to serve all three stakeholders simultaneously. This configuration defines separate pipelines for each persona’s needs: developers get application logs in LokiStack, SREs get infrastructure logs in Elasticsearch for performance analysis, and security officers get audit logs with sensitive fields pruned for compliance archival:
pipelines: - name: apps-to-loki inputRefs: - application outputRefs: - lokistack - name: infrastructure-to-elasticsearch inputRefs: - infrastructure outputRefs: - elasticsearch-infra - name: audit-to-s3 inputRefs: - audit filterRefs: - prune-sensitive-fields outputRefs: - s3-compliance
If you do not define a pipeline for a log type, the collector drops logs of that type. For example, if you create pipelines for application and audit logs but not for infrastructure logs, the collector does not collect infrastructure logs.
2.9.1.2. Complete example Copy linkLink copied to clipboard!
This example shows a complete ClusterLogForwarder CR with inputs, filters, outputs, and pipelines:
apiVersion: observability.openshift.io/v1
kind: ClusterLogForwarder
metadata:
name: instance
namespace: openshift-logging
spec:
serviceAccount:
name: collector
inputs:
- name: high-priority-apps
type: application
application:
selector:
matchLabels:
priority: high
filters:
- name: drop-debug-logs
type: drop
drop:
- test:
- field: .level
matches: debug
- name: remove-annotations
type: prune
prune:
in:
- .kubernetes.annotations
outputs:
- name: lokistack
type: lokiStack
lokiStack:
authentication:
token:
from: serviceAccount
target:
name: logging-loki
namespace: openshift-logging
tls:
ca:
configMapName: logging-loki-gateway-ca-bundle
key: service-ca.crt
- name: splunk-prod
type: splunk
splunk:
authentication:
token:
secretName: splunk-token
url: https://splunk.example.com:8088
pipelines:
- name: priority-apps-to-splunk
inputRefs:
- high-priority-apps
filterRefs:
- drop-debug-logs
outputRefs:
- splunk-prod
- name: all-apps-to-loki
inputRefs:
- application
filterRefs:
- remove-annotations
outputRefs:
- lokistack
- name: infrastructure-to-loki
inputRefs:
- infrastructure
outputRefs:
- lokistack
2.10. Advanced configuration Copy linkLink copied to clipboard!
2.10.1. Configuring rate limits Copy linkLink copied to clipboard!
You can configure rate limits on inputs and outputs to control log forwarding volume and prevent resource exhaustion. Rate limits specify the maximum number of log records per second that the collector can process. When the rate limit is exceeded, the collector drops excess log records.
Prerequisites
-
You have a working
ClusterLogForwardercustom resource (CR). -
You have
cluster-adminpermissions.
Procedure
Configure rate limits on inputs, outputs, or both.
apiVersion: observability.openshift.io/v1 kind: ClusterLogForwarder metadata: name: instance namespace: openshift-logging spec: serviceAccount: name: collector inputs: - name: limited-app-logs type: application application: tuning: rateLimitPerContainer: maxRecordsPerSecond: 100 outputs: - name: limited-splunk type: splunk splunk: url: https://splunk.example.com:8088 authentication: token: key: token secretName: splunk-secret rateLimit: maxRecordsPerSecond: 1000 pipelines: - name: app-to-splunk inputRefs: - limited-app-logs outputRefs: - limited-splunk- Input rate limit (
inputs[].application.tuning.rateLimitPerContainer) Limits the number of log records per second from each container that matches this input. This is a per-container limit. For example, if you set
maxRecordsPerSecond: 100and 10 containers match the input selector, the total input rate could be up to 1000 records per second (100 per container × 10 containers).Use case: Site reliability engineers can use input rate limits to prevent noisy applications from overwhelming the log collector and consuming excessive cluster resources.
- Output rate limit (
outputs[].rateLimit) Limits the total number of log records per second that the collector forwards to this output from a single collector pod. This is an aggregate limit across all pipelines that reference this output. Generally, one collector pod runs per cluster node.
Use case: Developers can use output rate limits to stay within the ingestion quotas imposed by third-party log aggregation services, preventing overage charges or throttling.
ImportantWhen rate limits are exceeded, the collector drops log records. The collector increments the
observability_log_forwarder_output_rate_limited_totalmetric for each dropped record. Monitor this metric to determine if your rate limits are too restrictive.Rate limit only on output
spec: outputs: - name: rate-limited-kafka type: kafka kafka: brokers: - kafka.example.com:9092 topic: logs rateLimit: maxRecordsPerSecond: 5000 pipelines: - name: all-logs-to-kafka inputRefs: - application - infrastructure outputRefs: - rate-limited-kafkaRate limit only on input
spec: inputs: - name: high-volume-namespace type: application application: includes: - namespace: "production" tuning: rateLimitPerContainer: maxRecordsPerSecond: 500 pipelines: - name: production-to-loki inputRefs: - high-volume-namespace outputRefs: - default-lokistackDifferent rate limits for different outputs
spec: outputs: - name: expensive-splunk type: splunk splunk: url: https://splunk.example.com:8088 authentication: token: key: token secretName: splunk-secret rateLimit: maxRecordsPerSecond: 500 - name: cheap-s3 type: s3 s3: url: https://s3.us-east-1.amazonaws.com bucket: log-archive rateLimit: maxRecordsPerSecond: 10000 pipelines: - name: critical-to-splunk inputRefs: - audit outputRefs: - expensive-splunk - name: bulk-to-s3 inputRefs: - application - infrastructure outputRefs: - cheap-s3
- Input rate limit (
Apply the updated
ClusterLogForwarderCR by running the following command:$ oc apply -f <filename>.yaml
Verification
Verify that the collector pods restarted by running the following command:
$ oc get pods -n openshift-logging -l app.kubernetes.io/component=collector
2.10.2. Tuning log payloads and delivery Copy linkLink copied to clipboard!
The tuning spec in the ClusterLogForwarder custom resource (CR) provides a means of configuring your deployment to prioritize either throughput or durability of logs.
For example, if you need to reduce the possibility of log loss when the collector restarts, or you require collected log messages to survive a collector restart to support regulatory mandates, you can tune your deployment to prioritize log durability. If you use outputs that have hard limitations on the size of batches they can receive, you might want to tune your deployment to prioritize log throughput.
You can tune both inputs and outputs in the ClusterLogForwarder CR.
2.10.2.1. Tuning inputs Copy linkLink copied to clipboard!
You can tune application and infrastructure inputs to control message size limits and rate limiting. These settings apply to container log collection and help prevent resource exhaustion from high-volume logging workloads.
The following example shows the ClusterLogForwarder CR options that you can change to tune log forwarder inputs:
Example ClusterLogForwarder CR input tuning options
apiVersion: observability.openshift.io/v1
kind: ClusterLogForwarder
metadata:
# ...
spec:
# ...
inputs:
- name: application
type: application
application:
tuning:
container:
maxMessageSize: 16Ki
rateLimitPerContainer:
maxRecordsPerSecond: 1000
- name: infrastructure
type: infrastructure
infrastructure:
tuning:
container:
maxMessageSize: 16Ki
rateLimitPerContainer:
maxRecordsPerSecond: 1000
maxMessageSize-
Specifies the maximum message length in bytes that a single log event can be when all partial log lines are merged. Messages exceeding this limit are dropped. You can specify this value as an integer or as a string with units such as
Ki(kibibytes) orMi(mebibytes). rateLimitPerContainer.maxRecordsPerSecond- Specifies the maximum number of log records allowed per second for each container. This limit is applied per collector deployment. When a container exceeds this rate, the collector drops excess log records until the rate falls below the limit.
2.10.2.2. Tuning outputs Copy linkLink copied to clipboard!
The following example shows the ClusterLogForwarder CR options that you can change to tune log forwarder outputs:
Example ClusterLogForwarder CR tuning options
apiVersion: observability.openshift.io/v1
kind: ClusterLogForwarder
metadata:
# ...
spec:
# ...
outputs:
- name: default-lokistack
type: lokiStack
lokiStack:
tuning:
deliveryMode: AtLeastOnce
compression: none
maxWrite: <integer>
minRetryDuration: 1s
maxRetryDuration: 1s
deliveryModeSpecify the delivery mode for log forwarding. When left unset, the system defaults to using an in-memory buffer, which offers the highest performance due to low latency but does not provide durability. Buffered data is lost on process termination or failure.
-
AtLeastOncedelivery means that if the log forwarder crashes or restarts, the collector re-sends any logs it read before the crash but did not send to their destination. The collector might duplicate some logs after a crash. -
AtMostOncedelivery means that the log forwarder makes no effort to recover logs lost during a crash. This mode gives better throughput, but might result in greater log loss.
-
compression-
Specifying a
compressionconfiguration causes the collector to compress data before sending it over the network. Note that not all output types support compression, and if the specified compression type is not supported by the output, this results in an error. For more information, see "Supported compression types for tuning outputs". maxWrite- Specifies a limit for the maximum payload of a single send operation to the output.
minRetryDuration-
Specifies a minimum duration to wait between attempts before retrying delivery after a failure. This value is a string, and you can specify it as milliseconds (
ms), seconds (s), or minutes (m). maxRetryDuration-
Specifies a maximum duration to wait between attempts before retrying delivery after a failure. This value is a string, and you can specify it as milliseconds (
ms), seconds (s), or minutes (m).
| Compression algorithm | Splunk | Amazon CloudWatch | Elasticsearch 8 | LokiStack | Apache Kafka | HTTP | Syslog | Google Cloud | Microsoft Azure Monitoring | Amazon S3 |
|---|---|---|---|---|---|---|---|---|---|---|
|
| X | X | X | X | X | X | ||||
|
| X | X | X | X | ||||||
|
| X | X | X | |||||||
|
| X | X | X | |||||||
|
| X |
2.10.3. Setting the collector log level Copy linkLink copied to clipboard!
Set the collector log level by adding the observability.openshift.io/log-level annotation to the ClusterLogForwarder custom resource (CR).
Prerequisites
-
You have a working
ClusterLogForwarderCR. -
You have
cluster-adminpermissions.
Procedure
Set the log level by running the following command:
$ oc annotate clusterlogforwarder instance -n openshift-logging \ observability.openshift.io/log-level=debug --overwriteThe supported log levels are
trace,debug,info,warn,error, andoff. The default level isinfo.Verify that the collector pod restarted with the new log level by running the following command:
$ oc logs -n openshift-logging -l app.kubernetes.io/component=collector --tail=5At the
debuglevel, entries begin withDEBUG.NoteUse
debugortraceonly for troubleshooting. These levels increase log volume significantly and can affect collector performance. Reset the level toinfoafter troubleshooting.
2.10.4. Setting collector resource limits Copy linkLink copied to clipboard!
Set CPU and memory resource limits by modifying the spec.collector.resources stanza in the ClusterLogForwarder custom resource (CR).
Prerequisites
-
You have a working
ClusterLogForwarderCR. -
You have
cluster-adminpermissions.
Procedure
Patch the
ClusterLogForwarderCR by running the following command:$ oc patch clusterlogforwarder instance -n openshift-logging \ --type=merge \ -p '{"spec":{"collector":{"resources":{"requests":{"cpu":"100m","memory":"256Mi"},"limits":{"cpu":"500m","memory":"512Mi"}}}}}'Verify that the collector pod restarted with the updated resources by running the following command:
$ oc get pods -n openshift-logging -l app.kubernetes.io/component=collectorThe pod age should show a recent restart.
NoteIf you do not set resource limits explicitly, the collector applies default limits: 500m CPU and 64Mi memory for requests, and 6000m CPU and 2048Mi memory for limits. Setting explicit limits prevents the collector from consuming more resources than expected on nodes with high log volume.
2.10.5. Creating the log file metric exporter Copy linkLink copied to clipboard!
Create a LogFileMetricExporter custom resource (CR) to generate metrics about the logs produced by running containers. The Operator does not deploy the exporter by default, so you must create it manually.
If you do not create the LogFileMetricExporter CR, the Produced Logs field in the OpenShift Container Platform web console dashboard shows No datapoints found.
Prerequisites
- You have administrator permissions.
- Ensure that you installed the Red Hat OpenShift Logging Operator.
-
You have installed the OpenShift CLI (
oc).
Procedure
Create a
LogFileMetricExporterCR as a YAML file:apiVersion: logging.openshift.io/v1alpha1 kind: LogFileMetricExporter metadata: name: instance namespace: openshift-logging spec: nodeSelector: {} resources: limits: cpu: 500m memory: 256Mi requests: cpu: 200m memory: 128Mi tolerations: []spec.nodeSelector- Optional: Define the nodes that the exporter pods run on.
spec.resources- Optional: Define CPU and memory resource limits and requests for the exporter.
spec.tolerationsOptional: Define tolerations that the exporter pods accept.
NoteThe
LogFileMetricExporteris a singleton. The Operator only honorsopenshift-logging/instancefor the namespace and name.
Apply the
LogFileMetricExporterCR by running the following command:$ oc apply -f <filename>.yaml
Verification
Verify that the
logfilesmetricexporterpods are running by running the following command:$ oc get pods -l app.kubernetes.io/component=logfilesmetricexporter \ -n openshift-loggingExample output
NAME READY STATUS RESTARTS AGE logfilesmetricexporter-9qbjj 1/1 Running 0 2m46s logfilesmetricexporter-cbc4v 1/1 Running 0 2m46sA
logfilesmetricexporterpod runs concurrently with acollectorpod on each node.
2.11. Troubleshooting log collection Copy linkLink copied to clipboard!
Use this reference to diagnose common problems when log collection does not work as expected.
2.11.1. TLS certificate errors Copy linkLink copied to clipboard!
Symptom: The ClusterLogForwarder custom resource (CR) reports Ready: True, but no logs appear in the LokiStack or other HTTP-based sink. The collector logs show the following error:
Example error output
error:0A000086:SSL routines:tls_post_process_server_certificate:certificate verify failed:ssl/statem/statem_clnt.c:2123:: self-signed certificate in certificate chain
Cause: The tls.ca block is missing or incorrect in the ClusterLogForwarder output configuration. The collector cannot verify the LokiStack gateway or destination sink certificate.
Resolution: Add the tls.ca block to the output:
spec:
outputs:
- name: default-lokistack
type: lokiStack
# ... other configuration
tls:
ca:
configMapName: logging-loki-gateway-ca-bundle
key: service-ca.crt
The Loki Operator creates the logging-loki-gateway-ca-bundle ConfigMap automatically.
2.11.2. Rate limiting (429 Too Many Requests) Copy linkLink copied to clipboard!
Symptom: The collector logs show 429 Too Many Requests responses and the collector retries requests.
Cause: The collector is sending logs faster than the LokiStack or destination sink can process them. This is common in two situations:
- During initial deployment, when the collector flushes a backlog of accumulated logs.
-
After restoring connectivity to a
LokiStackthat was temporarily unavailable.
Resolution: This condition resolves automatically. The collector automatically retries with exponential back-off. On a 1x.demo LokiStack, the backlog typically clears within several minutes. On larger LokiStack sizes, clearing takes less time.
2.11.3. Collector not running Copy linkLink copied to clipboard!
Symptom: No collector pod exists.
$ oc get pods -n openshift-logging -l app.kubernetes.io/component=collector
No resources found in openshift-logging namespace.
Cause: The ClusterLogForwarder has an authorization or validation error. When the ClusterLogForwarder is invalid or unauthorized, the Operator removes the collector DaemonSet.
Resolution:
Check the
ClusterLogForwarderstatus by running the following command:$ oc get clusterlogforwarder instance -n openshift-logging \ -o jsonpath='{.status.conditions}' | python3 -m json.tool-
If
AuthorizedshowsFalse, grant the missingClusterRoleBinding. See "Granting collector permissions for log collection." -
If
ValidshowsFalse, review themessagefor details about the validation error.
The Operator recreates the collector DaemonSet within about 45 seconds after you fix the error.
2.11.4. Enabling debug logging Copy linkLink copied to clipboard!
To enable debug logging for the collector, set the observability.openshift.io/log-level annotation:
$ oc annotate clusterlogforwarder instance -n openshift-logging \
observability.openshift.io/log-level=debug --overwrite
Review the collector logs:
$ oc logs -n openshift-logging -l app.kubernetes.io/component=collector --tail=50
Reset the log level to info after troubleshooting to reduce log volume:
$ oc annotate clusterlogforwarder instance -n openshift-logging \
observability.openshift.io/log-level=info --overwrite
2.12. Forwarding to third-party destinations Copy linkLink copied to clipboard!
2.12.1. External log forwarding destination compatibility Copy linkLink copied to clipboard!
The following table lists external log forwarding destinations tested and validated with Red Hat OpenShift Logging.
| Output type | Protocol | Tested versions | Logging versions |
|---|---|---|---|
| Elasticsearch v6 | HTTP 1.1 | 6.8.1 | 6.0+ |
| Elasticsearch v7 | HTTP 1.1 | 7.12.2 | 6.0+ |
| Elasticsearch v8 | HTTP 1.1 | 8.6.1 | 6.0+ |
| Elasticsearch v9 | HTTP 1.1 | 9.3.3 | 6.0+ |
| Google Cloud Logging | REST over HTTPS | Latest | 6.0+ |
| HTTP (Generic) | HTTP 1.1 | Vector 0.28-1, 0.34-1 | 6.0+ |
| Kafka | Kafka 0.11 | 2.4.1, 2.7.0 | 6.0+ |
| Loki (External) | REST over HTTP/HTTPS | 2.3.0 | 6.0+ |
| OTLP | HTTP/HTTPS | OpenTelemetry Collector 0.88+ | 6.1+ |
| Splunk | HEC | 9.0.0 | 6.0+ |
| Syslog | RFC3164, RFC5424 | rsyslog 8.39.0 | 6.0+ |
| Amazon CloudWatch | REST over HTTPS | Latest | 6.0+ |
| Amazon S3 | REST over HTTPS | Latest | 6.0+ |
| Azure Monitor Logs | REST over HTTPS | Latest | 6.0+ |
This table lists versions that Red Hat has tested. Other versions might work but Red Hat has not validated them. For Red Hat OpenShift Logging managed destinations (LokiStack), version compatibility is managed automatically.
2.12.2. About forwarding logs to third-party systems Copy linkLink copied to clipboard!
To send logs to specific endpoints inside and outside your OpenShift Container Platform cluster, you specify a combination of outputs and pipelines in a ClusterLogForwarder custom resource (CR). You can also use inputs to forward the application logs associated with a specific project to an endpoint. A Kubernetes Secret object provides authentication.
- pipeline
Defines simple routing from one log type to one or more outputs, or the logs to send. The log types are one of the following:
-
application. Container logs generated by user applications running in the cluster, except infrastructure container applications. -
infrastructure. Container logs from pods that run in theopenshift*,kube*, ordefaultprojects and journal logs sourced from node file system. -
audit. Audit logs generated by the node audit system,auditd, Kubernetes API server, OpenShift API server, and OVN network.
You can add labels to outbound log messages by using
key:valuepairs in the pipeline. For example, you might add a label to messages that the collector forwards to other data centers or label the logs by type. The collector also forwards labels added to objects with the log message.-
- input
Forwards the application logs associated with a specific project to a pipeline.
In the pipeline, you define the input sources to forward using an
inputRefparameter and where to forward the logs to using anoutputRefparameter.- Secret
-
A
key:value mapthat has confidential data such as user credentials.
Note the following:
-
You can use many types of outputs in the
ClusterLogForwardercustom resource (CR) to send logs to servers that support different protocols.
The following example forwards the audit logs to a secure external Elasticsearch instance.
Sample log forwarding outputs and pipelines
kind: ClusterLogForwarder
apiVersion: observability.openshift.io/v1
metadata:
name: instance
namespace: openshift-logging
spec:
serviceAccount:
name: logging-admin
outputs:
- name: external-es
type: elasticsearch
elasticsearch:
url: <elasticsearch_url>
version: 8
index: '{.log_type||"undefined"}'
authentication:
username:
key: username
secretName: es-secret
password:
key: password
secretName: es-secret
tls:
ca:
key: ca-bundle.crt
secretName: es-secret
certificate:
key: tls.crt
secretName: es-secret
key:
key: tls.key
secretName: es-secret
pipelines:
- name: my-logs
inputRefs:
- application
- infrastructure
outputRefs:
- external-es
version-
Forwarding to an external Elasticsearch of version 8.x or greater requires you to specify the
versionfield. index-
The
indexfield reads the.log_typefield value and falls back to "unknown" if not found. secretName- Use username and password to authenticate to the server
ca- Enable Mutual Transport Layer Security (mTLS) between collector and Elasticsearch. The spec identifies the keys and secret for the certificates that they represent.
2.12.2.1. Creating a Secret Copy linkLink copied to clipboard!
You can create a secret in the directory that has your certificate and key files by using the following command:
$ oc create secret generic -n <namespace> <secret_name> \
--from-file=ca-bundle.crt=<your_bundle_file> \
--from-literal=username=<your_username> \
--from-literal=password=<your_password>
Red Hat recommends generic or opaque secrets for best results.
2.12.3. Forwarding logs to Google Cloud Platform (GCP) Copy linkLink copied to clipboard!
You can forward logs to Google Cloud Logging.
Forwarding logs to GCP is not supported on Red Hat OpenShift on AWS.
Prerequisites
- Ensure that you installed the Red Hat OpenShift Logging Operator.
Procedure
Create a secret using your Google service account key.
$ oc -n openshift-logging create secret generic gcp-secret --from-file google-application-credentials.json=<your_service_account_key_file.json>Create a
ClusterLogForwarderCustom Resource YAML using the template below:apiVersion: observability.openshift.io/v1 kind: ClusterLogForwarder metadata: name: <log_forwarder_name> namespace: openshift-logging spec: serviceAccount: name: <service_account_name> outputs: - name: gcp-1 type: googleCloudLogging googleCloudLogging: authentication: credentials: secretName: gcp-secret key: google-application-credentials.json id: type : project value: openshift-gce-devel logId : app-gcp pipelines: - name: test-app inputRefs: - application outputRefs: - gcp-1serviceAccount.name- Specify the name of your service account.
value-
Set a
project,folder,organization, orbillingAccountfield and its corresponding value, depending on where you want to store your logs in the GCP resource hierarchy. logId-
Set the value to add to the
logNamefield of the log entry. The value can be a combination of static and dynamic values consisting of field paths followed by||, followed by another field path or a static value. You must encase a dynamic value in single curly brackets{}and follow it with a static fallback value separated with||. Static values can only contain alphanumeric characters along with dashes, underscores, dots and forward slashes. inputRefs-
Specify the names of inputs defined in the
input.namefield for this pipeline. You can also use the built-in valuesapplication,infrastructure,audit.
2.12.4. Configuring OTLP output Copy linkLink copied to clipboard!
Cluster administrators can use the OpenTelemetry Protocol (OTLP) output to collect and forward logs to OTLP receivers. The OTLP output uses the specification defined by the OpenTelemetry Observability framework to send data over HTTP with JSON encoding.
The OpenTelemetry Protocol (OTLP) output log forwarder is a Technology Preview feature only. Technology Preview features are not supported with Red Hat production service level agreements (SLAs) and might not be functionally complete. Red Hat does not recommend using them in production. These features provide early access to upcoming product features, enabling customers to test functionality and provide feedback during the development process.
For more information about the support scope of Red Hat Technology Preview features, see Technology Preview Features Support Scope.
Procedure
Create or edit a
ClusterLogForwardercustom resource (CR) to enable forwarding using OTLP.apiVersion: observability.openshift.io/v1 kind: ClusterLogForwarder metadata: annotations: observability.openshift.io/tech-preview-otlp-output: "enabled"1 name: clf-otlp spec: serviceAccount: name: <service_account_name> outputs: - name: otlp type: otlp otlp: tuning: compression: gzip deliveryMode: AtLeastOnce maxRetryDuration: 20 maxWrite: 10M minRetryDuration: 5 url: <otlp_url> pipelines: - inputRefs: - application - infrastructure - audit name: otlp-logs outputRefs: - otlpurl- This URL must be absolute and is a placeholder for the OTLP endpoint where logs are sent.
tuning.compression-
Compression algorithm to use. Valid values are
gzip,snappy, ornone. tuning.deliveryMode-
Delivery mode for log forwarding. Valid values are
AtLeastOnceorAtMostOnce. tuning.maxRetryDuration- Maximum time in seconds to retry failed deliveries.
tuning.maxWrite- Maximum size of a single write request.
tuning.minRetryDurationMinimum time in seconds between retries.
NoteThe OTLP output uses the OpenTelemetry data model, which is different from the ViaQ data model that is used by other output types. For more information, see OpenTelemetry Semantic Conventions.
Apply the
ClusterLogForwardercustom resource:$ oc apply -f <filename>.yaml
Verification
Verify that the
ClusterLogForwarderstatus showsReady:$ oc get clusterlogforwarder clf-otlp -n openshift-logging \ -o jsonpath='{.status.conditions[?(@.type=="Ready")].status}'The output should show
True.Verify that OTLP is functioning correctly by checking the LokiStack metrics dashboard:
-
In the OpenShift Container Platform web console, navigate to Observe
Dashboards. - From the Dashboard dropdown, select OpenShift Logging / LokiStack / Writes.
- Check the Distributor - structured metadata panel for incoming OTLP log records.
-
In the OpenShift Container Platform web console, navigate to Observe
2.12.5. Forwarding logs to Splunk Copy linkLink copied to clipboard!
2.12.5.1. Forwarding logs to Splunk HTTP Event Collector Copy linkLink copied to clipboard!
You can forward logs to the Splunk HTTP Event Collector (HEC).
Prerequisites
- Ensure that you installed the Red Hat OpenShift Logging Operator
- You have obtained a Base64 encoded Splunk HEC token.
Procedure
Create a secret using your Base64 encoded Splunk HEC token.
$ oc -n openshift-logging create secret generic vector-splunk-secret --from-literal hecToken=<HEC_Token>Create or edit the
ClusterLogForwarderCustom Resource (CR) using the template below:apiVersion: observability.openshift.io/v1 kind: ClusterLogForwarder metadata: name: <log_forwarder_name> namespace: openshift-logging spec: serviceAccount: name: <service_account_name> outputs: - name: splunk-receiver type: splunk splunk: url: '<http://your.splunk.hec.url:8088>' authentication: token: secretName: splunk-secret key: hecToken index: '{.log_type||"undefined"}' source: '{.log_source||"undefined"}' indexedFields: ['.log_type', '.log_source'] payloadKey: '.kubernetes' tuning: compression: gzip pipelines: - name: my-logs inputRefs: - application - infrastructure outputRefs: - splunk-receiverserviceAccount.name- The name of your service account.
outputs.name- Specify a name for the output.
type-
Specify the output type as
splunk. key- Specify the name of the secret that has your HEC token.
url- Specify the URL, including port, of your Splunk HEC.
index- Specify the name of the index to send events to. If you do not specify an index, the Splunk server uses its default index. This is an optional field.
source-
Specify the source of events to send to this sink. You can configure dynamic per-event values. This field is optional. If you do not specify a value, the
log_typeandlog_sourcevalues determine the value of the field. For example, see Default Splunk metadata key values. indexedFields-
Specify the fields to add to the Splunk index. This field is optional. The index stores the values directly alongside the raw event data, allowing for faster search performance on those fields. However,
indexed_fieldsfields increase storage use. Use them only for high-value fields that give significant search benefits, for example, large datasets with frequent queries on specific fields. You can use complex and nested fields as indexed fields. These are automatically transformed to meet Splunk’s requirements. payloadKey-
Specify the record field to use as the payload. By default, the
payloadKeyfield is not set, which means the collector forwards the complete log record as the payload. Use thepayloadKeyfield carefully. Selecting a single field as the payload might drop other important information in the log, potentially leading to inconsistent or incomplete log events. compression-
Specify the compression configuration, which can be either
gzipornone. The default value isnone. This field is optional. inputRefs- Specify the input names.
receiver- Specify the name of the output to use when forwarding logs with this pipeline.
2.12.5.2. Default Splunk metadata key values Copy linkLink copied to clipboard!
Red Hat OpenShift Logging Operator sets default values for some Splunk metadata keys if you do not configure them in the spec.output.splunk.source field of the ClusterLogForwarder Custom Resource (CR).
The following table describes the default value that the collector uses for Splunk metadata, depending on log_type and log_source attributes.
| Key | Infrastructure Journal
| Infrastructure or application container
| Audit
| Note |
|
| Not configured by default. | |||
|
| SYSLOG_IDENTIFIER |
| .log_source | |
|
| Not configured by default. | |||
|
|
|
|
| Determined automatically based on the type of the final event payload. |
|
|
|
|
| Not configurable. |
|
| Not configured by default. |
2.12.6. Forwarding logs over HTTP Copy linkLink copied to clipboard!
To enable forwarding logs over HTTP, specify http as the output type in the ClusterLogForwarder custom resource (CR).
Procedure
Create or edit the
ClusterLogForwarderCR using the template below:Example
ClusterLogForwarderCRapiVersion: observability.openshift.io/v1 kind: ClusterLogForwarder metadata: name: <log_forwarder_name> namespace: <log_forwarder_namespace> spec: managementState: Managed outputs: - name: <output_name> type: http http: headers: h1: v1 h2: v2 authentication: username: key: username secretName: <http_auth_secret> password: key: password secretName: <http_auth_secret> timeout: 300 proxyURL: <proxy_url> url: <url> tls: insecureSkipVerify: ca: key: <ca_certificate> secretName: <secret_name> pipelines: - inputRefs: - application name: pipe1 outputRefs: - <output_name> serviceAccount: name: <service_account_name>headers- Optional: Additional headers to send with each log record.
authentication.username- Optional: Username for HTTP Basic authentication. Specify the secret name and key containing the username.
authentication.password- Optional: Password for HTTP Basic authentication. Specify the secret name and key containing the password.
timeout- Optional: Timeout in seconds for HTTP requests. Default is 300 seconds (5 minutes).
proxyURL- Optional: URL of the HTTP/HTTPS proxy to forward logs over http or https from this output. This setting overrides any default proxy settings for the cluster or the node.
url- Destination address for logs.
tls.insecureSkipVerifyOptional: When set to
true, the collector skips verification of the server’s certificate. When set tofalse(the default), the collector verifies the server’s certificate against the CA specified intls.ca. IfinsecureSkipVerifyis set totrue, thetls.cafield is not required.WarningSetting
insecureSkipVerifytotrueis not recommended for production environments because it disables certificate validation and makes the connection vulnerable to man-in-the-middle attacks. Use this setting only for testing purposes or when connecting to trusted internal endpoints.tls.ca.secretName-
Secret name containing the certificate authority (CA) certificate for validating the server’s TLS certificate. Required when
insecureSkipVerifyisfalseor not set. tls.ca.key- The key name in the secret that contains the CA certificate.
<output_name>- This value should be the same as the output name.
serviceAccount.nameThe name of your service account.
NoteThe
tlsconfiguration shown in this example applies to HTTP outputs, but similar TLS settings are available for other output types that support TLS encryption, including Kafka, Syslog, Elasticsearch, and Splunk. For information about configuring TLS for other output types, run the commandoc explain clusterlogforwarders.spec.outputs.<output_type>.tls.
2.12.7. Forwarding logs to an external Loki logging system Copy linkLink copied to clipboard!
To configure log forwarding to Loki, you must create a ClusterLogForwarder custom resource (CR) with an output to Loki, and a pipeline that uses the output. The output to Loki can use the HTTP (insecure) or HTTPS (secure HTTP) connection.
Prerequisites
- You have installed Red Hat OpenShift Logging Operator.
- You have administrator access to OpenShift Container Platform.
-
You have installed OpenShift CLI (
oc). -
You have a Loki logging system running at the URL specified in the
urlfield.
Procedure
Create or edit a YAML file that defines the
ClusterLogForwarderCR object:apiVersion: observability.openshift.io/v1 kind: ClusterLogForwarder metadata: name: <log_forwarder_name> namespace: <log_forwarder_namespace> spec: serviceAccount: name: <service_account_name> outputs: - name: loki-output type: loki loki: authentication: username: key: username secretName: to-loki-secret password: key: password secretName: to-loki-secret token: from: secret secret: key: ca-bundle.crt name: to-loki-secret labelKeys: - <label_keys> tenantKey: '{.kubernetes.namespace_name||"application"}' url: https://loki.secure.com:3100 pipelines: - name: my-pipeline inputRefs: - application - audit outputRefs: - loki-outputserviceAccount.name- Specify the name of your service account.
outputs.name- Specify a name for the output.
type-
Specify the type as
loki. authentication- Specify the authentication information.
labelKeys-
Specify the log record keys to map to Loki stream labels. If you do not set the
labelKeysfield, theClusterLogForwarderCR uses these default keys:log_type,kubernetes.container_name,kubernetes.namespace_name,kubernetes.pod_name. tenantKey-
Specify the tenant for the logs. The value can be a combination of static and dynamic values consisting of field paths separated by
||. Encase dynamic values inside single curly brackets{}. Follow dynamic values with a static fallback value. url- Specify the URL for Loki.
inputRefs-
Specify the names of inputs defined in the
input.namefield for this pipeline. You can also use the built-in valuesapplication,infrastructure,audit. outputRefsSpecify the names of outputs defined in the
outputs.namefield for this pipeline.NoteBecause Loki requires log streams to be correctly ordered by timestamp,
labelKeysalways includes thekubernetes_hostlabel set, even if you do not specify it. This inclusion ensures that each stream originates from a single host, which prevents timestamps from becoming disordered due to clock differences on different hosts.
Apply the
ClusterLogForwarderCR object by running the following command:$ oc apply -f <filename>.yaml
2.12.8. Forwarding logs to a Kafka broker Copy linkLink copied to clipboard!
To configure log forwarding to an external Kafka instance, you must create a ClusterLogForwarder custom resource (CR) with an output to that instance, and a pipeline that uses the output. You can include a specific Kafka topic in the output or use the default. The Kafka output can use a TCP (insecure) or TLS (secure TCP) connection.
Procedure
Create or edit a YAML file that defines the
ClusterLogForwarderCR object:apiVersion: observability.openshift.io/v1 kind: ClusterLogForwarder metadata: name: <log_forwarder_name> namespace: <log_forwarder_namespace> spec: serviceAccount: name: <service_account_name> outputs: - name: kafka-output type: kafka kafka: authentication: sasl: username: key: <key> secretName: kafka-secret password: key: <key> secretName: kafka-secret mechanism: <sasl_mechanism> url: tls://kafka.example.devlab.com:9093/app-topic brokers: - tls://kafka-broker1.example.com:9093 - tls://kafka-broker2.example.com:9093 topic: pipelines: - name: app-topic inputRefs: - application outputRefs: - kafka-outputserviceAccount.name- Specify the name of your service account.
outputs.name- Specify a name for the output.
type-
Specify the
kafkatype. secretName-
If you use a
tlsprefix in the URL, you must specify the name of the secret required by the endpoint for TLS communication. mechanism-
Specify the Simple Authentication and Security Layer (SASL) mechanism to use. For example,
SCRAM-SHA-256,SCRAM-SHA-512, orPLAIN. The default value isPLAIN. url-
Optional: Specify the URL and port of the Kafka broker as a valid absolute URL, optionally with a specific topic. You can use the
tcp(insecure) ortls(secure TCP) protocol. If you enable the cluster-wide proxy by using the CIDR annotation, the output must be a server name or FQDN, and not an IP address. You must specify either the URL or Kafka brokers. brokers- Optional: Specify a list of broker endpoints of a Kafka cluster.
topic-
Specify the target topic. By default, the value for the field is
topic. The topic name can be a combination of static and dynamic values consisting of field paths separated by "||". Encase dynamic values in single curly brackets "{}". Follow dynamic values with a static fallback value. The topic specified here overrides the topic defined in theurlfield.
Apply the
ClusterLogForwarderCR by running the following command:$ oc apply -f <filename>.yaml
2.12.9. Forwarding to Azure Monitor Logs Copy linkLink copied to clipboard!
You can forward logs to Azure Monitor Logs. The Vector Azure Monitor Logs sink provides this functionality.
The azureMonitor output type is deprecated and will be removed in a future release. This output type will become obsolete in September 2026.
Prerequisites
- You have basic familiarity with Azure services.
- You have an Azure account configured for Azure Portal or Azure CLI access.
- You have obtained your Azure Monitor Logs primary or the secondary security key.
- You have determined which log types to forward.
-
You installed the OpenShift CLI (
oc). - You have installed Red Hat OpenShift Logging Operator.
- You have administrator permissions.
Procedure
Create a secret with your shared key:
apiVersion: v1 kind: Secret metadata: name: my-secret namespace: openshift-logging type: Opaque data: shared_key: <your_shared_key>shared_key- Must contain a primary or secondary key for the Log Analytics workspace making the request.
Obtain a shared key by running the following command in the Azure CLI:
Get-AzOperationalInsightsWorkspaceSharedKey -ResourceGroupName "<resource_name>" -Name "<workspace_name>”Create or edit your
ClusterLogForwarderCR using the template matching your log selection.Forward all logs
apiVersion: observability.openshift.io/v1 kind: ClusterLogForwarder metadata: name: <log_forwarder_name> namespace: openshift-logging spec: serviceAccount: name: <service_account_name> outputs: - name: azure-monitor type: azureMonitor azureMonitor: customerId: my-customer-id logType: my_log_type authentication: sharedKey: secretName: my-secret key: shared_key pipelines: - name: app-pipeline inputRefs: - application outputRefs: - azure-monitorserviceAccount.name- The name of your service account.
customerId- Unique identifier for the Log Analytics workspace. Required field.
logType- Record type of the submitted data. Can only contain letters, numbers, and underscores (_), and cannot exceed 100 characters. For more information, see Azure record type in the Microsoft Azure documentation.
2.12.10. Forwarding application logs from specific projects Copy linkLink copied to clipboard!
You can forward a copy of the application logs from specific projects to an external log aggregator, in addition to, or instead of, using the internal log store. You must also configure the external log aggregator to receive log data from OpenShift Container Platform.
To configure forwarding application logs from a project, you must create a ClusterLogForwarder custom resource (CR) with at least one input from a project, optional outputs for other log aggregators, and pipelines that use those inputs and outputs.
Prerequisites
- You must configure a logging server to receive the logging data using the specified protocol or format.
Procedure
Create or edit a YAML file that defines the
ClusterLogForwarderCR:Example
ClusterLogForwarderCRapiVersion: observability.openshift.io/v1 kind: ClusterLogForwarder metadata: name: <log_forwarder_name> namespace: <log_forwarder_namespace> spec: serviceAccount: name: <service_account_name> outputs: - name: <output_name> type: <output_type> inputs: - name: my-app-logs type: application application: includes: - namespace: my-project filters: - name: my-project-labels type: openshiftLabels openshiftLabels: project: my-project - name: cluster-labels type: openshiftLabels openshiftLabels: clusterId: C1234 pipelines: - name: <pipeline_name> inputRefs: - my-app-logs outputRefs: - <output_name> filterRefs: - my-project-labels - cluster-labelsinputs.name- Specify the name for the input.
type-
Specify the type as
applicationto collect logs from applications. includes- Specify the set of namespaces and containers to include when collecting logs.
openshiftLabels-
Specify the labels to apply to log records passing through this pipeline. These labels appear in the
openshift.labelsmap in the log record. pipelines.name- Specify a name for the pipeline.
Apply the
ClusterLogForwarderCR by running the following command:$ oc apply -f <filename>.yaml
2.12.11. Forwarding application logs from specific pods Copy linkLink copied to clipboard!
As a cluster administrator, you can use Kubernetes pod labels to gather log data from specific pods and forward it to a log collector.
Suppose that you have an application composed of pods running alongside other pods in various namespaces. If those pods have labels that identify the application, you can gather and output their log data to a specific log collector.
To specify the pod labels, you use one or more matchLabels key-value pairs. If you specify many key-value pairs, the collector selects only pods that match all of them.
Procedure
Create or edit a YAML file that defines the
ClusterLogForwarderCR object. In the file, specify the pod labels using simple equality-based selectors underinputs[].name.application.selector.matchLabels, as shown in the following example.apiVersion: observability.openshift.io/v1 kind: ClusterLogForwarder metadata: name: <log_forwarder_name> namespace: <log_forwarder_namespace> spec: serviceAccount: name: <service_account_name> outputs: - <output_name> # ... inputs: - name: exampleAppLogData type: application application: includes: - namespace: app1 - namespace: app2 selector: matchLabels: environment: production app: nginx pipelines: - inputRefs: - exampleAppLogData outputRefs: # ...serviceAccount.name- Specify the service account name.
inputs.name- Specify a name for the input.
type-
Specify the type as
applicationto collect logs from applications. includes- Specify the set of namespaces to include when collecting logs.
matchLabels- Specify the key-value pairs of pod labels whose log data you want to gather. You must specify both a key and value, not just a key. The collector selects only pods that match all the key-value pairs.
Optional: You can send log data from additional applications that have different pod labels to the same pipeline.
-
For each unique combination of pod labels, create an additional
inputs[].namesection similar to the one shown. -
Update the
selectorsto match the pod labels of this application. Add the new
inputs[].namevalue toinputRefs. For example:- inputRefs: [ myAppLogData, myOtherAppLogData ]
-
For each unique combination of pod labels, create an additional
Create the CR object:
$ oc create -f <file_name>.yaml
2.12.11.1. Forwarding logs using the syslog protocol Copy linkLink copied to clipboard!
You can use the syslog RFC3164 or RFC5424 protocol to send a copy of your logs to an external log aggregator. You are responsible for configuring the external log aggregator, such as a syslog server, to receive the logs from OpenShift Container Platform.
To configure log forwarding using the syslog protocol, you must create a ClusterLogForwarder custom resource (CR) with one or more outputs to the syslog servers, and pipelines that use those outputs. The syslog output can use a UDP, TCP, or TLS connection.
Prerequisites
- You must configure a logging server to receive the logging data using the specified protocol or format.
Procedure
Create or edit a YAML file that defines the
ClusterLogForwarderCR object:apiVersion: observability.openshift.io/v1 kind: ClusterLogForwarder metadata: name: collector spec: managementState: Managed outputs: - name: rsyslog-east syslog: appName: <app_name> enrichment: KubernetesMinimal facility: <facility_value> msgId: <message_ID> payloadKey: <record_field> procId: <process_ID> rfc: <RFC3164_or_RFC5424> severity: informational tuning: deliveryMode: <AtLeastOnce_or_AtMostOnce> url: <url> tls: ca: key: ca-bundle.crt secretName: syslog-secret type: syslog pipelines: - inputRefs: - application name: syslog-east outputRefs: - rsyslog-east serviceAccount: name: logcollectoroutputs.name- Specify a name for the output.
appName-
Optional: Specify the value for the
APP-NAMEpart of the syslog message header. The value must conform with The Syslog Protocol. The value can be a combination of static and dynamic values consisting of field paths followed by||, and then followed by another field path or a static value. The collector truncates the final values to a maximum length of 48 characters. You must encase a dynamic value in curly brackets and follow the value with a static fallback value separated with||. Static values can only contain alphanumeric characters along with dashes, underscores, dots and forward slashes. Example value: <value1>-{.<value2>||"none"}. enrichment-
Optional: Specify the enrichment level for Kubernetes metadata fields added to log records. The value can be
KubernetesMinimalto add minimal Kubernetes fields such as namespace, pod name, and container name. This parameter replaces theaddLogSourceparameter that was removed in Logging 6.0. facility-
Optional: Specify the value for
Facilitypart of the syslog-msg header. msgId-
Optional: Specify the value for
MSGIDpart of the syslog-msg header. The value can be a combination of static and dynamic values consisting of field paths followed by||, and then followed by another field path or a static value. The collector truncates the final values to a maximum length of 32 characters. You must encase a dynamic value in curly brackets and follow the value with a static fallback value separated with||. Static values can only contain alphanumeric characters along with dashes, underscores, dots and forward slashes. Example value: <value1>-{.<value2>||"none"}. payloadKey-
Optional: Specify the record field to use as the payload. The
payloadKeyvalue must be a single field path encased in single curly brackets{}. Example: {.<value>}. procId-
Optional: Specify the value for the
PROCIDpart of the syslog message header. The value must conform with The Syslog Protocol. The value can be a combination of static and dynamic values consisting of field paths followed by||, and then followed by another field path or a static value. The collector truncates the final values to a maximum length of 48 characters. You must encase a dynamic value in curly brackets and follow the value with a static fallback value separated with||. Static values can only contain alphanumeric characters along with dashes, underscores, dots and forward slashes. Example value: <value1>-{.<value2>||"none"}. rfc-
Optional: Set the RFC that the generated messages conform to. The value can be
RFC3164orRFC5424. severity- Optional: Set the severity level for the message. For more information, see The Syslog Protocol.
deliveryMode-
Optional: Set the delivery mode for log forwarding. The value can be either
AtLeastOnce, orAtMostOnce. url-
Specify the absolute URL with a scheme. Valid schemes are:
tcp,tls, andudp. For example:tls://syslog-receiver.example.com:6514. tls- Specify the settings for controlling options of the transport layer security (TLS) client connections.
inputRefs-
Specify which log types to forward by using the pipeline:
application,infrastructure, oraudit. pipelines.name- Specify a name for the pipeline.
serviceAccount- The name of your service account.
Create the CR object:
$ oc create -f <filename>.yaml
2.12.11.2. Adding log source information to the message output Copy linkLink copied to clipboard!
You can add namespace_name, pod_name, and container_name elements to the message field of the record by adding the enrichment field to your ClusterLogForwarder custom resource (CR).
# ...
spec:
outputs:
- name: syslogout
syslog:
enrichment: KubernetesMinimal
facility: user
payloadKey: message
rfc: RFC3164
severity: debug
type: syslog
url: tls://syslog-receiver.example.com:6514
pipelines:
- inputRefs:
- application
name: test-app
outputRefs:
- syslogout
# ...
This configuration is compatible with both RFC3164 and RFC5424.
Example syslog message output with enrichment: None
2025-03-03T11:48:01+00:00 example-worker-x syslogsyslogserverd846bb9b: {...}
Example syslog message output with enrichment: KubernetesMinimal
2025-03-03T11:48:01+00:00 example-worker-x syslogsyslogserverd846bb9b: namespace_name=cakephp-project container_name=mysql pod_name=mysql-1-wr96h,message: {...}
2.12.12. Forwarding logs to Amazon CloudWatch Copy linkLink copied to clipboard!
To configure log forwarding to CloudWatch, create a ClusterLogForwarder custom resource (CR) with an output for CloudWatch and a pipeline that uses the output.
Prerequisites
- You have installed Red Hat OpenShift Logging Operator.
- You have administrator access to OpenShift Container Platform.
-
You have installed OpenShift CLI (
oc).
Procedure
Create a
SecretYAML file that uses theaws_access_key_idandaws_secret_access_keyfields to specify your base64-encoded AWS credentials. For example:apiVersion: v1 kind: Secret metadata: name: aws-secret namespace: <namespace_name> data: aws_access_key_id: QUtJQUlPU0ZPRE5ON0VYQU1QTEUK aws_secret_access_key: d0phbHJYVXRuRkVNSS9LN01ERU5HL2JQeFJmaUNZRVhBTVBMRUtFWQo=namespace-
Specify the namespace where your
ClusterLogForwarderCR is deployed. The secret must be in the same namespace as theClusterLogForwarderCR.
Create the secret. For example:
$ oc apply -f aws-secret.yamlCreate or edit a YAML file that defines the
ClusterLogForwarderCR object. In the file, specify the name of the secret. For example:apiVersion: observability.openshift.io/v1 kind: ClusterLogForwarder metadata: name: <log_forwarder_name> namespace: <log_forwarder_namespace> spec: serviceAccount: name: <service_account_name> outputs: - name: cw-output type: cloudwatch cloudwatch: authentication: type: awsAccessKey awsAccessKey: keyId: key: <key> secretName: cw-secret keySecret: key: <key> secretName: cw-secret groupName: <prefix-{.dynamic_value||"none"}> region: us-east-2 pipelines: - name: infra-logs inputRefs: - infrastructure - audit - application outputRefs: - cw-outputserviceAccount.name- Specify the name of your service account.
outputs.name- Specify a name for the output.
type-
Specify the
cloudwatchtype. secretName- Specify the name of the secret that has your AWS credentials.
groupName- Specify the strategy for grouping log streams. The value can be a combination of static and dynamic values consisting of field paths separated by "||". Encase dynamic values in single curly brackets "{}". Follow dynamic values with a static fallback value.
region- Specify the AWS region.
pipelines.name- Specify a name for the pipeline.
inputRefs-
Specify the names of inputs defined in the
input.namefield for this pipeline. You can also use the built-in valuesapplication,infrastructure,audit. output-
Specify the names of outputs defined in the
outputs.namefield for this pipeline.
Apply the CR object:
$ oc apply -f <file_name>.yaml
2.12.13. Forwarding logs to Amazon S3 endpoint Copy linkLink copied to clipboard!
To configure log forwarding to an Amazon S3 endpoint, create a ClusterLogForwarder custom resource (CR) with an S3 output and a pipeline that uses it.
Prerequisites
- You have installed Red Hat OpenShift Logging Operator.
- You have administrator access to OpenShift Container Platform.
-
You have installed OpenShift CLI (
oc).
Procedure
Create a
SecretYAML file that uses theaws_access_key_idandaws_secret_access_keyfields to specify your base64-encoded AWS credentials. For example:apiVersion: v1 kind: Secret metadata: name: aws-secret namespace: <namespace_name> data: aws_access_key_id: QUtJQUlPU0ZPRE5ON0VYQU1QTEUK aws_secret_access_key: d0phbHJYVXRuRkVNSS9LN01ERU5HL2JQeFJmaUNZRVhBTVBMRUtFWQo=namespace-
Specify the namespace where your
ClusterLogForwarderCR is deployed. The secret must be in the same namespace as theClusterLogForwarderCR.
Create the secret. For example:
$ oc apply -f aws-secret.yamlCreate or edit a YAML file that defines the
ClusterLogForwarderCR object and specify the secret name. For example:apiVersion: observability.openshift.io/v1 kind: ClusterLogForwarder metadata: name: <log_forwarder_name> spec: serviceAccount: name: <service_account_name> outputs: - name: s3bucket type: s3 s3: authentication: type: awsAccessKey awsAccessKey: keyId: key: aws_access_key_id secretName: aws-secret keySecret: key: aws_secret_access_key secretName: aws-secret bucket: <bucket_name> keyPrefix: 's3{.log_type||"missing"}' region: us-east-1 url: 'https://s3.us-east-1.amazonaws.com' pipelines: - name: pipe1 inputRefs: - application outputRefs: - s3bucketserviceAccount.name- Specify the name of your service account.
outputs.name- Specify a name for the output.
type-
Specify the
s3type. secretName- Specify the name of the secret that has your AWS credentials.
bucket- Specify the Amazon S3 bucket name for log storage.
keyPrefix- Specify the S3 key prefix for log objects. The value can be a combination of static and dynamic values consisting of field paths separated by "||". Encase dynamic values in single curly brackets "{}". You must follow dynamic values with a static fallback value.
url-
Optional: Specify the S3 endpoint URL. If you do not specify this, the system uses the default AWS S3 endpoint
https://s3.<region>.amazonaws.combased on the region. Use this field for S3-compatible storage endpoints or custom endpoints.
Apply the CR object:
$ oc apply -f <file_name>.yaml
2.12.14. Forwarding logs to Amazon CloudWatch from STS-enabled clusters Copy linkLink copied to clipboard!
2.12.14.1. Creating an AWS IAM role Copy linkLink copied to clipboard!
Create an Amazon Web Services (AWS) IAM role that your service account can assume to securely access AWS resources.
The following procedure demonstrates creating an AWS IAM role by using the AWS CLI. You can also use the Cloud Credential Operator (CCO) utility ccoctl. Using the ccoctl utility creates many fields in the IAM role policy that are not required by the ClusterLogForwarder custom resource (CR). The CR ignores these extra fields. However, the ccoctl utility provides a convenient way for configuring IAM roles. For more information see Manual mode with short-term credentials for components.
Prerequisites
- You have access to an Red Hat OpenShift Logging cluster with Security Token Service (STS) enabled and configured for AWS.
- You have administrator access to the AWS account.
- AWS CLI installed.
Procedure
Create an IAM policy that grants permissions to write logs to CloudWatch.
Create a file, for example
cw-iam-role-policy.json, with the following content:{ "Version": "2012-10-17", "Statement": [ { "Effect": "Allow", "Action": [ "logs:PutLogEvents", "logs:CreateLogGroup", "logs:PutRetentionPolicy", "logs:CreateLogStream", "logs:DescribeLogGroups", "logs:DescribeLogStreams" ], "Resource": "arn:aws:logs:*:*:*" } ] }Create the IAM policy based on the earlier policy definition by running the following command:
$ aws iam create-policy \ --policy-name cluster-logging-allow \ --policy-document file://cw-iam-role-policy.jsonNote the
Arnvalue of the created policy.
Create a trust policy to allow the logging service account to assume an IAM role:
Create a file, for example
cw-trust-policy.json, with the following content:{ "Version": "2012-10-17", "Statement": [ { "Effect": "Allow", "Principal": { "Federated": "arn:aws:iam::123456789012:oidc-provider/<OPENSHIFT_OIDC_PROVIDER_URL>" }, "Action": "sts:AssumeRoleWithWebIdentity", "Condition": { "StringEquals": { "<OPENSHIFT_OIDC_PROVIDER_URL>:sub": "system:serviceaccount:openshift-logging:logcollector" } } } ] }
Create an IAM role based on the trust policy defined earlier by running the following command:
$ aws iam create-role --role-name openshift-logger --assume-role-policy-document file://cw-trust-policy.jsonNote the
Arnvalue of the created role.Attach the policy to the role by running the following command:
$ aws iam put-role-policy \ --role-name openshift-logger --policy-name cluster-logging-allow \ --policy-document file://cw-role-policy.json
Verification
Verify the role and the permissions policy by running the following command:
$ aws iam get-role --role-name openshift-loggerExample output
ROLE arn:aws:iam::123456789012:role/openshift-logger ASSUMEROLEPOLICYDOCUMENT 2012-10-17 STATEMENT sts:AssumeRoleWithWebIdentity Allow STRINGEQUALS system:serviceaccount:openshift-logging:openshift-logger PRINCIPAL arn:aws:iam::123456789012:oidc-provider/<OPENSHIFT_OIDC_PROVIDER_URL>
2.12.14.2. Creating a secret for AWS CloudWatch with an existing AWS role Copy linkLink copied to clipboard!
Create a secret for Amazon Web Services (AWS) Security Token Service (STS) from the configured AWS IAM role by using the oc create secret --from-literal command.
Prerequisites
- You have created an AWS IAM role.
- You have administrator access to Red Hat OpenShift Logging.
Procedure
In the CLI, enter the following to generate a secret for AWS:
$ oc create secret generic sts-secret -n openshift-logging --from-literal=role_arn=arn:aws:iam::123456789012:role/openshift-loggerExample Secret
apiVersion: v1 kind: Secret metadata: namespace: openshift-logging name: sts-secret stringData: role_arn: arn:aws:iam::123456789012:role/openshift-logger
2.12.14.3. Forwarding logs to Amazon CloudWatch from STS-enabled clusters Copy linkLink copied to clipboard!
You can forward logs from logging for Red Hat OpenShift deployed on clusters with Amazon Web Services (AWS) Security Token Service (STS)-enabled to Amazon CloudWatch. Amazon CloudWatch is a service that helps administrators observe and monitor resources and applications on AWS.
Prerequisites
- Ensure that you installed the Red Hat OpenShift Logging Operator.
- You have configured a credential secret.
- You have administrator access to Red Hat OpenShift Logging.
Procedure
Create or update a
ClusterLogForwardercustom resource (CR):apiVersion: observability.openshift.io/v1 kind: ClusterLogForwarder metadata: name: <log_forwarder_name> namespace: openshift-logging spec: serviceAccount: name: <service_account_name> outputs: - name: cw-output type: cloudwatch cloudwatch: groupName: 'prefix-{.log_type||"none"}' region: us-east-2 authentication: type: iamRole iamRole: roleARN: key: role_arn secretName: sts-secret token: from: serviceAccount pipelines: - name: to-cloudwatch inputRefs: - infrastructure - audit - application outputRefs: - cw-outputserviceAccount.name- Specify the name of your service account.
outputs.name- Specify a name for the output.
type-
Specify the
cloudwatchtype. groupName- Specify the group name for the log stream.
region- Specify the AWS region.
iamRole-
Specify
iamRoleas the authentication type for STS. roleARN-
Specify the name of the secret and the key where you store the
role_arnresource. token-
Specify the service account token to use for authentication. To use the projected service account token, use
from: serviceAccount. inputRefs-
Specify which log types to forward by using the pipeline:
application,infrastructure, oraudit. outputRefs- Specify the names of the output to use when forwarding logs with this pipeline.
2.12.14.4. Forwarding logs to Amazon S3 endpoint from STS-enabled clusters Copy linkLink copied to clipboard!
You can forward logs from logging for Red Hat OpenShift deployed on Amazon Web Services (AWS) Security Token Service (STS)-enabled clusters to an S3 configured endpoint.
Prerequisites
- You have installed Red Hat OpenShift Logging Operator.
- You have configured a credential secret.
- You have administrator access to OpenShift Container Platform.
-
You have installed OpenShift CLI (
oc).
Procedure
Create or update a
ClusterLogForwardercustom resource (CR):apiVersion: observability.openshift.io/v1 kind: ClusterLogForwarder metadata: name: <log_forwarder_name> spec: serviceAccount: name: <service_account_name> outputs: - name: s3-output type: s3 s3: keyPrefix: 's3{.log_type||"missing"}' bucket: <bucket_name> region: us-east-2 authentication: type: iamRole iamRole: roleARN: key: role_arn secretName: sts-secret token: from: serviceAccount pipelines: - name: to-s3 inputRefs: - infrastructure - audit - application outputRefs: - s3-output-
keyPrefix: The S3 key prefix for log objects. You can use static or dynamic values consisting of field paths separated by||and ending with a static fallback value. -
bucket: The S3 bucket name for log storage.
-
Apply the
ClusterLogForwarderCR by running the following command:$ oc apply -f <filename>.yaml
2.12.14.5. Cross-account log forwarding with AssumeRole Copy linkLink copied to clipboard!
You can forward logs to external AWS accounts by using the AWS Security Token Service (STS) AssumeRole functionality. Cross-account log forwarding enables centralized logging across many AWS accounts while maintaining security boundaries.
Cross-account log forwarding works as follows:
- Initial Authentication: The collector authenticates to the AWS account of your cluster using Identity and Access Management (IAM) roles or access keys.
- Role Assumption: After initial authentication, the collector assumes a role in the target AWS account.
- Log Forwarding: The collector forwards logs to CloudWatch or S3 bucket in the target account using credentials of the assumed role.
When using cross-account log forwarding, keep these security considerations in mind :
Use external IDs for cross-account role assumptions.
External ID serves as an additional identifier.
NoteExternal IDs appear in CloudTrail logs and API responses. Therefore, they are not considered secrets.
Take the following measures when creating external IDs:
- They should be unique for each trust relationship.
- They should be unpredictable and not based on public information.
- Grant only the minimum required permissions to assumed roles.
- Protect secrets containing role Amazon Resource Names (ARN) and tokens.
-
Monitor CloudTrail for
AssumeRoleactivity.
2.12.14.6. Configuring AWS IAM for cross-account access Copy linkLink copied to clipboard!
You can configure AWS Identity Access Management (IAM) for cross-account access.
Prerequisites
- You have administrator permissions.
- You have created the target role and the target role has permissions to send data to CloudWatch or S3 outputs.
- You have permissions to update the policy for the initial and the target role.
Procedure
Create an initial account in your cluster account to assume the target role with the required permissions.
The initial account can either be a user or an IAM role. This account assumes the target role.
{ "Version": "2012-10-17", "Statement": [ { "Effect": "Allow", "Action": "sts:AssumeRole", "Resource": "arn:aws:iam::<target_aws_account_id>:role/target-logging-role" } ] }In your target role, create a trust policy and specify the initial cluster role, and optionally an external id.
{ "Version": "2012-10-17", "Statement": [ { "Effect": "Allow", "Principal": { "AWS": "arn:aws:iam:::<role_or_user>/<role_name_or_user_name>" }, "Action": "sts:AssumeRole", "Condition": { "StringEquals": { "sts:ExternalId": "<your_unique_external_id>" } } } ] }Set the
Principal.AWSfield as follows:If the initial account is a user, use the format:
arn:aws:iam::<aws_account_id>:user/<user_name>If the initial account is an IAM role, use the format:
arn:aws:iam::<aws_account_id>:role/<role_name>
Configure CloudWatch or S3 permissions in the target role depending on whether you want to forward logs to the CloudWatch or S3 output:
CloudWatch permissions
{ "Version": "2012-10-17", "Statement": [ { "Effect": "Allow", "Action": [ "logs:CreateLogGroup", "logs:CreateLogStream", "logs:PutLogEvents", "logs:DescribeLogGroups", "logs:DescribeLogStreams" ], "Resource": "*" } ] }S3 permissions
{ "Version": "2012-10-17", "Statement": [ { "Sid": "AllowRoleToPutObjects", "Effect": "Allow", "Principal": { "AWS": "<assumerole_arn>" }, "Action": [ "s3:PutObject", "s3:PutObjectAcl" ], "Resource": [ "arn:<aws_partition>:s3:::<s3_bucket>", "arn:<aws_partition>:s3:::<s3_bucket>/*" ] } ] }
2.12.14.7. Example ClusterLogForwarder configuration for cross-account forwarding Copy linkLink copied to clipboard!
The following example illustrates using cross-account AssumeRole field configuration when forwarding logs to CloudWatch.
ClusterLogForwarder resource with AssumeRole authentication
apiVersion: observability.openshift.io/v1
kind: ClusterLogForwarder
metadata:
name: cross-account-example
namespace: openshift-logging
spec:
serviceAccount:
name: my-sa
outputs:
- name: cw-cross-account
type: cloudwatch
cloudwatch:
groupName: my-logs-{.log_type||"unknown"}
region: us-east-1
authentication:
type: iamRole
iamRole:
roleARN:
secretName: initial-role-secret
key: role_arn
token:
from: serviceAccount
# Cross-account assume role configuration
assumeRole:
roleARN:
secretName: cross-account-secret
key: assume_role_arn
externalID: "my-unique-id-1234"
pipelines:
- name: cross-account-logs
inputRefs:
- application
outputRefs:
- cw-cross-account
-
authentication.assumeRole.roleARN: Reference to a secret containing the Amazon Resource Name (ARN) of the role to assume in the target account. -
authentication.assumeRole.externalID: A string containing the external ID to enforce for assuming the role. This can add additional security by ensuring only entities with knowledge of the external ID can assume the role.
Session names for assumed role sessions are automatically generated by the Red Hat OpenShift Logging Operator to give meaningful identification in AWS CloudTrail logs for auditing purposes. The Operator generates session names by using cluster metadata as follows:
-
Primary format:
{clusterId}-{clfName}-{outputName}. -
Fallback format (if cluster metadata unavailable):
output-{outputName}. - Always truncated to 64 characters maximum (AWS requirement).
- Uses first 8 characters of cluster ID for uniqueness.
2.12.14.8. Cross-account log forwarding troubleshooting Copy linkLink copied to clipboard!
The following table describes issues that you might experience with cross-account log forwarding and the steps that you can take to resolve the issues.
| Issue | Troubleshooting steps |
|---|---|
| Role Assumption Fails |
|
| Permission Denied |
|
| Invalid role or user Amazon Resource Name (ARN) |
|