Skip to content

Camunda Pyzeebe Instrumentation #1385

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

Draft
wants to merge 8 commits into
base: main
Choose a base branch
from
Draft

Camunda Pyzeebe Instrumentation #1385

wants to merge 8 commits into from

Conversation

khpeet
Copy link

@khpeet khpeet commented May 7, 2025

This PR adds support for the Camunda Pyzeebe Module

  • Tracing and useful metadata collection for ZybeeClient functions
  • Tracing and useful metadata for ZybeeWorker decorators - @worker.task / @router.task

Need help with writing some tests for this instrumentation though

@khpeet khpeet requested a review from a team as a code owner May 7, 2025 20:31
@mergify mergify bot added the tests-failing label May 7, 2025
@codecov-commenter
Copy link

codecov-commenter commented May 7, 2025

Codecov Report

Attention: Patch coverage is 63.41463% with 30 lines in your changes missing coverage. Please review.

Project coverage is 81.01%. Comparing base (0e8722c) to head (cfe9eff).
Report is 42 commits behind head on main.

Files with missing lines Patch % Lines
newrelic/hooks/external_pyzeebe.py 62.96% 11 Missing and 19 partials ⚠️
Additional details and impacted files
@@            Coverage Diff             @@
##             main    #1385      +/-   ##
==========================================
- Coverage   81.57%   81.01%   -0.56%     
==========================================
  Files         205      206       +1     
  Lines       23217    23346     +129     
  Branches     3670     3697      +27     
==========================================
- Hits        18939    18914      -25     
- Misses       3055     3168     +113     
- Partials     1223     1264      +41     

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

@khpeet khpeet marked this pull request as draft May 7, 2025 21:06
@mergify mergify bot removed the tests-failing label May 8, 2025
async def wrapper(wrapped, instance, args, kwargs):
txn = current_transaction()
if txn:
add_fn = add_custom_span_attribute
Copy link
Contributor

Choose a reason for hiding this comment

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

To add the new pyzeebe attributes, you may want to check out the add_agent_attribute function for this rather than adding these as custom attributes. Here are some examples of its use in other places within the agent: http://github.com/newrelic/newrelic-python-agent/blob/main/newrelic/hooks/messagebroker_kombu.py#L204 https://github.com/newrelic/newrelic-python-agent/blob/main/newrelic/hooks/messagebroker_kafkapython.py#L145. You will also want to add all of these new pyzeebe attributes into this set: https://github.com/newrelic/newrelic-python-agent/blob/main/newrelic/core/attribute.py#L43

Copy link
Author

Choose a reason for hiding this comment

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

@umaannamalai - I tried using add_agent_attribute and it yields undesired behavior when adding those attributes in the existing txn if block. It will add them to the parent span instead of each of the individual FunctionTrace spans (i.e - run_process, deploy_resource, etc). What is your recommendation to achieve stamping those attributes on each individual span? Below is an example screenshot where those client methods are called inside a main() function that is annotated with @newrelic.agent.background_task()

image

Copy link
Author

Choose a reason for hiding this comment

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

@umaannamalai - following up here

@khpeet khpeet requested a review from umaannamalai May 28, 2025 17:56
@khpeet khpeet requested a review from umaannamalai June 18, 2025 13:56
return result
else:
# add_fn = add_custom_attribute
created_txn = BackgroundTask(application=application_instance(), name=method_name, group="ZeebeClient")
Copy link
Contributor

Choose a reason for hiding this comment

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

We actually will want to avoid starting a background task here and stick to only using function tracing for these client methods. This wrapper can be edited to early exit out if no transaction is found. If one is found, then the above function tracing logic should make sense to keep.

Copy link
Author

Choose a reason for hiding this comment

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

@umaannamalai - not sure on this - how would the client methods get picked up then if no current transaction exists? I tested only using FunctionTrace in the following scenario, and no data is picked up if the method where the client methods being called inside is not annotated (instrumented). I think part of the goal of the instrumentation is to allow customers to collect tracing for these methods without having to manually instrument.

Example (not picked up without using BackgroundTask):

async def main():
    ...
        
    zeebe_client = ZeebeClient(grpc_channel)
    await zeebe_client.deploy_resource('send-mail.bpmn')

asyncio.run(main())

task_type = getattr(job, "type", None) or "UnknownType"
txn_name = f"{process_id}/{task_type}"

with BackgroundTask(application_instance(), txn_name, group="ZeebeTask"):
Copy link
Contributor

Choose a reason for hiding this comment

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

We may want to swap the background task here with an actual WebTransaction.

Copy link
Author

Choose a reason for hiding this comment

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

Pyzeebe Workers/Tasks communicate via gRPC and are basically asyncio background tasks - wouldn't BackgroundTask be the appropriate type to use here?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants