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

[Analytics] Track install and error events #1984

Open
wants to merge 10 commits into
base: trunk
Choose a base branch
from

Conversation

bgrgicak
Copy link
Collaborator

@bgrgicak bgrgicak commented Nov 4, 2024

This PR will track which plugins and themes were installed during boot from a Blueprint, by sending a installTheme and installPlugin events.
An error event will be sent if Playground experiences a boot or PHP request error.

All events are sent to Google Analytics and don't contain any personal data information.

InstallTheme and InstallPlugin events will only include the theme/plugin slug.

Error events will only send an error source which can be:

  • bootSiteClient - error occurred during boot.
  • php-wasm - internal PHP.wasm error occurred during a PHP request.
  • request - a PHP or SQL error occurred during a PHP request.
  • unknown - for request errors that don't have a source. This shouldn't happen but we still want to catch it to confirm it's not happening in practice.

The purpose of the error event is to provide insights into how frequently users experience issues.
It's not intended for logging or debugging.

Fixes #1778

Testing Instructions (or ideally a Blueprint)

@bgrgicak bgrgicak requested a review from a team November 4, 2024 15:39
@bgrgicak bgrgicak self-assigned this Nov 4, 2024
@bgrgicak bgrgicak added [Type] Enhancement New feature or request [Type] Tracking Tactical breakdown of efforts across the codebase and/or tied to Overview issues. [Aspect] Website [Package][@wp-playground] Website labels Nov 4, 2024
*/
logTrackingEvent('step', { step: step.step });

if (step.step === 'installPlugin' && (step as any).pluginData.slug) {
Copy link
Collaborator

Choose a reason for hiding this comment

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

Does this account for blueprint.plugins? Or just blueprint.steps?

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Both. It will run whenever a step is completed.
During Blueprint compile, blueprint.plugins is converted to steps.

@adamziel
Copy link
Collaborator

adamziel commented Nov 5, 2024

What's the advantage of logging error events to GA instead of logstash as @brandonpayton once suggested? And how would we use GA to aggregate and analyze the error information?

@bgrgicak
Copy link
Collaborator Author

bgrgicak commented Nov 6, 2024

What's the advantage of logging error events to GA instead of logstash as @brandonpayton once suggested? And how would we use GA to aggregate and analyze the error information?

This PR won't log errors in GA, only an event that indicates an error occurred.
The error event isn't intended for debugging, it's here to show progress on our Zero crashes goal.

I would love to have Logstash for debugging! What we have in Slack today isn't great.
@brandonpayton let's start a separate discussion about storing logs in Logstash.

@brandonpayton
Copy link
Member

What's the advantage of logging error events to GA instead of logstash as @brandonpayton once suggested?

I don't recall the exact context, but IIRC, I think my intent was to point out what was possible rather than to promote logstash specifically. 😅 I don't currently have a preference, but it seems like it would be good to try to be open with whatever info is collected.

I would love to have Logstash for debugging! What we have in Slack today isn't great.
@brandonpayton let's start a separate discussion about storing logs in Logstash.

Sounds good! I've also seen some use of ClickHouse recently for collecting RUM data. And here's a marketing page for the logging use case:
https://clickhouse.com/use-cases/logging-and-metrics

It might be something to consider as well.

Whatever we choose will likely be better than Slack :)

Copy link
Member

@brandonpayton brandonpayton left a comment

Choose a reason for hiding this comment

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

This looks good to me. I left one question that could be addressed depending on your answer. :) Thanks!

@@ -159,6 +160,8 @@ function Modals(blueprint: Blueprint) {
useEffect(() => {
addCrashListener(logger, (e) => {
const error = e as CustomEvent;
logErrorEvent(error.detail?.source);
Copy link
Member

Choose a reason for hiding this comment

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

Non-rhetorical question:
It looks like this will log a generic error if error.detail is not defined. Do we want that?

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

This is a custom event we create, so detail.source should always be available, but let's be safe.
I added a check for the source in ad63c49

Comment on lines 163 to 165
if (error.detail?.source) {
logErrorEvent(error.detail.source);
}
Copy link
Collaborator Author

Choose a reason for hiding this comment

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

While testing this I realized that request errors show only a white screen without any error messages.
I think that we can improve this, so I opened an issue #1993

Copy link
Collaborator

Choose a reason for hiding this comment

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

Would it make sense to also log errors when the source is empty?

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

From reading the code this shouldn't happen, but let's track it to make sure it stays like that. a10dfc9

logTrackingEvent('step', { step: step.step });

if (step.step === 'installPlugin' && (step as any).pluginData.slug) {
logTrackingEvent('install', {
Copy link
Collaborator

Choose a reason for hiding this comment

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

What's the advantage of having a single install event with either a plugin or theme prop vs having separate installPlugin and installTheme events?

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

None, it will probably be easier to build reports with separate events.
I switched to two events beeb585

@adamziel
Copy link
Collaborator

The structure looks really good. I left a few tactical questions.

@bgrgicak bgrgicak requested a review from adamziel November 14, 2024 09:18
@@ -125,6 +118,9 @@ export function bootSiteClient(
onClientConnected: (playground) => {
(window as any)['playground'] = playground;
},
onBlueprintStepCompleted: (result, step) => {
logBlueprintStepEvent(step);
Copy link
Collaborator

Choose a reason for hiding this comment

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

Actually, why only log the completed steps instead of all the steps?

@bgrgicak bgrgicak requested a review from Copilot December 12, 2024 06:06
Copy link

@Copilot Copilot AI left a comment

Choose a reason for hiding this comment

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

Copilot reviewed 3 out of 3 changed files in this pull request and generated 1 suggestion.

*
* @param error The error
*/
export const logErrorEvent = (source: string) => {
Copy link
Preview

Copilot AI Dec 12, 2024

Choose a reason for hiding this comment

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

The error source is being logged as a string, which can lead to inconsistencies. Consider using an enum or predefined constants for the error sources to ensure consistency.

Suggested change
export const logErrorEvent = (source: string) => {
export const logErrorEvent = (source: ErrorSource) => {

Copilot is powered by AI, so mistakes are possible. Review output carefully before use.

Positive Feedback
Negative Feedback

Provide additional feedback

Please help us improve GitHub Copilot by sharing more details about this comment.

Please select one or more of the options
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
[Aspect] Website [Package][@wp-playground] Website [Type] Enhancement New feature or request [Type] Tracking Tactical breakdown of efforts across the codebase and/or tied to Overview issues.
Projects
Status: Reviewed
Development

Successfully merging this pull request may close these issues.

Quantitative logging of errors and plugins
3 participants