Skip to content

Commit

Permalink
Registration of fake opentelemetry extension to pass its existence ch…
Browse files Browse the repository at this point in the history
…ecks (#83)
  • Loading branch information
intuibase authored Sep 9, 2024
1 parent 0484fc9 commit 9ab4a4e
Show file tree
Hide file tree
Showing 5 changed files with 88 additions and 6 deletions.
11 changes: 11 additions & 0 deletions prod/native/extension/code/InternalFunctionInstrumentation.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -313,6 +313,17 @@ bool instrumentFunction(LoggerInterface *log, std::string_view cName, std::strin
auto ce = static_cast<zend_class_entry *>(zend_hash_str_find_ptr(EG(class_table), className.data(), className.length()));
if (!ce) {
ELOG_DEBUG(log, "instrumentFunction Class not found. Function " PRsv "::" PRsv " not found and cannot be instrumented.", PRsvArg(className), PRsvArg(functionName));

if (log->doesMeetsLevelCondition(logLevel_trace)) {
zend_string *argStrKey = nullptr;
ZEND_HASH_FOREACH_STR_KEY(EG(class_table), argStrKey) {
if (argStrKey) {
ELOG_DEBUG(log, "instrumentFunction Class not found. Function " PRsv "::" PRsv " not found and cannot be instrumented. %s", PRsvArg(className), PRsvArg(functionName), ZSTR_VAL(argStrKey));
}
}
ZEND_HASH_FOREACH_END();
}

return false;
}

Expand Down
21 changes: 21 additions & 0 deletions prod/native/extension/code/ModuleEntry.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -126,6 +126,22 @@ PHP_GSHUTDOWN_FUNCTION(elastic_otel) {
// }
}

zend_module_entry elastic_otel_fake = {STANDARD_MODULE_HEADER,
"opentelemetry", /* Extension name */
nullptr, /* zend_function_entry */
nullptr, /* PHP_MINIT - Module initialization */
nullptr, /* PHP_MSHUTDOWN - Module shutdown */
nullptr, /* PHP_RINIT - Request initialization */
nullptr, /* PHP_RSHUTDOWN - Request shutdown */
nullptr, /* PHP_MINFO - Module info */
"2.0", /* Version */
0, /* globals size */
nullptr, /* PHP_MODULE_GLOBALS */
nullptr, /* PHP_GINIT */
nullptr, /* PHP_GSHUTDOWN */
nullptr, /* post deactivate */
STANDARD_MODULE_PROPERTIES_EX};

PHP_MINIT_FUNCTION(elastic_otel) {
REGISTER_LONG_CONSTANT("ELASTIC_OTEL_LOG_LEVEL_OFF", logLevel_off, CONST_CS | CONST_PERSISTENT);
REGISTER_LONG_CONSTANT("ELASTIC_OTEL_LOG_LEVEL_CRITICAL", logLevel_critical, CONST_CS | CONST_PERSISTENT);
Expand All @@ -136,6 +152,11 @@ PHP_MINIT_FUNCTION(elastic_otel) {
REGISTER_LONG_CONSTANT("ELASTIC_OTEL_LOG_LEVEL_TRACE", logLevel_trace, CONST_CS | CONST_PERSISTENT);

elasticApmModuleInit(type, module_number);

if (!zend_register_internal_module(&elastic_otel_fake)) {
ELOG_WARNING(ELASTICAPM_G(globals)->logger_, "Unable to create artificial opentelemetry extension. There might be stability issues.");
}

return SUCCESS;
}

Expand Down
14 changes: 8 additions & 6 deletions prod/native/extension/code/ModuleFunctions.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -178,12 +178,13 @@ PHP_FUNCTION(elastic_otel_hook) {
std::string_view className = class_name ? std::string_view{ZSTR_VAL(class_name), ZSTR_LEN(class_name)} : std::string_view{};
std::string_view functionName = function_name ? std::string_view{ZSTR_VAL(function_name), ZSTR_LEN(function_name)} : std::string_view{};

if (!EAPM_GL(requestScope_)->isFunctional()) {
ELOG_DEBUG(EAPM_GL(logger_), "elastic_otel_hook. Can't instrument " PRsv "::" PRsv " beacuse agent is not functional.", PRsvArg(className), PRsvArg(functionName));
return;
}
// if (!EAPM_GL(requestScope_)->isFunctional()) {
// ELOG_DEBUG(EAPM_GL(logger_), "elastic_otel_hook. Can't instrument " PRsv "::" PRsv " beacuse agent is not functional.", PRsvArg(className), PRsvArg(functionName));
// RETURN_BOOL(false);
// return;
// }

elasticapm::php::instrumentFunction(EAPM_GL(logger_).get(), className, functionName, pre, post);
RETURN_BOOL(elasticapm::php::instrumentFunction(EAPM_GL(logger_).get(), className, functionName, pre, post));
}

// clang-format off
Expand All @@ -195,7 +196,8 @@ const zend_function_entry elastic_otel_functions[] = {
PHP_FE( elastic_otel_get_last_thrown, elastic_otel_get_last_thrown_arginfo )
PHP_FE( elastic_otel_get_last_php_error, elastic_otel_get_last_php_error_arginfo )
PHP_FE( elastic_otel_hook, elastic_otel_hook_arginfo )
// ZEND_NS_FE("OpenTelemetry\\Instrumentation", hook, arginfo_OpenTelemetry_Instrumentation_hook) ZEND_FE_END,

// ZEND_NS_FALIAS("OpenTelemetry\\Instrumentation", hook, elastic_otel_hook, elastic_otel_hook_arginfo) ZEND_FE_END,

PHP_FE_END
};
Expand Down
11 changes: 11 additions & 0 deletions prod/native/extension/phpt/tests/includes/test_class.inc
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
<?php

class TestClass {
function userspace($arg1, $arg2, $arg3) {
echo "* userspace() body start.\n";
echo "args:\n";
var_dump(func_get_args());
echo "* userspace() body end\n";
return "userspace_rv";
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
--TEST--
instrumentation - user method - retry to instrument after class loads
--ENV--
ELASTIC_OTEL_LOG_LEVEL_STDERR=INFO
--INI--
extension=/elastic/elastic_otel_php.so
elastic_otel.bootstrap_php_part_file={PWD}/includes/bootstrap_mock.inc
--FILE--
<?php
declare(strict_types=1);

echo "Hooking class doesn't exist:".PHP_EOL;

var_dump(elastic_otel_hook("testclass", "userspace", function () {
echo "*** prehook userspace()\n";
}, function () : string {
echo "*** posthook userspace()\n";
}));

require("includes/test_class.inc");

echo "Hooking class loaded:".PHP_EOL;

var_dump(elastic_otel_hook("testclass", "userspace", function () {
echo "*** prehook userspace()\n";
}, function () : string {
echo "*** posthook userspace()\n";
}));

echo "Test completed\n";
?>
--EXPECTF--
Hooking class doesn't exist:
bool(false)
Hooking class loaded:
bool(true)
Test completed

0 comments on commit 9ab4a4e

Please sign in to comment.