// Module included in the following assemblies:
//
// assembly-logging-configuration.adoc

[id='creating-logging-filters_{context}']
= Adding logging filters to Strimzi operators

[role="_abstract"]
Add logging filters to Strimzi operators by using a `ConfigMap` that contains a complete `log4j2.properties` file with your custom log4j2 configuration.

Filters are useful when too many logging messages are being produced. 
For instance, if `rootLogger.level="DEBUG"`, filters reduce the number of logs to focus on a specific resource by logging only messages matching the filter.

Markers specify what to include in the log using kind, namespace, and resource name values. 
For example, to isolate the logs of a failing Kafka cluster, set the kind to `Kafka` and use the namespace and name of the cluster.

.Basic logging filter configuration
[source,properties]
----
rootLogger.level = "INFO"
rootLogger.appenderRefs = console
rootLogger.appenderRef.console.ref = STDOUT

appender.console.type = Console
appender.console.name = STDOUT
appender.console.layout.type = PatternLayout
appender.console.layout.pattern = %d{yyyy-MM-dd HH:mm:ss} %-5p [%t] %c{1}:%L - %m%n

appender.console.filter.filter1.type = MarkerFilter <1>
appender.console.filter.filter1.onMatch = ACCEPT <2>
appender.console.filter.filter1.onMismatch = DENY <3>
appender.console.filter.filter1.marker = Kafka(my-namespace/my-kafka-cluster) <4>
----
<1> The `MarkerFilter` compares a specified marker.
<2> `onMatch` accepts logs if the marker matches.
<3> `onMismatch` rejects logs if the marker does not match.
<4> Marker format: `kind(namespace/resource_name)`.

For multiple filters, define each one separately:

.Multiple logging filter configuration
[source,properties]
----
# ...

appender.console.name = STDOUT

appender.console.filter.filter1.type = MarkerFilter
appender.console.filter.filter1.onMatch = ACCEPT
appender.console.filter.filter1.onMismatch = DENY
appender.console.filter.filter1.marker = Kafka(my-namespace/my-kafka-cluster-1)

appender.console.filter.filter2.type = MarkerFilter
appender.console.filter.filter2.onMatch = ACCEPT
appender.console.filter.filter2.onMismatch = DENY
appender.console.filter.filter2.marker = Kafka(my-namespace/my-kafka-cluster-2)
----

.Adding filters to the Cluster Operator

To add filters to the Cluster Operator, update the `ConfigMap` YAML file (`install/cluster-operator/050-ConfigMap-strimzi-cluster-operator.yaml`):

.Procedure

. Update the `050-ConfigMap-strimzi-cluster-operator.yaml` file to add the filter properties:
+
[source,yaml,subs="+attributes"]
----
kind: ConfigMap
apiVersion: v1
metadata:
  name: strimzi-cluster-operator
data:
  log4j2.properties: |
    rootLogger.level = "INFO"
    rootLogger.appenderRefs = console
    rootLogger.appenderRef.console.ref = STDOUT

    appender.console.type = Console
    appender.console.name = STDOUT
    appender.console.layout.type = PatternLayout
    appender.console.layout.pattern = %d{yyyy-MM-dd HH:mm:ss} %-5p [%t] %c{1}:%L - %m%n
    
    appender.console.filter.filter1.type=MarkerFilter
    appender.console.filter.filter1.onMatch=ACCEPT
    appender.console.filter.filter1.onMismatch=DENY
    appender.console.filter.filter1.marker=Kafka(my-namespace/my-kafka-cluster)
----
+
Alternatively, edit the `ConfigMap` directly:
+
[source,shell,subs=+quotes]
----
kubectl edit configmap strimzi-cluster-operator
----

. If updating the YAML file, apply the changes to the `ConfigMap` configuration.

.Adding filters to the Topic or User Operator

To add filters to the Topic or User Operator, create or edit a logging `ConfigMap`. 
The same method applies for both operators.

.Procedure

. Create the `ConfigMap` as a YAML file or from a properties file. 
+
.Example filter properties for `my-topic` topic
[source,yaml,subs="+attributes"]
----
kind: ConfigMap
apiVersion: v1
metadata:
  name: logging-configmap
data:
  log4j2.properties: |
    rootLogger.level = "INFO"
    rootLogger.appenderRefs = console
    rootLogger.appenderRef.console.ref = STDOUT

    appender.console.type = Console
    appender.console.name = STDOUT
    appender.console.layout.type = PatternLayout
    appender.console.layout.pattern = %d{yyyy-MM-dd HH:mm:ss} %-5p [%t] %c{1}:%L - %m%n

    appender.console.filter.filter1.type = MarkerFilter
    appender.console.filter.filter1.onMatch = ACCEPT
    appender.console.filter.filter1.onMismatch = DENY
    appender.console.filter.filter1.marker = KafkaTopic(my-namespace/my-topic)
----
+
If you are using a properties file, define the logging configuration and specify the file at the command line when creating the `ConfigMap`.
+
.Properties file definition
[source,text]
----
# Define the logger
rootLogger.level = "INFO"
rootLogger.appenderRefs = console
rootLogger.appenderRef.console.ref = STDOUT
# Define the appenders
appender.console.type = Console
appender.console.name = STDOUT
appender.console.layout.type = PatternLayout
appender.console.layout.pattern = %d{yyyy-MM-dd HH:mm:ss} %-5p [%t] %c{1}:%L - %m%n
# Set the filters
appender.console.filter.filter1.type = MarkerFilter
appender.console.filter.filter1.onMatch = ACCEPT
appender.console.filter.filter1.onMismatch = DENY
appender.console.filter.filter1.marker = KafkaTopic(my-namespace/my-topic)
# ...
----
+
.Specifying the properties file
[source,shell]
----
kubectl create configmap logging-configmap --from-file=log4j2.properties
----

. Define `external` logging in the `topicOperator` or `userOperator` configuration of the `Kafka` resource, specifying the `name` and `key` of the ConfigMap:
+
[source,shell,subs="+quotes,attributes"]
----
spec:
  # ...
  entityOperator:
    topicOperator:
      logging:
        type: external
        valueFrom:
          configMapKeyRef:
            name: logging-configmap
            key: log4j2.properties
----

. Apply the changes to the `Kafka` configuration.

[role="_additional-resources"]
.Additional resources
* xref:con-config-kafka-kraft-str[Configuring Kafka]
* xref:ref-operator-cluster-logging-configmap-str[Cluster Operator logging]
* link:{BookURLConfiguring}#property-topic-operator-logging-reference[Topic Operator logging^]
* link:{BookURLConfiguring}#property-user-operator-logging-reference[User Operator logging^]
