构建php自己的无浸入式的链路追踪和性能监控

Posted wuxian

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了构建php自己的无浸入式的链路追踪和性能监控相关的知识,希望对你有一定的参考价值。

最近阅读php源码,为了验证效果,写了一个php扩展,主要功能就是打造php自己的链路追踪和性能监控

先从github下载源码 https://github.com/wuxian12/i...

编译安装就可以使用了

现在只是一个基本功能,后面慢慢完善

核心功能就是改写php的执行函数,就是平时经常写的代理

PHP_MINIT_FUNCTION(pid)
{
    REGISTER_INI_ENTRIES();
    ori_execute_ex = zend_execute_ex;
    zend_execute_ex = pid_execute_ex;
    ori_execute_internal = zend_execute_internal;
    zend_execute_internal = pid_execute_internal;

    return SUCCESS;
}

执行时发现是要拦截的函数就获取函数的参数返回值记录日志,继续执行php原始的执行函数

ZEND_API void pid_execute_core(int internal, zend_execute_data *execute_data, zval *return_value)
{
    char *logs_dir = {0};
    char *re_func = {0};
    char *file_log = "trace.log";
    //从php.ini文件读取拦截函数和日志目录
    logs_dir = INI_STR("pid.log_path");
    re_func = INI_STR("pid.function");
    char *name = (char *) malloc(strlen(logs_dir) + strlen(file_log));
    sprintf(name, "%s%s", logs_dir, file_log);
    FILE *fp;
    if((fp = fopen(name, "a+")) == NULL){
        printf("file cannot open \\n");
    }

    zend_function *zf = obtain_zend_function(execute_data);
    int flag = 0;
    char str_1[512] = {0};
    char *token;
    const char s[2] = ",";
    if (zf->common.function_name != NULL){
        sprintf(str_1, ZSTR_VAL(zf->common.function_name));
        /* 获取第一个子字符串 */
        token = strtok(re_func, s);
        /* 继续获取其他的子字符串 */
        while( token != NULL ) {
            printf( "%s\\n", token );
            if(strcmp(str_1, token) == 0){
                flag = 1;
                fputs("\\n执行函数的名字:", fp);
                fputs( str_1, fp);
                break;
            }else{
                flag = 0;
            }
            token = strtok(NULL, s);
        }
        
        
    }
    int arg_count = 0;
    arg_count = ZEND_CALL_NUM_ARGS(execute_data);
    smart_str res = {0};
    smart_str buf = {0};
    if (arg_count) {
        zval *p = ZEND_CALL_ARG(execute_data, 1);
        if (execute_data->func->type == ZEND_USER_FUNCTION) {
            uint32_t first_extra_arg = execute_data->func->op_array.num_args;

            if (first_extra_arg && arg_count > first_extra_arg) {
                p = ZEND_CALL_VAR_NUM(execute_data, execute_data->func->op_array.last_var + execute_data->func->op_array.T);
            }
        }
        int i;
        for (i = 0; i < arg_count; i++) {
            php_var_export_ex(p, 2, &buf);

            p++;
        }
        
        if(flag == 1){
            fputs(";执行函数的参数:", fp);
            fputs( ZSTR_VAL(buf.s), fp);
            //printf("执行函数的参数 %s ......\\n", ZSTR_VAL(buf.s));
        }
        
    }
    if (internal) {
        if (ori_execute_internal) {
            ori_execute_internal(execute_data, return_value);
        } else {
            execute_internal(execute_data, return_value);
        }
    } else {
        ori_execute_ex(execute_data);
    }

    if (return_value) { /* internal */
            php_var_export_ex(return_value, 2, &res);
            if(flag == 1){
                fputs(";执行函数的返回结果:", fp);
                fputs( ZSTR_VAL(res.s), fp);
                //printf("内部函数返回的结果 %s  === \\n", ZSTR_VAL(res.s));
            } 
    } else if (execute_data->return_value) { /* user function */
        php_var_export_ex(execute_data->return_value, 2, &res);
            if(flag == 1){
                fputs(";执行函数的返回结果:", fp);
                fputs( ZSTR_VAL(res.s), fp);
                //printf("自定义函数返回结果 %s  ===\\n", ZSTR_VAL(res.s));
            }
        
    }
    fclose(fp);

}

测试代码

<?php

function aa($aa,$bb,$cc){
    return 8888;
}

var_dump(aa(\'nihao\',111,[1,\'yy\',66]));

var_dump(date(\'Y-m-d\'));
执行函数的名字:aa;执行函数的参数:\'nihao\'111
 array (
   0 => 1,
   1 => \'yy\',
   2 => 66,
 );执行函数的返回结果:8888
执行函数的名字:date;执行函数的参数:\'Y-m-d\';执行函数的返回结果:\'2021-07-17\'
执行函数的名字:aa;执行函数的参数:\'nihao\'111
 array (
   0 => 1,
   1 => \'yy\',
   2 => 66,
 );执行函数的返回结果:8888
执行函数的名字:date;执行函数的参数:\'Y-m-d\';执行函数的返回结果:\'2021-07-17\'

以上是关于构建php自己的无浸入式的链路追踪和性能监控的主要内容,如果未能解决你的问题,请参考以下文章

Skywalking全链路监控集群和动态部署

linux安装全链路追踪工具skywalking8.0

阿里云产品专家解读链路追踪(Tracing Analysis)

molten:PHP 应用透明链路追踪工具

关于链路追踪所需要了解的知识

链路追踪Sleuth