Skip to content

[BEAM-6138] Add User Counter Metric Support to Java SDK#6799

Merged
swegner merged 4 commits intoapache:masterfrom
ajamato:java_sdk_metrics
Dec 13, 2018
Merged

[BEAM-6138] Add User Counter Metric Support to Java SDK#6799
swegner merged 4 commits intoapache:masterfrom
ajamato:java_sdk_metrics

Conversation

@ajamato
Copy link

@ajamato ajamato commented Oct 23, 2018

Please add a meaningful description for your change here
Adds Java User Metrics to the Java SDK.

Metrics set using Metrics.counter, inside the bundle processing thread (start, finish, process) will be collected and reported in the ProcesBundleResponse.

Follow this checklist to help us incorporate your contribution quickly and easily:

  • Format the pull request title like [BEAM-XXX] Fixes bug in ApproximateQuantiles, where you replace BEAM-XXX with the appropriate JIRA issue, if applicable. This will automatically link the pull request to the issue.
  • If this contribution is large, please file an Apache Individual Contributor License Agreement.

It will help us expedite review of your Pull Request if you tag someone (e.g. @username) to look at it.

Post-Commit Tests Status (on master branch)

Lang SDK Apex Dataflow Flink Gearpump Samza Spark
Go Build Status --- --- --- --- --- ---
Java Build Status Build Status Build Status Build Status Build Status Build Status Build Status Build Status
Python Build Status --- Build Status
Build Status
Build Status --- --- ---

@ajamato ajamato force-pushed the java_sdk_metrics branch 10 times, most recently from 50050a1 to 4806ac9 Compare November 27, 2018 22:12
@ajamato ajamato changed the title Do not submit (yet) Java SDK User Metrics [BEAM-6138] Add User Metric Supoprt to Java SDK (DO NOT SUBMIT YET) Nov 27, 2018
@ajamato ajamato force-pushed the java_sdk_metrics branch 7 times, most recently from ee0eb8a to de6304a Compare November 28, 2018 18:37
@ajamato ajamato changed the title [BEAM-6138] Add User Metric Supoprt to Java SDK (DO NOT SUBMIT YET) [BEAM-6138] Add User Metric Supoprt to Java SDK Nov 28, 2018
@ajamato
Copy link
Author

ajamato commented Nov 28, 2018

This is ready for review now. There are two commits because this depends on a separate PR to be submitted first (#6786).

PTAL appreciate the review :).
@robertwb @lukecwik @echauchot

@ajamato ajamato force-pushed the java_sdk_metrics branch 2 times, most recently from 4f9fcde to c5ef127 Compare November 28, 2018 19:00
@ajamato
Copy link
Author

ajamato commented Nov 29, 2018

@Ardagan

@ajamato ajamato changed the title [BEAM-6138] Add User Metric Supoprt to Java SDK [BEAM-6138] Add User Metric Support to Java SDK Nov 29, 2018
@ajamato ajamato changed the title [BEAM-6138] Add User Metric Support to Java SDK [BEAM-6138] Add User Counter Metric Support to Java SDK Nov 29, 2018
Copy link
Contributor

@Ardagan Ardagan left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I tried to avoid commenting on changes that are pending in PR 6786.

}

// Extract user metrics and store as MonitoringInfos.
MetricUpdates mus = metricsContainer.getUpdates();
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

extract response building to separate method.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done


// Enum extension to store the MonitoringInfoSpecs.
extend google.protobuf.EnumValueOptions {
MonitoringInfoSpec monitoring_info_spec = 207174266;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do we have any guidelines on how to generate this number to avoid collisions? I failed to find good docs on this.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I believe that we should use the commit number, and converted it from hex to dec.

*
* <p>Example Usage (ElementCount counter):
*
* <p>SimpleMonitoringInfoBuilder builder = new SimpleMonitoringInfoBuilder();
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If there is a way to preserve formatting on autoformat, it would be great to keep setters on new lines.
I didn't find a way to properly invoke relevant formatter, so can't suggest a solution here atm.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think that we would need to reconfigure spotless. @swegner any ideas here?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Our spotless config is here, which currently just used googleJavaFormat(). My preference would be to generally limit our customization and deviate only where it's important. GitHub isn't showing me the original diff so I can't tell exactly what's going wrong here.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There are also various javadoc constructs which could help; this article has some guidance: A Guide to Formatting Code Snippets in Javadoc

}

