diff --git a/README.md b/README.md index 7ec97de0e4ea2596220ab367a4ebf9ad728ae91b..76d4c47a2eef70d6b7bfea740b162ea2e970c5b5 100644 --- a/README.md +++ b/README.md @@ -23,6 +23,8 @@ Host in Beijing. Go to [demo](http://106.75.237.45:8080/). 1. PDO 1. Mysqli 1. Yar Client ([Yar](https://www.php.net/manual/en/book.yar.php)) +1. Predis Client ([Predis](https://packagist.org/packages/predis/predis)) +1. Redis Extension ([Redis Extension](https://github.com/phpredis/phpredis)) ## Contact Us * Submit an [issue](https://github.com/SkyAPM/SkyAPM-php-sdk/issues) diff --git a/docs/zh/qa.md b/docs/zh/qa.md index 29a972ccd73722a1d9c9ad546b5076782ac0a50c..676c1475d5daec175ac9ddb7865212c76bf5dc1c 100644 --- a/docs/zh/qa.md +++ b/docs/zh/qa.md @@ -20,6 +20,8 @@ * php PDO扩展发出的请求 * php mysqli扩展发出的请求 * php yar扩展(client)发出的请求 + * php redis扩展发出的请求 + * php predis库发出的请求 1. skywalking_get_trace_info()函数的返回值格式? * 返回值为数组。如果扩展加载但是未启用(`skywalking.enable=0`), 则返回空数组 diff --git a/php_skywalking.h b/php_skywalking.h index 4a461dd846d04a7d37ef87397515bafb4481e8ea..dcf6bac7d9fccddbfde06c77db860c32c390f73b 100644 --- a/php_skywalking.h +++ b/php_skywalking.h @@ -151,6 +151,8 @@ static void write_log( char *text); static void request_init(); static void zval_b64_encode(zval *out, char *in); static void zval_b64_decode(zval *out, char *in); +static char *sky_redis_fnamewall(const char *function_name); +static int sky_redis_opt_for_string_key(char *fnamewall); void sky_curl_exec_handler(INTERNAL_FUNCTION_PARAMETERS); void sky_curl_setopt_handler(INTERNAL_FUNCTION_PARAMETERS); diff --git a/skywalking.c b/skywalking.c index 9002298ee7a1c04e11f23bf7fc63af5a8a6abe3d..740af6b08a6ebe43596a4e491075f8d0858d66e4 100644 --- a/skywalking.c +++ b/skywalking.c @@ -69,7 +69,6 @@ ZEND_DECLARE_MODULE_GLOBALS(skywalking) static int le_skywalking; static int application_instance = 0; static int application_id = 0; -static int sky_close = 0; static int sky_increment_id = 0; static int cli_debug = 0; @@ -154,6 +153,28 @@ static char *pcre_match(char *pattern, int len, char *subject) { } +static char *sky_redis_fnamewall(const char *function_name) { + char *fnamewall = (char *) emalloc(strlen(function_name) + 3); + sprintf(fnamewall, "|%s|", function_name); + fnamewall = php_strtolower(fnamewall, strlen(fnamewall)); + return fnamewall; +} + +static int sky_redis_opt_for_string_key(char *fnamewall) { + if (strstr(REDIS_KEY_STRING, fnamewall) + || strstr(REDIS_KEY_KEY, fnamewall) + || strstr(REDIS_KEY_HASH, fnamewall) + || strstr(REDIS_KEY_LIST, fnamewall) + || strstr(REDIS_KEY_SET, fnamewall) + || strstr(REDIS_KEY_SORT, fnamewall) + || strstr(REDIS_KEY_HLL, fnamewall) + || strstr(REDIS_KEY_GEO, fnamewall) + ) { + return 1; + } + return 0; +} + ZEND_API void sky_execute_ex(zend_execute_data *execute_data) { if (application_instance == 0) { @@ -205,11 +226,7 @@ ZEND_API void sky_execute_ex(zend_execute_data *execute_data) { smart_str command = {0}; ZEND_HASH_FOREACH_NUM_KEY_VAL(Z_ARRVAL_P(pam), num_key, entry) { - char *fnamewall = (char *) emalloc(strlen(Z_STRVAL_P(fname)) + 3); - sprintf(fnamewall, "|%s|", Z_STRVAL_P(fname)); - - // strtolower for matching redis key - fnamewall = php_strtolower(fnamewall, strlen(fnamewall)); + char *fnamewall = sky_redis_fnamewall(Z_STRVAL_P(fname)); // first params if (num_key == 0) { switch (Z_TYPE_P(entry)) { @@ -219,15 +236,7 @@ ZEND_API void sky_execute_ex(zend_execute_data *execute_data) { smart_str_appends(&command, " "); // string - if (strstr(REDIS_KEY_STRING, fnamewall) - || strstr(REDIS_KEY_KEY, fnamewall) - || strstr(REDIS_KEY_HASH, fnamewall) - || strstr(REDIS_KEY_LIST, fnamewall) - || strstr(REDIS_KEY_SET, fnamewall) - || strstr(REDIS_KEY_SORT, fnamewall) - || strstr(REDIS_KEY_HLL, fnamewall) - || strstr(REDIS_KEY_GEO, fnamewall) - ) { // add tag key + if (sky_redis_opt_for_string_key(fnamewall) == 1) { // add tag key add_assoc_string(&tags, "redis.key", Z_STRVAL_P(entry)); } else if (strstr(REDIS_OPERATION_STRING, fnamewall)) { // add tag operation add_assoc_string(&tags, "redis.operation", Z_STRVAL_P(entry)); @@ -304,7 +313,7 @@ ZEND_API void sky_execute_ex(zend_execute_data *execute_data) { ZEND_API void sky_execute_internal(zend_execute_data *execute_data, zval *return_value) { - if (sky_close == 1) { + if (application_instance == 0) { if (ori_execute_internal) { ori_execute_internal(execute_data, return_value); } else { @@ -375,6 +384,18 @@ ZEND_API void sky_execute_internal(zend_execute_data *execute_data, zval *return } } } + } else if (strcmp(class_name, "Redis") == 0 || strcmp(class_name, "RedisCluster") == 0) { + char *fnamewall = sky_redis_fnamewall(function_name); + if (sky_redis_opt_for_string_key(fnamewall) == 1) { + componentId = COMPONENT_JEDIS; + component = (char *) emalloc(strlen("Redis") + 1); + strcpy(component, "Redis"); + operationName = (char *) emalloc(strlen(class_name) + strlen(function_name) + 3); + strcpy(operationName, class_name); + strcat(operationName, "->"); + strcat(operationName, function_name); + } + efree(fnamewall); } } else if (function_name != NULL) { if (strcmp(function_name, "mysqli_query") == 0) { @@ -513,6 +534,39 @@ ZEND_API void sky_execute_internal(zend_execute_data *execute_data, zval *return } } } + } else if (strcmp(class_name, "Redis") == 0 || strcmp(class_name, "RedisCluster") == 0) { + add_assoc_string(&tags, "db.type", "redis"); + uint32_t arg_count = ZEND_CALL_NUM_ARGS(execute_data); + + smart_str command = {0}; + smart_str_appends(&command, php_strtolower((char *) function_name, strlen((char *) function_name))); + smart_str_appends(&command, " "); + + int is_string_command = 1; + int i; + for (i = 1; i < arg_count + 1; ++i) { + zval *p = ZEND_CALL_ARG(execute_data, i); + if (Z_TYPE_P(p) == IS_ARRAY) { + is_string_command = 0; + break; + } + if (Z_TYPE_P(p) != IS_STRING) { + convert_to_string(p); + } + if (i == 1) { + add_assoc_string(&tags, "redis.key", Z_STRVAL_P(p)); + } + smart_str_appends(&command, php_strtolower(Z_STRVAL_P(p), Z_STRLEN_P(p))); + smart_str_appends(&command, " "); + } + // store command to tags + if (command.s) { + smart_str_0(&command); + if (is_string_command) { + add_assoc_string(&tags, "redis.command", ZSTR_VAL(php_trim(command.s, NULL, 0, 3))); + } + smart_str_free(&command); + } } zval temp; @@ -578,7 +632,7 @@ ZEND_API void sky_execute_internal(zend_execute_data *execute_data, zval *return void sky_curl_exec_handler(INTERNAL_FUNCTION_PARAMETERS) { - if(sky_close == 1) { + if(application_instance == 0) { orig_curl_exec(INTERNAL_FUNCTION_PARAM_PASSTHRU); return; } @@ -817,7 +871,7 @@ void sky_curl_exec_handler(INTERNAL_FUNCTION_PARAMETERS) } void sky_curl_setopt_handler(INTERNAL_FUNCTION_PARAMETERS) { - if(sky_close == 1) { + if(application_instance == 0) { orig_curl_setopt(INTERNAL_FUNCTION_PARAM_PASSTHRU); return; } @@ -847,7 +901,7 @@ void sky_curl_setopt_handler(INTERNAL_FUNCTION_PARAMETERS) { void sky_curl_setopt_array_handler(INTERNAL_FUNCTION_PARAMETERS) { - if(sky_close == 1) { + if(application_instance == 0) { orig_curl_setopt_array(INTERNAL_FUNCTION_PARAM_PASSTHRU); return; } @@ -874,7 +928,7 @@ void sky_curl_setopt_array_handler(INTERNAL_FUNCTION_PARAMETERS) { void sky_curl_close_handler(INTERNAL_FUNCTION_PARAMETERS) { - if(sky_close == 1) { + if(application_instance == 0) { orig_curl_close(INTERNAL_FUNCTION_PARAM_PASSTHRU); return; } @@ -1564,10 +1618,7 @@ PHP_RINIT_FUNCTION(skywalking) } sky_register(); if (application_instance == 0) { - sky_close = 1; return SUCCESS; - } else { - sky_close = 0; } sky_increment_id++; if (sky_increment_id >= 9999) { @@ -1589,7 +1640,7 @@ PHP_RSHUTDOWN_FUNCTION(skywalking) if (strcasecmp("cli", sapi_module.name) == 0 && cli_debug == 0) { return SUCCESS; } - if (sky_close == 1) { + if (application_instance == 0) { return SUCCESS; } sky_flush_all();