skywalking.c 30.6 KB
Newer Older
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32
/*
  +----------------------------------------------------------------------+
  | PHP Version 7                                                        |
  +----------------------------------------------------------------------+
  | Copyright (c) 1997-2017 The PHP Group                                |
  +----------------------------------------------------------------------+
  | This source file is subject to version 3.01 of the PHP license,      |
  | that is bundled with this package in the file LICENSE, and is        |
  | available through the world-wide-web at the following url:           |
  | http://www.php.net/license/3_01.txt                                  |
  | If you did not receive a copy of the PHP license and are unable to   |
  | obtain it through the world-wide-web, please send a note to          |
  | license@php.net so we can mail you a copy immediately.               |
  +----------------------------------------------------------------------+
  | Author:                                                              |
  +----------------------------------------------------------------------+
*/

/* $Id$ */

#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#include <sys/time.h>


#include "main/SAPI.h" /* for sapi_module */
#include "zend_smart_str.h" /* for smart_str */
#include "php.h"
#include "php_ini.h"
#include "ext/standard/info.h"
#include "ext/standard/php_string.h"
H
heyanlong 已提交
33
#include "src/components.h"
34 35
#include "php_skywalking.h"
#include "ext/standard/url.h" /* for php_url */
H
heyanlong 已提交
36
#include "ext/standard/php_var.h"
37 38 39 40 41 42 43 44

#include "ext/standard/basic_functions.h"
#include "ext/standard/php_math.h"
#include <string.h>
#include "ext/json/php_json.h"
#include "ext/date/php_date.h"
#include <curl/curl.h>
#include <curl/easy.h>
S
songzhian 已提交
45 46 47 48 49 50 51 52 53
#include <unistd.h>
#include <netdb.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <pthread.h>
#include <fcntl.h>
#include <dirent.h>

H
heyanlong 已提交
54

H
report  
heyanlong 已提交
55
extern int applicationCodeRegister(char *grpc_server, char *code);
56

H
heyanlong 已提交
57
extern int registerInstance(char *grpc_server, int appId, long registertime, char *osname, char *hostname,
H
report  
heyanlong 已提交
58
                            int processno, char *ipv4s);
S
songzhian 已提交
59 60

/* If you declare any globals in php_skywalking.h uncomment this:
61 62 63 64 65
*/
ZEND_DECLARE_MODULE_GLOBALS(skywalking)

/* True global resources - no need for thread safety here */
static int le_skywalking;
H
report  
heyanlong 已提交
66 67
static int application_instance = 0;
static int application_id = 0;
S
songzhian 已提交
68 69 70
static int sky_close = 0;
static int sky_increment_id = 0;

71 72 73 74
/* {{{ PHP_INI
 */
/* Remove comments and fill if you need to have entries in php.ini*/
PHP_INI_BEGIN()
H
heyanlong 已提交
75
	STD_PHP_INI_BOOLEAN("skywalking.enable",   	"0", PHP_INI_ALL, OnUpdateBool, enable, zend_skywalking_globals, skywalking_globals)
H
heyanlong 已提交
76
	STD_PHP_INI_ENTRY("skywalking.version",   	"5", PHP_INI_ALL, OnUpdateLong, version, zend_skywalking_globals, skywalking_globals)
