Configures a ZooKeeper cluster.

[id='property-zookeeper-config-{context}']
= `config`

Use the `config` properties to configure ZooKeeper options as keys.

The values can be one of the following JSON types:

* String
* Number
* Boolean

*Exceptions*

You can specify and configure the options listed in the {ApacheZookeeperConfig}.

However, Strimzi takes care of configuring and managing options related to the following, which cannot be changed:

* Security (encryption, authentication, and authorization)
* Listener configuration
* Configuration of data directories
* ZooKeeper cluster composition

Properties with the following prefixes cannot be set:

* `4lw.commands.whitelist`
* `authProvider`
* `clientPort`
* `dataDir`
* `dataLogDir`
* `quorum.auth`
* `reconfigEnabled`
* `requireClientAuthScheme`
* `secureClientPort`
* `server.`
* `snapshot.trust.empty`
* `standaloneEnabled`
* `serverCnxnFactory`
* `ssl.`
* `sslQuorum`

If the `config` property contains an option that cannot be changed, it is disregarded, and a warning message is logged to the Cluster Operator log file.
All other supported options are forwarded to ZooKeeper, including the following exceptions to the options configured by Strimzi:

* Any `ssl` configuration for xref:con-common-configuration-ssl-reference[supported TLS versions and cipher suites]

.Example ZooKeeper configuration
[source,yaml,subs="attributes+"]
----
apiVersion: {KafkaApiVersion}
kind: Kafka
spec:
  kafka:
    # ...
  zookeeper:
    # ...
    config:
      autopurge.snapRetainCount: 3
      autopurge.purgeInterval: 2
    # ...
----

[id='property-zookeeper-logging-{context}']
= `logging`

ZooKeeper has a configurable logger:

* `zookeeper.root.logger`

ZooKeeper uses the Apache `log4j` logger implementation.

Use the `logging` property to configure loggers and logger levels.

You can set the log levels by specifying the logger and level directly (inline) or use a custom (external) ConfigMap.
If a ConfigMap is used, you set `logging.valueFrom.configMapKeyRef.name` property to the name of the ConfigMap containing the external logging configuration. Inside the ConfigMap, the logging configuration is described using `log4j.properties`. Both `logging.valueFrom.configMapKeyRef.name` and `logging.valueFrom.configMapKeyRef.key` properties are mandatory. A ConfigMap using the exact logging configuration specified is created with the custom resource when the Cluster Operator is running, then recreated after each reconciliation. If you do not specify a custom ConfigMap, default logging settings are used. If a specific logger value is not set, upper-level logger settings are inherited for that logger.
For more information about log levels, see {ApacheLoggers}.

Here we see examples of `inline` and `external` logging.
The `inline` logging specifies the root logger level.
You can also set log levels for specific classes or loggers by adding them to the loggers property.

.Inline logging
[source,yaml,subs="+quotes,attributes"]
----
apiVersion: {KafkaApiVersion}
kind: Kafka
spec:
  # ...
  zookeeper:
    # ...
    logging:
      type: inline
      loggers:
        zookeeper.root.logger: INFO
        log4j.logger.org.apache.zookeeper.server.FinalRequestProcessor: TRACE
        log4j.logger.org.apache.zookeeper.server.ZooKeeperServer: DEBUG
    # ...
----

NOTE: Setting a log level to `DEBUG` may result in a large amount of log output and may have performance implications.


.External logging
[source,yaml,subs="+quotes,attributes"]
----
apiVersion: {KafkaApiVersion}
kind: Kafka
spec:
  # ...
  zookeeper:
    # ...
    logging:
      type: external
      valueFrom:
        configMapKeyRef:
          name: customConfigMap
          key: zookeeper-log4j.properties
  # ...
----

.Garbage collector (GC)

Garbage collector logging can also be enabled (or disabled) using the xref:con-common-configuration-garbage-collection-reference[`jvmOptions` property].
