embulk-filter-speedometer 0.3.2 → 0.3.5
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/README.md +15 -1
- data/build.gradle +4 -3
- data/classpath/embulk-filter-speedometer-0.3.5.jar +0 -0
- data/src/integration-test/java/org/embulk/filter/TestSingleRun.java +83 -14
- data/src/integration-test/resources/config_json.yml +20 -0
- data/src/integration-test/resources/config_label.yml +43 -0
- data/src/integration-test/resources/json_01.json.gz +0 -0
- data/src/integration-test/resources/label_01.csv.gz +0 -0
- data/src/integration-test/resources/ref_json_result_01.csv.gz +0 -0
- data/src/main/java/org/embulk/filter/SpeedometerFilterPlugin.java +29 -4
- data/src/main/java/org/embulk/filter/SpeedometerSpeedAggregator.java +32 -7
- data/src/main/java/org/embulk/filter/SpeedometerSpeedController.java +7 -0
- data/src/test/java/org/embulk/filter/TestSpeedometerFilterPlugin.java +0 -1
- data/src/test/java/org/embulk/filter/TestSpeedometerSpeedAggregator.java +16 -4
- metadata +8 -3
- data/classpath/embulk-filter-speedometer-0.3.2.jar +0 -0
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: ff41aeb838dae6df3aaf4b6d5847e83c36ea9fce
|
4
|
+
data.tar.gz: 0537d47fbc97b2d9b2a30d3fea19e22c4cabb4d7
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: ab2110df906ba8bdaf82e9d24dc798fa47aa8aa4fee70f8bcbb7237459f9b4fa0d4f416adcd53fc43613639a83a442dde10e9c0e44599cd02d6024644ac56d98
|
7
|
+
data.tar.gz: cc962bc8123ad29385835348b333b33559bd96f9c8b212d021c740766177edff79df20d19bb1280933e37fe51d4a70e8f759029f46b9e5d0f7a4c632c6b3080f
|
data/README.md
CHANGED
@@ -3,7 +3,7 @@
|
|
3
3
|
[](https://travis-ci.org/hata/embulk-filter-speedometer.svg?branch=master)
|
4
4
|
|
5
5
|
Write log message of processed bytes and throughput periodically.
|
6
|
-
This plugin works with embulk:0.
|
6
|
+
This plugin works with embulk:0.8.0 or later versions.
|
7
7
|
|
8
8
|
## Overview
|
9
9
|
|
@@ -16,6 +16,7 @@ This plugin works with embulk:0.6.17 or later versions because of removing depre
|
|
16
16
|
- **delimiter**: Delimiter text to calculate delimiter length. (string, optional, default: ",")
|
17
17
|
- **record_padding_size**: Additional byte size for each record like a return code length. (integer, optional, default: 1)
|
18
18
|
- **column_options**: A map whose keys are name of columns like csv formatter plugin (hash, optional, default: {})
|
19
|
+
- **label**: Add this text to log output as label value. (string, optional, default: null)
|
19
20
|
|
20
21
|
## Example of Configuration
|
21
22
|
|
@@ -66,6 +67,19 @@ filters:
|
|
66
67
|
```
|
67
68
|
|
68
69
|
|
70
|
+
- Set label text to distinguish log file. The following example can see label text like **{speedometer: {label: foo, active: ...**
|
71
|
+
|
72
|
+
```yaml
|
73
|
+
filters:
|
74
|
+
- type: speedometer
|
75
|
+
speed_limit: 250000
|
76
|
+
column_options:
|
77
|
+
time: {format: '%Y-%m-%d %H:%M:%S'}
|
78
|
+
purchase: {format: '%Y%m%d'}
|
79
|
+
label: 'foo'
|
80
|
+
```
|
81
|
+
|
82
|
+
|
69
83
|
## Sample Log Message
|
70
84
|
|
71
85
|
```
|
data/build.gradle
CHANGED
@@ -18,11 +18,12 @@ configurations {
|
|
18
18
|
provided
|
19
19
|
}
|
20
20
|
|
21
|
-
version = "0.3.
|
21
|
+
version = "0.3.5"
|
22
22
|
|
23
23
|
dependencies {
|
24
|
-
compile "org.embulk:embulk-core:0.
|
25
|
-
|
24
|
+
compile "org.embulk:embulk-core:0.8.0+"
|
25
|
+
compile "org.msgpack:msgpack-core:0.7.1"
|
26
|
+
provided "org.embulk:embulk-core:0.8.0+"
|
26
27
|
// compile "YOUR_JAR_DEPENDENCY_GROUP:YOUR_JAR_DEPENDENCY_MODULE:YOUR_JAR_DEPENDENCY_VERSION"
|
27
28
|
testCompile "org.jmockit:jmockit:1.15+"
|
28
29
|
testCompile "junit:junit:4.+"
|
Binary file
|
@@ -5,16 +5,17 @@ import static org.junit.Assert.assertTrue;
|
|
5
5
|
|
6
6
|
import java.io.BufferedReader;
|
7
7
|
import java.io.File;
|
8
|
-
import java.io.FilenameFilter;
|
9
8
|
import java.io.FileInputStream;
|
10
9
|
import java.io.FileReader;
|
11
|
-
import java.io.
|
10
|
+
import java.io.FilenameFilter;
|
12
11
|
import java.io.IOException;
|
13
|
-
import java.io.
|
14
|
-
import java.util.regex.Pattern;
|
15
|
-
import java.util.zip.GZIPInputStream;
|
12
|
+
import java.io.InputStreamReader;
|
16
13
|
import java.util.ArrayList;
|
17
14
|
import java.util.Collections;
|
15
|
+
import java.util.List;
|
16
|
+
import java.util.TreeSet;
|
17
|
+
import java.util.regex.Pattern;
|
18
|
+
import java.util.zip.GZIPInputStream;
|
18
19
|
|
19
20
|
import org.junit.Test;
|
20
21
|
|
@@ -24,6 +25,9 @@ public class TestSingleRun {
|
|
24
25
|
// e.g. {speedometer: {active: 4, total: 13.5mb, sec: 1:51, speed: 121kb/s, records: 269,748, record-speed: 2,435/s}}
|
25
26
|
static final Pattern logLinePattern = Pattern.compile("\\{speedometer: \\{active: [^,]+, total: [^,]+, sec: [^,]+, speed: [^,]+, records: \\S+, record-speed: [^\\}]+\\}\\}");
|
26
27
|
|
28
|
+
// Add label to the log.
|
29
|
+
static final Pattern logLabelLinePattern = Pattern.compile("\\{speedometer: \\{label: [^,]+, active: [^,]+, total: [^,]+, sec: [^,]+, speed: [^,]+, records: \\S+, record-speed: [^\\}]+\\}\\}");
|
30
|
+
|
27
31
|
private static String getTestFile(String name) {
|
28
32
|
return TEST_DIR + File.separator + name;
|
29
33
|
}
|
@@ -38,6 +42,16 @@ public class TestSingleRun {
|
|
38
42
|
validateResultFiles("big_01.csv.gz", "result_big_");
|
39
43
|
}
|
40
44
|
|
45
|
+
@Test
|
46
|
+
public void testValidateJsonOutputFile() throws Exception {
|
47
|
+
validateJsonResultFiles("ref_json_result_01.csv.gz", "result_json_");
|
48
|
+
}
|
49
|
+
|
50
|
+
@Test
|
51
|
+
public void testValidateLabelOutputFile() throws Exception {
|
52
|
+
validateResultFiles("label_01.csv.gz", "result_label_");
|
53
|
+
}
|
54
|
+
|
41
55
|
@Test
|
42
56
|
public void testSpeedometerMinLog() throws Exception {
|
43
57
|
validateSpeedometerLog("config_min.yml.run.log");
|
@@ -48,12 +62,26 @@ public class TestSingleRun {
|
|
48
62
|
validateSpeedometerLog("config_big.yml.run.log");
|
49
63
|
}
|
50
64
|
|
65
|
+
@Test
|
66
|
+
public void testSpeedometerJsonLog() throws Exception {
|
67
|
+
validateSpeedometerLog("config_json.yml.run.log");
|
68
|
+
}
|
69
|
+
|
70
|
+
@Test
|
71
|
+
public void testSpeedometerLabelLog() throws Exception {
|
72
|
+
validateSpeedometerLog("config_label.yml.run.log", logLabelLinePattern);
|
73
|
+
}
|
74
|
+
|
51
75
|
private void validateSpeedometerLog(String logFile) throws Exception {
|
76
|
+
validateSpeedometerLog(logFile, logLinePattern);
|
77
|
+
}
|
78
|
+
|
79
|
+
private void validateSpeedometerLog(String logFile, Pattern pattern) throws Exception {
|
52
80
|
boolean found = false;
|
53
81
|
try (BufferedReader r = new BufferedReader(new FileReader(getTestFile(logFile)))) {
|
54
82
|
String line = r.readLine();
|
55
83
|
while (line != null) {
|
56
|
-
if (
|
84
|
+
if (pattern.matcher(line).find()) {
|
57
85
|
found = true;
|
58
86
|
break;
|
59
87
|
}
|
@@ -64,19 +92,44 @@ public class TestSingleRun {
|
|
64
92
|
}
|
65
93
|
|
66
94
|
private void validateResultFiles(String gzipSrcFile, final String prefix) throws Exception {
|
67
|
-
ArrayList inList = new ArrayList();
|
68
|
-
ArrayList outList = new ArrayList();
|
95
|
+
ArrayList<String> inList = new ArrayList();
|
96
|
+
ArrayList<String> outList = new ArrayList();
|
97
|
+
|
98
|
+
readToListFromGzipFile(gzipSrcFile, inList);
|
99
|
+
readToListFromPrefixMatching(prefix, outList);
|
69
100
|
|
101
|
+
Collections.sort(inList);
|
102
|
+
Collections.sort(outList);
|
103
|
+
|
104
|
+
assertEquals("Verify input and output lines are identical. in:" +
|
105
|
+
inList.size() + ", out:" + outList.size(), inList.toString(), outList.toString());
|
106
|
+
}
|
107
|
+
|
108
|
+
|
109
|
+
private void validateJsonResultFiles(String gzipSrcFile, final String prefix) throws Exception {
|
110
|
+
ArrayList<String> inList = new ArrayList();
|
111
|
+
ArrayList<String> outList = new ArrayList();
|
112
|
+
|
113
|
+
readToListFromGzipFile(gzipSrcFile, inList);
|
114
|
+
readToListFromPrefixMatching(prefix, outList);
|
115
|
+
|
116
|
+
assertEquals("Verify input and output lines are identical. in:" +
|
117
|
+
inList.size() + ", out:" + outList.size(), readToSet(inList), readToSet(outList));
|
118
|
+
}
|
119
|
+
|
120
|
+
private void readToListFromGzipFile(String gzipSrcFile, List<String> lineList) throws IOException {
|
70
121
|
try (BufferedReader reader = new BufferedReader(new InputStreamReader(
|
71
122
|
new GZIPInputStream(new FileInputStream(getTestFile(gzipSrcFile)))))) {
|
72
123
|
String line = reader.readLine(); // Discard a header line
|
73
124
|
line = reader.readLine();
|
74
125
|
while (line != null) {
|
75
|
-
|
126
|
+
lineList.add(line);
|
76
127
|
line = reader.readLine();
|
77
128
|
}
|
78
129
|
}
|
130
|
+
}
|
79
131
|
|
132
|
+
private void readToListFromPrefixMatching(final String prefix, List<String> lineList) throws IOException {
|
80
133
|
// In travis env, there are many cpus and it may be different from
|
81
134
|
// my local environment. From this, list all files using File.list method.
|
82
135
|
String[] resultFiles = new File(TEST_DIR).list(new FilenameFilter() {
|
@@ -90,16 +143,32 @@ public class TestSingleRun {
|
|
90
143
|
String line = reader.readLine(); // Discard a header line
|
91
144
|
line = reader.readLine();
|
92
145
|
while (line != null) {
|
93
|
-
|
146
|
+
lineList.add(line);
|
94
147
|
line = reader.readLine();
|
95
148
|
}
|
96
149
|
}
|
97
150
|
}
|
151
|
+
}
|
98
152
|
|
99
|
-
|
100
|
-
|
153
|
+
private TreeSet<String> readToSet(List<String> lineList) throws Exception {
|
154
|
+
TreeSet<String> set = new TreeSet<>();
|
155
|
+
for (String line : lineList) {
|
156
|
+
line = stripQuote(line);
|
157
|
+
if (line.startsWith("{") && line.endsWith("}")) {
|
158
|
+
ArrayList<String> fields = new ArrayList<>();
|
159
|
+
for (String field : line.substring(1, line.length() - 1).split(",")) {
|
160
|
+
fields.add(field);
|
161
|
+
}
|
162
|
+
Collections.sort(fields);
|
163
|
+
set.add(fields.toString());
|
164
|
+
} else {
|
165
|
+
throw new Exception("Unexpected lines." + lineList);
|
166
|
+
}
|
167
|
+
}
|
168
|
+
return set;
|
169
|
+
}
|
101
170
|
|
102
|
-
|
103
|
-
|
171
|
+
private String stripQuote(String line) {
|
172
|
+
return line.startsWith("'") && line.endsWith("'") ? line.substring(1, line.length() -1) : line;
|
104
173
|
}
|
105
174
|
}
|
@@ -0,0 +1,20 @@
|
|
1
|
+
in:
|
2
|
+
type: file
|
3
|
+
path_prefix: ./json_
|
4
|
+
decoders:
|
5
|
+
- {type: gzip}
|
6
|
+
parser:
|
7
|
+
type: json
|
8
|
+
filters:
|
9
|
+
- type: speedometer
|
10
|
+
speed_limit: 250000
|
11
|
+
out:
|
12
|
+
type: file
|
13
|
+
path_prefix: ./result_json_
|
14
|
+
file_ext: csv
|
15
|
+
formatter:
|
16
|
+
type: csv
|
17
|
+
quote_policy: MINIMAL
|
18
|
+
default_timezone: UTC
|
19
|
+
newline: LF
|
20
|
+
quote: "'"
|
@@ -0,0 +1,43 @@
|
|
1
|
+
in:
|
2
|
+
type: file
|
3
|
+
path_prefix: ./min_
|
4
|
+
decoders:
|
5
|
+
- {type: gzip}
|
6
|
+
parser:
|
7
|
+
charset: UTF-8
|
8
|
+
newline: CRLF
|
9
|
+
type: csv
|
10
|
+
delimiter: ','
|
11
|
+
quote: '"'
|
12
|
+
trim_if_not_quoted: false
|
13
|
+
skip_header_lines: 1
|
14
|
+
allow_extra_columns: false
|
15
|
+
allow_optional_columns: false
|
16
|
+
columns:
|
17
|
+
- {name: id, type: long}
|
18
|
+
- {name: account, type: long}
|
19
|
+
- {name: time, type: timestamp, format: '%Y-%m-%d %H:%M:%S'}
|
20
|
+
- {name: purchase, type: timestamp, format: '%Y%m%d'}
|
21
|
+
- {name: enabled, type: boolean}
|
22
|
+
- {name: comment, type: string}
|
23
|
+
filters:
|
24
|
+
- type: speedometer
|
25
|
+
speed_limit: 250000
|
26
|
+
column_options:
|
27
|
+
time: {format: '%Y-%m-%d %H:%M:%S'}
|
28
|
+
purchase: {format: '%Y%m%d'}
|
29
|
+
label: 'foo'
|
30
|
+
out:
|
31
|
+
type: file
|
32
|
+
path_prefix: ./result_label_
|
33
|
+
file_ext: csv
|
34
|
+
formatter:
|
35
|
+
type: csv
|
36
|
+
quote_policy: MINIMAL
|
37
|
+
default_timezone: UTC
|
38
|
+
newline: LF
|
39
|
+
column_options:
|
40
|
+
time: {format: '%Y-%m-%d %H:%M:%S'}
|
41
|
+
purchase: {format: '%Y%m%d'}
|
42
|
+
|
43
|
+
|
Binary file
|
Binary file
|
Binary file
|
@@ -22,6 +22,9 @@ import org.embulk.spi.Schema;
|
|
22
22
|
import org.embulk.spi.time.Timestamp;
|
23
23
|
import org.embulk.spi.time.TimestampFormatter;
|
24
24
|
import org.embulk.spi.util.Timestamps;
|
25
|
+
import org.msgpack.value.Value;
|
26
|
+
|
27
|
+
import com.google.common.base.Optional;
|
25
28
|
|
26
29
|
public class SpeedometerFilterPlugin
|
27
30
|
implements FilterPlugin
|
@@ -57,7 +60,11 @@ public class SpeedometerFilterPlugin
|
|
57
60
|
|
58
61
|
@Config("column_options")
|
59
62
|
@ConfigDefault("{}")
|
60
|
-
Map<String, TimestampColumnOption> getColumnOptions();
|
63
|
+
public Map<String, TimestampColumnOption> getColumnOptions();
|
64
|
+
|
65
|
+
@Config("label")
|
66
|
+
@ConfigDefault("null")
|
67
|
+
public Optional<String> getLabel();
|
61
68
|
|
62
69
|
@ConfigInject
|
63
70
|
public BufferAllocator getBufferAllocator();
|
@@ -96,7 +103,7 @@ public class SpeedometerFilterPlugin
|
|
96
103
|
private final PageBuilder pageBuilder;
|
97
104
|
|
98
105
|
SpeedControlPageOutput(PluginTask task, Schema schema, PageOutput pageOutput) {
|
99
|
-
this.controller = new SpeedometerSpeedController(task, SpeedometerSpeedAggregator.getInstance());
|
106
|
+
this.controller = new SpeedometerSpeedController(task, SpeedometerSpeedAggregator.getInstance(task));
|
100
107
|
this.schema = schema;
|
101
108
|
this.allocator = task.getBufferAllocator();
|
102
109
|
this.delimiterLength = task.getDelimiter().length();
|
@@ -104,6 +111,7 @@ public class SpeedometerFilterPlugin
|
|
104
111
|
this.pageReader = new PageReader(schema);
|
105
112
|
this.timestampFormatters = Timestamps.newTimestampColumnFormatters(task, schema, task.getColumnOptions());
|
106
113
|
this.pageBuilder = new PageBuilder(allocator, schema, pageOutput);
|
114
|
+
this.controller.start(System.currentTimeMillis());
|
107
115
|
}
|
108
116
|
|
109
117
|
@Override
|
@@ -120,14 +128,13 @@ public class SpeedometerFilterPlugin
|
|
120
128
|
|
121
129
|
@Override
|
122
130
|
public void finish() {
|
131
|
+
controller.stop();
|
123
132
|
pageBuilder.finish();
|
124
133
|
}
|
125
134
|
|
126
135
|
@Override
|
127
136
|
public void close() {
|
128
|
-
controller.stop();
|
129
137
|
pageBuilder.close();
|
130
|
-
pageReader.close();
|
131
138
|
}
|
132
139
|
|
133
140
|
class ColumnVisitorImpl implements ColumnVisitor {
|
@@ -188,6 +195,16 @@ public class SpeedometerFilterPlugin
|
|
188
195
|
}
|
189
196
|
}
|
190
197
|
|
198
|
+
@Override
|
199
|
+
public void jsonColumn(Column column) {
|
200
|
+
if (pageReader.isNull(column)) {
|
201
|
+
speedMonitor(column);
|
202
|
+
pageBuilder.setNull(column);
|
203
|
+
} else {
|
204
|
+
pageBuilder.setJson(column, speedMonitor(column, pageReader.getJson(column)));
|
205
|
+
}
|
206
|
+
}
|
207
|
+
|
191
208
|
private void speedMonitorStartRecord() {
|
192
209
|
startRecordTime = System.currentTimeMillis();
|
193
210
|
}
|
@@ -232,6 +249,14 @@ public class SpeedometerFilterPlugin
|
|
232
249
|
return t;
|
233
250
|
}
|
234
251
|
|
252
|
+
private Value speedMonitor(Column column, Value v) {
|
253
|
+
speedMonitorForDelimiter(column);
|
254
|
+
// NOTE: This may not be good for performance. But, I have no other idea.
|
255
|
+
String s = v.toJson();
|
256
|
+
controller.checkSpeedLimit(startRecordTime, s != null ? s.length() : 0);
|
257
|
+
return v;
|
258
|
+
}
|
259
|
+
|
235
260
|
private void speedMonitorForDelimiter(Column column) {
|
236
261
|
if (column.getIndex() > 0) {
|
237
262
|
controller.checkSpeedLimit(startRecordTime, delimiterLength);
|
@@ -5,13 +5,13 @@ import java.util.List;
|
|
5
5
|
import java.util.concurrent.atomic.AtomicInteger;
|
6
6
|
import java.util.concurrent.atomic.AtomicLong;
|
7
7
|
|
8
|
+
import org.embulk.filter.SpeedometerFilterPlugin.PluginTask;
|
8
9
|
import org.embulk.spi.Exec;
|
9
10
|
import org.slf4j.Logger;
|
10
11
|
|
11
12
|
class SpeedometerSpeedAggregator {
|
12
|
-
private static
|
13
|
-
|
14
|
-
}
|
13
|
+
private static final Object INSTANCE_LOCK = new Object();
|
14
|
+
private static SpeedometerSpeedAggregator INSTANCE;
|
15
15
|
|
16
16
|
private final long INITAL_START_TIME = 0;
|
17
17
|
|
@@ -20,15 +20,26 @@ class SpeedometerSpeedAggregator {
|
|
20
20
|
private final AtomicLong globalTotalBytes = new AtomicLong(0);
|
21
21
|
private final AtomicLong globalTotalRecords = new AtomicLong(0);
|
22
22
|
private final AtomicLong previousLogReportTimeMillisec = new AtomicLong(INITAL_START_TIME);
|
23
|
+
private final String logFormat;
|
23
24
|
|
24
25
|
// TODO: We can use google's library.
|
25
26
|
private final List<SpeedometerSpeedController> controllerList = new ArrayList<>();
|
26
27
|
|
27
|
-
public static SpeedometerSpeedAggregator getInstance() {
|
28
|
-
|
28
|
+
public static SpeedometerSpeedAggregator getInstance(PluginTask task) {
|
29
|
+
synchronized (INSTANCE_LOCK) {
|
30
|
+
if (INSTANCE == null) {
|
31
|
+
INSTANCE = new SpeedometerSpeedAggregator(task != null && task.getLabel().isPresent() ? task.getLabel().get() : null);
|
32
|
+
}
|
33
|
+
return INSTANCE;
|
34
|
+
}
|
35
|
+
}
|
36
|
+
|
37
|
+
SpeedometerSpeedAggregator() {
|
38
|
+
this(null);
|
29
39
|
}
|
30
40
|
|
31
|
-
|
41
|
+
SpeedometerSpeedAggregator(String label) {
|
42
|
+
logFormat = initLogFormat(label);
|
32
43
|
showLogMessage(activeControllerCount.get(), 0, 0, 0, 0, 0);
|
33
44
|
}
|
34
45
|
|
@@ -106,6 +117,10 @@ class SpeedometerSpeedAggregator {
|
|
106
117
|
return copyList;
|
107
118
|
}
|
108
119
|
|
120
|
+
String getLogFormat() {
|
121
|
+
return logFormat;
|
122
|
+
}
|
123
|
+
|
109
124
|
private void renewPeriods() {
|
110
125
|
for (SpeedometerSpeedController controller : getControllerList()) {
|
111
126
|
controller.renewPeriod();
|
@@ -142,7 +157,7 @@ class SpeedometerSpeedAggregator {
|
|
142
157
|
private void showLogMessage(int activeThreads, long totalBytes, long timeMilliSec, long bytesPerSec, long totalRecords, long recordsPerSec) {
|
143
158
|
Logger logger = getLogger();
|
144
159
|
if (logger != null) {
|
145
|
-
logger.info(String.format(
|
160
|
+
logger.info(String.format(logFormat,
|
146
161
|
activeThreads,
|
147
162
|
SpeedometerUtil.toByteText(totalBytes),
|
148
163
|
SpeedometerUtil.toTimeText(timeMilliSec),
|
@@ -151,4 +166,14 @@ class SpeedometerSpeedAggregator {
|
|
151
166
|
SpeedometerUtil.toDecimalText(recordsPerSec)));
|
152
167
|
}
|
153
168
|
}
|
169
|
+
|
170
|
+
private String initLogFormat(String label) {
|
171
|
+
StringBuilder builder = new StringBuilder();
|
172
|
+
builder.append("{speedometer: {");
|
173
|
+
if (label != null && label.length() > 0) {
|
174
|
+
builder.append("label: ").append(label).append(", ");
|
175
|
+
}
|
176
|
+
builder.append("active: %d, total: %s, sec: %s, speed: %s/s, records: %s, record-speed: %s/s}}");
|
177
|
+
return builder.toString();
|
178
|
+
}
|
154
179
|
}
|
@@ -25,6 +25,13 @@ class SpeedometerSpeedController {
|
|
25
25
|
this.aggregator = aggregator;
|
26
26
|
}
|
27
27
|
|
28
|
+
public void start(long nowTime) {
|
29
|
+
if (startTime == 0) {
|
30
|
+
startTime = nowTime;
|
31
|
+
aggregator.startController(this, startTime);
|
32
|
+
}
|
33
|
+
}
|
34
|
+
|
28
35
|
public void stop() {
|
29
36
|
startNewPeriod(0);
|
30
37
|
aggregator.stopController(this);
|
@@ -4,21 +4,24 @@ import static org.junit.Assert.assertEquals;
|
|
4
4
|
import static org.junit.Assert.assertFalse;
|
5
5
|
import static org.junit.Assert.assertNotNull;
|
6
6
|
import static org.junit.Assert.assertTrue;
|
7
|
-
import mockit.Mocked;
|
8
|
-
import mockit.NonStrictExpectations;
|
9
|
-
import mockit.Verifications;
|
10
7
|
|
8
|
+
import org.embulk.filter.SpeedometerFilterPlugin.PluginTask;
|
11
9
|
import org.embulk.spi.Exec;
|
12
10
|
import org.junit.Test;
|
13
11
|
import org.slf4j.Logger;
|
14
12
|
|
13
|
+
import mockit.Mocked;
|
14
|
+
import mockit.NonStrictExpectations;
|
15
|
+
import mockit.Verifications;
|
16
|
+
|
15
17
|
public class TestSpeedometerSpeedAggregator {
|
16
18
|
@Mocked SpeedometerSpeedController controller;
|
17
19
|
@Mocked Exec exec;
|
20
|
+
@Mocked PluginTask task;
|
18
21
|
|
19
22
|
@Test
|
20
23
|
public void testGetInstance() {
|
21
|
-
assertNotNull("Verify there is a singleton.", SpeedometerSpeedAggregator.getInstance());
|
24
|
+
assertNotNull("Verify there is a singleton.", SpeedometerSpeedAggregator.getInstance(task));
|
22
25
|
}
|
23
26
|
|
24
27
|
@Test
|
@@ -26,6 +29,15 @@ public class TestSpeedometerSpeedAggregator {
|
|
26
29
|
SpeedometerSpeedAggregator aggregator = new SpeedometerSpeedAggregator();
|
27
30
|
assertEquals("Verify the default global start time is zero.", 0, aggregator.getGlobalStartTime());
|
28
31
|
assertEquals("Verify the default active count is zero.", 0, aggregator.getActiveControllerCount());
|
32
|
+
assertEquals("{speedometer: {active: %d, total: %s, sec: %s, speed: %s/s, records: %s, record-speed: %s/s}}", aggregator.getLogFormat());
|
33
|
+
}
|
34
|
+
|
35
|
+
@Test
|
36
|
+
public void testSpeedometerSpeedAggregatorWithLabel() {
|
37
|
+
SpeedometerSpeedAggregator aggregator = new SpeedometerSpeedAggregator("foo");
|
38
|
+
assertEquals("Verify the default global start time is zero.", 0, aggregator.getGlobalStartTime());
|
39
|
+
assertEquals("Verify the default active count is zero.", 0, aggregator.getActiveControllerCount());
|
40
|
+
assertEquals("{speedometer: {label: foo, active: %d, total: %s, sec: %s, speed: %s/s, records: %s, record-speed: %s/s}}", aggregator.getLogFormat());
|
29
41
|
}
|
30
42
|
|
31
43
|
@Test
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: embulk-filter-speedometer
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.3.
|
4
|
+
version: 0.3.5
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- hata
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2022-03-23 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
requirement: !ruby/object:Gem::Requirement
|
@@ -58,8 +58,13 @@ files:
|
|
58
58
|
- src/integration-test/java/org/embulk/filter/TestSingleRun.java
|
59
59
|
- src/integration-test/resources/big_01.csv.gz
|
60
60
|
- src/integration-test/resources/config_big.yml
|
61
|
+
- src/integration-test/resources/config_json.yml
|
62
|
+
- src/integration-test/resources/config_label.yml
|
61
63
|
- src/integration-test/resources/config_min.yml
|
64
|
+
- src/integration-test/resources/json_01.json.gz
|
65
|
+
- src/integration-test/resources/label_01.csv.gz
|
62
66
|
- src/integration-test/resources/min_01.csv.gz
|
67
|
+
- src/integration-test/resources/ref_json_result_01.csv.gz
|
63
68
|
- src/main/java/org/embulk/filter/SpeedometerFilterPlugin.java
|
64
69
|
- src/main/java/org/embulk/filter/SpeedometerSpeedAggregator.java
|
65
70
|
- src/main/java/org/embulk/filter/SpeedometerSpeedController.java
|
@@ -68,7 +73,7 @@ files:
|
|
68
73
|
- src/test/java/org/embulk/filter/TestSpeedometerSpeedAggregator.java
|
69
74
|
- src/test/java/org/embulk/filter/TestSpeedometerSpeedController.java
|
70
75
|
- src/test/java/org/embulk/filter/TestSpeedometerUtil.java
|
71
|
-
- classpath/embulk-filter-speedometer-0.3.
|
76
|
+
- classpath/embulk-filter-speedometer-0.3.5.jar
|
72
77
|
homepage: https://github.com/hata/embulk-filter-speedometer
|
73
78
|
licenses:
|
74
79
|
- MIT
|
Binary file
|