H
report  
heyanlong 已提交
77 78 79
	STD_PHP_INI_ENTRY("skywalking.app_code", "", 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.grpc", "127.0.0.1:11800", PHP_INI_ALL, OnUpdateString, grpc, zend_skywalking_globals, skywalking_globals)
80 81 82 83 84 85 86 87 88 89 90
PHP_INI_END()

/* }}} */



/* {{{ skywalking_functions[]
 *
 * Every user visible function must have an entry in skywalking_functions[].
 */
const zend_function_entry skywalking_functions[] = {
S
songzhian 已提交
91
		/* For testing, remove later. */
92 93 94 95 96 97 98 99 100 101
	PHP_FE_END	/* Must be the last line in skywalking_functions[] */
};
/* }}} */



const zend_function_entry class_skywalking[] = {
	PHP_FE_END
};

S
songzhian 已提交
102 103 104



105 106 107 108 109 110
/* The previous line is meant for vim and emacs, so it can correctly fold and
   unfold functions in source code. See the corresponding marks just before
   function definition, where the functions purpose is also documented. Please
   follow this convention for the convenience of others editing your code.
*/

H
heyanlong 已提交
111
void sky_curl_exec_handler(INTERNAL_FUNCTION_PARAMETERS)
112 113 114 115 116 117
{
	zval		*zid;
	if (zend_parse_parameters(ZEND_NUM_ARGS(), "r", &zid) == FAILURE) {
		return;
	}

H
heyanlong 已提交
118
	int is_send = 1;
H
heyanlong 已提交
119

H
report  
heyanlong 已提交
120 121 122 123 124
    zval function_name,curlInfo;
    zval params[1];
    ZVAL_COPY(&params[0], zid);
    ZVAL_STRING(&function_name,  "curl_getinfo");
    call_user_function(CG(function_table), NULL, &function_name, &curlInfo, 1, params);
H
memory  
heyanlong 已提交
125 126 127
    zval_dtor(&function_name);
    zval_dtor(&params[0]);

H
report  
heyanlong 已提交
128
    zval *z_url = zend_hash_str_find(Z_ARRVAL(curlInfo),  ZEND_STRL("url"));
H
heyanlong 已提交
129
    char *url_str = Z_STRVAL_P(z_url);
H
heyanlong 已提交
130 131
    if(strlen(url_str) <= 0) {
        zval_dtor(&curlInfo);
H
heyanlong 已提交
132
        is_send = 0;
H
heyanlong 已提交
133
    }
H
heyanlong 已提交
134
    php_url *url_info = NULL;
H
heyanlong 已提交
135 136 137 138 139 140
    if(is_send == 1) {
        url_info = php_url_parse(url_str);
        if(url_info->scheme == NULL || url_info->host == NULL) {
            zval_dtor(&curlInfo);
            php_url_free(url_info);
            is_send = 0;
H
heyanlong 已提交
141 142 143
        }
    }

H
heyanlong 已提交
144 145 146 147
    char *sw3 = NULL;
    zval *spans = NULL;
    zval *last_span = NULL;
    zval *span_id = NULL;
H
heyanlong 已提交
148
    char *peer = NULL;
H
heyanlong 已提交
149 150
    ssize_t operation_name_l = 0;
    char *operation_name = NULL;
H
heyanlong 已提交
151 152 153 154 155 156
    if (is_send == 1) {
        int peer_port = 0;
        if (url_info->port) {
            peer_port = url_info->port;
        } else {
            if (strcasecmp("http", url_info->scheme) == 0) {
H
heyanlong 已提交
157
                peer_port = 80;
H
heyanlong 已提交
158
            } else {
H
heyanlong 已提交
159
                peer_port = 443;
H
heyanlong 已提交
160 161
            }
        }
H
heyanlong 已提交
162

H
heyanlong 已提交
163 164 165
        peer = (char *) emalloc(strlen(url_info->scheme) + 3 + strlen(url_info->host) + 7);
        bzero(peer, strlen(url_info->scheme) + 3 + strlen(url_info->host) + 7);
        sprintf(peer, "%s://%s:%d", url_info->scheme, url_info->host, peer_port);
H
report  
heyanlong 已提交
166

H
heyanlong 已提交
167 168
        if (url_info->query) {
            if (url_info->path == NULL) {
H
heyanlong 已提交
169
                operation_name_l = snprintf(NULL, 0, "%s?%s", "/", url_info->query);
H
heyanlong 已提交
170
                operation_name = (char *) emalloc(operation_name_l + 1);
H
heyanlong 已提交
171
                bzero(operation_name, operation_name_l + 1);
H
heyanlong 已提交
172
                sprintf(operation_name, "%s?%s", "/", url_info->query);
H
heyanlong 已提交
173
            } else {
H
heyanlong 已提交
174
                operation_name_l = snprintf(NULL, 0, "%s?%s", url_info->path, url_info->query);
H
heyanlong 已提交
175
                operation_name = (char *) emalloc(operation_name_l + 1);
H
heyanlong 已提交
176
                bzero(operation_name, operation_name_l + 1);
H
heyanlong 已提交
177
                sprintf(operation_name, "%s?%s", url_info->path, url_info->query);
H
heyanlong 已提交
178
            }
H
heyanlong 已提交
179
        } else {
H
heyanlong 已提交
180
            if (url_info->path == NULL) {
H
heyanlong 已提交
181
                operation_name_l = snprintf(NULL, 0, "%s", "/");
H
heyanlong 已提交
182
                operation_name = (char *) emalloc(operation_name_l + 1);
H
heyanlong 已提交
183
                bzero(operation_name, operation_name_l + 1);
H
heyanlong 已提交
184
                sprintf(operation_name, "%s", "/");
H
heyanlong 已提交
185
            } else {
H
heyanlong 已提交
186
                operation_name_l = snprintf(NULL, 0, "%s", url_info->path);
H
heyanlong 已提交
187
                operation_name = (char *) emalloc(operation_name_l + 1);
H
heyanlong 已提交
188
                bzero(operation_name, operation_name_l + 1);
H
heyanlong 已提交
189
                sprintf(operation_name, "%s", url_info->path);
H
heyanlong 已提交
190
            }
H
heyanlong 已提交
191
        }
H
heyanlong 已提交
192 193 194 195

        spans = get_spans();
        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);
H
heyanlong 已提交
196
        sw3 = generate_sw3(Z_LVAL_P(span_id) + 1, peer, operation_name);
H
report  
heyanlong 已提交
197 198
    }

H
heyanlong 已提交
199 200 201 202 203 204 205 206 207 208 209

    if (sw3 != NULL) {
        zval *option = NULL;
        int is_init = 0;
        option = zend_hash_index_find(Z_ARRVAL_P(&SKYWALKING_G(curl_header)), Z_RES_HANDLE_P(zid));

        if(option == NULL) {
            option = emalloc(sizeof(zval));
            bzero(option, sizeof(zval));
            array_init(option);
            is_init = 1;
H
heyanlong 已提交
210
        }
H
heyanlong 已提交
211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228

        add_next_index_string(option, sw3);
        add_index_bool(&SKYWALKING_G(curl_header_send), (zend_ulong)Z_RES_HANDLE_P(zid), IS_TRUE);

        zval func;
        zval argv[3];
        zval ret;
        ZVAL_STRING(&func, "curl_setopt");

        ZVAL_COPY(&argv[0], zid);
        ZVAL_LONG(&argv[1], CURLOPT_HTTPHEADER);
        ZVAL_COPY(&argv[2], option);
        call_user_function(CG(function_table), NULL, &func, &ret, 3, argv);
        zval_dtor(&ret);
        zval_dtor(&func);
        if(is_init == 1) {
            zval_ptr_dtor(option);
            efree(option);
H
heyanlong 已提交
229
        }
H
heyanlong 已提交
230 231 232
        zval_dtor(&argv[0]);
        zval_dtor(&argv[1]);
        zval_dtor(&argv[2]);
H
heyanlong 已提交
233
        efree(sw3);
H
report  
heyanlong 已提交
234
    }
H
heyanlong 已提交
235 236 237 238

    zval temp;
    char *l_millisecond;
    long millisecond;
H
heyanlong 已提交
239
    if(is_send == 1) {
H
heyanlong 已提交
240

H
heyanlong 已提交
241
        array_init(&temp);
H
heyanlong 已提交
242

H
heyanlong 已提交
243 244 245 246 247 248 249 250 251
        add_assoc_long(&temp, "spanId", Z_LVAL_P(span_id) + 1);
        add_assoc_long(&temp, "parentSpanId", 0);
        l_millisecond = get_millisecond();
        millisecond = zend_atol(l_millisecond, strlen(l_millisecond));
        efree(l_millisecond);
        add_assoc_long(&temp, "startTime", millisecond);
        add_assoc_long(&temp, "spanType", 1);
        add_assoc_long(&temp, "spanLayer", 3);
        add_assoc_long(&temp, "componentId", COMPONENT_HTTPCLIENT);
H
report  
heyanlong 已提交
252
    }
H
heyanlong 已提交
253 254


H
heyanlong 已提交
255
	orig_curl_exec(INTERNAL_FUNCTION_PARAM_PASSTHRU);
H
heyanlong 已提交
256

H
heyanlong 已提交
257 258 259 260 261 262 263 264
    if (is_send == 1) {
        zval function_name_1, curlInfo_1;
        zval params_1[1];
        ZVAL_COPY(&params_1[0], zid);
        ZVAL_STRING(&function_name_1, "curl_getinfo");
        call_user_function(CG(function_table), NULL, &function_name_1, &curlInfo_1, 1, params_1);
        zval_dtor(&params_1[0]);
        zval_dtor(&function_name_1);
H
heyanlong 已提交
265

H
heyanlong 已提交
266 267 268 269
        zval *z_http_code;
        l_millisecond = get_millisecond();
        millisecond = zend_atol(l_millisecond, strlen(l_millisecond));
        efree(l_millisecond);
H
heyanlong 已提交
270

H
heyanlong 已提交
271
        z_http_code = zend_hash_str_find(Z_ARRVAL(curlInfo_1), ZEND_STRL("http_code"));
H
heyanlong 已提交
272

H
heyanlong 已提交
273
        add_assoc_long(&temp, "endTime", millisecond);
H
heyanlong 已提交
274 275


H
heyanlong 已提交
276 277 278 279
        add_assoc_string(&temp, "operationName", operation_name);
        add_assoc_string(&temp, "peer", peer);
        efree(peer);
        efree(operation_name);
H
heyanlong 已提交
280

H
heyanlong 已提交
281 282 283 284 285 286 287 288 289 290 291 292 293 294
        php_url_free(url_info);

        if (Z_LVAL_P(z_http_code) != 200) {
            add_assoc_long(&temp, "isError", 1);
        } else {
            add_assoc_long(&temp, "isError", 0);
        }
        zval _refs;
        array_init(&_refs);
        add_assoc_zval(&temp, "refs", &_refs);
        zend_hash_next_index_insert(Z_ARRVAL_P(spans), &temp);
        zval_dtor(&curlInfo_1);
        zval_dtor(&curlInfo);
    }
295
}
H
heyanlong 已提交
296 297 298 299 300 301 302 303 304

