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

[Synthetics] Template string syntax breaks inline monitors when running against the service #176094

Open
wants to merge 79 commits into
base: main
Choose a base branch
from

Conversation

justinkambic
Copy link
Contributor

@justinkambic justinkambic commented Feb 1, 2024

Summary

Fixes #169963.

Code is in WIP state.

Makes it so inline monitor scripts can make use of JavaScript template strings.

This PR will migrate data from the inline fields to use the project fields instead. This approach combined with b64 encoding will allow us to avoid the instance where we try to put JS template strings in dynamic YML, which breaks the YML syntax.

Testing instructions

Pre-requisites

  • Create a script to break the service. You can use the example script from the linked issue, something like:
step('Go to example,com', async () => { 
  const url = "https://example.com"
  // basically any code with a template string will break Heartbeat
  await page.goto(`${url}`);
});
  • Create a cloud deployment in CFT against 8.13.0-SNAPSHOT version
  • I have created a test deployment with a custom Kibana image using this PR branch

Testing the fix

  1. Go to your cloud testing deployment and create a browser monitor using the script from the pre-req section.
  2. Verify that your monitor fails to run appropriately with an error like the one in the linked issue.
  3. Go to the custom image deployment and create a monitor with the same script.
  4. Verify that the monitor succeeds to run.
  5. Verify that the Test Now feature (available in Detail view or on the Overview page) also works, as this is a separate route/transmission procedure.

This covers the fix for the bug. As part of this patch, we also made some changes to the ways monitors are stored/transmitted to the service. I'll add more detail in a footnote section below explaining what we did and why. The TLDR; of this, however is: we need to verify the add/edit functionality still works after these changes.

Verify edits still work

  1. In the custom image deployment, edit your monitor. This can be done from the monitor detail view, the Synthetics management view, or the popover menu from the monitor's card on the overview page.
  2. Modify your monitor script in some meaningful way that will cause visual changes in the test run. For example, you could add a second step to the script that throws an error.
  3. Save your monitor, and wait for the next test run, you should be able to see your new code in the test run details in the Kibana UI. This step ensures we are generating new zip data for each persist.

Feel free to do any additional checking you might think is appropriate.

Additional testing note

I left it off the main testing instructions because it's significantly more effort to set up, but an important code path to test is for an existing, failing monitor, to be fixed by this change. To perform this test, I created a local Stack hitting a locally-running Synthetics Service. I made a monitor with template strings that would fail, and verified it broke on my local service:

image

Then, I swapped Kibana into this branch and verified that after its next sync, the monitor succeeded:

image

In this case, the monitor data is never being stored as zipped, but the pre-existing script is being zipped on the fly before the monitor is transmitted to the service.

Why and How does this work

On the Agent side of this bug, Heartbeat generates dynamic YAML when executing inline journeys. Unfortunately, there's no easy way to escape template strings users add in JS code for inline monitors, and this breaks the YAML syntax when Heartbeat tries to parse the config code.

The workaround is to use a field normally reserved for project monitors. This patch takes the user-provided script content and zips/b64-encodes it, storing that data in the project source field we normally use for a project. When we transmit the monitor data for an inline test run, Kibana now drops the plaintext monitor script and only transmits the zipped data. When Heartbeat evaluates the fields it receives, it will treat the monitor as a project and execute it in a different manner, thus un-breaking this bug.

We elected to zip the data for inline monitors in the persist stage to avoid requiring the Kibana server to handle the added burden of re-zipping all inline monitors every time it proceeds to transmit them. In the worst case this could be 250 monitors per transmission, and we'd be re-zipping and re-encoding them each time Kibana sync'd with the service.

One caveat to this change is that it is not retroactive. For any existing inline monitor that is not zipped at the time this code starts to run, the Kibana server will be required to perform the zip at transmission time, until the monitor is edited again.

Checklist

Delete any items that are not applicable to this PR.

For maintainers

@justinkambic justinkambic added bug Fixes for quality problems that affect the customer experience release_note:fix Team:obs-ux-infra_services Observability Infrastructure & Services User Experience Team labels Feb 1, 2024
@justinkambic justinkambic self-assigned this Feb 1, 2024
@apmmachine
Copy link
Contributor

🤖 GitHub comments

Expand to view the GitHub comments

Just comment with:

  • /oblt-deploy : Deploy a Kibana instance using the Observability test environments.
  • /oblt-deploy-serverless : Deploy a serverless Kibana instance using the Observability test environments.
  • run elasticsearch-ci/docs : Re-trigger the docs validation. (use unformatted text in the comment!)

