当前位置: 首页 > 后端技术 > PHP

构建php自己的非沉浸式链接跟踪和性能监控

时间:2023-03-29 20:04:34 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;=pid_execute_internal;returnSUCCESS;}当执行过程中发现是要拦截的函数时,会获取函数的参数返回值并记录日志,继续执行原来的PHP执行函数ZEND_APIvoidpid_execute_core(intinternal,zend_execute_data*execute_data,zval*return_value){char*logs_dir={0};字符*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(名称,"%s%s",logs_dir,file_log);文件*fp;if((fp=fopen(name,"a+"))==NULL){printf("文件无法打开\n");}zend_function*zf=obtain_zend_function(执行数据);int标志=0;字符str_1[512]={0};字符*令牌;常量字符s[2]=",";如果(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){标志=1;fputs("\n执行函数的名称:",fp);fputs(str_1,fp);休息;}else{标志=0;}token=strtok(NULL,s);}}intarg_count=0;arg_count=ZEND_CALL_NUM_ARGS(execute_data);smart_str资源={0};smart_strbuf={0};if(arg_count){zval*p=ZEND_CALL_ARG(execute_data,1);if(execute_data->func->type==ZEND_USER_FUNCTION){uint32_tfirst_extra_arg=执行_data->func->op_array.num_args;如果(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);}}诠释我;对于(i=0;ireturn_value){/*用户函数*/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);}测试代码1,1=>'yy',2=>66,);执行函数返回结果:8888执行函数名称:date;执行函数的参数:'Y-m-d';执行函数返回结果:'2021-07-17'执行函数名称:aa;执行函数的参数:'nihao'111array(0=>1,1=>'yy',2=>66,);执行函数返回结果:8888执行函数名称:date;执行函数的参数:'Y-m-d';执行函数的返回结果:'2021-07-17'