You are viewing a plain text version of this content. The canonical link for it is here.
Posted to issues@flink.apache.org by zentol <gi...@git.apache.org> on 2018/02/16 08:34:27 UTC

[GitHub] flink pull request #5501: [FLINK-6053][metrics] Add new Number-/StringGauge ...

GitHub user zentol opened a pull request:

    https://github.com/apache/flink/pull/5501

    [FLINK-6053][metrics] Add new Number-/StringGauge metric types

    ## What is the purpose of the change
    
    This PR deprecates the `Gauge` metric type and introduces 2 new metric types: `StringGauge` and `NumberGauge`. The generic nature of `Gauges` is a big headache as it encourages exposing arbitrary objects, which not a single reporter actually supports. Furthermore, making the type distinction also proved to be difficult, as gauges may return null which fails `instanceof` checks.
    
    This change is for the most part backwards compatible:
    * `StringGauges` are wrapped such that they are registered as both `Gauge<String>` and `StringGauge`
    * `NumberGauges` are wrapped such that they are registered as both `Gauge<Number>` and `NumberGauge`
    * `Gauges<?>` are wrapper such that they are registered as both `Gauge<?>` and `StringGauge`.
    
    Thus, legacy reporters still work with the new metric types, and old metrics still work with new reporters, provided the reporter supports strings. We _could_ improve the compatibility for old metrics by checking the return type of the gauge for whether it is a number and register a `NumberGauge` instead.
    
    A new overloaded method `void register` was added to `MetricGroup`. We could not overload `gauge()` as this would forbid lambdas from being used without explicit class declaration.
    The signature of `register` is different than other registration methods. Neither do they return the given metric nor do they have generic parameters. This is done to support lambdas, as they have inherent problems with generic methods (ambiguity). This change has no effect on our code-base as we nowhere made use of this feature (which i think is still neat).
    
    The first commit introduces the new types, deprecates Gauges and sets up the compatibility layer.
    The second commit updates all reporters to work against the new metric types.
    The third commit replaces all existing usages of `Gauges` to instead use the new metric types.
    
    ## Verifying this change
    
    Existing tests were updated.
    
    ## Does this pull request potentially affect one of the following parts:
    
      - Dependencies (does it add or upgrade a dependency): (no)
      - The public API, i.e., is any changed class annotated with `@Public(Evolving)`: (yes)
      - The serializers: (no)
      - The runtime per-record code paths (performance sensitive): (no)
      - Anything that affects deployment or recovery: JobManager (and its components), Checkpointing, Yarn/Mesos, ZooKeeper: (no)
      - The S3 file system connector: (no)
    
    ## Documentation
    
    The documentation was not updated yet.


You can merge this pull request into a Git repository by running:

    $ git pull https://github.com/zentol/flink 6053

Alternatively you can review and apply these changes as the patch at:

    https://github.com/apache/flink/pull/5501.patch

To close this pull request, make a commit to your master/trunk branch
with (at least) the following in the commit message:

    This closes #5501
    
----
commit 7bc13f9f8dcb814fa88b746c1839511a639b234e
Author: zentol <ch...@...>
Date:   2018-02-07T10:11:56Z

    [FLINK-6053][metrics] Add new Number-/StringGauge metric types

commit 85a48c02fbd58edc822949cf9f9177c9c36661cc
Author: zentol <ch...@...>
Date:   2018-02-07T10:34:50Z

    update reporters

commit 2046d3ee79adeb0528169686c3fddf980232614d
Author: zentol <ch...@...>
Date:   2018-02-14T14:26:04Z

    replace all usages of now deprecated Gauge

----


---

[GitHub] flink issue #5501: [FLINK-6053][metrics] Add new Number-/StringGauge metric ...

Posted by zentol <gi...@git.apache.org>.
Github user zentol commented on the issue:

    https://github.com/apache/flink/pull/5501
  
    Yeah I'm not happy that we now added another instanceof clause.
    
    Ultimately we could modify `Counter` and `Meter` to implement `NumberGauge` (returning the count and rate, respectively), but that still leaves us with 3 metric types (StringGauge, NumberGauge, Histogram).
    (Long-term i would still like to throw out StringGauges, or force reporters to implement a dedicated interface)
    
    We could also hide histograms behind a series of `NumberGauges`, but it is difficult to ensure that all gauges refer to the same `HistogramStatistics`, i.e. are consistent as a whole, as they do currently.
    
    I didn't do anything in that regard in this PR as it would change behavior of some reporters that try to map our types to whatever types the backend uses. But this is very problematic anyway as our metric types are mostly syntactic sugar; the choice between counter/gauge is rather arbitrary.