void sky_curl_setopt_handler(INTERNAL_FUNCTION_PARAMETERS) {
    zval *zid, *zvalue;
    zend_long options;

    if (zend_parse_parameters(ZEND_NUM_ARGS(), "rlz", &zid, &options, &zvalue) == FAILURE) {
        return;
    }

H
heyanlong 已提交
305 306 307 308 309 310 311 312 313 314
    zval *is_send = zend_hash_index_find(Z_ARRVAL_P(&SKYWALKING_G(curl_header_send)), Z_RES_HANDLE_P(zid));
    //
    if (is_send != NULL &&  CURLOPT_HTTPHEADER == options && Z_TYPE_P(is_send) == IS_TRUE) {
        add_index_bool(&SKYWALKING_G(curl_header_send), Z_RES_HANDLE_P(zid), IS_FALSE);
        orig_curl_setopt(INTERNAL_FUNCTION_PARAM_PASSTHRU);
    } else {
        if (CURLOPT_HTTPHEADER == options && Z_TYPE_P(zvalue) == IS_ARRAY) {
            zval copy_header;
            ZVAL_DUP(&copy_header, zvalue);
            add_index_zval(&SKYWALKING_G(curl_header), Z_RES_HANDLE_P(zid), &copy_header);
H
heyanlong 已提交
315
        } else {
H
heyanlong 已提交
316
            orig_curl_setopt(INTERNAL_FUNCTION_PARAM_PASSTHRU);
H
heyanlong 已提交
317 318 319
        }
    }
}
H
heyanlong 已提交
320 321

void sky_curl_setopt_array_handler(INTERNAL_FUNCTION_PARAMETERS) {
H
heyanlong 已提交
322 323 324
    zval *zid, *arr, *entry;
    zend_ulong option;
    zend_string *string_key;
H
heyanlong 已提交
325 326 327 328 329 330

    ZEND_PARSE_PARAMETERS_START(2, 2)
            Z_PARAM_RESOURCE(zid)
            Z_PARAM_ARRAY(arr)
    ZEND_PARSE_PARAMETERS_END();

H
heyanlong 已提交
331 332 333 334 335 336
    zval *http_header = zend_hash_index_find(Z_ARRVAL_P(arr), CURLOPT_HTTPHEADER);

    if (http_header != NULL) {
        zval copy_header;
        ZVAL_DUP(&copy_header, http_header);
        add_index_zval(&SKYWALKING_G(curl_header), Z_RES_HANDLE_P(zid), &copy_header);
H
heyanlong 已提交
337
    }
H
heyanlong 已提交
338 339 340 341

    orig_curl_setopt_array(INTERNAL_FUNCTION_PARAM_PASSTHRU);
}

H
heyanlong 已提交
342 343 344 345 346 347 348
void sky_curl_close_handler(INTERNAL_FUNCTION_PARAMETERS) {
    zval *zid;

    if (zend_parse_parameters(ZEND_NUM_ARGS(), "r", &zid) == FAILURE) {
        return;
    }

H
heyanlong 已提交
349 350 351
    zval *http_header = zend_hash_index_find(Z_ARRVAL_P(&SKYWALKING_G(curl_header)), Z_RES_HANDLE_P(zid));
    if (http_header != NULL) {
        zend_hash_index_del(Z_ARRVAL_P(&SKYWALKING_G(curl_header)), Z_RES_HANDLE_P(zid));
H
heyanlong 已提交
352 353 354 355
    }

    orig_curl_close(INTERNAL_FUNCTION_PARAM_PASSTHRU);
}
356 357 358 359 360
/* {{{ php_skywalking_init_globals
 */
/* Uncomment this function if you have INI entries*/
static void php_skywalking_init_globals(zend_skywalking_globals *skywalking_globals)
{
H
report  
heyanlong 已提交
361 362
	skywalking_globals->app_code = NULL;
	skywalking_globals->log_path = NULL;
H
heyanlong 已提交
363 364
	skywalking_globals->enable = 0;
	skywalking_globals->version = 5;
H
report  
heyanlong 已提交
365
	skywalking_globals->grpc = NULL;
366 367 368 369 370 371 372
}



