-
Notifications
You must be signed in to change notification settings - Fork 1k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Exports GRPC call metrics and Feast resource metrics in Core (#345)
* Add dependency for prometheus client and servlet * Add MonitoringInterceptor to Feast core service To obtain request latency histogram for all RPC call in Prometheus * Register servlet for Prometheus client * Add custom Prometheus collector to export metrics about Feast resources * Add JVMResourceCollector to collect JVM metrics and garbage collection * Apply maven spotless
- Loading branch information
1 parent
9216159
commit a53e06b
Showing
10 changed files
with
325 additions
and
2 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
77 changes: 77 additions & 0 deletions
77
core/src/main/java/feast/core/config/MonitoringConfig.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,77 @@ | ||
/* | ||
* SPDX-License-Identifier: Apache-2.0 | ||
* Copyright 2018-2019 The Feast Authors | ||
* | ||
* Licensed under the Apache License, Version 2.0 (the "License"); | ||
* you may not use this file except in compliance with the License. | ||
* You may obtain a copy of the License at | ||
* | ||
* https://www.apache.org/licenses/LICENSE-2.0 | ||
* | ||
* Unless required by applicable law or agreed to in writing, software | ||
* distributed under the License is distributed on an "AS IS" BASIS, | ||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
* See the License for the specific language governing permissions and | ||
* limitations under the License. | ||
*/ | ||
package feast.core.config; | ||
|
||
import feast.core.dao.FeatureSetRepository; | ||
import feast.core.dao.StoreRepository; | ||
import feast.core.metrics.collector.FeastResourceCollector; | ||
import feast.core.metrics.collector.JVMResourceCollector; | ||
import io.prometheus.client.exporter.MetricsServlet; | ||
import javax.servlet.http.HttpServlet; | ||
import org.springframework.beans.factory.annotation.Autowired; | ||
import org.springframework.boot.web.servlet.ServletRegistrationBean; | ||
import org.springframework.context.annotation.Bean; | ||
import org.springframework.context.annotation.Configuration; | ||
|
||
@Configuration | ||
public class MonitoringConfig { | ||
|
||
private static final String PROMETHEUS_METRICS_PATH = "/metrics"; | ||
|
||
/** | ||
* Add Prometheus exposition to an existing HTTP server using servlets. | ||
* | ||
* <p>https://github.com/prometheus/client_java/tree/b61dd232a504e20dad404a2bf3e2c0b8661c212a#http | ||
* | ||
* @return HTTP servlet for returning metrics data | ||
*/ | ||
@Bean | ||
public ServletRegistrationBean<HttpServlet> metricsServlet() { | ||
return new ServletRegistrationBean<>(new MetricsServlet(), PROMETHEUS_METRICS_PATH); | ||
} | ||
|
||
/** | ||
* Register custom Prometheus collector that exports metrics about Feast Resources. | ||
* | ||
* <p>For example: total number of registered feature sets and stores. | ||
* | ||
* @param featureSetRepository {@link FeatureSetRepository} | ||
* @param storeRepository {@link StoreRepository} | ||
* @return {@link FeastResourceCollector} | ||
*/ | ||
@Bean | ||
@Autowired | ||
public FeastResourceCollector feastResourceCollector( | ||
FeatureSetRepository featureSetRepository, StoreRepository storeRepository) { | ||
FeastResourceCollector collector = | ||
new FeastResourceCollector(featureSetRepository, storeRepository); | ||
collector.register(); | ||
return collector; | ||
} | ||
|
||
/** | ||
* Register custom Prometheus collector that exports metrics about JVM resource usage. | ||
* | ||
* @return @{link {@link JVMResourceCollector}} | ||
*/ | ||
@Bean | ||
public JVMResourceCollector jvmResourceCollector() { | ||
JVMResourceCollector jvmResourceCollector = new JVMResourceCollector(); | ||
jvmResourceCollector.register(); | ||
return jvmResourceCollector; | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
56 changes: 56 additions & 0 deletions
56
core/src/main/java/feast/core/grpc/interceptors/MonitoringInterceptor.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,56 @@ | ||
/* | ||
* SPDX-License-Identifier: Apache-2.0 | ||
* Copyright 2018-2019 The Feast Authors | ||
* | ||
* Licensed under the Apache License, Version 2.0 (the "License"); | ||
* you may not use this file except in compliance with the License. | ||
* You may obtain a copy of the License at | ||
* | ||
* https://www.apache.org/licenses/LICENSE-2.0 | ||
* | ||
* Unless required by applicable law or agreed to in writing, software | ||
* distributed under the License is distributed on an "AS IS" BASIS, | ||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
* See the License for the specific language governing permissions and | ||
* limitations under the License. | ||
*/ | ||
package feast.core.grpc.interceptors; | ||
|
||
import feast.core.metrics.GrpcMetrics; | ||
import io.grpc.ForwardingServerCall.SimpleForwardingServerCall; | ||
import io.grpc.Metadata; | ||
import io.grpc.MethodDescriptor; | ||
import io.grpc.ServerCall; | ||
import io.grpc.ServerCall.Listener; | ||
import io.grpc.ServerCallHandler; | ||
import io.grpc.ServerInterceptor; | ||
import io.grpc.Status; | ||
|
||
/** | ||
* MonitoringInterceptor intercepts a GRPC call to provide a request latency historgram metrics in | ||
* the Prometheus client. | ||
*/ | ||
public class MonitoringInterceptor implements ServerInterceptor { | ||
|
||
@Override | ||
public <ReqT, RespT> Listener<ReqT> interceptCall( | ||
ServerCall<ReqT, RespT> call, Metadata headers, ServerCallHandler<ReqT, RespT> next) { | ||
|
||
long startCallMillis = System.currentTimeMillis(); | ||
String fullMethodName = call.getMethodDescriptor().getFullMethodName(); | ||
String serviceName = MethodDescriptor.extractFullServiceName(fullMethodName); | ||
String methodName = fullMethodName.substring(fullMethodName.indexOf("/") + 1); | ||
|
||
return next.startCall( | ||
new SimpleForwardingServerCall<ReqT, RespT>(call) { | ||
@Override | ||
public void close(Status status, Metadata trailers) { | ||
GrpcMetrics.requestLatency | ||
.labels(serviceName, methodName, status.getCode().name()) | ||
.observe((System.currentTimeMillis() - startCallMillis) / 1000f); | ||
super.close(status, trailers); | ||
} | ||
}, | ||
headers); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,29 @@ | ||
/* | ||
* SPDX-License-Identifier: Apache-2.0 | ||
* Copyright 2018-2019 The Feast Authors | ||
* | ||
* Licensed under the Apache License, Version 2.0 (the "License"); | ||
* you may not use this file except in compliance with the License. | ||
* You may obtain a copy of the License at | ||
* | ||
* https://www.apache.org/licenses/LICENSE-2.0 | ||
* | ||
* Unless required by applicable law or agreed to in writing, software | ||
* distributed under the License is distributed on an "AS IS" BASIS, | ||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
* See the License for the specific language governing permissions and | ||
* limitations under the License. | ||
*/ | ||
package feast.core.metrics; | ||
|
||
import io.prometheus.client.Histogram; | ||
|
||
public class GrpcMetrics { | ||
|
||
public static final Histogram requestLatency = | ||
Histogram.build() | ||
.name("feast_core_request_latency_seconds") | ||
.labelNames("service", "method", "status_code") | ||
.help("Request latency in seconds") | ||
.register(); | ||
} |
57 changes: 57 additions & 0 deletions
57
core/src/main/java/feast/core/metrics/collector/FeastResourceCollector.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,57 @@ | ||
/* | ||
* SPDX-License-Identifier: Apache-2.0 | ||
* Copyright 2018-2019 The Feast Authors | ||
* | ||
* Licensed under the Apache License, Version 2.0 (the "License"); | ||
* you may not use this file except in compliance with the License. | ||
* You may obtain a copy of the License at | ||
* | ||
* https://www.apache.org/licenses/LICENSE-2.0 | ||
* | ||
* Unless required by applicable law or agreed to in writing, software | ||
* distributed under the License is distributed on an "AS IS" BASIS, | ||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
* See the License for the specific language governing permissions and | ||
* limitations under the License. | ||
*/ | ||
package feast.core.metrics.collector; | ||
|
||
import feast.core.dao.FeatureSetRepository; | ||
import feast.core.dao.StoreRepository; | ||
import io.prometheus.client.Collector; | ||
import io.prometheus.client.GaugeMetricFamily; | ||
import java.util.ArrayList; | ||
import java.util.List; | ||
|
||
/** | ||
* FeastResourceCollector exports metrics about Feast Resources. | ||
* | ||
* <p>For example: total number of registered feature sets and stores. | ||
*/ | ||
public class FeastResourceCollector extends Collector { | ||
|
||
private final FeatureSetRepository featureSetRepository; | ||
private final StoreRepository storeRepository; | ||
|
||
public FeastResourceCollector( | ||
FeatureSetRepository featureSetRepository, StoreRepository storeRepository) { | ||
this.featureSetRepository = featureSetRepository; | ||
this.storeRepository = storeRepository; | ||
} | ||
|
||
@Override | ||
public List<MetricFamilySamples> collect() { | ||
List<MetricFamilySamples> samples = new ArrayList<>(); | ||
samples.add( | ||
new GaugeMetricFamily( | ||
"feast_core_feature_set_total", | ||
"Total number of registered feature sets", | ||
featureSetRepository.count())); | ||
samples.add( | ||
new GaugeMetricFamily( | ||
"feast_core_store_total", | ||
"Total number of registered stores", | ||
storeRepository.count())); | ||
return samples; | ||
} | ||
} |
76 changes: 76 additions & 0 deletions
76
core/src/main/java/feast/core/metrics/collector/JVMResourceCollector.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,76 @@ | ||
/* | ||
* SPDX-License-Identifier: Apache-2.0 | ||
* Copyright 2018-2019 The Feast Authors | ||
* | ||
* Licensed under the Apache License, Version 2.0 (the "License"); | ||
* you may not use this file except in compliance with the License. | ||
* You may obtain a copy of the License at | ||
* | ||
* https://www.apache.org/licenses/LICENSE-2.0 | ||
* | ||
* Unless required by applicable law or agreed to in writing, software | ||
* distributed under the License is distributed on an "AS IS" BASIS, | ||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
* See the License for the specific language governing permissions and | ||
* limitations under the License. | ||
*/ | ||
package feast.core.metrics.collector; | ||
|
||
import io.prometheus.client.Collector; | ||
import io.prometheus.client.GaugeMetricFamily; | ||
import io.prometheus.client.SummaryMetricFamily; | ||
import java.lang.management.GarbageCollectorMXBean; | ||
import java.lang.management.ManagementFactory; | ||
import java.util.ArrayList; | ||
import java.util.Collections; | ||
import java.util.List; | ||
|
||
/** | ||
* JVMResourceCollector exports metrics about Java virtual machine memory and garbage collection. | ||
*/ | ||
public class JVMResourceCollector extends Collector { | ||
|
||
private final List<GarbageCollectorMXBean> garbageCollectors; | ||
private final Runtime runtime; | ||
|
||
public JVMResourceCollector() { | ||
garbageCollectors = ManagementFactory.getGarbageCollectorMXBeans(); | ||
runtime = Runtime.getRuntime(); | ||
} | ||
|
||
@Override | ||
public List<MetricFamilySamples> collect() { | ||
List<MetricFamilySamples> samples = new ArrayList<>(); | ||
|
||
samples.add( | ||
new GaugeMetricFamily( | ||
"feast_core_max_memory_bytes", | ||
"Max amount of memory the Java virtual machine will attempt to use", | ||
runtime.maxMemory())); | ||
samples.add( | ||
new GaugeMetricFamily( | ||
"feast_core_total_memory_bytes", | ||
"Total amount of memory in the Java virtual machine", | ||
runtime.totalMemory())); | ||
samples.add( | ||
new GaugeMetricFamily( | ||
"feast_core_free_memory_bytes", | ||
"Total amount of free memory in the Java virtual machine", | ||
runtime.freeMemory())); | ||
|
||
SummaryMetricFamily gcMetricFamily = | ||
new SummaryMetricFamily( | ||
"feast_core_gc_collection_seconds", | ||
"Time spent in a given JVM garbage collector in seconds", | ||
Collections.singletonList("gc")); | ||
for (final GarbageCollectorMXBean gc : garbageCollectors) { | ||
gcMetricFamily.addMetric( | ||
Collections.singletonList(gc.getName()), | ||
gc.getCollectionCount(), | ||
gc.getCollectionTime() / MILLISECONDS_PER_SECOND); | ||
} | ||
samples.add(gcMetricFamily); | ||
|
||
return samples; | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters