embulk-filter-speedometer 0.3.3 → 0.3.4
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 +14 -0
- data/build.gradle +1 -1
- data/src/integration-test/java/org/embulk/filter/TestSingleRun.java +24 -9
- data/src/integration-test/resources/config_label.yml +43 -0
- data/src/integration-test/resources/label_01.csv.gz +0 -0
- data/src/main/java/org/embulk/filter/SpeedometerFilterPlugin.java +8 -2
- data/src/main/java/org/embulk/filter/SpeedometerSpeedAggregator.java +32 -7
- data/src/test/java/org/embulk/filter/TestSpeedometerSpeedAggregator.java +16 -4
- metadata +5 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 5548ab739e2722a078ef056885ea9e579e8630fb
|
4
|
+
data.tar.gz: 6f7317591c00c5d0e05bd30d91fc9063b112fa87
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 301275d05d35c6ac17651ba81a548d4c73ac1a675bcd9793383da4832437b3edb869c820f96a81f810ad8c14a33c0bbbfdd292b1e3f3822a64fac1bcac99ee9f
|
7
|
+
data.tar.gz: ddf85d31b06c47f9880ce29dcf60f5223a1d37df6fe70322f886f968c007e2f91c2bcf0f9fc7749e0ecf67571b473c45c05f7d27673974a55ff6818da7b52aa6
|
data/README.md
CHANGED
@@ -16,6 +16,7 @@ This plugin works with embulk:0.8.0 or later versions.
|
|
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
@@ -5,19 +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
|
-
import java.util.TreeSet;
|
18
|
-
import java.util.List;
|
19
14
|
import java.util.Collections;
|
20
|
-
import java.util.
|
15
|
+
import java.util.List;
|
16
|
+
import java.util.TreeSet;
|
17
|
+
import java.util.regex.Pattern;
|
18
|
+
import java.util.zip.GZIPInputStream;
|
21
19
|
|
22
20
|
import org.junit.Test;
|
23
21
|
|
@@ -27,6 +25,9 @@ public class TestSingleRun {
|
|
27
25
|
// e.g. {speedometer: {active: 4, total: 13.5mb, sec: 1:51, speed: 121kb/s, records: 269,748, record-speed: 2,435/s}}
|
28
26
|
static final Pattern logLinePattern = Pattern.compile("\\{speedometer: \\{active: [^,]+, total: [^,]+, sec: [^,]+, speed: [^,]+, records: \\S+, record-speed: [^\\}]+\\}\\}");
|
29
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
|
+
|
30
31
|
private static String getTestFile(String name) {
|
31
32
|
return TEST_DIR + File.separator + name;
|
32
33
|
}
|
@@ -46,6 +47,11 @@ public class TestSingleRun {
|
|
46
47
|
validateJsonResultFiles("ref_json_result_01.csv.gz", "result_json_");
|
47
48
|
}
|
48
49
|
|
50
|
+
@Test
|
51
|
+
public void testValidateLabelOutputFile() throws Exception {
|
52
|
+
validateResultFiles("label_01.csv.gz", "result_label_");
|
53
|
+
}
|
54
|
+
|
49
55
|
@Test
|
50
56
|
public void testSpeedometerMinLog() throws Exception {
|
51
57
|
validateSpeedometerLog("config_min.yml.run.log");
|
@@ -61,12 +67,21 @@ public class TestSingleRun {
|
|
61
67
|
validateSpeedometerLog("config_json.yml.run.log");
|
62
68
|
}
|
63
69
|
|
70
|
+
@Test
|
71
|
+
public void testSpeedometerLabelLog() throws Exception {
|
72
|
+
validateSpeedometerLog("config_label.yml.run.log", logLabelLinePattern);
|
73
|
+
}
|
74
|
+
|
64
75
|
private void validateSpeedometerLog(String logFile) throws Exception {
|
76
|
+
validateSpeedometerLog(logFile, logLinePattern);
|
77
|
+
}
|
78
|
+
|
79
|
+
private void validateSpeedometerLog(String logFile, Pattern pattern) throws Exception {
|
65
80
|
boolean found = false;
|
66
81
|
try (BufferedReader r = new BufferedReader(new FileReader(getTestFile(logFile)))) {
|
67
82
|
String line = r.readLine();
|
68
83
|
while (line != null) {
|
69
|
-
if (
|
84
|
+
if (pattern.matcher(line).find()) {
|
70
85
|
found = true;
|
71
86
|
break;
|
72
87
|
}
|
@@ -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
|
@@ -24,6 +24,8 @@ import org.embulk.spi.time.TimestampFormatter;
|
|
24
24
|
import org.embulk.spi.util.Timestamps;
|
25
25
|
import org.msgpack.value.Value;
|
26
26
|
|
27
|
+
import com.google.common.base.Optional;
|
28
|
+
|
27
29
|
public class SpeedometerFilterPlugin
|
28
30
|
implements FilterPlugin
|
29
31
|
{
|
@@ -58,7 +60,11 @@ public class SpeedometerFilterPlugin
|
|
58
60
|
|
59
61
|
@Config("column_options")
|
60
62
|
@ConfigDefault("{}")
|
61
|
-
Map<String, TimestampColumnOption> getColumnOptions();
|
63
|
+
public Map<String, TimestampColumnOption> getColumnOptions();
|
64
|
+
|
65
|
+
@Config("label")
|
66
|
+
@ConfigDefault("null")
|
67
|
+
public Optional<String> getLabel();
|
62
68
|
|
63
69
|
@ConfigInject
|
64
70
|
public BufferAllocator getBufferAllocator();
|
@@ -97,7 +103,7 @@ public class SpeedometerFilterPlugin
|
|
97
103
|
private final PageBuilder pageBuilder;
|
98
104
|
|
99
105
|
SpeedControlPageOutput(PluginTask task, Schema schema, PageOutput pageOutput) {
|
100
|
-
this.controller = new SpeedometerSpeedController(task, SpeedometerSpeedAggregator.getInstance());
|
106
|
+
this.controller = new SpeedometerSpeedController(task, SpeedometerSpeedAggregator.getInstance(task));
|
101
107
|
this.schema = schema;
|
102
108
|
this.allocator = task.getBufferAllocator();
|
103
109
|
this.delimiterLength = task.getDelimiter().length();
|
@@ -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
|
}
|
@@ -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.4
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- hata
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2017-
|
11
|
+
date: 2017-03-28 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
requirement: !ruby/object:Gem::Requirement
|
@@ -59,8 +59,10 @@ files:
|
|
59
59
|
- src/integration-test/resources/big_01.csv.gz
|
60
60
|
- src/integration-test/resources/config_big.yml
|
61
61
|
- src/integration-test/resources/config_json.yml
|
62
|
+
- src/integration-test/resources/config_label.yml
|
62
63
|
- src/integration-test/resources/config_min.yml
|
63
64
|
- src/integration-test/resources/json_01.json.gz
|
65
|
+
- src/integration-test/resources/label_01.csv.gz
|
64
66
|
- src/integration-test/resources/min_01.csv.gz
|
65
67
|
- src/integration-test/resources/ref_json_result_01.csv.gz
|
66
68
|
- src/main/java/org/embulk/filter/SpeedometerFilterPlugin.java
|
@@ -71,7 +73,7 @@ files:
|
|
71
73
|
- src/test/java/org/embulk/filter/TestSpeedometerSpeedAggregator.java
|
72
74
|
- src/test/java/org/embulk/filter/TestSpeedometerSpeedController.java
|
73
75
|
- src/test/java/org/embulk/filter/TestSpeedometerUtil.java
|
74
|
-
- classpath/embulk-filter-speedometer-0.3.
|
76
|
+
- classpath/embulk-filter-speedometer-0.3.4.jar
|
75
77
|
homepage: https://github.com/hata/embulk-filter-speedometer
|
76
78
|
licenses:
|
77
79
|
- MIT
|