TestOrderErr.php 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441
  1. <?php
  2. use PHPUnit\Framework\TestCase;
  3. define('APP_ID', 'OrderErr');
  4. define('BASE_ROOT_PATH', str_replace('/test', '', dirname(__FILE__)));
  5. require_once(BASE_ROOT_PATH . '/global.php');
  6. require_once(BASE_CORE_PATH . '/lrlz.php');
  7. require_once(BASE_ROOT_PATH . '/fooder.php');
  8. class TestOrderErr extends TestCase
  9. {
  10. public static function setUpBeforeClass(): void
  11. {
  12. Base::run_util();
  13. }
  14. //docker-compose run -d phpcli php /var/www/html/phpunit-9.2.5.phar --filter "/(TestOrderErr::testRecoverPdlog)( .*)?$/" --test-suffix TestOrderErr.php /var/www/html/test
  15. public function testRecoverPdlog()
  16. {
  17. $names = ['4', '45', '55', '81', '116'];
  18. foreach ($names as $name) {
  19. $filename = BASE_DATA_PATH . "/log/recover/{$name}.log";
  20. $this->recover($filename);
  21. }
  22. }
  23. private function recover($filename)
  24. {
  25. $reader = function ($fp) {
  26. while (!feof($fp)) {
  27. $logs = [];
  28. for ($index = 0; $index < 100 && !feof($fp); $index++) {
  29. $log = fgets($fp);
  30. $logs[] = $log;
  31. }
  32. yield $logs;
  33. }
  34. };
  35. $filter = function ($lines) {
  36. $logs = [];
  37. foreach ($lines as $line) {
  38. $ret = preg_match('/lrlz_pd_log[^(]+[(]{1}(?P<key>[^)]+)[)]{1}[\s]+VALUES[^(][(]{1}(?P<value>[^)]+)[)]{1}/u', $line, $matches);
  39. if ($ret) {
  40. $skey = $matches['key'];
  41. $svalue = $matches['value'];
  42. $keys = explode(',', $skey);
  43. $values = explode(',', $svalue);
  44. $conveter = function ($value) {
  45. $val = trim($value, '\'');
  46. return $val;
  47. };
  48. $values = array_map($conveter, $values);
  49. $log = array_combine($keys, $values);
  50. $logs[] = $log;
  51. }
  52. }
  53. return $logs;
  54. };
  55. $mod_log = Model();
  56. $inserter = function ($logs) use ($mod_log) {
  57. // $mod_log->table('acclog')->insertAll($logs);
  58. foreach ($logs as $log) {
  59. $ret = $mod_log->table('acclog')->insert($log);
  60. if (!$ret) {
  61. Log::record("import error", Log::ERR);
  62. }
  63. }
  64. };
  65. $file = fopen($filename, 'r');
  66. $batches = $reader($file);
  67. foreach ($batches as $batch) {
  68. $logs = $filter($batch);
  69. $inserter($logs);
  70. }
  71. fclose($file);
  72. }
  73. public function testSQLMatch()
  74. {
  75. // $line =<<< line
  76. // [cordispatcher 38-123975 2021-12-28 15:22:10 0.261198] ERR: DbError eno=1062 msg=Duplicate entry '2147483647' for key 'lrlz_pd_log.PRIMARY' sql=INSERT INTO `lrlz_pd_log` (lg_member_id,lg_member_name,lg_add_time,lg_type,lg_order_sn,lg_av_amount,lg_desc,lg_available) VALUES ('66025','5d322c4ee98781023b16d9a3c21cbfb4',1640676130,'order_pay','6861760694020130235975',-48,'下单,支付预存款,订单号: 6861760694020130235975','954256.6700')
  77. // line;
  78. $line = <<< line
  79. [cordispatcher 29-126259 2021-12-28 15:22:10 0.836849] ERR: DbError eno=1062 msg=Duplicate entry '2147483647' for key 'lrlz_pd_log.PRIMARY' sql=INSERT INTO `lrlz_pd_log` (lg_member_id,lg_member_name,lg_add_time,lg_type,lg_order_sn,lg_av_amount,lg_freeze_amount,lg_desc,lg_available) VALUES ('66240','c27517c6553a6f783b8df974c3d2d219',1640676130,'order_cancel','9031520694020106890799',48,-48,'取消订单,解冻预存款,订单
  80. 号: 9031520694020106890799','42192.9500')
  81. line;
  82. $ret = preg_match('/lrlz_pd_log[^(]+[(]{1}(?P<key>[^)]+)[)]{1}[\s]+VALUES[^(][(]{1}(?P<value>[^)]+)[)]{1}/u', $line, $matches);
  83. if ($ret) {
  84. $skey = $matches['key'];
  85. $svalue = $matches['value'];
  86. $keys = explode(',', $skey);
  87. $values = explode(',', $svalue);
  88. $conveter = function ($value) {
  89. $val = trim($value, '\'');
  90. return $val;
  91. };
  92. $values = array_map($conveter, $values);
  93. $log = array_combine($keys, $values);
  94. }
  95. }
  96. public function testGetLatestSending()
  97. {
  98. $mod = Model();
  99. $item = $mod->table('refill_detail')->field('min(order_time) as mintime')->where(['order_time' => ['egt', time() - 5 * 86400], 'order_state' => 30])->find();
  100. }
  101. public function testLoadAcc()
  102. {
  103. $line = <<< line
  104. [crontab 1 2021-12-28 00:12:28] SQL: UPDATE `lrlz_member` SET available_predeposit='74496.9500',freeze_predeposit='0.0000' WHERE ( member_id = 66240 ) [ RunTime:0.000156s ]
  105. line;
  106. // $ret = preg_match('/lrlz_pd_log[^(]+[(]{1}(?P<key>[^)]+)[)]{1}[\s]+VALUES[^(][(]{1}(?P<value>[^)]+)[)]{1}/u', $line, $matches);
  107. $ret = preg_match('/2021-12-28[\s]+(?P<time>[\d:^\]]+)]{1}[\s\S]+available_predeposit=[\']{1}(?P<amount>[\d\.]+)[\']{1}[\s\S]+member_id[\s=]+(?P<member>[\d]+)/u', $line, $matches);
  108. if ($ret) {
  109. $time = $matches['time'];
  110. $amount = $matches['amount'];
  111. $member = $matches['member'];
  112. $add_time = "2021-12-28 {$time}";
  113. $add_time = strtotime($add_time);
  114. $log = ['member_id' => $member, 'available_predeposit' => $amount, 'add_time' => $add_time];
  115. } else {
  116. }
  117. }
  118. //docker-compose run -d phpcli php /var/www/html/phpunit-9.2.5.phar --filter "/(TestOrderErr::testRecoverAcclog)( .*)?$/" --test-suffix TestOrderErr.php /var/www/html/test
  119. public function testRecoverAcclog()
  120. {
  121. $filename = BASE_DATA_PATH . "/log/recover/update.log";
  122. $this->recover_acclog($filename);
  123. }
  124. private function recover_acclog($filename)
  125. {
  126. $reader = function ($fp) {
  127. while (!feof($fp)) {
  128. $logs = [];
  129. for ($index = 0; $index < 100 && !feof($fp); $index++) {
  130. $log = fgets($fp);
  131. $logs[] = $log;
  132. }
  133. yield $logs;
  134. }
  135. };
  136. $filter = function ($lines) {
  137. $logs = [];
  138. foreach ($lines as $line) {
  139. $ret = preg_match('/2021-12-28[\s]+(?P<time>[\d:^\]]+)]{1}[\s\S]+available_predeposit=[\']{1}(?P<amount>[-\d\.]+)[\']{1}[\s\S]+member_id[\s=]+(?P<member>[\d]+)/u', $line, $matches);
  140. if ($ret) {
  141. $time = $matches['time'];
  142. $amount = $matches['amount'];
  143. $member = $matches['member'];
  144. $add_time = "2021-12-28 {$time}";
  145. $add_time = strtotime($add_time);
  146. $log = ['member_id' => $member, 'available_predeposit' => $amount, 'add_time' => $add_time];
  147. $logs[] = $log;
  148. } else {
  149. Log::record("{$line}", Log::ERR);
  150. }
  151. }
  152. return $logs;
  153. };
  154. $mod_log = Model();
  155. $inserter = function ($logs) use ($mod_log) {
  156. foreach ($logs as $log) {
  157. $ret = $mod_log->table('macclog')->insert($log);
  158. if (!$ret) {
  159. Log::record("import error", Log::ERR);
  160. }
  161. }
  162. };
  163. $file = fopen($filename, 'r');
  164. $batches = $reader($file);
  165. foreach ($batches as $batch) {
  166. $logs = $filter($batch);
  167. $inserter($logs);
  168. }
  169. fclose($file);
  170. }
  171. //docker-compose run -d phpcli php /var/www/html/phpunit-9.2.5.phar --filter "/(TestOrderErr::testFilterErrorLog)( .*)?$/" --test-suffix TestOrderErr.php /var/www/html/test
  172. public function testFilterErrorLog()
  173. {
  174. $start_time = '2021-12-28 15:22:00';
  175. $end_time = '2021-12-28 16:00:00';
  176. $files = ['45' => 'xaj'];
  177. $prefix = BASE_DATA_PATH . "/log/pdlog";
  178. foreach ($files as $path => $name) {
  179. $input = "{$prefix}/{$path}/{$name}";
  180. $outpath = "{$prefix}/{$path}";
  181. $this->filter_time($input, $outpath, $start_time, $end_time);
  182. }
  183. }
  184. private function filter_time($input_file, $outpath, $start_time, $end_time)
  185. {
  186. $start = strtotime($start_time);
  187. $end = strtotime($end_time);
  188. $reader = function ($fp) use ($start, $end)
  189. {
  190. while (!feof($fp))
  191. {
  192. $line = fgets($fp);
  193. $ret = preg_match('/\[cordispatcher[\s]+(?P<pid>[\d]+)-[\d]+[\s]+(?P<time>[\d-]+[\s]{1}[\d:]+)[\s]{1}/u', $line, $matches);
  194. if ($ret)
  195. {
  196. $time = strtotime($matches['time']);
  197. if ($time < $start) {
  198. continue;
  199. } elseif ($time > $end) {
  200. break;
  201. } else {
  202. yield $line;
  203. }
  204. }
  205. }
  206. };
  207. $filter_pid = function ($line)
  208. {
  209. $ret = preg_match('/\[cordispatcher[\s]+(?P<pid>[\d]+)-[\d]+[\s]+(?P<time>[\d-]+[\s]{1}[\d:]+)[\s]{1}/u', $line, $matches);
  210. if ($ret) {
  211. $pid = intval($matches['pid']);
  212. return $pid;
  213. }
  214. return 0;
  215. };
  216. $beginer = function ($line)
  217. {
  218. $ret = preg_match('/[\s]+BeginGoFunction[\s]+/u', $line, $matches);
  219. if ($ret) {
  220. return true;
  221. } else {
  222. return false;
  223. }
  224. };
  225. $pid_fp = [];
  226. $spliter = function ($pid, $line) use ($outpath, &$pid_fp,$beginer)
  227. {
  228. $begin = $beginer($line);
  229. if (array_key_exists($pid, $pid_fp))
  230. {
  231. $fp = $pid_fp[$pid];
  232. if($begin) {
  233. fwrite($fp, "\r\n");
  234. }
  235. }
  236. else {
  237. $name = "{$outpath}/{$pid}.log";
  238. $fp = fopen($name, 'w');
  239. $pid_fp[$pid] = $fp;
  240. }
  241. fwrite($fp, $line);
  242. };
  243. $input = fopen($input_file, 'r');
  244. $lines = $reader($input);
  245. foreach ($lines as $line)
  246. {
  247. $pid = $filter_pid($line);
  248. if ($pid > 0) {
  249. $spliter($pid, $line);
  250. }
  251. }
  252. fclose($input);
  253. foreach ($pid_fp as $pid => $fp) {
  254. fclose($fp);
  255. }
  256. }
  257. ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  258. public function testFindErrAcc()
  259. {
  260. $files = ['45' => ['7.log']];
  261. $prefix = BASE_DATA_PATH . "/log/pdlog";
  262. foreach ($files as $path => $names)
  263. {
  264. foreach ($names as $name) {
  265. $input = "{$prefix}/{$path}/{$name}";
  266. $this->filter_error($input);
  267. }
  268. }
  269. }
  270. private function filter_error($file)
  271. {
  272. $task_reader = function ($fp)
  273. {
  274. $task = [];
  275. $time = '';
  276. $pid = 0;
  277. $cid = 0;
  278. while (!feof($fp))
  279. {
  280. $line = fgets($fp);
  281. $ret = preg_match('/\[cordispatcher[\s]+(?P<pid>[\d]+)-(?P<cid>[\d]+)[\s]+(?P<time>[\d-]+[\s]{1}[\d:]+)[\s]{1}[\s\S]+BeginGoFunction[\s]+/u', $line, $matches);
  282. if ($ret)
  283. {
  284. if(!empty($task)) {
  285. yield [$time,$pid,$cid,$task];
  286. $task = [];
  287. }
  288. $time = $matches['time'];
  289. $pid = intval($matches['pid']);
  290. $cid = intval($matches['cid']);
  291. $task[] = $line;
  292. }
  293. else {
  294. $task[] = $line;
  295. }
  296. }
  297. if(!empty($task)) {
  298. yield [$time,$pid,$cid,$task];
  299. }
  300. };
  301. $methoder = function ($task)
  302. {
  303. foreach ($task as $line)
  304. {
  305. $ret = preg_match('/[\s]+method[=]{1}(?P<method>[\S]+)/u', $line, $matches);
  306. if ($ret) {
  307. $method = $matches['method'];
  308. return $method;
  309. }
  310. }
  311. return false;
  312. };
  313. $trans_filter = function ($task)
  314. {
  315. $tran = [];
  316. foreach ($task as $line)
  317. {
  318. $ret = preg_match('/[\s]+transaction[\s]+(?P<type>[\S]+)/u', $line, $matches);
  319. if ($ret)
  320. {
  321. $type = $matches['type'];
  322. if($type == 'begin') {
  323. $tran = [];
  324. $tran[] = $line;
  325. }
  326. elseif($type == 'commit') {
  327. $tran[] = $line;
  328. yield [$type,$tran];
  329. $tran = [];
  330. }
  331. elseif($type == 'rollback') {
  332. $tran[] = $line;
  333. yield [$type,$tran];
  334. $tran = [];
  335. }
  336. else {
  337. $tran[] = $line;
  338. yield [$type,$tran];
  339. $tran = [];
  340. }
  341. }
  342. else {
  343. $tran[] = $line;
  344. }
  345. }
  346. };
  347. $input = fopen($file, 'r');
  348. $tasks = $task_reader($input);
  349. foreach ($tasks as $time_task)
  350. {
  351. [$time,$pid,$cid,$task] = $time_task;
  352. $method = $methoder($task);
  353. Log::record("{$pid}-{$cid} method={$method} time={$time}",Log::DEBUG);
  354. $trans = $trans_filter($task);
  355. foreach ($trans as $type_tran) {
  356. [$type,$tran] = $type_tran;
  357. Log::record("\ttrans type={$type}",Log::DEBUG);
  358. }
  359. Log::record("\r\n",Log::DEBUG);
  360. }
  361. fclose($input);
  362. }
  363. public function testBegin()
  364. {
  365. $beginer = function ($line)
  366. {
  367. $ret = preg_match('/[\s]+BeginGoFunction[\s]+/u', $line, $matches);
  368. if ($ret) {
  369. return true;
  370. } else {
  371. return false;
  372. }
  373. };
  374. $line = '[cordispatcher 7-114568 2021-12-28 15:22:02 0.861740] DEBUG: BeginGoFunction coroutin_num=2 memory=24006608';
  375. $begin = $beginer($line);
  376. }
  377. }