Skip to content

Commit

Permalink
Merge pull request #882 from wimdeblauwe/allow-pluggable-csv-filename
Browse files Browse the repository at this point in the history
Allow a pluggable strategy for the name of the CSV files that the CsvReporter uses
  • Loading branch information
ryantenney committed Nov 2, 2015
2 parents 258e80b + 869742e commit 4112b29
Show file tree
Hide file tree
Showing 5 changed files with 97 additions and 21 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
package io.dropwizard.metrics;

import java.io.File;

/**
* This interface allows a pluggable implementation of what file names
* the {@link CsvReporter} will write to.
*/
public interface CsvFileProvider
{
File getFile( File directory, MetricName metricName );
}
22 changes: 15 additions & 7 deletions metrics-core/src/main/java/io/dropwizard/metrics/CsvReporter.java
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,7 @@ public static class Builder {
private TimeUnit durationUnit;
private Clock clock;
private MetricFilter filter;
private CsvFileProvider csvFileProvider;

private Builder(MetricRegistry registry) {
this.registry = registry;
Expand All @@ -55,6 +56,7 @@ private Builder(MetricRegistry registry) {
this.durationUnit = TimeUnit.MILLISECONDS;
this.clock = Clock.defaultClock();
this.filter = MetricFilter.ALL;
this.csvFileProvider = new FixedNameCsvFileProvider();
}

/**
Expand Down Expand Up @@ -112,6 +114,12 @@ public Builder filter(MetricFilter filter) {
return this;
}

public Builder withCsvFileProvider( CsvFileProvider csvFileProvider )
{
this.csvFileProvider = csvFileProvider;
return this;
}

/**
* Builds a {@link CsvReporter} with the given properties, writing {@code .csv} files to the
* given directory.
Expand All @@ -126,7 +134,8 @@ public CsvReporter build(File directory) {
rateUnit,
durationUnit,
clock,
filter);
filter,
csvFileProvider);
}
}

Expand All @@ -136,18 +145,21 @@ public CsvReporter build(File directory) {
private final File directory;
private final Locale locale;
private final Clock clock;
private final CsvFileProvider csvFileProvider;

private CsvReporter(MetricRegistry registry,
File directory,
Locale locale,
TimeUnit rateUnit,
TimeUnit durationUnit,
Clock clock,
MetricFilter filter) {
MetricFilter filter,
CsvFileProvider csvFileProvider) {
super(registry, "csv-reporter", filter, rateUnit, durationUnit);
this.directory = directory;
this.locale = locale;
this.clock = clock;
this.csvFileProvider = csvFileProvider;
}

@Override
Expand Down Expand Up @@ -248,7 +260,7 @@ private void reportGauge(long timestamp, MetricName name, Gauge gauge) {

private void report(long timestamp, MetricName name, String header, String line, Object... values) {
try {
final File file = new File(directory, sanitize(name) + ".csv");
final File file = csvFileProvider.getFile(directory, name);
final boolean fileAlreadyExists = file.exists();
if (fileAlreadyExists || file.createNewFile()) {
final PrintWriter out = new PrintWriter(new OutputStreamWriter(new FileOutputStream(file,true), UTF_8));
Expand All @@ -265,8 +277,4 @@ private void report(long timestamp, MetricName name, String header, String line,
LOGGER.warn("Error writing to {}", name, e);
}
}

protected String sanitize(MetricName name) {
return name.getKey();
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
package io.dropwizard.metrics;

import java.io.File;

/**
* This implementation of the {@link CsvFileProvider} will always return the same name
* for the same metric. This means the CSV file will grow indefinitely.
*/
public class FixedNameCsvFileProvider implements CsvFileProvider {
@Override
public File getFile(File directory, MetricName metricName) {
return new File(directory, sanitize(metricName) + ".csv");
}

private String sanitize(MetricName metricName) {
return metricName.getKey();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -5,18 +5,6 @@
import org.junit.Test;
import org.junit.rules.TemporaryFolder;

import io.dropwizard.metrics.Clock;
import io.dropwizard.metrics.Counter;
import io.dropwizard.metrics.CsvReporter;
import io.dropwizard.metrics.Gauge;
import io.dropwizard.metrics.Histogram;
import io.dropwizard.metrics.Meter;
import io.dropwizard.metrics.MetricFilter;
import io.dropwizard.metrics.MetricName;
import io.dropwizard.metrics.MetricRegistry;
import io.dropwizard.metrics.Snapshot;
import io.dropwizard.metrics.Timer;

import java.io.*;
import java.nio.CharBuffer;
import java.util.Locale;
Expand All @@ -25,8 +13,7 @@
import java.util.concurrent.TimeUnit;

import static org.assertj.core.api.Assertions.assertThat;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.when;
import static org.mockito.Mockito.*;

public class CsvReporterTest {
@Rule public final TemporaryFolder folder = new TemporaryFolder();
Expand Down Expand Up @@ -178,6 +165,27 @@ public void reportsTimerValues() throws Exception {
));
}

@Test
public void testCsvFileProviderIsUsed() {
CsvFileProvider fileProvider = mock(CsvFileProvider.class);
when(fileProvider.getFile(dataDirectory, MetricName.build("gauge"))).thenReturn(new File(dataDirectory, "guage.csv"));

CsvReporter reporter = CsvReporter.forRegistry(registry)
.withCsvFileProvider(fileProvider)
.build(dataDirectory);

final Gauge gauge = mock(Gauge.class);
when(gauge.getValue()).thenReturn(1);

reporter.report(map("gauge", gauge),
this.<Counter>map(),
this.<Histogram>map(),
this.<Meter>map(),
this.<Timer>map());

verify(fileProvider).getFile(dataDirectory, MetricName.build("gauge"));
}

private String csv(String... lines) {
final StringBuilder builder = new StringBuilder();
for (String line : lines) {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
package io.dropwizard.metrics;

import org.junit.Before;
import org.junit.Rule;
import org.junit.Test;
import org.junit.rules.TemporaryFolder;

import java.io.File;

import static org.assertj.core.api.Assertions.assertThat;

public class FixedNameCsvFileProviderTest {
@Rule
public final TemporaryFolder folder = new TemporaryFolder();

private File dataDirectory;

@Before
public void setUp() throws Exception {
this.dataDirectory = folder.newFolder();
}

@Test
public void testGetFile() {
FixedNameCsvFileProvider provider = new FixedNameCsvFileProvider();
File file = provider.getFile(dataDirectory, MetricName.build("test"));
assertThat(file.getParentFile()).isEqualTo(dataDirectory);
assertThat(file.getName()).isEqualTo("test.csv");
}
}

0 comments on commit 4112b29

Please sign in to comment.