Skip to content

Commit 3c690e2

Browse files
authored
Enable docker-entrypoint and support configurable monitoring sinks. (#130)
1 parent 8554ee0 commit 3c690e2

File tree

9 files changed

+327
-74
lines changed

9 files changed

+327
-74
lines changed

config/config.conf

Lines changed: 47 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,56 @@
1-
monitoringCluster="cagg"
1+
# Pipelines
2+
# ~~~~
3+
hostPipelineConfiguration="config/hostPipeline.conf"
4+
clusterPipelineConfiguration="config/clusterPipeline.conf"
5+
6+
# Http Server
7+
# ~~~~
8+
#httpHost="0.0.0.0"
9+
#httpPort=7066
10+
#httpHealthCheckPath="/ping"
11+
#httpStatusPath="/status"
12+
#httpVersionPath="/version"
13+
14+
# Metrics
15+
# ~~~~
16+
monitoringCluster="cluster_aggregator"
17+
#monitoringService="cluster_aggregator"
18+
#monitoringSinks=[
19+
# {
20+
# class = "com.arpnetworking.metrics.impl.ApacheHttpSink"
21+
# bufferSize = 10000
22+
# uri = "http://localhost:7090/metrics/v3/application"
23+
# parallelism = 2
24+
# maxBatchSize = 500
25+
# emptyQueueInterval = "PT0.5S"
26+
# eventsDroppedLoggingInterval = "PT1M"
27+
# dispatchErrorLoggingInterval = "PT1M"
28+
# unsupportedDataLoggingInterval = "PT1M"
29+
# }
30+
#]
31+
#jvmMetricsCollectionInterval="PT1.0S"
32+
33+
# NOTES:
34+
# - monitoringHost and monitoringPort are deprecated
35+
# - specifying monitoringHost or monitoringPort disables monitoringSinks
36+
# - for backwards compatibility the legacy fields monitoringHost and monitoringPort
37+
# take precedence over monitoringSinks
38+
# - migrate to monitoringSinks as soon as possible
39+
40+
# Logging
41+
# ~~~~
242
logDirectory="logs"
3-
hostPipelineConfiguration="/opt/cluster-aggregator/config/hostPipeline.conf"
4-
clusterPipelineConfiguration="/opt/cluster-aggregator/config/clusterPipeline.conf"
5-
httpHost="0.0.0.0"
6-
httpPort=7066
7-
httpHealthCheckPath="/ping"
8-
httpStatusPath="/status"
9-
httpVersionPath="/version"
43+
44+
# Aggregation
45+
# ~~~~
1046
aggregationHost="0.0.0.0"
1147
aggregationPort=7065
12-
jvmMetricsCollectionInterval="PT0.5S"
1348
maxConnectionTimeout="PT2M"
1449
minConnectionTimeout="PT1M"
1550
clusterHostSuffix=".cluster"
51+
52+
# Akka
53+
# ~~~~
1654
rebalanceConfiguration {
1755
maxParallel=100
1856
threshold=500

pom.xml

Lines changed: 24 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@
1818
<parent>
1919
<groupId>com.arpnetworking.build</groupId>
2020
<artifactId>arpnetworking-parent-pom</artifactId>
21-
<version>2.0.6</version>
21+
<version>2.0.7</version>
2222
<relativePath />
2323
</parent>
2424

@@ -132,9 +132,9 @@
132132
<logback.version>1.2.3</logback.version>
133133
<logback.steno.version>1.18.0</logback.steno.version>
134134
<log4j.over.slf4j.version>1.7.22</log4j.over.slf4j.version>
135-
<metrics.client.version>0.11.1</metrics.client.version>
136-
<metrics.jvm.extra.version>0.11.0</metrics.jvm.extra.version>
137-
<metrics.http.extra.version>0.11.1</metrics.http.extra.version>
135+
<metrics.client.version>0.11.3</metrics.client.version>
136+
<metrics.jvm.extra.version>0.11.2</metrics.jvm.extra.version>
137+
<metrics.http.extra.version>0.11.2</metrics.http.extra.version>
138138
<metrics.aggregator.protocol.version>1.0.10</metrics.aggregator.protocol.version>
139139
<mockito.version>2.12.0</mockito.version>
140140
<netty.version>3.10.3.Final</netty.version>
@@ -159,7 +159,7 @@
159159
<avaje.ebeanorm.mavenenhancer.version>4.7.1</avaje.ebeanorm.mavenenhancer.version>
160160
<aspectjtools.maven.plugin>1.9.1</aspectjtools.maven.plugin>
161161
<aspectj.maven.plugin.version>1.11</aspectj.maven.plugin.version>
162-
<docker.maven.plugin.version>0.15.9</docker.maven.plugin.version>
162+
<docker.maven.plugin.version>0.27.2</docker.maven.plugin.version>
163163
<javassist.maven.plugin.version>0.1.2</javassist.maven.plugin.version>
164164
<maven.assembly.plugin.version>3.3.0</maven.assembly.plugin.version>
165165
<rpm.maven.plugin.version>2.1.5</rpm.maven.plugin.version>
@@ -282,6 +282,7 @@
282282
<filesets>
283283
<fileset>
284284
<directory>${project.build.directory}/docker-assembly</directory>
285+
<directory>${project.build.directory}/appassembler</directory>
285286
</fileset>
286287
</filesets>
287288
</configuration>
@@ -474,32 +475,44 @@
474475
</execution>
475476
</executions>
476477
<configuration>
478+
<autoCreateCustomNetworks>true</autoCreateCustomNetworks>
477479
<showLogs>true</showLogs>
478480
<images>
479481
<image>
480482
<name>arpnetworking/cluster-aggregator:${project.version}</name>
483+
<alias>cagg</alias>
481484
<build>
482485
<dockerFile>${project.build.directory}/docker-assembly/Dockerfile</dockerFile>
483486
<tags>
484487
<tag>${buildNumber}</tag>
485488
</tags>
486489
</build>
487490
<run>
488-
<env>
489-
<ADDITIONAL_JAVA_OPTS>${debugJavaOptions}</ADDITIONAL_JAVA_OPTS>
490-
</env>
491+
<network>
492+
<mode>custom</mode>
493+
<name>cagg-net</name>
494+
<alias>cagg</alias>
495+
</network>
491496
<ports>
492-
<port>${debugJavaPort}:${debugJavaPort}</port>
493-
<port>7066:7066</port>
497+
<port>+cagg.ip:${debugJavaPort}:${debugJavaPort}</port>
498+
<port>+cagg.ip:7066:7066</port>
499+
<port>+cagg.ip:7065:7065</port>
494500
</ports>
501+
<env>
502+
<JAVA_OPTS>${debugJavaOptions}</JAVA_OPTS>
503+
<!-- TODO(ville): Obtain these from the current user! -->
504+
<!-- Ref: https://github.com/rynr/user-id-maven-plugin -->
505+
<CAGG_UID>1000</CAGG_UID>
506+
<CAGG_GID>1000</CAGG_GID>
507+
</env>
495508
<volumes>
496509
<bind>
497510
<volume>${project.basedir}/logs/docker:/opt/cluster-aggregator/logs</volume>
498511
</bind>
499512
</volumes>
500513
<wait>
501514
<http>
502-
<url>http://${docker.host.address}:7066/ping</url>
515+
<url>http://${cagg.ip}:7066/ping</url>
503516
<method>GET</method>
504517
<status>200</status>
505518
</http>

src/assembly/assembly.xml

Lines changed: 0 additions & 27 deletions
This file was deleted.

src/main/assembly/bin.xml

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,14 @@
3737
<include>cluster-aggregator</include>
3838
</includes>
3939
</fileSet>
40+
<fileSet>
41+
<directory>${buildDirectory}</directory>
42+
<outputDirectory>bin</outputDirectory>
43+
<fileMode>0755</fileMode>
44+
<includes>
45+
<include>docker-entrypoint.sh</include>
46+
</includes>
47+
</fileSet>
4048
<fileSet>
4149
<directory>${buildDirectory}/appassembler/lib</directory>
4250
<outputDirectory>lib</outputDirectory>

src/main/assembly/docker.xml

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,14 @@
4646
<include>cluster-aggregator</include>
4747
</includes>
4848
</fileSet>
49+
<fileSet>
50+
<directory>${buildDirectory}</directory>
51+
<outputDirectory>bin</outputDirectory>
52+
<fileMode>0755</fileMode>
53+
<includes>
54+
<include>docker-entrypoint.sh</include>
55+
</includes>
56+
</fileSet>
4957
<fileSet>
5058
<directory>${buildDirectory}/appassembler/lib</directory>
5159
<outputDirectory>lib</outputDirectory>

src/main/docker/Dockerfile

Lines changed: 18 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@
1212
# See the License for the specific language governing permissions and
1313
# limitations under the License.
1414

15-
FROM openjdk:8u151-jre-alpine
15+
FROM openjdk:8u212-jre-alpine
1616

1717
MAINTAINER arpnetworking
1818

@@ -21,14 +21,17 @@ EXPOSE 7066
2121
WORKDIR /opt/cluster-aggregator
2222

2323
# Configuration
24+
ENV CAGG_USER="cagg"
25+
ENV CAGG_UID=1000
26+
ENV CAGG_GID=1000
2427
ENV JVM_XMS="64m"
2528
ENV JVM_XMX="1024m"
2629
ENV LOGBACK_CONFIG="-Dlogback.configurationFile=/opt/cluster-aggregator/config/logback.xml"
2730
ENV CAGG_CONFIG="/opt/cluster-aggregator/config/config.conf"
2831
ENV JAVA_OPTS=""
2932

3033
# Build
31-
RUN apk -U add libstdc++ && \
34+
RUN apk add --no-cache libstdc++ su-exec && \
3235
mkdir -p /opt/cluster-aggregator/lib/ext && \
3336
mkdir -p /opt/cluster-aggregator/logs && \
3437
mkdir -p /opt/cluster-aggregator/config
@@ -38,7 +41,19 @@ ADD config /opt/cluster-aggregator/config/
3841
ADD lib /opt/cluster-aggregator/lib/
3942

4043
# Entry point
41-
ENTRYPOINT [ \
44+
ENTRYPOINT [ "/opt/cluster-aggregator/bin/docker-entrypoint.sh" ]
45+
46+
# Default arguments
47+
CMD [ \
48+
"-n", \
49+
"${CAGG_USER}", \
50+
"-u", \
51+
"${CAGG_UID}", \
52+
"-g", \
53+
"${CAGG_GID}", \
54+
"-d", \
55+
"/opt/cluster-aggregator", \
56+
"--", \
4257
"/opt/cluster-aggregator/bin/cluster-aggregator", \
4358
"${LOGBACK_CONFIG}", \
4459
"-XX:+HeapDumpOnOutOfMemoryError", \

src/main/java/com/arpnetworking/clusteraggregator/GuiceModule.java

Lines changed: 52 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -59,7 +59,9 @@
5959
import com.arpnetworking.utility.Database;
6060
import com.arpnetworking.utility.ParallelLeastShardAllocationStrategy;
6161
import com.arpnetworking.utility.partitioning.PartitionSet;
62+
import com.fasterxml.jackson.databind.JsonNode;
6263
import com.fasterxml.jackson.databind.ObjectMapper;
64+
import com.google.common.collect.ImmutableList;
6365
import com.google.common.collect.ImmutableSet;
6466
import com.google.inject.AbstractModule;
6567
import com.google.inject.Injector;
@@ -79,11 +81,13 @@
7981
import java.net.URI;
8082
import java.net.URISyntaxException;
8183
import java.time.Duration;
82-
import java.util.Collections;
84+
import java.util.ArrayList;
85+
import java.util.List;
8386
import java.util.Locale;
8487
import java.util.Map;
8588
import java.util.Optional;
8689
import java.util.concurrent.CompletionStage;
90+
import javax.annotation.Nullable;
8791

8892
/**
8993
* The primary Guice module used to bootstrap the cluster aggregator. NOTE: this module will be constructed whenever
@@ -143,19 +147,30 @@ private Config provideAkkaConfig() {
143147

144148
@Provides
145149
@Singleton
150+
@SuppressWarnings("deprecation")
146151
@SuppressFBWarnings("UPM_UNCALLED_PRIVATE_METHOD") // Invoked reflectively by Guice
147152
private MetricsFactory provideMetricsFactory() throws URISyntaxException {
148-
final Sink sink = new ApacheHttpSink.Builder()
149-
.setUri(new URI(String.format(
150-
"http://%s:%d/metrics/v3/application",
151-
_configuration.getMonitoringHost(),
152-
_configuration.getMonitoringPort())))
153-
.build();
153+
final ImmutableList.Builder<com.arpnetworking.metrics.Sink> monitoringSinksBuilder =
154+
new ImmutableList.Builder<>();
155+
if (_configuration.getMonitoringHost().isPresent()
156+
|| _configuration.getMonitoringPort().isPresent()) {
157+
final String endpoint = String.format(
158+
"http://%s:%d/metrics/v3/application",
159+
_configuration.getMonitoringHost().orElse("localhost"),
160+
_configuration.getMonitoringPort().orElse(7090));
161+
162+
monitoringSinksBuilder.add(
163+
new ApacheHttpSink.Builder()
164+
.setUri(URI.create(endpoint))
165+
.build());
166+
} else {
167+
monitoringSinksBuilder.addAll(createSinks(_configuration.getMonitoringSinks()));
168+
}
154169

155170
return new TsdMetricsFactory.Builder()
156171
.setClusterName(_configuration.getMonitoringCluster())
157172
.setServiceName(_configuration.getMonitoringService())
158-
.setSinks(Collections.singletonList(sink))
173+
.setSinks(monitoringSinksBuilder.build())
159174
.build();
160175
}
161176

@@ -357,6 +372,35 @@ private PartitionSet provideDatabasePartitionSet(final Injector injector) {
357372
return new DatabasePartitionSet(database, partitionSet);
358373
}
359374

375+
@SuppressFBWarnings("REC_CATCH_EXCEPTION")
376+
static List<Sink> createSinks(final ImmutableList<JsonNode> monitoringSinks) {
377+
// Until we implement the Commons Builder pattern in the metrics client
378+
// library we need to resort to a more brute-force deserialization
379+
// style. The benefit of this approach is that it will be forwards
380+
// compatible with the Commons Builder approach. The drawbacks are
381+
// the ugly way the configuration is passed around (as JsonNode) and
382+
// then two-step deserialized.
383+
final List<com.arpnetworking.metrics.Sink> sinks = new ArrayList<>();
384+
for (final JsonNode sinkNode : monitoringSinks) {
385+
@Nullable final JsonNode classNode = sinkNode.get("class");
386+
try {
387+
if (classNode != null) {
388+
final Class<?> builderClass = Class.forName(classNode.textValue() + "$Builder");
389+
final Object builder = OBJECT_MAPPER.treeToValue(sinkNode, builderClass);
390+
@SuppressWarnings("unchecked")
391+
final com.arpnetworking.metrics.Sink sink =
392+
(com.arpnetworking.metrics.Sink) builderClass.getMethod("build").invoke(builder);
393+
sinks.add(sink);
394+
}
395+
// CHECKSTYLE.OFF: IllegalCatch - There are so many ways this hack can fail!
396+
} catch (final Exception e) {
397+
// CHECKSTYLE.ON: IllegalCatch
398+
throw new RuntimeException("Unable to create sink from: " + sinkNode.toString(), e);
399+
}
400+
}
401+
return sinks;
402+
}
403+
360404
private final ClusterAggregatorConfiguration _configuration;
361405

362406
private static final String HOCON_FILE_EXTENSION = ".conf";

0 commit comments

Comments
 (0)