static char *sky_json_encode(zval *parameter){

	smart_str buf = {0};
H
report  
heyanlong 已提交
373
	zend_long options = 64;
374 375 376 377 378 379 380 381 382 383
#if PHP_VERSION_ID >= 71000
	return_code = php_json_encode(&buf, parameter, (int)options);
	if (return_code != SUCCESS) {
		smart_str_free(&buf);
		return NULL;
	}
#else
	php_json_encode(&buf, parameter, (int)options);
#endif
	smart_str_0(&buf);
H
memory  
heyanlong 已提交
384 385 386
	char *bufs = ZSTR_VAL(buf.s);
	smart_str_free(&buf);
	return bufs;
387 388
}

S
songzhian 已提交
389

H
memory  
heyanlong 已提交
390 391
static void write_log(char *text) {
    if (application_instance != -100000) {
H
report  
heyanlong 已提交
392 393 394 395
        char *log_path;
        char logFilename[100];
        char message[strlen(text) + 1];
        log_path = SKY_G(log_path);
396

H
heyanlong 已提交
397
        zend_string *_log_path, *_log_path_lower;
H
memory  
heyanlong 已提交
398 399
        _log_path = zend_string_init(log_path, strlen(log_path), 0);
        _log_path_lower = php_string_tolower(_log_path);
400

H
report  
heyanlong 已提交
401
        bzero(logFilename, 100);
H
heyanlong 已提交
402
        sprintf(logFilename, "%s/skywalking.%d-%d.log", ZSTR_VAL(_log_path_lower), get_second(), getpid());
403

H
memory  
heyanlong 已提交
404 405
        zend_string_release(_log_path);
        zend_string_release(_log_path_lower);
H
report  
heyanlong 已提交
406 407 408 409
        bzero(message, strlen(text));
        sprintf(message, "%s\n", text);
        _php_error_log_ex(3, message, strlen(message), logFilename, NULL);
    }
410 411 412 413

}


H
heyanlong 已提交
414
static char *generate_sw3(zend_long span_id, char *peer_host, char *operation_name) {
H
heyanlong 已提交
415

H
heyanlong 已提交
416 417 418 419 420 421 422
    zval *traceId = zend_hash_str_find(Z_ARRVAL(SKYWALKING_G(context)), "currentTraceId", sizeof("currentTraceId") - 1);
    zval *entryApplicationInstance = zend_hash_str_find(Z_ARRVAL(SKYWALKING_G(context)), "entryApplicationInstance",
                                                        sizeof("entryApplicationInstance") - 1);
    zval *entryOperationName = zend_hash_str_find(Z_ARRVAL(SKYWALKING_G(context)), "entryOperationName",
                                                  sizeof("entryOperationName") - 1);
    zval *distributedTraceId = zend_hash_str_find(Z_ARRVAL(SKYWALKING_G(context)), "distributedTraceId",
                                                  sizeof("distributedTraceId") - 1);
H
heyanlong 已提交
423 424 425 426 427 428 429 430 431 432
    ssize_t sw3_l = 0;
    sw3_l = snprintf(NULL, 0, "sw3: %s|%d|%d|%d|#%s|#%s|#%s|%s", Z_STRVAL_P(traceId), span_id,
                     application_instance, Z_LVAL_P(entryApplicationInstance), peer_host,
                     Z_STRVAL_P(entryOperationName), operation_name, Z_STRVAL_P(distributedTraceId));
    char *sw3 = (char*)emalloc(sw3_l + 1);
    bzero(sw3, sw3_l + 1);
    snprintf(sw3, sw3_l + 1, "sw3: %s|%d|%d|%d|#%s|#%s|#%s|%s", Z_STRVAL_P(traceId), span_id,
             application_instance, Z_LVAL_P(entryApplicationInstance), peer_host,
             Z_STRVAL_P(entryOperationName), operation_name, Z_STRVAL_P(distributedTraceId));
    return sw3;
H
heyanlong 已提交
433 434
}

H
heyanlong 已提交
435 436 437 438
static zend_string *trim_sharp(zval *tmp) {
    return php_trim(Z_STR_P(tmp), "#", sizeof("#") - 1, 1);
}

