# Configure logging

Client-side logging helps you debug connection issues, monitor cluster health, and troubleshoot performance problems.

## Why client logging matters

The Developer SDK runs background threads that:

-   Maintain cluster topology (node discovery)
-   Monitor connection health
-   Handle failover events

These events are logged and crucial for diagnosing production issues.

## Enable logging

-   [Java](#tab-panel-3142)
-   [Python](#tab-panel-3143)

The Java client uses SLF4J for logging. Add a logging implementation to your project:

```xml
<!-- Logback (recommended) -->

<dependency>

    <groupId>ch.qos.logback</groupId>

    <artifactId>logback-classic</artifactId>

    <version>1.4.14</version>

</dependency>
```

Configure `logback.xml`:

```xml
<configuration>

    <appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">

        <encoder>

            <pattern>%d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n</pattern>

        </encoder>

    </appender>

    <!-- Aerospike Java SDK (preview) -->

    <logger name="com.aerospike.client.sdk" level="INFO"/>

    <root level="WARN">

        <appender-ref ref="STDOUT"/>

    </root>

</configuration>
```

The Python client uses the standard `logging` module:

```python
import logging

# Configure logging

logging.basicConfig(

    level=logging.INFO,

    format='%(asctime)s - %(name)s - %(levelname)s - %(message)s'

)

# Set Aerospike client log level

logging.getLogger('aerospike_sdk').setLevel(logging.INFO)
```

## Log levels

| Level | When to Use | What’s Logged |
| --- | --- | --- |
| `ERROR` | Production | Connection failures, unrecoverable errors |
| `WARN` | Production | Retries, temporary failures, deprecation notices |
| `INFO` | Staging | Cluster topology changes, connection events |
| `DEBUG` | Development | All operations, request/response details |
| `TRACE` | Troubleshooting | Wire protocol, internal state |

### Recommended settings

-   [Java](#tab-panel-3144)
-   [Python](#tab-panel-3145)

```xml
<!-- Production -->

<logger name="com.aerospike.client.sdk" level="WARN"/>

<!-- Development -->

<logger name="com.aerospike.client.sdk" level="DEBUG"/>

<!-- Troubleshooting connection issues -->

<logger name="com.aerospike.client.sdk" level="DEBUG"/>
```

```python
# Production

logging.getLogger('aerospike_sdk').setLevel(logging.WARNING)

# Development

logging.getLogger('aerospike_sdk').setLevel(logging.DEBUG)

# Troubleshooting connection issues

logging.getLogger('aerospike_sdk.cluster').setLevel(logging.DEBUG)
```

## Disable logging

To completely disable client logging:

-   [Java](#tab-panel-3146)
-   [Python](#tab-panel-3147)

```xml
<logger name="com.aerospike.client.sdk" level="OFF"/>
```

Or programmatically:

```java
import org.slf4j.LoggerFactory;

import ch.qos.logback.classic.Level;

import ch.qos.logback.classic.Logger;

Logger aerospikeLogger = (Logger) LoggerFactory.getLogger("com.aerospike.client.sdk");

aerospikeLogger.setLevel(Level.OFF);
```

```python
logging.getLogger('aerospike_sdk').setLevel(logging.CRITICAL + 1)
```

Or disable propagation:

```python
logging.getLogger('aerospike_sdk').propagate = False
```

## Custom logger implementation

For advanced scenarios, you can provide a custom logger:

-   [Java](#tab-panel-3148)
-   [Python](#tab-panel-3149)

```java
// The client uses SLF4J, so any SLF4J-compatible logger works

// No custom implementation needed - just configure your logging framework
```

```python
import logging

class CustomHandler(logging.Handler):

    def emit(self, record):

        # Send to your monitoring system

        send_to_monitoring(record.getMessage(), record.levelname)

# Add custom handler

logger = logging.getLogger('aerospike_sdk')

logger.addHandler(CustomHandler())
```

## Log message reference

### Cluster events

| Message Pattern | Meaning |
| --- | --- |
| `Node added: <address>` | New node discovered in cluster |
| `Node removed: <address>` | Node left cluster or unreachable |
| `Cluster tender` | Background topology refresh |
| `Connection pool` | Connection lifecycle events |

### Error messages

| Message Pattern | Likely Cause | Action |
| --- | --- | --- |
| `Connection refused` | Server not running | Check server status |
| `Timeout` | Network or server overload | Check latency, adjust timeouts |
| `Cluster not found` | DNS or firewall issue | Verify network connectivity |

## Next steps

Enable Metrics

Monitor client performance with metrics.

[Metrics →](https://aerospike.com/docs/develop/client/sdk/usage/metrics)

Handle Errors

Implement robust error handling.

[Error Handling →](https://aerospike.com/docs/develop/client/sdk/concepts/errors)