@justinkambic justinkambic force-pushed the 169963/inline-scripts-with-template-syntax-fail-to-run-migrate-to-project-monitor branch from e5743d5 to 668ae4c Compare February 9, 2024 23:00
@justinkambic
Copy link
Contributor Author

/oblt-deploy

1 similar comment
@justinkambic
Copy link
Contributor Author

/oblt-deploy

@justinkambic justinkambic force-pushed the 169963/inline-scripts-with-template-syntax-fail-to-run-migrate-to-project-monitor branch from 668ae4c to d0f96d9 Compare February 12, 2024 19:34
@justinkambic justinkambic marked this pull request as ready for review February 12, 2024 20:00
@justinkambic justinkambic requested a review from a team as a code owner February 12, 2024 20:00
@elasticmachine
Copy link
Contributor

Pinging @elastic/obs-ux-infra_services-team (Team:obs-ux-infra_services)

Copy link
Contributor

@cauemarcondes cauemarcondes left a comment

Choose a reason for hiding this comment

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

Code LGTM

@justinkambic justinkambic force-pushed the 169963/inline-scripts-with-template-syntax-fail-to-run-migrate-to-project-monitor branch from 7da0905 to 45246c2 Compare February 14, 2024 23:01
Copy link
Member

@vigneshshanmugam vigneshshanmugam left a comment

Choose a reason for hiding this comment

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

I just checked the core zip part, added some comments. Mostly LGTM

const locMonitors = await Promise.all(
bucketsByLocation[location.id].splice(0, PER_PAGE).map(async (monitorData) => {
// no inline script data, sync without further processing
if (!monitorData?.['source.inline.script']) return monitorData;
Copy link
Member

Choose a reason for hiding this comment

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

ques: why are we not setting [ConfigKey.SOURCE_INLINE]: undefined here?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Fair question - in this case there is no inline script so there's no reason to modify the monitor in any way.

This means it's either lightweight or already a project monitor, so basically we let those objects pass through unchanged.

x-pack/plugins/synthetics/server/common/mem_writable.ts Outdated Show resolved Hide resolved
x-pack/plugins/synthetics/server/common/mem_writable.ts Outdated Show resolved Hide resolved
@justinkambic justinkambic force-pushed the 169963/inline-scripts-with-template-syntax-fail-to-run-migrate-to-project-monitor branch from b0060b1 to 7d6ae2b Compare October 30, 2024 19:09
Copy link
Member

@vigneshshanmugam vigneshshanmugam left a comment

Choose a reason for hiding this comment

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

Bundling part LGTM

@justinkambic
Copy link
Contributor Author

/oblt-deploy

@elasticmachine
Copy link
Contributor

elasticmachine commented Nov 25, 2024

💔 Build Failed

  • Buildkite Build
  • Commit: e604c5d
  • Kibana Serverless Image: docker.elastic.co/kibana-ci/kibana-serverless:pr-176094-e604c5d98ea3

Failed CI Steps

Test Failures

  • [job] [logs] FTR Configs #59 / Synthetics API Tests SyncGlobalParams adds a monitor in private location
  • [job] [logs] FTR Configs #72 / Synthetics API Tests SyncGlobalParams adds a monitor in private location
  • [job] [logs] FTR Configs #59 / Synthetics API Tests SyncGlobalParams adds a monitor in private location
  • [job] [logs] FTR Configs #72 / Synthetics API Tests SyncGlobalParams adds a monitor in private location
  • [job] [logs] Jest Tests #18 / TableSearch renders with initial value correctly
  • [job] [logs] Jest Tests #10 / useActionStatus should post cancel and invoke callback on cancel upgrade - plural
  • [job] [logs] Jest Tests #10 / useActionStatus should report error on cancel upgrade failure

Metrics [docs]

Unknown metric groups

References to deprecated APIs

id before after diff
synthetics 20 25 +5

History

cc @justinkambic

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
apm:review backport:prev-major Backport to (8.x, 8.17, 8.16) the previous major branch and other branches in development bug Fixes for quality problems that affect the customer experience ci:project-deploy-observability Create an Observability project release_note:fix Team:obs-ux-infra_services Observability Infrastructure & Services User Experience Team Team:obs-ux-management Observability Management User Experience Team v8.16.0 v8.17.0 v9.0.0
Projects
None yet
Development

Successfully merging this pull request may close these issues.

[Synthetics] Monitor config serialization is incorrect for inline monitors
9 participants