H
report  
heyanlong 已提交
439 440 441 442 443 444
static void generate_context() {
    int sys_pid = getpid();
    long second = get_second();
    second = second * 10000 + sky_increment_id;
    char *makeTraceId;
    makeTraceId = (char *) emalloc(sizeof(char) * 180);
H
heyanlong 已提交
445

H
heyanlong 已提交
446
    bzero(makeTraceId, sizeof(char) * 180);
S
songzhian 已提交
447

H
report  
heyanlong 已提交
448
    sprintf(makeTraceId, "%d.%d.%ld", application_instance, sys_pid, second);
S
songzhian 已提交
449

H
report  
heyanlong 已提交
450
    add_assoc_string(&SKYWALKING_G(context), "currentTraceId", makeTraceId);
H
heyanlong 已提交
451
    add_assoc_long(&SKYWALKING_G(context), "isChild", 0);
H
heyanlong 已提交
452

H
report  
heyanlong 已提交
453 454 455
    // parent
    zval *carrier = NULL;
    zval *sw3;
H
heyanlong 已提交
456

H
report  
heyanlong 已提交
457
    zend_bool jit_initialization = PG(auto_globals_jit);
H
heyanlong 已提交
458

H
report  
heyanlong 已提交
459 460 461 462 463
    if (jit_initialization) {
        zend_string *server_str = zend_string_init("_SERVER", sizeof("_SERVER") - 1, 0);
        zend_is_auto_global(server_str);
        zend_string_release(server_str);
    }
H
heyanlong 已提交
464
    carrier = zend_hash_str_find(&EG(symbol_table), ZEND_STRL("_SERVER"));
H
report  
heyanlong 已提交
465
    sw3 = zend_hash_str_find(Z_ARRVAL_P(carrier), "HTTP_SW3", sizeof("HTTP_SW3") - 1);
S
songzhian 已提交
466

H
heyanlong 已提交
467
    if (sw3 != NULL && Z_TYPE_P(sw3) == IS_STRING && Z_STRLEN_P(sw3) > 10) {
H
heyanlong 已提交
468 469 470 471 472 473 474
        add_assoc_string(&SKYWALKING_G(context), "sw3", Z_STRVAL_P(sw3));

        zval temp;
        array_init(&temp);

        php_explode(zend_string_init(ZEND_STRL("|"), 0), Z_STR_P(sw3), &temp, 10);

H
heyanlong 已提交
475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498
        if(zend_array_count(Z_ARRVAL_P(&temp)) >= 8) {
            zval *sw3_0 = zend_hash_index_find(Z_ARRVAL(temp), 0);
            zval *sw3_1 = zend_hash_index_find(Z_ARRVAL(temp), 1);
            zval *sw3_2 = zend_hash_index_find(Z_ARRVAL(temp), 2);
            zval *sw3_3 = zend_hash_index_find(Z_ARRVAL(temp), 3);
            zval *sw3_4 = zend_hash_index_find(Z_ARRVAL(temp), 4);
            zval *sw3_5 = zend_hash_index_find(Z_ARRVAL(temp), 5);
            zval *sw3_6 = zend_hash_index_find(Z_ARRVAL(temp), 6);
            zval *sw3_7 = zend_hash_index_find(Z_ARRVAL(temp), 7);

            zval child;
            array_init(&child);
            ZVAL_LONG(&child, 1);
            zend_hash_str_update(Z_ARRVAL_P(&SKYWALKING_G(context)), "isChild", sizeof("isChild") - 1, &child);

            add_assoc_string(&SKYWALKING_G(context), "parentTraceSegmentId", Z_STRVAL_P(sw3_0));
            add_assoc_long(&SKYWALKING_G(context), "parentSpanId", zend_atol(Z_STRVAL_P(sw3_1), sizeof(Z_STRVAL_P(sw3_1)) - 1));
            add_assoc_long(&SKYWALKING_G(context), "parentApplicationInstance", zend_atol(Z_STRVAL_P(sw3_2), sizeof(Z_STRVAL_P(sw3_2)) - 1));
            add_assoc_long(&SKYWALKING_G(context), "entryApplicationInstance", zend_atol(Z_STRVAL_P(sw3_3), sizeof(Z_STRVAL_P(sw3_3)) - 1));
            add_assoc_str(&SKYWALKING_G(context), "networkAddress", trim_sharp(sw3_4));
            add_assoc_str(&SKYWALKING_G(context), "entryOperationName", trim_sharp(sw3_5));
            add_assoc_str(&SKYWALKING_G(context), "parentOperationName", trim_sharp(sw3_6));
            add_assoc_string(&SKYWALKING_G(context), "distributedTraceId", Z_STRVAL_P(sw3_7));
        }
H
heyanlong 已提交
499 500 501
    } else {
        add_assoc_long(&SKYWALKING_G(context), "parentApplicationInstance", application_instance);
        add_assoc_long(&SKYWALKING_G(context), "entryApplicationInstance", application_instance);
H
report  
heyanlong 已提交
502
        add_assoc_string(&SKYWALKING_G(context), "entryOperationName", get_page_request_uri());
H
heyanlong 已提交
503 504
        add_assoc_string(&SKYWALKING_G(context), "distributedTraceId", makeTraceId);
    }
H
memory  
heyanlong 已提交
505
    efree(makeTraceId);
506 507
}

H
report  
heyanlong 已提交
508 509 510 511 512 513 514

static long get_second() {
    struct timeval tv;
    gettimeofday(&tv,NULL);
    return tv.tv_sec;
}

515 516 517 518 519 520 521 522 523 524 525 526 527 528
static char *get_millisecond(){
	struct timeval tv;
	gettimeofday(&tv,NULL);
	char *buffer;
	buffer = (char *)emalloc(sizeof(char)*20);
	bzero(buffer, 20);
	long millisecond;
	millisecond = tv.tv_sec*1000 + tv.tv_usec/1000;
	sprintf(buffer, "%ld",  millisecond);

	return buffer;
}


H
heyanlong 已提交
529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 549 550 551
static char *get_page_request_uri() {
    zval *carrier = NULL;
    zval *request_uri;

    smart_str uri = {0};

    if (strcasecmp("cli", sapi_module.name) == 0) {
        smart_str_appendl(&uri, "cli", strlen("cli"));
    } else {
        zend_bool jit_initialization = PG(auto_globals_jit);

        if (jit_initialization) {
            zend_string *server_str = zend_string_init("_SERVER", sizeof("_SERVER") - 1, 0);
            zend_is_auto_global(server_str);
            zend_string_release(server_str);
        }
        carrier = zend_hash_str_find(&EG(symbol_table), ZEND_STRL("_SERVER"));

        request_uri = zend_hash_str_find(Z_ARRVAL_P(carrier), "REQUEST_URI", sizeof("REQUEST_URI") - 1);
        smart_str_appendl(&uri, Z_STRVAL_P(request_uri), strlen(Z_STRVAL_P(request_uri)));
    }

    smart_str_0(&uri);
H
memory  
heyanlong 已提交
552 553 554
    char *uris = ZSTR_VAL(uri.s);
    smart_str_free(&uri);
    return uris;
H
heyanlong 已提交
555
}
556 557


S
songzhian 已提交
558
/**
H
report  
heyanlong 已提交
559
 * ip
S
songzhian 已提交
560 561 562 563 564 565 566
 * 
 * @since 2017年11月23日
 * @copyright
 * @return return_type
//  */
static char* _get_current_machine_ip(){

H
heyanlong 已提交
567

S
songzhian 已提交
568 569 570 571 572 573 574 575 576 577 578 579 580 581 582 583 584 585 586 587 588 589
	char *ip;
	zval *carrier = NULL;
	ip  = (char *)emalloc(sizeof(char)*100);

	bzero(ip, 100);

	carrier = &PG(http_globals)[TRACK_VARS_SERVER];

	if (strcasecmp("cli", sapi_module.name) == 0){
		strcpy(ip, "127.0.0.1");
	}else{
		char hname[128];
    	struct hostent *hent;
     	gethostname(hname, sizeof(hname));
		hent = gethostbyname(hname);
		ip = inet_ntoa(*(struct in_addr*)(hent->h_addr_list[0]));
	}


    return ip;
}