/**
* Builds the provided MonitoringInfo, if validateAndDropInvalid is set then it drops any
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Builds the provided MonitoringInfo.
Returns null if validateAndDropInvalid set and fields do not match respecting MonitoringInfoSpec based on urn.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done

}

/**
* @param namespace The namespace of the metric.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[Ignore if adding @param tags is required by linter]
Remove these param specs, since you do not provide any extra information here.
You can rename name and namespace to metricName and metricNamespace respectively, if you think this clarification is required.
Same for other cases.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done

public class SimpleMonitoringInfoBuilderTest {

@Test
public void testSpecNotFullyMet() {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please rename to "testReturnsNullIfSpecRequirementsNotMet"
same for other test methods.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done

}

SimpleMonitoringInfoBuilder builder = new SimpleMonitoringInfoBuilder();
builder.setUrnForUserMetric(RemoteExecutionTest.class.getName(), "counterMetric");
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Extract counter name to constant.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

done

Iterables.getOnlyElement(startFunctions).run();
mainOutputValues.clear();

assertThat(consumers.keySet(), containsInAnyOrder(inputPCollectionId, outputPCollectionId));
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We are testing metrics here, so we can skip other check.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done

Copy link
Author

@ajamato ajamato left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Couldn't seem to comment inline about moving the declaration in ProcessBundleHandler
ProcessBundleResponse.Builder response = ProcessBundleResponse.newBuilder();

This can't be moved because it is used outside of the try block at the end, so this is the closest place it can be defined

*
* <p>Example Usage (ElementCount counter):
*
* <p>SimpleMonitoringInfoBuilder builder = new SimpleMonitoringInfoBuilder();
Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think that we would need to reconfigure spotless. @swegner any ideas here?

}

/**
* @param namespace The namespace of the metric.
Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done

}

/**
* Builds the provided MonitoringInfo, if validateAndDropInvalid is set then it drops any
Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done

public class SimpleMonitoringInfoBuilderTest {

@Test
public void testSpecNotFullyMet() {
Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done

}

SimpleMonitoringInfoBuilder builder = new SimpleMonitoringInfoBuilder();
builder.setUrnForUserMetric(RemoteExecutionTest.class.getName(), "counterMetric");
Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

done

Iterables.getOnlyElement(startFunctions).run();
mainOutputValues.clear();

assertThat(consumers.keySet(), containsInAnyOrder(inputPCollectionId, outputPCollectionId));
Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done

@ajamato
Copy link
Author

ajamato commented Dec 7, 2018

@swegner Would you like to review as well?

@ajamato
Copy link
Author

ajamato commented Dec 7, 2018

Retest this please


static {
for (MonitoringInfoSpecs.Enum val : MonitoringInfoSpecs.Enum.values()) {
// Ignore the UNRECOGNIZED = -1 value;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This comment is redundant. It is better to remove it, or replace with explanation why we ignore "UNRECOGNIZED" values.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done

return false;
}

Set<String> requiredLabels = new HashSet<String>(spec.getRequiredLabelsList());
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We can also add validation of different labels values. Such as PTransform should be a valid pTransform name, etc.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'll put a TODO in that, to enhance it. Let's consider that out of scope for now.

*
* @param pTransform
*/
public void setPTransformLabel(String pTransform) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It is better to define generalized method setLabel(String labelName, String labelValue) and provide a list of standard label names.
This is one of examples that might work
https://stackoverflow.com/questions/3978654/best-way-to-create-enum-of-strings

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done, I think this is more or less what you mean

assertNull(builder.build());

builder.setPCollectionLabel("myPcollection");
assertTrue(builder.build() != null);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Would be good idea to validate result values here as well.

new UnknownPTransformRunnerFactory(urnToPTransformRunnerFactoryMap.keySet());
}

private void extractMonitoringInfosToResponse(
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This method should build a list of MonitoringInfos and caller should set MonitoringInfos to response.
Doing this will simplify reading code greatly and prevent further complexity growth.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm using this style to prevent putting it on a temp list. We could return an iterator object instead?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Iterator would be good.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Returning an iterable now, moved it to MetricContainerImpl

Ardagan pushed a commit to Ardagan/beam that referenced this pull request Dec 7, 2018
This is subset of code from apache#6799
Extracting it for unblocking counter validation changes in
Dataflow Java Runner.
@Ardagan Ardagan mentioned this pull request Dec 7, 2018
2 tasks
@ajamato
Copy link
Author

ajamato commented Dec 11, 2018

@robertwb @echauchot @Ardagan

@ajamato
Copy link
Author

ajamato commented Dec 11, 2018

Retest this please

@ajamato ajamato force-pushed the java_sdk_metrics branch 2 times, most recently from a0cf246 to 50dbf6d Compare December 11, 2018 18:41
Copy link
Contributor

@Ardagan Ardagan left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM. with one comment.

new UnknownPTransformRunnerFactory(urnToPTransformRunnerFactoryMap.keySet());
}

private void extractMonitoringInfosToResponse(
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Iterator would be good.

Copy link
Contributor

@echauchot echauchot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nice to see that there is portable user metrics now (at least counter) !
I only took a quick overlook. The only question I have is: If I understand correctly metrics updates are only sent at the end of the bundle processing. Is it planed to add metrics updates as part of the status updates during the bundle processing?

@ajamato
Copy link
Author

ajamato commented Dec 12, 2018

Yes @echauchot later on we will enhance this to also send metrics on the ProcessBundleProgressResponse, instead of just the ProcessBundleResponse.

@swegner swegner self-requested a review December 13, 2018 18:08
@swegner
Copy link
Contributor

swegner commented Dec 13, 2018

LGTM. I am going to merge this. but @echauchot if you have additional questions feel free to keep the conversation going.

@swegner swegner merged commit 0b3b9e0 into apache:master Dec 13, 2018
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants