Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Adding simple support for backend telemetry. #19257

Merged
merged 15 commits into from May 14, 2024

Conversation

dennisoelkers
Copy link
Member

@dennisoelkers dennisoelkers commented May 6, 2024

Description

Motivation and Context

This PR is providing a simple foundation for sending telemetry from the backend. It bootstraps the client using the (already available) API key and endpoint and adds a simple periodical (TelemetrySubmissionPeriodical) which is executed every day (to avoid sending excessive telemetry events) to submit metrics (if they are present).

For this, it provides the ability to bind simple suppliers (implemented as subclasses of TelemetryMetricSupplier) which create (optional) metrics for each invocation. If none are registered or none of them returns actual metrics, metrics submission is skipped. Each supplier is registered with a (unique) key, which is used as the event id for the captured event.

A simple supplier could be registered as simple as this:

class SampleModule extends PluginModule {
  protected void configure() {
    addTelemetryMetricProvider("My Metric", () -> Optional.of(TelemetryEvent.of("my_metric", 42)));
  }
}

A supplier does not have to provide a metric, if e.g. the feature was not used:

  addTelemetryMetricProvider("Feature X Metrics", () -> isFeatureUsed ? Optional.of(....) : Optional.empty());

/nocl

How Has This Been Tested?

Screenshots (if appropriate):

Types of changes

  • Bug fix (non-breaking change which fixes an issue)
  • New feature (non-breaking change which adds functionality)
  • Refactoring (non-breaking change)
  • Breaking change (fix or feature that would cause existing functionality to change)

Checklist:

  • My code follows the code style of this project.
  • My change requires a change to the documentation.
  • I have updated the documentation accordingly.
  • I have read the CONTRIBUTING document.
  • I have added tests to cover my changes.

@dennisoelkers dennisoelkers requested a review from a team May 6, 2024 09:24
@janheise janheise self-requested a review May 6, 2024 12:00
Copy link
Member

@bernd bernd left a comment

Choose a reason for hiding this comment

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

Thank you! A few comments.

Comment on lines 47 to 51
final var telemetryMetrics = metricsProviders.entrySet()
.stream()
.collect(Collectors.toMap(Map.Entry::getKey, entry -> entry.getValue().get()));
telemetryMetrics.forEach((key, value) -> value.map(TelemetryEvent::metrics)
.ifPresent(metrics -> telemetryClient.capture(key, metrics)));
Copy link
Member

Choose a reason for hiding this comment

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

Should we catch any exception here and log a good message instead of letting the periodical system log a generic error message?

pom.xml Outdated
@@ -490,6 +491,11 @@
<artifactId>auto-value-javabean</artifactId>
<version>${auto-value-javabean.version}</version>
</dependency>
<dependency>
<groupId>com.posthog.java</groupId>
<artifactId>posthog</artifactId>
Copy link
Member

Choose a reason for hiding this comment

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

The library looks a bit funky. Using System.out.println and e.printStackTrace() for logging, for example. 😬

https://github.com/PostHog/posthog-java/blob/e230c6417088d26a03c00905d3c301b341eff624/posthog/src/main/java/com/posthog/java/HttpSender.java#L98

I wonder if it's worth including or if we should rather implement our own small client based on our OkHttp client. Not sure how much work the client saves us. I don't think we need the client's queueing mechanism.

Copy link
Member Author

Choose a reason for hiding this comment

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

I see no way to specify a proxy for the client, so that is already a good reason to roll our own, unfortunately. My only concern are future changes that we cannot mitigate by just bumping the client, but maybe at that point the client is in a better shape, so we can switch.

Copy link
Member

Choose a reason for hiding this comment

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

Thanks!

Their HTTP API should be rather stable. If that's not the case, it would be pretty painful for everyone using the product. 😄

Comment on lines 37 to 39
this.posthog = () -> new PostHog.Builder(telemetryConfiguration.getTelemetryApiKey())
.host(telemetryConfiguration.getTelemetryApiHost())
.build();
Copy link
Member

Choose a reason for hiding this comment

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

If we stick with the client (see comment in pom.xml below), we need to set the proxy server if it's configured in the server config.

Copy link
Member

@bernd bernd left a comment

Choose a reason for hiding this comment

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

Thanks for replacing the lib! 🙏

Two comments below.

}
}

@POST
Copy link
Member

Choose a reason for hiding this comment

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

Is the /batch path missing here?

Copy link
Member Author

Choose a reason for hiding this comment

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

🤦

.map(entry -> PosthogAPI.Event.create(clusterId, entry.getKey(), entry.getValue().metrics()))
.toList();
final var request = new PosthogAPI.BatchRequest(apiKey, batch);
posthog.batchSend(request);
Copy link
Member

Choose a reason for hiding this comment

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

Let's handle response codes and errors here. (https://posthog.com/docs/api/post-only-endpoints#responses)

Copy link
Member Author

Choose a reason for hiding this comment

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

@dennisoelkers dennisoelkers requested a review from bernd May 7, 2024 08:09
Copy link
Member

@bernd bernd left a comment

Choose a reason for hiding this comment

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

Thanks for addressing my comments. I didn't test the code, but the approach looks good! 👍

@dennisoelkers dennisoelkers marked this pull request as ready for review May 8, 2024 08:02

@Override
public boolean startOnThisNode() {
return true;
Copy link
Member

Choose a reason for hiding this comment

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

I just noticed: we can do the telemetryClient.isEnabled() call here so the periodical doesn't even run if telemetry is disabled.

Copy link
Member Author

Choose a reason for hiding this comment

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

Fixed that. Had to rebase the branch unfortunately, messed up a merge.

Copy link
Contributor

@janheise janheise left a comment

Choose a reason for hiding this comment

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

LGTM!

@janheise janheise merged commit b569b1a into master May 14, 2024
5 checks passed
@janheise janheise deleted the feat/backend-telemetry-setup branch May 14, 2024 09:23
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.

None yet

3 participants