H
heyanlong 已提交
590
static void request_init() {
S
songzhian 已提交
591

H
heyanlong 已提交
592
    array_init(&SKYWALKING_G(curl_header));
H
heyanlong 已提交
593
    array_init(&SKYWALKING_G(curl_header_send));
H
heyanlong 已提交
594 595
    array_init(&SKYWALKING_G(context));
	array_init(&SKYWALKING_G(UpstreamSegment));
S
songzhian 已提交
596

H
report  
heyanlong 已提交
597
    generate_context();
S
songzhian 已提交
598

H
report  
heyanlong 已提交
599
    add_assoc_long(&SKYWALKING_G(UpstreamSegment), "application_instance", application_instance);
H
heyanlong 已提交
600
    add_assoc_long(&SKYWALKING_G(UpstreamSegment), "pid", getppid());
H
report  
heyanlong 已提交
601
    add_assoc_long(&SKYWALKING_G(UpstreamSegment), "application_id", application_id);
H
heyanlong 已提交
602
    add_assoc_long(&SKYWALKING_G(UpstreamSegment), "version", SKYWALKING_G(version));
H
heyanlong 已提交
603
	SKY_ADD_ASSOC_ZVAL(&SKYWALKING_G(UpstreamSegment), "segment");
H
report  
heyanlong 已提交
604 605 606
	SKY_ADD_ASSOC_ZVAL(&SKYWALKING_G(UpstreamSegment), "globalTraceIds");

	zval *traceId = zend_hash_str_find(Z_ARRVAL(SKYWALKING_G(context)), "currentTraceId", sizeof("currentTraceId") - 1);
S
songzhian 已提交
607

H
heyanlong 已提交
608 609 610 611
	zval traceSegmentObject;
	zval spans;
	array_init(&spans);
	array_init(&traceSegmentObject);
H
report  
heyanlong 已提交
612 613
	add_assoc_string(&traceSegmentObject, "traceSegmentId", Z_STRVAL_P(traceId));
	add_assoc_long(&traceSegmentObject, "isSizeLimited", 0);
S
songzhian 已提交
614

H
heyanlong 已提交
615 616
	zval temp;
	array_init(&temp);
S
songzhian 已提交
617

H
heyanlong 已提交
618 619 620 621 622 623 624
    add_assoc_long(&temp, "spanId", 0);
    add_assoc_long(&temp, "parentSpanId", -1);
    char *l_millisecond = get_millisecond();
    long millisecond = zend_atol(l_millisecond, strlen(l_millisecond));
    efree(l_millisecond);
    add_assoc_long(&temp, "startTime", millisecond);
    add_assoc_string(&temp, "operationName", get_page_request_uri());
H
report  
heyanlong 已提交
625
    add_assoc_string(&temp, "peer", "");
H
heyanlong 已提交
626 627 628
    add_assoc_long(&temp, "spanType", 0);
    add_assoc_long(&temp, "spanLayer", 3);
    add_assoc_long(&temp, "componentId", COMPONENT_HTTPCLIENT);
S
songzhian 已提交
629

H
heyanlong 已提交
630 631 632 633
    zval *isChild = zend_hash_str_find(Z_ARRVAL_P(&SKYWALKING_G(context)), "isChild", sizeof("isChild") - 1);
    // refs
    zval refs;
    array_init(&refs);
H
heyanlong 已提交
634 635 636 637 638

    zval globalTraceIds;
    array_init(&globalTraceIds);
    zval tmpGlobalTraceIds;

H
heyanlong 已提交
639
    if(Z_LVAL_P(isChild) == 1) {
H
memory  
heyanlong 已提交
640 641
        zval ref;
        array_init(&ref);
H
heyanlong 已提交
642 643 644 645 646 647
        zval *parentTraceSegmentId = zend_hash_str_find(Z_ARRVAL(SKYWALKING_G(context)), "parentTraceSegmentId", sizeof("parentTraceSegmentId") - 1);
        zval *parentSpanId = zend_hash_str_find(Z_ARRVAL(SKYWALKING_G(context)), "parentSpanId", sizeof("parentSpanId") - 1);
        zval *parentApplicationInstance = zend_hash_str_find(Z_ARRVAL(SKYWALKING_G(context)), "parentApplicationInstance", sizeof("parentApplicationInstance") - 1);
        zval *entryApplicationInstance = zend_hash_str_find(Z_ARRVAL(SKYWALKING_G(context)), "entryApplicationInstance", sizeof("entryApplicationInstance") - 1);
        zval *entryOperationName = zend_hash_str_find(Z_ARRVAL(SKYWALKING_G(context)), "entryOperationName", sizeof("entryOperationName") - 1);
        zval *networkAddress = zend_hash_str_find(Z_ARRVAL(SKYWALKING_G(context)), "networkAddress", sizeof("networkAddress") - 1);
H
heyanlong 已提交
648
        zval *parentOperationName = zend_hash_str_find(Z_ARRVAL(SKYWALKING_G(context)), "parentOperationName", sizeof("parentOperationName") - 1);
H
heyanlong 已提交
649
        zval *distributedTraceId = zend_hash_str_find(Z_ARRVAL(SKYWALKING_G(context)), "distributedTraceId", sizeof("distributedTraceId") - 1);
H
heyanlong 已提交
650 651 652 653 654 655 656
        add_assoc_long(&ref, "type", 0);
        add_assoc_string(&ref, "parentTraceSegmentId", Z_STRVAL_P(parentTraceSegmentId));
        add_assoc_long(&ref, "parentSpanId", Z_LVAL_P(parentSpanId));
        add_assoc_long(&ref, "parentApplicationInstanceId", Z_LVAL_P(parentApplicationInstance));
        add_assoc_string(&ref, "networkAddress", Z_STRVAL_P(networkAddress));
        add_assoc_long(&ref, "entryApplicationInstanceId", Z_LVAL_P(entryApplicationInstance));
        add_assoc_string(&ref, "entryServiceName", Z_STRVAL_P(entryOperationName));
H
heyanlong 已提交
657
        add_assoc_string(&ref, "parentServiceName", Z_STRVAL_P(parentOperationName));
H
heyanlong 已提交
658
        zend_hash_next_index_insert(Z_ARRVAL(refs), &ref);
H
heyanlong 已提交
659 660 661
        ZVAL_STRING(&tmpGlobalTraceIds, Z_STRVAL_P(distributedTraceId));
    } else {
        ZVAL_STRING(&tmpGlobalTraceIds, Z_STRVAL_P(traceId));
H
heyanlong 已提交
662 663 664 665

    }

    zend_hash_str_add(Z_ARRVAL(temp), "refs", sizeof("refs") - 1, &refs);
H
heyanlong 已提交
666
    zend_hash_next_index_insert(Z_ARRVAL(spans), &temp);
S
songzhian 已提交
667

H
heyanlong 已提交
668
    add_assoc_zval(&traceSegmentObject, "spans", &spans);
S
songzhian 已提交
669

H
report  
heyanlong 已提交
670
    zend_hash_next_index_insert(Z_ARRVAL(globalTraceIds), &tmpGlobalTraceIds);
S
songzhian 已提交
671

H
report  
heyanlong 已提交
672 673
    zend_hash_str_update(Z_ARRVAL(SKYWALKING_G(UpstreamSegment)), "segment", sizeof("segment") - 1, &traceSegmentObject);
    zend_hash_str_update(Z_ARRVAL(SKYWALKING_G(UpstreamSegment)), "globalTraceIds", sizeof("globalTraceIds") - 1, &globalTraceIds);
S
songzhian 已提交
674 675 676
}


