diff --git a/README.md b/README.md index 3283a3ae1985ee4cc11437a15bad122cb5025dda..c006cebbf53234673465c1422b30dccabc5edb74 100644 --- a/README.md +++ b/README.md @@ -21,6 +21,7 @@ Host in Beijing. Go to [demo](http://106.75.237.45:8080/). ## Support List 1. CURL 1. PDO +1. Mysqli ## Contact Us * Submit an [issue](https://github.com/SkyAPM/SkyAPM-php-sdk/issues) diff --git a/docs/zh/change-log.md b/docs/zh/change-log.md index 9c6f7c48da2e16ee7923cabf8db6075fa15c2892..168bf907b67f283ad90e05d3a8e52b51fd40f7bc 100644 --- a/docs/zh/change-log.md +++ b/docs/zh/change-log.md @@ -1,10 +1,13 @@ +# 20190722 +## SkyWalking 扩展修改 +1. 支持对mysqli扩展的支持(目前暂时仅支持`mysqli::query()`) + # 20190719 ## Agent 修改 1. agent创建的文件权限修改为0666, 文件的类型修改为sock类型。修复php与sock文件进行通信时提示"Permission Deny"的问题 2. agent的参数接收方式修改, 执行`sky_php_agent -h` 查看可用参数 3. agent支持在参数中指定sock文件的路径 - ## SkyWalking 扩展修改 1. 新增 skywalking_get_trace_info():array 方法,获取trace数据,以方便业务日志获取当前请求trace信息。 2. 删除无用的skywalking.log_path及skywalking.grpc配置项 diff --git a/docs/zh/install-sdk.md b/docs/zh/install-sdk.md index d570563a5522752b7f6201c848d7e44b3b101804..f1134d646c95055518482ab3938c06815065a01a 100644 --- a/docs/zh/install-sdk.md +++ b/docs/zh/install-sdk.md @@ -50,7 +50,7 @@ skywalking.enable=1 # skywalking的版本:5或者6(默认值为6) skywalking.version=6 # app_code代码,不要含特殊字符,请使用数字、字母、下换线。(默认为:hello_skywalking) -skywalking.app_code=dada_www_001 +skywalking.app_code=hello_skywalking # sock文件路径(默认值为/tmp/sky_agent.sock) skywalking.sock_path=/tmp/sky_agent.sock ``` diff --git a/docs/zh/qa.md b/docs/zh/qa.md index 4ad6a26afa2ed41f211d9b15609abd456651ed81..9b20e05771a5671ae50c6fc0069b0d4e7cd07acc 100644 --- a/docs/zh/qa.md +++ b/docs/zh/qa.md @@ -1,27 +1,26 @@ # 常见问题 - -1.linux下php不能读取/tmp文件夹下文件,即php无法与/tmp目录下的sock文件进行通信。 + ----- +1. linux下php不能读取/tmp文件夹下文件,即php无法与/tmp目录下的sock文件进行通信。 该问题一般是由`systemd`服务的`PrivateTmp`属性配置导致的。 `systemd`中服务的配置文件都在目录`/lib/systemd/system/`中: * 检查SELinux配置,可尝试关闭SELinux * `apache`的配置文件为`apache2.service` - * `php-fpm`的配置文件为`php-fpm.service` (可能会存在版本号,例如`php7.2-fpm.service`) - -修改`PrivateTmp`属性的取值为`false`, 再执行`sudo systemctl daemon-reload`, 最后再重启`apache`或者`php-fpm` + * `php-fpm`的配置文件为`php-fpm.service` (可能会存在版本号,例如`php7.2-fpm.service`) + + 修改`PrivateTmp`属性的取值为`false`, 再执行`sudo systemctl daemon-reload`, 最后再重启`apache`或者`php-fpm` - -2.对于已经安装并启用了`SkyWalking`扩展的PHP环境的主机,所发送的trace信息在哪里? - * 如果`skywalking.version=5`, 则`http`请求的`header`中会加入一个名为`SW3`的数据。PHP可使用`$_SERVER['HTTP_SW3']`获取。 - * 如果`skywalking.version=6`, 则`http`请求的`header`中会加入一个名为`SW6`的数据。PHP可使用`$_SERVER['HTTP_SW6']`获取。 - * 值格式为:`1-{distributedTraceIdEncode}-{traceSegmentIdEncode}-{span_id}-{application_instance}-{entryApplicationInstance}-{peerHostEncode}-{entryEndpointNameEncode}-{parentEndpointNameEncode}`, Encode算法为base64_encode()。示例取值为:`1-OTQuMjIyMzUuMTU2MjkxMDg1MzAwMDM=-OTQuMjIyMzUuMTU2MjkxMDg1MzAwMDM=-1-94-94-IwE6NDQz-Iy9pbmRleC5waHA/ZGRkZGRkZA==-IwE=` +1. 对于已经安装并启用了`SkyWalking`扩展的PHP环境的主机,所发送的trace信息在哪里? + * 如果`skywalking.version=5`, 则`http`请求的`header`中会加入一个名为`SW3`的数据。PHP可使用`$_SERVER['HTTP_SW3']`获取。[协议文档](https://github.com/apache/skywalking/blob/master/docs/en/protocols/Skywalking-Cross-Process-Propagation-Headers-Protocol-v1.md) + * 如果`skywalking.version=6`, 则`http`请求的`header`中会加入一个名为`SW6`的数据。PHP可使用`$_SERVER['HTTP_SW6']`获取。[协议文档](https://github.com/apache/skywalking/blob/master/docs/en/protocols/Skywalking-Cross-Process-Propagation-Headers-Protocol-v2.md) + * SW6值格式为:`1-{distributedTraceIdEncode}-{traceSegmentIdEncode}-{span_id}-{application_instance}-{entryApplicationInstance}-{peerHostEncode}-{entryEndpointNameEncode}-{parentEndpointNameEncode}`, Encode算法为base64_encode()。示例取值为:`1-OTQuMjIyMzUuMTU2MjkxMDg1MzAwMDM=-OTQuMjIyMzUuMTU2MjkxMDg1MzAwMDM=-1-94-94-IwE6NDQz-Iy9pbmRleC5waHA/ZGRkZGRkZA==-IwE=` * 值中`distributedTraceId`即下方的`globalTraceIds[0]`的取值 - -3.会传递trace信息的请求类型有哪些? +1. 会传递trace信息的请求类型有哪些? * php curl扩展发出的请求 * php PDO扩展发出的请求 + * php mysqli扩展发出的请求 -4.skywalking_get_trace_info()函数的返回值格式? +1. skywalking_get_trace_info()函数的返回值格式? * 返回值为数组。如果扩展加载但是未启用(`skywalking.enable=0`), 则返回空数组 ```php # skywalking_get_trace_info 返回值格式如下: @@ -65,4 +64,7 @@ '94.22235.15629108530003', ], ] - ``` \ No newline at end of file + ``` + +1. mysqli有过程式风格和对象式风格,上报的数据有何不同? + * 目前扩展仅监控mysqli_query()、mysqli::query()方法, 并记录对应执行的sql, 在上报到oapServer的时候,统一按照mysqli->query()的格式进行上报 \ No newline at end of file diff --git a/skywalking.c b/skywalking.c index 8209fe0b2fc5f83221525decee1538530ffd9324..57973d12b012ebfd70db315763542ad5d8d4c6bf 100644 --- a/skywalking.c +++ b/skywalking.c @@ -248,6 +248,7 @@ ZEND_API void sky_execute_internal(zend_execute_data *execute_data, zval *return zf->common.scope->name) : NULL; const char *function_name = zf->common.function_name == NULL ? NULL : ZSTR_VAL(zf->common.function_name); + int is_procedural_mysqli = 0; // "Procedural style" or "Object oriented style" ? char *operationName = NULL; char *component = NULL; if (class_name != NULL) { @@ -272,8 +273,29 @@ ZEND_API void sky_execute_internal(zend_execute_data *execute_data, zval *return strcat(operationName, "->"); strcat(operationName, function_name); } + } else if (strcmp(class_name, "mysqli") == 0) { + if (strcmp(function_name, "query") == 0) { + component = (char *) emalloc(strlen("mysqli") + 1); + strcpy(component, "mysqli"); + operationName = (char *) emalloc(strlen(class_name) + strlen(function_name) + 3); + strcpy(operationName, class_name); + strcat(operationName, "->"); + strcat(operationName, function_name); + } } } else if (function_name != NULL) { + if (strcmp(function_name, "mysqli_query") == 0) { + class_name = "mysqli"; + function_name = "query"; + component = (char *) emalloc(strlen(class_name) + 1); + strcpy(component, class_name); + operationName = (char *) emalloc(strlen(class_name) + strlen(function_name) + 3); + strcpy(operationName, class_name); + strcat(operationName, "->"); + strcat(operationName, function_name); + + is_procedural_mysqli = 1; + } } if (operationName != NULL) { @@ -323,8 +345,25 @@ ZEND_API void sky_execute_internal(zend_execute_data *execute_data, zval *return add_assoc_string(&tags, "db.data_source", (char *) stmt->dbh->data_source); } } + } else if (function_name != NULL) { + if (strcmp(class_name, "mysqli") == 0 && strcmp(function_name, "query") == 0) { + add_assoc_string(&tags, "db.type", "mysqli"); + // params + uint32_t arg_count = ZEND_CALL_NUM_ARGS(execute_data); + if (arg_count) { + zval *p = is_procedural_mysqli ? ZEND_CALL_ARG(execute_data, 2) : ZEND_CALL_ARG(execute_data, 1); + //db.statement + switch (Z_TYPE_P(p)) { + case IS_STRING: + add_assoc_string(&tags, "db.statement", Z_STRVAL_P(p)); + break; + + } + } + } } + zval temp; zval *spans = NULL; zval *span_id = NULL; @@ -1303,9 +1342,11 @@ PHP_MINIT_FUNCTION (skywalking) { return SUCCESS; } + // 用户自定义函数执行器(php脚本定义的类、函数) ori_execute_ex = zend_execute_ex; zend_execute_ex = sky_execute_ex; + // 内部函数执行器(c语言定义的类、函数) ori_execute_internal = zend_execute_internal; zend_execute_internal = sky_execute_internal;