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

Package manual Instrumentation part as a "pure" PHP library #119

Closed
SergeyKleyman opened this issue Aug 10, 2020 · 4 comments
Closed

Package manual Instrumentation part as a "pure" PHP library #119

SergeyKleyman opened this issue Aug 10, 2020 · 4 comments

Comments

@SergeyKleyman
Copy link
Contributor

SergeyKleyman commented Aug 10, 2020

This issue is to cover the use case when the user cannot deploy the agent as a PHP extension on production server (for example because the user doesn't have admin rights on production server) - this deployment option should allow the user to effectively "bundle" the agent with the monitored application and thus won't require the PHP extension part of the agent. The trade-off is that this approach won't support automatically creating events for the scenarios relying on extension (for example automatically beginning/end transaction for each request, spans for HTTP/DB operations, etc.)

This issue is related but it's not the same as #4 - while #4 is about exposing a public API when agent is deployed as PHP extension, this issue is about the agent exposing the same public API but with alternative deployment approach.

Implementation details

The main effort here is setting up PHP code under src/ElasticApm (probably excluding all the code related to automatic instrumentation and interaction with C extension part of the agent - for example src/ElasticApm/AutoInstrument and src/ElasticApm/Impl/AutoInstrument) and publishing it at http://packagist.org/.

Clash of PHP files from the extension and from the agent-as-a-library

There is a potential issue of a clash if both the extension is used and application tries to load the agent-as-a-library.
Background: the extension (i.e., the C part of the agent, the code under src/ext) serves mainly as thin bootstrapping layer for the PHP part of the agent (the code under src/ElasticApm) but it's the PHP part of the agent that contains all the "business logic" of the agent.
So the PHP part will be packaged as agent-as-a-library. But now we might have a problem: - if the extension is enabled in php.ini and the application's composer.json having direct/indirect dependency on agent-as-a-library composer package then
the same set of PHP classes (the "business logic" of the agent) is available from two sources:

  1. From autoloader registered when the extension bootstrapped the PHP part.
  2. From Composer's autoloader for agent-as-a-library package.

First we need to decide what should be the outcome if both the extension is used and application has dependency on the agent-as-a-library. Ideally if the version of agent's "business logic" bootstrapped by the extension is "compatible" with the application's agent-as-a-library then we should just have application use the agent's "business logic" bootstrapped by the extension. Of course, "compatible" might be hard to define in this case. The public API might be compatible but maybe agent-as-a-library version (let's say 1.1.9) has some bug fixed in the implementation that is not fixed yet in the version bootstrapped by the extension (let's say 1.2.1 and bug fixed only in 1.2.2 and the fix was backported to 1.1.9).

Possible ways to prevent source from agent-as-a-library from being loaded if extension is already loaded:

  1. Instead of using autoloader (thus only loading agent's classes on demand) approach when bootstrapping PHP part from the extension we can eagerly require all the files under src/ElasticApm and thus preventing source from agent-as-a-library package to be mixed in because bootstrapping by the extension occurs at much earlier stage than application registering Composer's autoloader
  2. Maybe the extension can hook up into PHP's autoloading and ensure that classes from Elastic\Apm\* namespaces are loaded only from location configured by elastic_apm.bootstrap_php_part_file?
  3. Maybe there's a way we can hook up into Composer loading sequence and prevent agent-as-a-library from loading if the extension is already loaded?

Adding some automatic capturing to agent-as-a-library

Agent-as-a-library doesn't have to be strictly "manual-only" capture - even without access to hooks available to PHP extension (the C part of the agent) we might still be able to have some automatic capture. For example, @ezimuel implemented POC based Go! AOP PHP framework to intercept a function execution. This kind of follow-up to this issue is extracted to #63.

@belkone
Copy link

belkone commented Aug 20, 2020

+1

the above approach may also enable possibility to use apm agent on environments using ionCube Loader.

@science695
Copy link

Could the agent-as-a-library easily detect if the c functions are available, and if so, the methods just shim to the c versions? (this may be what you are saying by hooking into composer)

@SergeyKleyman
Copy link
Contributor Author

SergeyKleyman commented Aug 21, 2020

Could the agent-as-a-library easily detect if the c functions are available, and if so, the methods just shim to the c versions? (this may be what you are saying by hooking into composer)

No exactly - I've edited the initial comment to clarify the context in which I mentioned "hooking into composer" - that mention was only to solve "same PHP classes can be autoloaded from the extension and from agent-as-a-library" issue.

IIUC you refer to "manual only" limitation of agent-as-a-library approach - I've added "Adding some automatic capturing to agent-as-a-library" section to the initial comment to clarify that indeed it doesn't have to be so - we might still have some automatic capturing even with agent-as-a-library approach.

@SergeyKleyman
Copy link
Contributor Author

There is OpenTelemetry now that can accomplish this so we are closing it for now.

@SergeyKleyman SergeyKleyman closed this as not planned Won't fix, can't repro, duplicate, stale Jul 18, 2023
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

No branches or pull requests

3 participants