H
report  
heyanlong 已提交
677
static void sky_flush_all() {
S
songzhian 已提交
678
	char *l_millisecond = get_millisecond();
H
heyanlong 已提交
679 680 681 682
	long millisecond = zend_atol(l_millisecond, strlen(l_millisecond));
	efree(l_millisecond);

	zval *span = get_first_span();
S
songzhian 已提交
683

H
heyanlong 已提交
684 685
	add_assoc_long(span, "endTime", millisecond);
	if ((SG(sapi_headers).http_response_code >= 500)) {
H
heyanlong 已提交
686
		add_assoc_long(span, "isError", 1);
H
heyanlong 已提交
687
	} else {
H
heyanlong 已提交
688
		add_assoc_long(span, "isError", 0);
H
heyanlong 已提交
689
	}
S
songzhian 已提交
690

H
heyanlong 已提交
691 692
	write_log(sky_json_encode(&SKYWALKING_G(UpstreamSegment)));
}
S
songzhian 已提交
693

H
heyanlong 已提交
694 695 696 697 698 699
static zval *get_first_span() {
	zval *segment = zend_hash_str_find(Z_ARRVAL(SKYWALKING_G(UpstreamSegment)), "segment", sizeof("segment") - 1);
	zval *spans = zend_hash_str_find(Z_ARRVAL_P(segment), "spans", sizeof("spans") - 1);
	zval *span = zend_hash_index_find(Z_ARRVAL_P(spans), 0);
	return span;
}
S
songzhian 已提交
700

H
heyanlong 已提交
701 702 703 704
static zval *get_spans() {
	zval *segment = zend_hash_str_find(Z_ARRVAL(SKYWALKING_G(UpstreamSegment)), "segment", sizeof("segment") - 1);
	zval *spans = zend_hash_str_find(Z_ARRVAL_P(segment), "spans", sizeof("spans") - 1);
	return spans;
S
songzhian 已提交
705 706 707
}


H
heyanlong 已提交
708 709
static void module_init() {

H
report  
heyanlong 已提交
710 711
    application_instance = -100000;
    application_id = -100000;
H
report  
heyanlong 已提交
712 713 714 715 716 717

    int i = 0;

    do {
        application_id = applicationCodeRegister(SKYWALKING_G(grpc), SKYWALKING_G(app_code));

H
report  
heyanlong 已提交
718 719 720 721
        if(application_id == -100000) {
            sleep(1);
        }

H
report  
heyanlong 已提交
722 723
        i++;
    } while (application_id == -100000 && i <= 3);
H
report  
heyanlong 已提交
724 725 726 727

    if (application_id == -100000) {
        sky_close = 1;
        return;
S
songzhian 已提交
728
    }
H
heyanlong 已提交
729

H
report  
heyanlong 已提交
730
    char *ipv4s = _get_current_machine_ip();
S
songzhian 已提交
731

H
report  
heyanlong 已提交
732 733 734 735 736 737 738 739 740
    char hostname[100] = {0};
    if (gethostname(hostname, sizeof(hostname)) < 0) {
        strcpy(hostname, "");
    }

    char *l_millisecond = get_millisecond();
    long millisecond = zend_atol(l_millisecond, strlen(l_millisecond));
    efree(l_millisecond);

H
report  
heyanlong 已提交
741 742
    i = 0;
    do {
H
heyanlong 已提交
743
        application_instance = registerInstance(SKYWALKING_G(grpc), application_id, millisecond, SKY_OS_NAME,
H
report  
heyanlong 已提交
744 745
                                                hostname, getpid(),
                                                ipv4s);
H
report  
heyanlong 已提交
746 747 748
        if(application_instance == -100000) {
            sleep(1);
        }
H
report  
heyanlong 已提交
749 750 751
        i++;
    } while (application_instance == -100000 && i <= 3);

H
heyanlong 已提交
752

H
report  
heyanlong 已提交
753
    if (application_instance == -100000) {
H
report  
heyanlong 已提交
754 755 756
        sky_close = 1;
        return;
    }
S
songzhian 已提交
757 758 759
}


760 761
/* {{{ PHP_MINIT_FUNCTION
 */
