Problem with generateId on macOS PHP 7.0, 7.1
I have a weird problem which seems to only affect PHP versions (of MAMP) on macOS where the trace ID is always 10000000000000001. I have tested with 7.0.33 and 7.1.32, both have the issue. 7.2.22 is not affected. Also other operating system versions (at least Alpine Linux and Debian) are seemingly not affected.
Jaeger has the method
private function generateId(){
return microtime(true) * 10000 . rand(10000, 99999);
}
In the mentioned environments this produces e.g. 1.58375696973E+1330420 a very large number that cannot be processed. It seems that on that systems microtime(true) * 10000 is in exponent notation 1.58375693969E+13 and then the rand part is concatenated to the exponent yielding that large number.
On not affected systems the output is the correct e.g. 1583757054325111449.
I have tried to work around the problem but I don't know enough about how trace IDs have to be composed. I get a lot of zeros in the middle which then show up in JaegerUI too.
Do you see the possibility of modifying the method to work around that PHP bug (or whatever it is) on the mentioned systems?
I got the error when I install PHP 7.0.33 and 7.1.33 on my macOS.
7.0.33
FAILED TEST SUMMARY
---------------------------------------------------------------------
dns_get_record() CAA tests [ext/standard/tests/network/dns_get_record_caa.phpt]
Bug #64438 proc_open hangs with stdin/out with 4097+ bytes [ext/standard/tests/streams/proc_open_bug64438.phpt]
int stream_socket_sendto ( resource $socket , string $data [, int $flags = 0 [, string $address ]] ); [ext/standard/tests/streams/stream_socket_sendto.phpt]
Check cli_process_title support on Unix [sapi/cli/tests/cli_process_title_unix.phpt]
=====================================================================
7.1.32
FAILED TEST SUMMARY
---------------------------------------------------------------------
Test basic date_sun_info() [ext/date/tests/date_sun_info_001.phpt]
Test basic date_sun_info() [ext/date/tests/date_sun_info_002.phpt]
Test basic date_sun_info() [ext/date/tests/date_sun_info_003.phpt]
Test date_sun_info() function : error variations - Pass unexpected values for time argument [ext/date/tests/date_sun_info_variation1.phpt]
Test date_sun_info() function : error variations - Pass unexpected values for latitude argument [ext/date/tests/date_sun_info_variation2.phpt]
Test date_sun_info() function : usage variations - Pass unexpected values for longitude argument [ext/date/tests/date_sun_info_variation3.phpt]
Test date_sunrise() function : usage variation - Passing unexpected values to first argument time. [ext/date/tests/date_sunrise_variation1.phpt]
Test date_sunrise() function : usage variation - Passing unexpected values to third argument latitude. [ext/date/tests/date_sunrise_variation3.phpt]
Test date_sunrise() function : usage variation - Passing unexpected values to fourth argument longitude. [ext/date/tests/date_sunrise_variation4.phpt]
Test date_sunrise() function : usage variation - Passing unexpected values to fifth argument zenith [ext/date/tests/date_sunrise_variation5.phpt]
Test date_sunrise() function : usage variation - Passing unexpected values to sixth argument gmt_offset. [ext/date/tests/date_sunrise_variation6.phpt]
Test date_sunrise() function : usage variation - Checking sunrise for consecutive days in specific timezone [ext/date/tests/date_sunrise_variation7.phpt]
Test date_sunset() function : usage variation - Passing unexpected values to first argument time. [ext/date/tests/date_sunset_variation1.phpt]
Test date_sunset() function : usage variation - Passing unexpected values to third argument latitude. [ext/date/tests/date_sunset_variation3.phpt]
Test date_sunset() function : usage variation - Passing unexpected values to fourth argument longitude. [ext/date/tests/date_sunset_variation4.phpt]
Test date_sunset() function : usage variation - Passing unexpected values to fifth argument zenith. [ext/date/tests/date_sunset_variation5.phpt]
Test date_sunset() function : usage variation - Passing unexpected values to sixth argument gmt_offset. [ext/date/tests/date_sunset_variation6.phpt]
Test date_sunset() function : usage variation - Checking sunrise for consecutive days in specific timezone [ext/date/tests/date_sunset_variation7.phpt]
date_sunrise() and date_sunset() functions [ext/date/tests/sunfuncts.phpt]
Blacklist (with glob, quote and comments) [ext/opcache/tests/blacklist.phpt]
Bug #64438 proc_open hangs with stdin/out with 4097+ bytes [ext/standard/tests/streams/proc_open_bug64438.phpt]
int stream_socket_sendto ( resource $socket , string $data [, int $flags = 0 [, string $address ]] ); [ext/standard/tests/streams/stream_socket_sendto.phpt]
Check cli_process_title support on Unix [sapi/cli/tests/cli_process_title_unix.phpt]
=====================================================================
In that case, I can't fix the issues whick you created. I suggest you upgrade PHP version
Thanks, do you see a way how to generate IDs a little bit differently to work around the issue?
it doesnt work for PHP 7.4 on CentOS 8.3 as well
php -r 'var_dump(microtime(true) * 10000 . rand(10000, 99999));'
string(22) "1.61730268102E+1355412"
so the most quickest fix with the same logic is to convert float to int explicitly
php -r 'var_dump(intval(microtime(true) * 10_000 ) * 100_000 + rand(10_000, 99_999));'
int(1617303057782825841)
so the function will be
private function generateId() : int {
return intval(microtime(true) * 10_000 ) * 100_000 + rand(10_000, 99_999)
}
but you can use this one instead, which in my opinion is even better
private function generateId() : int {
try {
return random_int(PHP_INT_MIN, PHP_INT_MAX);
} catch (\Exception $exception) {
return intval( /* 19 digits */
intval(microtime(true) * 1_000_000) * 1_000 /* 16 digits */
+ mt_rand(0, 999) /* 3 digits */
);
}
}