Skip to content

Add logging abstraction with SLF4J backend#740

Open
mihaimitrea-db wants to merge 1 commit intomainfrom
mihaimitrea-db/stack/logging-abstraction
Open

Add logging abstraction with SLF4J backend#740
mihaimitrea-db wants to merge 1 commit intomainfrom
mihaimitrea-db/stack/logging-abstraction

Conversation

@mihaimitrea-db
Copy link
Contributor

@mihaimitrea-db mihaimitrea-db commented Mar 26, 2026

🥞 Stacked PR

Use this link to review incremental changes.


Summary

Introduces a logging abstraction layer (com.databricks.sdk.core.logging) that decouples the SDK's internal logging from any specific backend. SLF4J remains the default. This PR contains only the abstraction and the SLF4J backend; the JUL backend and the call-site migration follow in stacked PRs.

Why

The SDK currently imports org.slf4j.Logger and org.slf4j.LoggerFactory directly in every class that logs. This hard coupling means users who embed the SDK in environments where SLF4J is impractical (e.g. BI tools with constrained classpaths) have no way to switch to an alternative logging backend like java.util.logging.

We need an indirection layer that lets users swap the logging backend programmatically while keeping SLF4J as the zero-configuration default so that existing users don't have to change anything.

The design follows the pattern established by Netty's InternalLoggerFactory: an abstract LoggerFactory class with concrete subclasses for each backend, a setDefault method to override the backend, and a separate Logger abstract class that serves as a clean extension point for custom implementations.

What changed

Interface changes

  • Logger — new abstract class in com.databricks.sdk.core.logging. Defines the logging contract: debug, info, warn, error (each with plain-string and varargs overloads), and isDebugEnabled. Users extend this to build custom loggers.
  • LoggerFactory — new abstract class. Static methods getLogger(Class<?>) and getLogger(String) return loggers from the current default factory. setDefault(LoggerFactory) overrides the backend — must be called before creating any SDK client.
  • Slf4jLoggerFactory — public concrete factory with a singleton INSTANCE. This is the default.

Behavioral changes

None. SLF4J is the default backend and all logging calls pass through to org.slf4j.Logger exactly as before. Existing users see no difference.

Internal changes

  • Slf4jLogger — package-private class that delegates all calls to an org.slf4j.Logger. Fully qualifies org.slf4j.LoggerFactory references to avoid collision with the SDK's LoggerFactory.
  • All new classes live in com.databricks.sdk.core.logging.

How is this tested?

  • LoggerFactoryTest — verifies the default factory is SLF4J, that setDefault(null) is rejected, and that getLogger(String) works.
  • Slf4jLoggerTest — verifies Slf4jLogger.create returns the correct type, and exercises all logging methods including varargs and trailing Throwable.
  • Full test suite (1140 tests) passes.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant