spring-boot-data-source-decorator
spring-boot-data-source-decorator copied to clipboard
Allow specifying timeunit for datasource-proxy
Current implementation of decoratpr hard-codes timeunit as seconds (in ProxyDataSourceBuilderConfigurer)
I want time-unit to be milliseconds (so that to log queries slower than 500 ms, for instance)
The only way I can do it now - is by subclassing/overriding ProxyDataSourceBuilderConfigurer bean in context, and I don't like it
I'd love to have one more property -
decorator.datasource.datasource-proxy.slow-query.timeunit=milliseconds // default seconds for compatibility
and then to specify threshold in ms
decorator.datasource.datasource-proxy.slow-query.threshold=500
And here is my hacky hack for overriding ->
@Configuration
public class ProxyDataSourceBuilderConfigurerOverrideConfig {
// not mandatory, but it's better to unregister default bean
@Autowired
void unregisterLibraryBean(ConfigurableBeanFactory beanFactory) {
((BeanDefinitionRegistry) beanFactory).removeBeanDefinition("proxyDataSourceBuilderConfigurer");
}
@Bean
@Primary
public ProxyDataSourceBuilderConfigurer milliProxyDataSourceBuilderConfigurer() {
return new ProxyDataSourceBuilderConfigurerMillisOverride();
}
/**
* Whole purpose of this class is to replace SECONDS with MILLISECONDS
*
* everything else is copy-paste from {@link ProxyDataSourceBuilderConfigurer}
*/
private static class ProxyDataSourceBuilderConfigurerMillisOverride extends ProxyDataSourceBuilderConfigurer {
@Override
public void configure(ProxyDataSourceBuilder proxyDataSourceBuilder, DataSourceProxyProperties datasourceProxy) {
super.configure(proxyDataSourceBuilder, datasourceProxy);
if (datasourceProxy.getLogging() == SLF4J && datasourceProxy.getSlowQuery().isEnableLogging()) {
proxyDataSourceBuilder.logSlowQueryBySlf4j(
datasourceProxy.getSlowQuery().getThreshold(),
// this is actual change for parent class
TimeUnit.MILLISECONDS,
toSlf4JLogLevel(datasourceProxy.getSlowQuery().getLogLevel()),
datasourceProxy.getSlowQuery().getLoggerName());
}
}
private SLF4JLogLevel toSlf4JLogLevel(String logLevel) {
if (logLevel == null) {
return null;
}
for (SLF4JLogLevel slf4JLogLevel : SLF4JLogLevel.values()) {
if (slf4JLogLevel.name().equalsIgnoreCase(logLevel)) {
return slf4JLogLevel;
}
}
throw new IllegalArgumentException("Unresolved log level " + logLevel + " for slf4j logger, "
+ "known levels: " + Arrays.toString(SLF4JLogLevel.values()));
}
}
}
Thanks for filing the issue, I definitely should have used milliseconds from the start :) I wonder if that's possible to switch it to Duration under the hood, but still leave setter for int values and treating this as seconds for compatibility?