H
heyanlong 已提交
762
PHP_MINIT_FUNCTION (skywalking) {
H
docs  
heyanlong 已提交
763
	ZEND_INIT_MODULE_GLOBALS(skywalking, php_skywalking_init_globals, NULL);
S
songzhian 已提交
764
	//data_register_hashtable();
765 766 767
	REGISTER_INI_ENTRIES();
	/* If you have INI entries, uncomment these lines
	*/
H
report  
heyanlong 已提交
768
	if (SKYWALKING_G(enable)) {
H
heyanlong 已提交
769 770
		module_init();
		if (sky_close == 1) {
S
songzhian 已提交
771 772
			return SUCCESS;
		}
H
heyanlong 已提交
773
//		set_sampling_rate(SKY_G(global_sampling_rate));
774
		zend_function *old_function;
H
heyanlong 已提交
775
		if ((old_function = zend_hash_str_find_ptr(CG(function_table), "curl_exec", sizeof("curl_exec") - 1)) != NULL) {
776
			orig_curl_exec = old_function->internal_function.handler;
H
heyanlong 已提交
777
			old_function->internal_function.handler = sky_curl_exec_handler;
778
		}
H
heyanlong 已提交
779 780 781 782
        if ((old_function = zend_hash_str_find_ptr(CG(function_table), "curl_setopt", sizeof("curl_setopt")-1)) != NULL) {
            orig_curl_setopt = old_function->internal_function.handler;
            old_function->internal_function.handler = sky_curl_setopt_handler;
        }
H
heyanlong 已提交
783 784 785 786
        if ((old_function = zend_hash_str_find_ptr(CG(function_table), "curl_setopt_array", sizeof("curl_setopt_array")-1)) != NULL) {
            orig_curl_setopt_array = old_function->internal_function.handler;
            old_function->internal_function.handler = sky_curl_setopt_array_handler;
        }
H
heyanlong 已提交
787 788 789 790
        if ((old_function = zend_hash_str_find_ptr(CG(function_table), "curl_close", sizeof("curl_close")-1)) != NULL) {
            orig_curl_close = old_function->internal_function.handler;
            old_function->internal_function.handler = sky_curl_close_handler;
        }
791 792 793 794 795 796 797 798 799 800 801
	}

	return SUCCESS;
}
/* }}} */

/* {{{ PHP_MSHUTDOWN_FUNCTION
 */
PHP_MSHUTDOWN_FUNCTION(skywalking)
{
	UNREGISTER_INI_ENTRIES();
H
memory  
heyanlong 已提交
802
    return SUCCESS;
803 804 805 806
}
/* }}} */

/* Remove if there's nothing to do at request start */
S
songzhian 已提交
807
/* {{{ PHP_RINIT_FUNCTION7
808 809 810
 */
PHP_RINIT_FUNCTION(skywalking)
{
S
songzhian 已提交
811

812 813 814
#if defined(COMPILE_DL_SKYWALKING) && defined(ZTS)
	ZEND_TSRMLS_CACHE_UPDATE();
#endif
H
report  
heyanlong 已提交
815
	if (SKYWALKING_G(enable)) {
H
heyanlong 已提交
816 817 818
        if (sky_close == 1) {
            return SUCCESS;
        }
H
report  
heyanlong 已提交
819 820 821 822
		sky_increment_id++;
		if (sky_increment_id >= 9999) {
			sky_increment_id = 0;
		}
H
memory  
heyanlong 已提交
823
        request_init();
H
report  
heyanlong 已提交
824
	}
825 826 827 828 829 830 831 832 833
	return SUCCESS;
}
/* }}} */

/* Remove if there's nothing to do at request end */
/* {{{ PHP_RSHUTDOWN_FUNCTION
 */
PHP_RSHUTDOWN_FUNCTION(skywalking)
{
H
heyanlong 已提交
834

H
report  
heyanlong 已提交
835
	if(SKYWALKING_G(enable)){
H
memory  
heyanlong 已提交
836 837 838
        if (sky_close == 1) {
            return SUCCESS;
        }
S
songzhian 已提交
839
		sky_flush_all();
H
memory  
heyanlong 已提交
840
        zval_dtor(&SKYWALKING_G(context));
H
heyanlong 已提交
841
        zval_dtor(&SKYWALKING_G(curl_header));
H
heyanlong 已提交
842
        zval_dtor(&SKYWALKING_G(curl_header_send));
H
memory  
heyanlong 已提交
843
        zval_dtor(&SKYWALKING_G(UpstreamSegment));
844 845 846 847 848 849 850 851 852
	}
	return SUCCESS;
}
/* }}} */

/* {{{ PHP_MINFO_FUNCTION
 */
PHP_MINFO_FUNCTION(skywalking)
{
S
songzhian 已提交
853

854
	php_info_print_table_start();
H
docs  
heyanlong 已提交
855 856 857 858 859
    if (sky_close) {
        php_info_print_table_header(2, "skywalking Support", "disabled (register fail)");
    } else {
        php_info_print_table_header(2, "skywalking Support", "enabled");
    }
860 861 862 863 864 865
	php_info_print_table_end();

	DISPLAY_INI_ENTRIES();
}
/* }}} */

H
memory  
heyanlong 已提交
866 867 868 869 870 871 872 873 874 875 876 877
/* {{{ PHP_MINFO_FUNCTION
 */
PHP_GINIT_FUNCTION(skywalking)
{
    memset(skywalking_globals, 0, sizeof(*skywalking_globals));
}
/* }}} */

zend_module_dep skywalking_deps[] = {
        ZEND_MOD_REQUIRED("json")
        {NULL, NULL, NULL}
};
878 879 880 881 882 883 884 885 886 887 888 889 890 891 892 893 894 895 896 897 898 899 900 901 902 903 904 905 906 907 908 909

/* {{{ skywalking_module_entry
 */
zend_module_entry skywalking_module_entry = {
	STANDARD_MODULE_HEADER,
	"skywalking",
	skywalking_functions,
	PHP_MINIT(skywalking),
	PHP_MSHUTDOWN(skywalking),
	PHP_RINIT(skywalking),		/* Replace with NULL if there's nothing to do at request start */
	PHP_RSHUTDOWN(skywalking),	/* Replace with NULL if there's nothing to do at request end */
	PHP_MINFO(skywalking),
	PHP_SKYWALKING_VERSION,
	STANDARD_MODULE_PROPERTIES
};
/* }}} */

#ifdef COMPILE_DL_SKYWALKING
#ifdef ZTS
ZEND_TSRMLS_CACHE_DEFINE()
#endif
ZEND_GET_MODULE(skywalking)
#endif

/*
 * Local variables:
 * tab-width: 4
 * c-basic-offset: 4
 * End:
 * vim600: noet sw=4 ts=4 fdm=marker
 * vim<600: noet sw=4 ts=4
 */