未验证 提交 d8460ed0 编写于 作者: 何延龙 提交者: GitHub

Merge pull request #88 from bostin/feature/bostin_20190719

添加中文文档;Skywalking扩展及Agent修改;添加对PHP 7.3.0+的支持
...@@ -7,6 +7,7 @@ SkyAPM PHP ...@@ -7,6 +7,7 @@ SkyAPM PHP
## Documents ## Documents
* [Documents in English](docs/README.md) * [Documents in English](docs/README.md)
* [中文文档](docs/README_ZH.md)
## Live Demo ## Live Demo
Host in Beijing. Go to [demo](http://106.75.237.45:8080/). Host in Beijing. Go to [demo](http://106.75.237.45:8080/).
......
文档
=====
* [更改记录](./zh/change-log.md)
* [安装php扩展](./zh/install-sdk.md)
* [启动agent](./zh/start-agent.md)
* [常见问题](./zh/qa.md)
\ No newline at end of file
# 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配置项
3. 新增 skywalking.sock_path 配置项,支持自定义sock文件的路径
# 环境
PHP7+
# 安装
## 安装PHP的SkyWalking扩展(Ubuntu环境)
1.安装php-dev (具体的PHP版本以你的环境为准,必须php7+)
```shell
sudo apt install php7.2-dev
```
2.安装curl开发包
```shell
sudo apt install curl-dev
```
3.git clone 源码
```shell
git clone https://github.com/SkyAPM/SkyAPM-php-sdk.git /path/to/SkyAPM-php-sdk
```
4.编译安装SkyAPM-php-sdk
```shell
cd /path/to/SkyAPM-php-sdk
phpize
./configure
make
sudo make install
```
5.新建php的skywalking扩展配置文件,写入配置
```shell
# 扩展so
extension=skywalking.so
# 是否启用:0 关闭;1 启用 (默认值为0)
skywalking.enable=1
# skywalking的版本:5或者6(默认值为6)
skywalking.version=6
# app_code代码,不要含特殊字符,请使用数字、字母、下换线。(默认为:hello_skywalking)
skywalking.app_code=dada_www_001
# sock文件路径(默认值为/tmp/sky_agent.sock)
skywalking.sock_path=/tmp/sky_agent.sock
```
6.重启php-fpm服务
```shell
sudo service php-fpm restart
```
7.查看skywalking扩展是否成功加载
```shell
php -m | grep skywalking
```
查看具体配置,请使用`php -i`或者`phpinfo()`函数
# 常见问题
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`
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=`
* 值中`distributedTraceId`即下方的`globalTraceIds[0]`的取值
3.会传递trace信息的请求类型有哪些?
* php curl扩展发出的请求
* php PDO扩展发出的请求
4.skywalking_get_trace_info()函数的返回值格式?
* 返回值为数组。如果扩展加载但是未启用(`skywalking.enable=0`), 则返回空数组
```php
# skywalking_get_trace_info 返回值格式如下:
[
'application_instance' => 94,
'pid' => 22230,
'application_id' => 29,
'version' => 6,
'segment' => [
'traceSegmentId' => '94.22412.15629106130002',
'isSizeLimited' => 0,
'spans' => [
[
'tags' => [
'url' => '/index.php?id=123'
],
'spanId' => 0,
'parentSpanId' => -1,
'startTime' => 1562910613896,
'operationName' => '/index.php',
'peer' => '127.0.0.1:80',
'spanType' => 0,
'spanLayer' => 3,
'componentId' => 2,
'refs' => [
[
'type' => 0,
'parentTraceSegmentId' => '94.22412.15629106130002',
'parentSpanId' => 1,
'parentApplicationInstanceId' => 94,
'networkAddress' => ':443',
'entryApplicationInstanceId' => 94,
'entryServiceName' => 'index.php?to=123',
'parentServiceName' => '',
],
],
],
],
],
'globalTraceIds' => [
'94.22235.15629108530003',
],
]
```
\ No newline at end of file
# 启动agent
1.选择你的操作系统对应的agent应用程序
darwin指MacOS操作系统, linux指Linux操作系统
x64/x86分别指64位操作系统/32位操作系统
```
sky_php_agent_darwin_x64
sky_php_agent_darwin_x86
sky_php_agent_linux_x64
sky_php_agent_linux_x86
sky_php_agent_linux_arm64
sky_php_agent_linux_arm86
```
2.启动agent(以 Ubuntu x64 平台示例)
```shell
# 添加可执行权限
sudo chmod +x ./sky_php_agent_linux_x64
# 启动
./sky_php_agent_linux_x64 -grpc=127.0.0.1:11800 -sock=/tmp/sky_agent.sock
```
3.agent 参数说明
* `-grpc` 后面为SkyWalking服务端的GRPC地址
* `-sock` 后面为sock文件的绝对路径,必须与php中skywalking.sock_path的路径一致。默认值为:`/tmp/sky_agent.sock`
* `-h` 可查看帮助信息
...@@ -8,10 +8,7 @@ ...@@ -8,10 +8,7 @@
[skywalking] [skywalking]
skywalking.app_code = api skywalking.app_code = hello_skywalking
skywalking.sampling_rate = 99.22; skywalking.enable = 0
skywalking.log_path = /tmp/log skywalking.version = 6
skywalking.header_client_ip_name = HTTP_DD_REAL_IP skywalking.sock_path = /tmp/sky_agent.sock
skywalking.auto_open = On \ No newline at end of file
skywalking.send_type = 1
skywalking.grpc_trace = 127.0.0.1:50051
\ No newline at end of file
...@@ -170,10 +170,9 @@ static void (*orig_curl_close)(INTERNAL_FUNCTION_PARAMETERS) = NULL; ...@@ -170,10 +170,9 @@ static void (*orig_curl_close)(INTERNAL_FUNCTION_PARAMETERS) = NULL;
and END macros here: and END macros here:
*/ */
ZEND_BEGIN_MODULE_GLOBALS(skywalking) ZEND_BEGIN_MODULE_GLOBALS(skywalking)
char *log_path; char *sock_path;
char *app_code; char *app_code;
zend_bool enable; zend_bool enable;
char *grpc;
zval UpstreamSegment; zval UpstreamSegment;
zval context; zval context;
zval curl_header; zval curl_header;
......
...@@ -67,7 +67,7 @@ static int application_id = 0; ...@@ -67,7 +67,7 @@ static int application_id = 0;
static int sky_close = 0; static int sky_close = 0;
static int sky_increment_id = 0; static int sky_increment_id = 0;
static int cli_debug = 0; static int cli_debug = 0;
const char *sock_path = "/tmp/sky_agent.sock"; static char *sock_path = "/tmp/sky_agent.sock";
static void (*ori_execute_ex)(zend_execute_data *execute_data); static void (*ori_execute_ex)(zend_execute_data *execute_data);
static void (*ori_execute_internal)(zend_execute_data *execute_data, zval *return_value); static void (*ori_execute_internal)(zend_execute_data *execute_data, zval *return_value);
...@@ -81,17 +81,35 @@ PHP_INI_BEGIN() ...@@ -81,17 +81,35 @@ PHP_INI_BEGIN()
STD_PHP_INI_BOOLEAN("skywalking.enable", "0", PHP_INI_ALL, OnUpdateBool, enable, zend_skywalking_globals, skywalking_globals) STD_PHP_INI_BOOLEAN("skywalking.enable", "0", PHP_INI_ALL, OnUpdateBool, enable, zend_skywalking_globals, skywalking_globals)
STD_PHP_INI_ENTRY("skywalking.version", "6", PHP_INI_ALL, OnUpdateLong, version, zend_skywalking_globals, skywalking_globals) STD_PHP_INI_ENTRY("skywalking.version", "6", PHP_INI_ALL, OnUpdateLong, version, zend_skywalking_globals, skywalking_globals)
STD_PHP_INI_ENTRY("skywalking.app_code", "hello_skywalking", PHP_INI_ALL, OnUpdateString, app_code, zend_skywalking_globals, skywalking_globals) STD_PHP_INI_ENTRY("skywalking.app_code", "hello_skywalking", PHP_INI_ALL, OnUpdateString, app_code, zend_skywalking_globals, skywalking_globals)
STD_PHP_INI_ENTRY("skywalking.log_path", "/tmp", PHP_INI_ALL, OnUpdateString, log_path, zend_skywalking_globals, skywalking_globals) STD_PHP_INI_ENTRY("skywalking.sock_path", "/tmp/sky_agent.sock", PHP_INI_ALL, OnUpdateString, sock_path, zend_skywalking_globals, skywalking_globals)
STD_PHP_INI_ENTRY("skywalking.grpc", "127.0.0.1:11800", PHP_INI_ALL, OnUpdateString, grpc, zend_skywalking_globals, skywalking_globals)
PHP_INI_END() PHP_INI_END()
/* }}} */ /* }}} */
// declare args for skywalking_get_trace_info()
ZEND_BEGIN_ARG_INFO(arginfo_skywalking_get_trace_info, 0)
ZEND_END_ARG_INFO()
// declare function skywalking_get_trace_info()
PHP_FUNCTION(skywalking_get_trace_info)
{
if (application_instance == 0) {
zval empty;
array_init(&empty);
RETURN_ZVAL(&empty, 0, 1);
}
// return array
RETURN_ZVAL(&SKYWALKING_G(UpstreamSegment), 1, 0)
}
/* {{{ skywalking_functions[] /* {{{ skywalking_functions[]
* *
* Every user visible function must have an entry in skywalking_functions[]. * Every user visible function must have an entry in skywalking_functions[].
*/ */
const zend_function_entry skywalking_functions[] = { const zend_function_entry skywalking_functions[] = {
PHP_FE(skywalking_get_trace_info, arginfo_skywalking_get_trace_info)
PHP_FE_END /* Must be the last line in skywalking_functions[] */ PHP_FE_END /* Must be the last line in skywalking_functions[] */
}; };
/* }}} */ /* }}} */
...@@ -414,20 +432,35 @@ void sky_curl_exec_handler(INTERNAL_FUNCTION_PARAMETERS) ...@@ -414,20 +432,35 @@ void sky_curl_exec_handler(INTERNAL_FUNCTION_PARAMETERS)
ssize_t full_url_l = 0; ssize_t full_url_l = 0;
char *full_url = NULL; char *full_url = NULL;
if (is_send == 1) { if (is_send == 1) {
// for php7.3.0+
#if PHP_VERSION_ID >= 70300
char *php_url_scheme = ZSTR_VAL(url_info->scheme);
char *php_url_host = ZSTR_VAL(url_info->host);
char *php_url_path = ZSTR_VAL(url_info->path);
char *php_url_query = ZSTR_VAL(url_info->query);
#else
char *php_url_scheme = url_info->scheme;
char *php_url_host = url_info->host;
char *php_url_path = url_info->path;
char *php_url_query = url_info->query;
#endif
int peer_port = 0; int peer_port = 0;
if (url_info->port) { if (url_info->port) {
peer_port = url_info->port; peer_port = url_info->port;
} else { } else {
if (strcasecmp("http", url_info->scheme) == 0) { if (strcasecmp("http", php_url_scheme) == 0) {
peer_port = 80; peer_port = 80;
} else { } else {
peer_port = 443; peer_port = 443;
} }
} }
peer = (char *) emalloc(strlen(url_info->scheme) + 3 + strlen(url_info->host) + 7); peer = (char *) emalloc(strlen(php_url_scheme) + 3 + strlen(php_url_host) + 7);
bzero(peer, strlen(url_info->scheme) + 3 + strlen(url_info->host) + 7); bzero(peer, strlen(php_url_scheme) + 3 + strlen(php_url_host) + 7);
if (url_info->query) { if (url_info->query) {
if (url_info->path == NULL) { if (url_info->path == NULL) {
...@@ -436,20 +469,20 @@ void sky_curl_exec_handler(INTERNAL_FUNCTION_PARAMETERS) ...@@ -436,20 +469,20 @@ void sky_curl_exec_handler(INTERNAL_FUNCTION_PARAMETERS)
bzero(operation_name, operation_name_l + 1); bzero(operation_name, operation_name_l + 1);
sprintf(operation_name, "%s", "/"); sprintf(operation_name, "%s", "/");
full_url_l = snprintf(NULL, 0, "%s?%s", "/", url_info->query); full_url_l = snprintf(NULL, 0, "%s?%s", "/", php_url_query);
full_url = (char *) emalloc(full_url_l + 1); full_url = (char *) emalloc(full_url_l + 1);
bzero(full_url, full_url_l + 1); bzero(full_url, full_url_l + 1);
sprintf(full_url, "%s?%s", "/", url_info->query); sprintf(full_url, "%s?%s", "/", php_url_query);
} else { } else {
operation_name_l = snprintf(NULL, 0, "%s", url_info->path); operation_name_l = snprintf(NULL, 0, "%s", php_url_path);
operation_name = (char *) emalloc(operation_name_l + 1); operation_name = (char *) emalloc(operation_name_l + 1);
bzero(operation_name, operation_name_l + 1); bzero(operation_name, operation_name_l + 1);
sprintf(operation_name, "%s", url_info->path); sprintf(operation_name, "%s", php_url_path);
full_url_l = snprintf(NULL, 0, "%s?%s", url_info->path, url_info->query); full_url_l = snprintf(NULL, 0, "%s?%s", php_url_path, php_url_query);
full_url = (char *) emalloc(full_url_l + 1); full_url = (char *) emalloc(full_url_l + 1);
bzero(full_url, full_url_l + 1); bzero(full_url, full_url_l + 1);
sprintf(full_url, "%s?%s", url_info->path, url_info->query); sprintf(full_url, "%s?%s", php_url_path, php_url_query);
} }
} else { } else {
if (url_info->path == NULL) { if (url_info->path == NULL) {
...@@ -463,15 +496,15 @@ void sky_curl_exec_handler(INTERNAL_FUNCTION_PARAMETERS) ...@@ -463,15 +496,15 @@ void sky_curl_exec_handler(INTERNAL_FUNCTION_PARAMETERS)
bzero(full_url, full_url_l + 1); bzero(full_url, full_url_l + 1);
sprintf(full_url, "%s", "/"); sprintf(full_url, "%s", "/");
} else { } else {
operation_name_l = snprintf(NULL, 0, "%s", url_info->path); operation_name_l = snprintf(NULL, 0, "%s", php_url_path);
operation_name = (char *) emalloc(operation_name_l + 1); operation_name = (char *) emalloc(operation_name_l + 1);
bzero(operation_name, operation_name_l + 1); bzero(operation_name, operation_name_l + 1);
sprintf(operation_name, "%s", url_info->path); sprintf(operation_name, "%s", php_url_path);
full_url_l = snprintf(NULL, 0, "%s", url_info->path); full_url_l = snprintf(NULL, 0, "%s", php_url_path);
full_url = (char *) emalloc(full_url_l + 1); full_url = (char *) emalloc(full_url_l + 1);
bzero(full_url, full_url_l + 1); bzero(full_url, full_url_l + 1);
sprintf(full_url, "%s", url_info->path); sprintf(full_url, "%s", php_url_path);
} }
} }
...@@ -479,10 +512,10 @@ void sky_curl_exec_handler(INTERNAL_FUNCTION_PARAMETERS) ...@@ -479,10 +512,10 @@ void sky_curl_exec_handler(INTERNAL_FUNCTION_PARAMETERS)
last_span = zend_hash_index_find(Z_ARRVAL_P(spans), zend_hash_num_elements(Z_ARRVAL_P(spans)) - 1); last_span = zend_hash_index_find(Z_ARRVAL_P(spans), zend_hash_num_elements(Z_ARRVAL_P(spans)) - 1);
span_id = zend_hash_str_find(Z_ARRVAL_P(last_span), "spanId", sizeof("spanId") - 1); span_id = zend_hash_str_find(Z_ARRVAL_P(last_span), "spanId", sizeof("spanId") - 1);
if (SKYWALKING_G(version) == 5) { // skywalking 5.x if (SKYWALKING_G(version) == 5) { // skywalking 5.x
sprintf(peer, "%s://%s:%d", url_info->scheme, url_info->host, peer_port); sprintf(peer, "%s://%s:%d", php_url_scheme, php_url_host, peer_port);
sw = generate_sw3(Z_LVAL_P(span_id) + 1, peer, operation_name); sw = generate_sw3(Z_LVAL_P(span_id) + 1, peer, operation_name);
} else if (SKYWALKING_G(version) == 6) { // skywalking 6.x } else if (SKYWALKING_G(version) == 6) { // skywalking 6.x
sprintf(peer, "%s:%d", url_info->host, peer_port); sprintf(peer, "%s:%d", php_url_host, peer_port);
sw = generate_sw6(Z_LVAL_P(span_id) + 1, peer, operation_name); sw = generate_sw6(Z_LVAL_P(span_id) + 1, peer, operation_name);
} }
} }
...@@ -673,10 +706,9 @@ void sky_curl_close_handler(INTERNAL_FUNCTION_PARAMETERS) { ...@@ -673,10 +706,9 @@ void sky_curl_close_handler(INTERNAL_FUNCTION_PARAMETERS) {
static void php_skywalking_init_globals(zend_skywalking_globals *skywalking_globals) static void php_skywalking_init_globals(zend_skywalking_globals *skywalking_globals)
{ {
skywalking_globals->app_code = NULL; skywalking_globals->app_code = NULL;
skywalking_globals->log_path = NULL;
skywalking_globals->enable = 0; skywalking_globals->enable = 0;
skywalking_globals->version = 6; skywalking_globals->version = 6;
skywalking_globals->grpc = NULL; skywalking_globals->sock_path = "/tmp/sky_agent.sock";
} }
...@@ -703,30 +735,11 @@ static char *sky_json_encode(zval *parameter){ ...@@ -703,30 +735,11 @@ static char *sky_json_encode(zval *parameter){
static void write_log(char *text) { static void write_log(char *text) {
if (application_instance != 0) { if (application_instance != 0) {
// to file
// char *log_path;
// char logFilename[100];
// char message[strlen(text) + 1];
// log_path = SKY_G(log_path);
//
// zend_string *_log_path, *_log_path_lower;
// _log_path = zend_string_init(log_path, strlen(log_path), 0);
// _log_path_lower = php_string_tolower(_log_path);
//
// bzero(logFilename, 100);
// sprintf(logFilename, "%s/skywalking.%d-%d.log", ZSTR_VAL(_log_path_lower), get_second(), getpid());
//
// zend_string_release(_log_path);
// zend_string_release(_log_path_lower);
// bzero(message, strlen(text));
// sprintf(message, "%s\n", text);
// _php_error_log_ex(3, message, strlen(message), logFilename, NULL);
// to stream // to stream
struct sockaddr_un un; struct sockaddr_un un;
un.sun_family = AF_UNIX; un.sun_family = AF_UNIX;
strcpy(un.sun_path, sock_path); strcpy(un.sun_path, SKYWALKING_G(sock_path));
int fd; int fd;
char message[strlen(text) + 2]; char message[strlen(text) + 2];
...@@ -1235,7 +1248,7 @@ static int sky_register() { ...@@ -1235,7 +1248,7 @@ static int sky_register() {
if (application_instance == 0) { if (application_instance == 0) {
struct sockaddr_un un; struct sockaddr_un un;
un.sun_family = AF_UNIX; un.sun_family = AF_UNIX;
strcpy(un.sun_path, sock_path); strcpy(un.sun_path, SKYWALKING_G(sock_path));
int fd; int fd;
char message[4096]; char message[4096];
char return_message[4096]; char return_message[4096];
...@@ -1387,18 +1400,6 @@ PHP_RSHUTDOWN_FUNCTION(skywalking) ...@@ -1387,18 +1400,6 @@ PHP_RSHUTDOWN_FUNCTION(skywalking)
*/ */
PHP_MINFO_FUNCTION(skywalking) PHP_MINFO_FUNCTION(skywalking)
{ {
php_info_print_table_start();
if (SKYWALKING_G(enable)) {
php_info_print_table_header(2, "SkyWalking Support", "enabled");
} else {
php_info_print_table_header(2, "SkyWalking Support", "disabled");
}
php_info_print_table_header(2, "SkyWalking Agent", "/tmp/sky_agent.sock");
php_info_print_table_end();
DISPLAY_INI_ENTRIES(); DISPLAY_INI_ENTRIES();
} }
/* }}} */ /* }}} */
......
...@@ -7,6 +7,7 @@ import ( ...@@ -7,6 +7,7 @@ import (
"agent/agent/service" "agent/agent/service"
"context" "context"
"encoding/json" "encoding/json"
"flag"
"fmt" "fmt"
"github.com/google/uuid" "github.com/google/uuid"
"google.golang.org/grpc" "google.golang.org/grpc"
...@@ -366,30 +367,41 @@ func heartbeat() { ...@@ -366,30 +367,41 @@ func heartbeat() {
} }
func main() { func main() {
grpcHost := flag.String("grpc", "127.0.0.1:11800", "SkyWalking GRPC Host")
args := os.Args sockPath := flag.String("sock", "/tmp/sky_agent.sock", "SkyWalking PHP SDK sock file path")
flag.Parse()
// connection to sky server // connection to sky server
fmt.Println("hello skywalking") fmt.Println("hello skywalking")
fmt.Println("GRPC Host: ", *grpcHost)
fmt.Println("Sock Path: ", *sockPath)
var err error var err error
grpcConn, err = grpc.Dial(args[1], grpc.WithInsecure()) grpcConn, err = grpc.Dial(*grpcHost, grpc.WithInsecure())
if err != nil { if err != nil {
fmt.Println(err) fmt.Println(err)
} }
defer grpcConn.Close() defer grpcConn.Close()
if err := os.RemoveAll("/tmp/sky_agent.sock"); err != nil { if err := os.RemoveAll(*sockPath); err != nil {
fmt.Println(err) fmt.Println(err)
} }
l, err := net.Listen("unix", "/tmp/sky_agent.sock") l, err := net.Listen("unix", *sockPath)
if err != nil { if err != nil {
fmt.Println("listen error:", err) fmt.Println("listen error:", err)
return return
} }
defer l.Close() defer l.Close()
// change sock file type and mode
err = os.Chmod(*sockPath, os.ModeSocket | 0666)
if err != nil {
fmt.Println("sock file change mod error:", err)
return
}
go heartbeat() go heartbeat()
for { for {
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册