---

[GitHub] flink pull request #5501: [FLINK-6053][metrics] Add new Number-/StringGauge ...

Posted by StephanEwen <gi...@git.apache.org>.
Github user StephanEwen commented on a diff in the pull request:

    https://github.com/apache/flink/pull/5501#discussion_r173146558
  
    --- Diff: flink-metrics/flink-metrics-core/src/main/java/org/apache/flink/metrics/StringGauge.java ---
    @@ -0,0 +1,26 @@
    +/*
    + * Licensed to the Apache Software Foundation (ASF) under one
    + * or more contributor license agreements.  See the NOTICE file
    + * distributed with this work for additional information
    + * regarding copyright ownership.  The ASF licenses this file
    + * to you 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
    + *
    + *     http://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 org.apache.flink.metrics;
    +
    +/**
    + * A StringGauge is a {@link Metric} that calculates a specific {@link String} value at a point in time.
    + */
    +public interface StringGauge extends Metric {
    --- End diff --
    
    Should be annotated with `@FunctionalInterface` to guard that this always stays lambda-able.
    
    Also annotate with Public / PublicEvolving?


---

[GitHub] flink issue #5501: [FLINK-6053][metrics] Add new Number-/StringGauge metric ...

Posted by zentol <gi...@git.apache.org>.
Github user zentol commented on the issue:

    https://github.com/apache/flink/pull/5501
  
    They are not registered twice. For gauges we create Wrapper that would, for a `Gauge<Custom>`, implements both `Gauge<Custom>` and `StringGauge`.
    
    Legacy reporters would go through the Gauge interface and behave as they always did, reporter going through the `StringGauge` interface would stringify whatever the gauge returns.
    
    Similarly, the new gauge types are wrapped so that we register something that implements both `Gauge<String/Number>` and `String-/NumberGauge`.
    
    see `AbstractMetricGroup`:
    ```
    	public <T, G extends Gauge<T>> G gauge(int name, G gauge) {
    		return gauge(String.valueOf(name), gauge);
    	}
    
    	public <T, G extends Gauge<T>> G gauge(String name, G gauge) {
    		addMetric(name, new LegacyGaugeWrapper<>(gauge));
    		return gauge;
    	}
    
    	public void register(String name, StringGauge gauge) {
    		addMetric(name, new StringGaugeWrapper(gauge));
    	}
    
    	@Override
    	public void register(String name, NumberGauge gauge) {
    		addMetric(name, new NumberGaugeWrapper(gauge));
    	}
    
    	private static class LegacyGaugeWrapper<T> implements StringGauge, Gauge<T> {
    		private final Gauge<T> legacyGauge;
    
    		private LegacyGaugeWrapper(Gauge<T> legacyGauge) {
    			this.legacyGauge = legacyGauge;
    		}
    
    		@Override
    		public String getStringValue() {
    			T value = legacyGauge.getValue();
    			if (value == null) {
    				return null;
    			} else {
    				return value.toString();
    			}
    		}
    
    		@Override
    		public T getValue() {
    			return legacyGauge.getValue();
    		}
    	}
    ```



---

[GitHub] flink pull request #5501: [FLINK-6053][metrics] Add new Number-/StringGauge ...

Posted by StephanEwen <gi...@git.apache.org>.
Github user StephanEwen commented on a diff in the pull request:

    https://github.com/apache/flink/pull/5501#discussion_r173146108
  
    --- Diff: flink-metrics/flink-metrics-core/src/main/java/org/apache/flink/metrics/NumberGauge.java ---
    @@ -0,0 +1,26 @@
    +/*
    + * Licensed to the Apache Software Foundation (ASF) under one
    + * or more contributor license agreements.  See the NOTICE file
    + * distributed with this work for additional information
    + * regarding copyright ownership.  The ASF licenses this file
    + * to you 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
    + *
    + *     http://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 org.apache.flink.metrics;
    +
    +/**
    + * A NumberGauge is a {@link Metric} that calculates a specific {@link Number} value at a point in time.
    + */
    +public interface NumberGauge extends Metric {
    --- End diff --
    
    This could be generic, as in
    ```java
    public interface NumberGauge<T extends Number> extends Metric {
        T getNumberValue();
    }
    ```
    Was there a specific reason to not make this generic?


---

[GitHub] flink pull request #5501: [FLINK-6053][metrics] Add new Number-/StringGauge ...

Posted by StephanEwen <gi...@git.apache.org>.
Github user StephanEwen commented on a diff in the pull request:

    https://github.com/apache/flink/pull/5501#discussion_r173148163
  
    --- Diff: flink-metrics/flink-metrics-core/src/main/java/org/apache/flink/metrics/MetricGroup.java ---
    @@ -87,9 +89,27 @@
     	 * @param gauge gauge to register
     	 * @param <T>   return type of the gauge
     	 * @return the given gauge
    +	 * @deprecated use {@link #register(String, NumberGauge)} or {@link #register(String, StringGauge)} instead
     	 */
    +	@Deprecated
     	<T, G extends Gauge<T>> G gauge(String name, G gauge);
     
    +	/**
    +	 * Registers a new {@link org.apache.flink.metrics.NumberGauge} with Flink.
    --- End diff --
    
    Minor: You don't need the fully qualified class name, the JavaDocs actually read easier with just the class names.


---

[GitHub] flink issue #5501: [FLINK-6053][metrics] Add new Number-/StringGauge metric ...

Posted by bowenli86 <gi...@git.apache.org>.
Github user bowenli86 commented on the issue:

    https://github.com/apache/flink/pull/5501
  
    LGTM, +1 on merging to 1.6.0


---

[GitHub] flink pull request #5501: [FLINK-6053][metrics] Add new Number-/StringGauge ...

Posted by StephanEwen <gi...@git.apache.org>.
Github user StephanEwen commented on a diff in the pull request:

    https://github.com/apache/flink/pull/5501#discussion_r173149289
  
    --- Diff: flink-metrics/flink-metrics-core/src/main/java/org/apache/flink/metrics/reporter/AbstractReporterV2.java ---
    @@ -0,0 +1,89 @@
    +/*
    + * Licensed to the Apache Software Foundation (ASF) under one
    + * or more contributor license agreements.  See the NOTICE file
    + * distributed with this work for additional information
    + * regarding copyright ownership.  The ASF licenses this file
    + * to you 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
    + *
    + *     http://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 org.apache.flink.metrics.reporter;
    +
    +import org.apache.flink.metrics.CharacterFilter;
    +import org.apache.flink.metrics.Counter;
    +import org.apache.flink.metrics.Histogram;
    +import org.apache.flink.metrics.Meter;
    +import org.apache.flink.metrics.Metric;
    +import org.apache.flink.metrics.MetricGroup;
    +import org.apache.flink.metrics.NumberGauge;
    +import org.apache.flink.metrics.StringGauge;
    +
    +import org.slf4j.Logger;
    +import org.slf4j.LoggerFactory;
    +
    +import java.util.HashMap;
    +import java.util.Map;
    +
    +/**
    + * Base interface for custom metric reporters.
    + */
    +public abstract class AbstractReporterV2 implements MetricReporter, CharacterFilter {
    +	protected final Logger log = LoggerFactory.getLogger(getClass());
    +
    +	protected final Map<StringGauge, String> stringGauges = new HashMap<>();
    +	protected final Map<NumberGauge, String> numberGauges = new HashMap<>();
    +	protected final Map<Counter, String> counters = new HashMap<>();
    +	protected final Map<Histogram, String> histograms = new HashMap<>();
    +	protected final Map<Meter, String> meters = new HashMap<>();
    +
    +	@Override
    +	public void notifyOfAddedMetric(Metric metric, String metricName, MetricGroup group) {
    +		final String name = group.getMetricIdentifier(metricName, this);
    +
    +		synchronized (this) {
    --- End diff --
    
    Minor: It is good practice to not lock on `this` for strictly internal mutual exclusion, because someone from the outside can lock on the same object - it is outside the class's control. Having a dedicated lock object instead is the recommendation.


---

[GitHub] flink pull request #5501: [FLINK-6053][metrics] Add new Number-/StringGauge ...

Posted by StephanEwen <gi...@git.apache.org>.
Github user StephanEwen commented on a diff in the pull request:

    https://github.com/apache/flink/pull/5501#discussion_r173147513
  
    --- Diff: flink-runtime/src/main/java/org/apache/flink/runtime/metrics/groups/AbstractMetricGroup.java ---
    @@ -460,4 +474,77 @@ protected GenericMetricGroup createChildGroup(String name, ChildType childType)
     		VALUE,
     		GENERIC
     	}
    +
    +	/**
    +	 * This class wraps a legacy {@link Gauge} to ensure that legacy metrics are not ignored by reporters that only work
    +	 * against the {@link StringGauge} and {@link NumberGauge} interfaces.
    +	 *
    +	 * @param <T> type of the gauge
    +	 */
    +	private static class LegacyGaugeWrapper<T> implements StringGauge, Gauge<T> {
    +		private final Gauge<T> legacyGauge;
    +
    +		private LegacyGaugeWrapper(Gauge<T> legacyGauge) {
    +			this.legacyGauge = legacyGauge;
    +		}
    +
    +		@Override
    +		public String getStringValue() {
    +			T value = legacyGauge.getValue();
    --- End diff --
    
    Do we actually want/support Gauges that return null? Or should they return "(null)", so that downstream code can assume non-null values?
    
    If we always want non null values, you can use `return String.valueOf(legacyGauge.getValue())`.
    
    Otherwise, all methods should be annotated with `@Nullable`.


---

[GitHub] flink issue #5501: [FLINK-6053][metrics] Add new Number-/StringGauge metric ...

Posted by bowenli86 <gi...@git.apache.org>.
Github user bowenli86 commented on the issue:

    https://github.com/apache/flink/pull/5501
  
    LGTM generally.
    
    I still feel having all the `instanceof` in `notifyOfAddedMetric` and `notifyOfRemovedMetric` is a bit inelegant. I'm fine with it since there'll (hopefully) be only a limited number of metric types, so the `instanceof` clauses won't grow insanely.
    



---

[GitHub] flink issue #5501: [FLINK-6053][metrics] Add new Number-/StringGauge metric ...

Posted by StephanEwen <gi...@git.apache.org>.
Github user StephanEwen commented on the issue:

    https://github.com/apache/flink/pull/5501
  
    Thanks, makes sense!


---

[GitHub] flink issue #5501: [FLINK-6053][metrics] Add new Number-/StringGauge metric ...

Posted by StephanEwen <gi...@git.apache.org>.
Github user StephanEwen commented on the issue:

    https://github.com/apache/flink/pull/5501
  
    If I understand correctly, all Gauges are now registered twice? Could we just register them once and map `Gauge<?>` always to a `StringGauge` calling `Objects.toString()` on its value?


---

[GitHub] flink pull request #5501: [FLINK-6053][metrics] Add new Number-/StringGauge ...

Posted by StephanEwen <gi...@git.apache.org>.
Github user StephanEwen commented on a diff in the pull request:

    https://github.com/apache/flink/pull/5501#discussion_r173146575
  
    --- Diff: flink-metrics/flink-metrics-core/src/main/java/org/apache/flink/metrics/NumberGauge.java ---
    @@ -0,0 +1,26 @@
    +/*
    + * Licensed to the Apache Software Foundation (ASF) under one
    + * or more contributor license agreements.  See the NOTICE file
    + * distributed with this work for additional information
    + * regarding copyright ownership.  The ASF licenses this file
    + * to you 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
    + *
    + *     http://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 org.apache.flink.metrics;
    +
    +/**
    + * A NumberGauge is a {@link Metric} that calculates a specific {@link Number} value at a point in time.
    + */
    +public interface NumberGauge extends Metric {
    --- End diff --
    
    Should be annotated with `@FunctionalInterface` to guard that this always stays lambda-able.
    
    Also annotate with Public / PublicEvolving?


---

[GitHub] flink pull request #5501: [FLINK-6053][metrics] Add new Number-/StringGauge ...

Posted by StephanEwen <gi...@git.apache.org>.
Github user StephanEwen commented on a diff in the pull request:

    https://github.com/apache/flink/pull/5501#discussion_r173150593
  
    --- Diff: flink-scala/src/main/scala/org/apache/flink/api/scala/metrics/ScalaGauge.scala ---
    @@ -23,6 +23,7 @@ import org.apache.flink.metrics.Gauge
     /**
       * This class allows the concise definition of a gauge from Scala using function references.
       */
    +@deprecated("use NumberGauge or StringGauge instead")
    --- End diff --
    
    Would be good to add a `ScalaStringGauge` and a `ScalaNumericGauge`.


---