vladmihalcea / flexy-pool

FlexyPool adds metrics and failover strategies to a given Connection Pool, allowing it to resize on demand.
Apache License 2.0
1.09k stars 120 forks source link

Dropwizard Metrics #32

Closed sheldon-sminq closed 8 years ago

sheldon-sminq commented 8 years ago

We are using Flexypool with HikariCP for our dropwizard app. We push our dropwizard metrics to a graphite server.

Wanted to push flexy pool metrics to the same graphite server, how do we proceed with the same. Can we pass the Dropwizard metrics registry to flexypool metric factory?

vladmihalcea commented 8 years ago

That's easy. FlexyPool supports both CodaHale Metrics and Dropwizard. However, the Dropwizard Metrics use the new io.dropwizard.metrics package which hasn't been released yet by Dropwizard.

So, you can use the CodahaleMetricsFactory like in this test case:

ReservoirFactory reservoirFactory = ...;

Configuration<DataSource> configuration = new Configuration.Builder<DataSource>(
    "unique", 
    dataSource, 
    poolAdapterFactory)
.setMetricsFactory(new CodahaleMetrics.ReservoirMetricsFactory(reservoirFactory))
.build();
sheldon-sminq commented 8 years ago

Is this also valid?

Configuration configuration = new Configuration.Builder( "unique", dataSource, poolAdapterFactory) .setMetricsFactory(new CodahaleMetricsFactoryService().load()) .build();

vladmihalcea commented 8 years ago

That can work too, but it will use a new MetricRegistry, not the one that you might already have. At least, that's what I thought you wanted in the first place.

sheldon-sminq commented 8 years ago

Yes actually want to use the existing metrics factory, but how do pass the existing MetricsFactory instance to FlexyPool?

    ReservoirFactory reservoirFactory = ?
sheldon-sminq commented 8 years ago

Also i am using Dropwizard 1.0.2

vladmihalcea commented 8 years ago

I guess, it's not possible now. However, it's not very difficult to add support for this feature. You'd just have to provide the MetricsFactory as Configuration parameter. Unfortunately, I don't have time to do it right now, but if you send me a Pull request, I would integrate it right away.

vladmihalcea commented 8 years ago

I released a new version 1.2.5. Now you can customize the MetricRegistry like this:

CodahaleMetrics codahaleMetrics = new CodahaleMetrics(
    configurationProperties, metricRegistry, reservoirFactory);

This way, you can do something like this:

Configuration<DataSource> configuration = new Configuration.Builder<DataSource>(
"unique", dataSource, poolAdapterFactory)
.setConnectionProxyFactory(connectionProxyFactory)
.setJmxAutoStart(true)
.setJmxEnabled(true)
.setMetricLogReporterMillis(120)
.setMetricsFactory(new MetricsFactory() {
    @Override
    public Metrics newInstance(ConfigurationProperties configurationProperties) {
        return new CodahaleMetrics(configurationProperties, metricRegistry, new ReservoirFactory() {
            @Override
            public Reservoir newInstance(Class<? extends Metric> metricClass, String metricName) {
                return new ExponentiallyDecayingReservoir();
            }
        });
    }
})
.build();

There's this ConfigurationTest unit test that you can run and see how it works.

rripken commented 6 years ago

Is there a way to do something like your example above but from a Spring xml config?

vladmihalcea commented 6 years ago

Yes, of course. In the documentation and source code you can find XML configuration examples.

rripken commented 6 years ago

Could you suggest an example I should look at? I downloaded the entire repo and looked at all the *.xml files and I didn't see any that showed passing a metricRegistry into Flexypool. Did I miss it? Do I need to create my own MetricsFactory implementation to be able to pass a metricRegistry in?

vladmihalcea commented 6 years ago

Like this:

Configuration<DataSource> configuration = new Configuration.Builder<DataSource>(
"unique", dataSource, poolAdapterFactory)
.setConnectionProxyFactory(connectionProxyFactory)
.setJmxAutoStart(true)
.setJmxEnabled(true)
.setMetricLogReporterMillis(120)
.setMetricsFactory(new MetricsFactory() {
    @Override
    public Metrics newInstance(ConfigurationProperties configurationProperties) {
        return new CodahaleMetrics(configurationProperties, metricRegistry, new ReservoirFactory() {
            @Override
            public Reservoir newInstance(Class<? extends Metric> metricClass, String metricName) {
                return new ExponentiallyDecayingReservoir();
            }
        });
    }
})
.build();

You can translate this into XML too. Likee any other Spring XML configuration. Of course, it's much simpler with Java-based configs, but doable in XML too.

For instance, a simple XML config looks slike this:

<bean id="configurationBuilder" class="com.vladmihalcea.flexypool.config.Configuration$Builder">
    <constructor-arg value="uniqueId"/>
    <constructor-arg ref="poolingDataSource"/>
    <constructor-arg value="#{ T(com.vladmihalcea.flexypool.adaptor.BoneCPPoolAdapter).FACTORY }"/>
</bean>

<bean id="configuration" factory-bean="configurationBuilder" factory-method="build"/>

<bean id="dataSource" class="com.vladmihalcea.flexypool.FlexyPoolDataSource" init-method="start" destroy-method="stop">
    <constructor-arg ref="configuration"/>
    <constructor-arg>
        <array>
            <bean class="com.vladmihalcea.flexypool.strategy.RetryConnectionAcquiringStrategy.Factory">
                <constructor-arg value="2"/>
            </bean>
        </array>
    </constructor-arg>
</bean>

You can also pass a MetricsFactory if you want. Just encapsulate that in a dedicated class and instantiate that instead.

But why would you want to do that? Do you want to change the default configs? You can also do some behavior changes through the config properties that are also documented.

rripken commented 6 years ago

I haven't seen how to create an anonymous inner class in an xml config. I'll do some googling, thanks.

vladmihalcea commented 6 years ago

I just told you that you don't have to create an anonymous inner class in XML. Create a proper class that extends that interface and use that class to configure it in XML.

rripken commented 6 years ago

Yeah, ok. That sounds perfect - I'll do that. Thanks!

vladmihalcea commented 6 years ago

Great. When you're done, you can send me a Pull Request with an update to the documentation which presents this use case. Add a test case in the flexy-pool-core module that demonstrates it's all working as well.