├── .DS_Store
├── .idea
├── MySQL_Diagnose.iml
├── encodings.xml
├── misc.xml
├── modules.xml
├── vcs.xml
└── workspace.xml
├── AWR_report
└── MySQL_AWR_192.168.20.88_20171113_222403.html
├── README.md
├── __pycache__
└── monitor.cpython-35.pyc
├── conf
├── account_info.json
└── diagnose.cnf
├── imgs
├── favicon.ico
└── flow_chart.png
├── lib
├── __init__.py
├── __pycache__
│ ├── __init__.cpython-35.pyc
│ └── funcs.cpython-35.pyc
└── funcs.py
├── logs
└── mysql_diagnose.log
├── machine
├── __pycache__
│ └── machine_html_result.cpython-35.pyc
└── machine_html_result.py
├── monitor.py
├── mysql
├── __pycache__
│ ├── mysql_html_result.cpython-35.pyc
│ └── sys_variables_status.cpython-35.pyc
├── mysql_html_result.py
└── sys_variables_status.py
├── mysql_diagnose.py
├── requestment.txt
└── t.py
/.DS_Store:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/thinkdb/MySQL_Diagnose/e37cc20928102c859f0b75dd153726dfae4042fe/.DS_Store
--------------------------------------------------------------------------------
/.idea/MySQL_Diagnose.iml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/.idea/encodings.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
--------------------------------------------------------------------------------
/.idea/misc.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
--------------------------------------------------------------------------------
/.idea/modules.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/.idea/vcs.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
--------------------------------------------------------------------------------
/.idea/workspace.xml:
--------------------------------------------------------------------------------
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 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
45 |
46 |
47 |
48 |
49 |
50 |
51 |
52 |
53 |
54 |
55 |
56 |
57 |
58 |
59 |
60 |
61 |
62 |
63 |
64 | '
65 |
66 |
67 | "
68 |
69 |
70 |
71 |
72 |
73 |
74 |
75 |
76 |
77 |
78 |
79 |
80 |
81 |
82 |
83 |
84 |
85 |
86 |
87 |
88 |
89 |
90 |
91 |
92 |
93 |
94 |
95 |
96 |
97 |
98 | true
99 | DEFINITION_ORDER
100 |
101 |
102 |
103 |
104 |
105 |
106 |
107 |
108 |
109 |
110 |
111 |
112 |
113 |
114 |
115 |
116 |
117 |
118 |
119 |
120 |
121 |
122 |
123 |
124 |
125 |
126 |
127 |
128 |
129 |
130 |
131 |
132 |
133 |
134 |
135 |
136 |
137 |
138 |
139 |
140 |
141 |
142 |
143 |
144 |
145 |
146 |
147 |
148 |
149 |
150 |
151 |
152 |
153 |
154 |
155 |
156 |
157 |
158 |
159 |
160 |
161 |
162 |
163 |
164 |
165 |
166 |
167 |
168 |
169 |
170 |
171 |
172 |
173 |
174 |
175 |
176 |
177 |
178 |
179 |
180 | project
181 |
182 |
183 |
184 |
185 |
186 |
187 |
188 |
189 |
190 |
191 |
192 |
193 |
194 |
195 |
196 |
197 |
198 |
199 |
200 |
201 |
202 |
203 |
204 |
205 |
206 |
207 |
208 |
209 |
210 |
211 |
212 |
213 |
214 |
215 |
216 |
217 |
218 |
219 |
220 |
221 |
222 |
223 |
224 |
225 |
226 |
227 |
228 |
229 |
230 |
231 |
232 |
233 |
234 |
235 |
236 |
237 |
238 |
239 |
240 |
241 |
242 |
243 |
244 |
245 |
246 |
247 |
248 |
249 |
250 |
251 |
252 |
253 |
254 |
255 |
256 |
257 |
258 |
259 |
260 |
261 |
262 |
263 |
264 |
265 |
266 |
267 |
268 |
269 |
270 |
271 |
272 |
273 |
274 |
275 |
276 |
277 |
278 |
279 |
280 |
281 |
282 |
283 |
284 |
285 |
286 |
287 |
288 |
289 |
290 |
291 |
292 |
293 |
294 |
295 |
296 |
297 |
298 |
299 |
300 |
301 |
302 |
303 |
304 |
305 |
306 |
307 |
308 |
309 |
310 |
311 |
312 |
313 |
314 |
315 |
316 |
317 |
318 |
319 |
320 |
321 |
322 |
323 |
324 |
325 |
326 |
327 |
328 |
329 |
330 |
331 |
332 |
333 |
334 |
335 |
336 |
337 |
338 |
339 |
340 |
341 |
342 |
343 |
344 |
345 |
346 |
347 |
348 |
349 |
350 |
351 |
352 |
353 |
354 |
355 |
356 |
357 |
358 |
359 |
360 |
361 |
362 |
363 |
364 |
365 |
366 |
367 |
368 |
369 |
370 |
371 |
372 |
373 |
374 |
375 |
376 |
377 |
378 |
379 |
380 |
381 |
382 |
383 |
384 |
385 |
386 |
387 |
388 |
389 |
390 |
391 |
392 |
393 |
394 |
395 |
396 |
397 |
398 |
399 |
400 |
401 |
402 |
403 |
404 |
405 |
406 |
407 |
408 |
409 |
410 |
411 |
412 |
413 |
414 |
415 |
416 |
417 |
418 |
419 |
420 |
421 |
422 |
423 |
424 |
425 |
426 |
427 |
428 |
429 |
430 |
431 |
432 |
433 |
434 |
435 |
436 |
437 |
438 |
439 |
440 |
441 |
442 |
443 |
444 | 1510140777632
445 |
446 |
447 | 1510140777632
448 |
449 |
450 | 1510447615025
451 |
452 |
453 |
454 | 1510447615025
455 |
456 |
457 | 1510579570283
458 |
459 |
460 |
461 | 1510579570283
462 |
463 |
464 |
465 |
466 |
467 |
468 |
469 |
470 |
471 |
472 |
473 |
474 |
475 |
476 |
477 |
478 |
479 |
480 |
481 |
482 |
483 |
484 |
485 |
486 |
487 |
488 |
489 |
490 |
491 |
492 |
493 |
494 |
495 |
496 |
497 |
498 |
499 |
500 |
501 |
502 |
503 |
504 |
505 |
506 |
507 |
508 |
509 |
510 |
511 |
512 |
513 |
514 |
515 |
516 |
517 |
518 |
519 |
520 |
521 |
522 |
523 |
524 |
525 |
526 |
527 |
528 |
529 |
530 |
531 |
532 |
533 |
534 |
535 |
536 |
537 |
538 |
539 |
540 |
541 |
542 |
543 |
544 |
545 |
546 |
547 |
548 |
549 |
550 |
551 |
552 |
553 |
554 |
555 |
556 |
557 |
558 |
559 |
560 |
561 |
562 |
563 |
564 |
565 |
566 |
567 |
568 |
569 |
570 |
571 |
572 |
573 |
574 |
575 |
576 |
577 |
578 |
579 |
580 |
581 |
582 |
583 |
584 |
585 |
586 |
587 |
588 |
589 |
590 |
591 |
592 |
593 |
594 |
595 |
596 |
597 |
598 |
599 |
600 |
601 |
602 |
603 |
604 |
605 |
606 |
607 |
608 |
609 |
610 |
611 |
612 |
613 |
614 |
615 |
616 |
617 |
618 |
619 |
620 |
621 |
622 |
623 |
624 |
625 |
626 |
627 |
628 |
629 |
630 |
631 |
632 |
633 |
634 |
635 |
636 |
637 |
638 |
639 |
640 |
641 |
642 |
643 |
644 |
645 |
646 |
647 |
648 |
649 |
650 |
651 |
652 |
653 |
654 |
655 |
656 |
657 |
658 |
659 |
660 |
661 |
662 |
663 |
664 |
665 |
666 |
667 |
668 |
669 |
670 |
671 |
672 |
673 |
674 |
675 |
676 |
677 |
678 |
679 |
680 |
681 |
682 |
683 |
684 |
685 |
686 |
687 |
688 |
689 |
690 |
691 |
692 |
693 |
694 |
695 |
696 |
697 |
698 |
699 |
700 |
701 |
702 |
703 |
704 |
705 |
706 |
707 |
708 |
709 |
710 |
711 |
712 |
713 |
714 |
715 |
716 |
717 |
718 |
719 |
720 |
721 |
722 |
723 |
724 |
725 |
726 |
727 |
728 |
729 |
730 |
731 |
732 |
733 |
734 |
735 |
736 |
737 |
738 |
739 |
740 |
741 |
742 |
743 |
744 |
745 |
746 |
747 |
748 |
749 |
750 |
751 |
752 |
753 |
754 |
755 |
756 |
757 |
758 |
759 |
760 |
761 |
762 |
763 |
764 |
765 |
766 |
767 |
768 |
769 |
770 |
771 |
772 |
773 |
774 |
775 |
776 |
777 |
778 |
779 |
780 |
781 |
782 |
783 |
784 |
785 |
786 |
787 |
788 |
789 |
790 |
791 |
792 |
793 |
794 |
795 |
796 |
797 |
798 |
799 |
800 |
801 |
802 |
803 |
804 |
805 |
806 |
807 |
808 |
809 |
810 |
811 |
812 |
813 |
814 |
815 |
816 |
817 |
818 |
819 |
820 |
821 |
822 |
823 |
824 |
825 |
826 |
827 |
828 |
829 |
830 |
831 |
832 |
833 |
834 |
835 |
836 |
837 |
838 |
839 |
840 |
841 |
842 |
843 |
844 |
845 |
846 |
847 |
848 |
849 |
850 |
851 |
852 |
853 |
854 |
855 |
856 |
857 |
858 |
859 |
860 |
861 |
862 |
863 |
864 |
865 |
866 |
867 |
868 |
869 |
870 |
871 |
872 |
873 |
874 |
875 |
876 |
877 |
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 |
910 |
911 |
912 |
913 |
914 |
915 |
916 |
917 |
918 |
919 |
920 |
921 |
922 |
923 |
924 |
925 |
926 |
927 |
928 |
929 |
930 |
931 |
932 |
933 |
934 |
935 |
936 |
937 |
938 |
939 |
940 |
941 |
942 |
943 |
944 |
945 |
946 |
947 |
948 |
949 |
950 |
951 |
952 |
953 |
954 |
955 |
956 |
957 |
958 |
959 |
960 |
961 |
962 |
963 |
964 |
965 |
966 |
967 |
968 |
969 |
970 |
971 |
972 |
973 |
974 |
975 |
976 |
977 |
978 |
979 |
980 |
981 |
982 |
983 |
984 |
985 |
986 |
987 |
988 |
989 |
990 |
991 |
992 |
993 |
994 |
995 |
996 |
997 |
998 |
999 |
1000 |
1001 |
1002 |
1003 |
1004 |
1005 |
1006 |
1007 |
1008 |
1009 |
1010 |
1011 |
1012 |
1013 |
1014 |
1015 |
1016 |
1017 |
1018 |
1019 |
1020 |
1021 |
1022 |
1023 |
1024 |
1025 |
1026 |
1027 |
1028 |
1029 |
1030 |
1031 |
1032 |
1033 |
1034 |
1035 |
1036 |
1037 |
1038 |
1039 |
1040 |
1041 |
1042 |
1043 |
1044 |
1045 |
1046 |
1047 |
1048 |
1049 |
1050 |
1051 |
1052 |
1053 |
1054 |
1055 |
1056 |
1057 |
1058 |
1059 |
1060 |
1061 |
1062 |
1063 |
1064 |
1065 |
1066 |
1067 |
1068 |
1069 |
--------------------------------------------------------------------------------
/AWR_report/MySQL_AWR_192.168.20.88_20171113_222403.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | Name Value innodb_flush_method O_DIRECT lock_wait_timeout 31536000 have_query_cache YES validate_password max_binlog_size 536870912 rpl_semi_sync_master_enabled bulk_insert_buffer_size 16777216 enforce_gtid_consistency OFF innodb_buffer_pool_dump_at_shutdown OFF innodb_thread_concurrency 0 rpl_semi_sync_master_timeout max_allowed_packet 67108864 log_bin_trust_function_creators ON max_sort_length 1024 innodb_lock_wait_timeout 120 innodb_buffer_pool_instances 2 optimizer_search_depth 62 table_open_cache 400 key_cache_age_threshold 300 wait_timeout 172800 table_definition_cache 600 range_alloc_block_size 4096 query_cache_size 0 relay_log /usr/local/mysql/data/mysql_relay_bin innodb_file_format Barracuda log_slow_slave_statements OFF innodb_buffer_pool_chunk_size slow_query_log ON read_buffer_size 1048576 read_rnd_buffer_size 8388608 character_set_server utf8 query_cache_type OFF innodb_file_per_table ON innodb_print_all_deadlocks OFF autocommit ON innodb_undo_log_truncate slave_transaction_retries 10 query_prealloc_size 8192 relay_log_info_repository FILE interactive_timeout 172800 innodb_sort_buffer_size 16777216 locked_in_memory OFF log_slave_updates ON innodb_log_files_in_group 2 slow_query_log_file /usr/local/mysql/data/slow_query.log slave_parallel_workers 0 thread_cache_size 128 expire_logs_days 10 slave_rows_search_algorithms TABLE_SCAN,INDEX_SCAN innodb_stats_persistent_sample_pages 20 max_user_connections 7900 table_open_cache_instances 16 log_throttle_queries_not_using_indexes 0 tmp_table_size 2097152 log_slow_admin_statements OFF innodb_file_format_max Antelope binlog_gtid_simple_recovery OFF long_query_time 1.000000 innodb_open_files 400 key_buffer_size 8388608 gtid_mode OFF binlog_row_image FULL max_connect_errors 99999 min_examined_row_limit 0 validate_password_policy relay_log_recovery OFF optimizer_prune_level 1 sync_binlog 0 innodb_log_buffer_size 67108864 large_pages OFF sql_mode STRICT_TRANS_TABLES,NO_ENGINE_SUBSTITUTION innodb_max_undo_log_size innodb_write_io_threads 8 log_timestamps key_cache_division_limit 100 loose_innodb_numa_interleave innodb_page_size 16384 max_tmp_tables 32 innodb_undo_tablespaces 0 skip_name_resolve ON innodb_buffer_pool_size 536870912 binlog_rows_query_log_events OFF innodb_online_alter_log_max_size 134217728 tx_read_only OFF master_info_repository FILE innodb_buffer_pool_dump_pct innodb_purge_rseg_truncate_frequency plugin_load innodb_buffer_pool_load_at_startup OFF innodb_strict_mode OFF innodb_flush_log_at_trx_commit 2 innodb_io_capacity 200 slave_skip_errors OFF slave_preserve_commit_order show_compatibility_56 innodb_log_file_size 1073741824 max_connections 214 innodb_undo_logs 128 innodb_flush_neighbors 0 innodb_lru_scan_depth 1024 key_cache_block_size 1024 innodb_purge_threads 1 join_buffer_size 4194304 tx_isolation REPEATABLE-READ max_length_for_sort_data 16384 innodb_large_prefix OFF innodb_autoinc_lock_mode 1 log_error /usr/local/mysql/data/error.log rpl_semi_sync_slave_enabled binlog_cache_size 262144 innodb_io_capacity_max 2000 slave_parallel_type log_queries_not_using_indexes OFF sort_buffer_size 8388608 innodb_read_io_threads 8 innodb_page_cleaners binlog_format ROW metadata_locks_hash_instances 8
/usr/local/mysql/my.cnf [myisamchk] read_buffer 8M key_buffer 512M sort_buffer_size 512M write_buffer 8M [client] default_character_set utf8 [mysql] prompt "\\u@\\h : \\d \\r:\\m:\\s> " default_character_set utf8 no_auto_rehash show_warnings [mysqlhotcopy] interactive_timeout [mysqldump] quick default_character_set utf8 max_allowed_packet 1G [mysqld_multi] user root mysqld /usr/bin/mysqld_safe [mysqld_safe] user mysql open_files_limit 8192 ledir /usr/sbin [mysqld] innodb_flush_method O_DIRECT group_concat_max_len 1048576 server_id 3306 myisam_sort_buffer_size 64M bulk_insert_buffer_size 16M max_heap_table_size 1G innodb_autoextend_increment 128 join_buffer_size 4M #bka innodb_change_buffering all relay_log /usr/local/mysql/data/mysql_relay_bin max_allowed_packet 64M log_bin_trust_function_creators 1 myisam_repair_threads 1 flush OFF innodb_lock_wait_timeout 120 innodb_buffer_pool_instances 2 table_open_cache 1024 auto_increment_increment 1 lower_case_table_names 1 wait_timeout 172800 query_cache_size 0 skip_federated innodb_file_format Barracuda max_binlog_size 512M innodb_rollback_on_timeout 1 innodb_commit_concurrency 0 slow_query_log allow_suspicious_udfs read_buffer_size 1M read_rnd_buffer_size 8M #mrr log_bin_index /usr/local/mysql/data/mysql_bin.index innodb_fast_shutdown 1 innodb_data_file_path ibdata1:1024M:autoextend user mysql query_cache_type 0 innodb_file_per_table relay_log_index /usr/local/mysql/data/mysql_relay_bin.index interactive_timeout 172800 auto_increment_offset 1 tmpdir /usr/local/mysql/data innodb_sort_buffer_size 16M log_slave_updates 1 myisam_max_sort_file_size 1G innodb_log_files_in_group 2 slow_query_log_file /usr/local/mysql/data/slow_query.log thread_cache_size 128 expire_logs_days 10 innodb_thread_concurrency 0 max_user_connections 7900 character_set_server utf8 table_open_cache_instances 16 tmp_table_size 2M max_length_for_sort_data 16k long_query_time 1 innodb_open_files 7168 net_buffer_length 8K key_buffer_size 8M performance_schema 0 port 3306 max_connect_errors 99999 skip_external_locking innodb_data_home_dir /usr/local/mysql/data/ innodb_force_recovery 0 sync_binlog 0 innodb_log_buffer_size 64M sql_mode 'STRICT_TRANS_TABLES,NO_ENGINE_SUBSTITUTION' myisam_recover_options default sysdate_is_now innodb_adaptive_flushing_lwm 30 pid_file /usr/local/mysql/data/mysql.pid innodb_write_io_threads 8 socket /usr/local/mysql/data/mysql.sock skip_name_resolve innodb_buffer_pool_size 512M innodb_io_capacity 200 default_storage_engine InnoDB log_bin /usr/local/mysql/data/mysql_bin innodb_concurrency_tickets 1024 skip_blackhole innodb_flush_log_at_trx_commit 2 innodb_use_sys_malloc 1 log_warnings 2 innodb_log_file_size 1G max_connections 8000 sort_buffer_size 8M innodb_lru_scan_depth 1024 innodb_purge_threads collation_server utf8_general_ci innodb_max_dirty_pages_pct 40 innodb_autoinc_lock_mode 1 log_error /usr/local/mysql/data/error.log explicit_defaults_for_timestamp event_scheduler ON datadir /usr/local/mysql/data innodb_support_xa 1 binlog_cache_size 256K binlog_checksum CRC32 innodb_log_group_home_dir /usr/local/mysql/data/ innodb_stats_on_metadata 0 back_log 1000 innodb_flush_neighbors 0 innodb_read_io_threads 8 innodb_file_format_check 1 basedir /usr/local/mysql binlog_format row
31 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | 此工具主要是用来 __远程__ 收集 MySQL 实例及所在机器的相关信息。
2 |
3 | 目标机器信息可以由两种方式存放:
4 | 1. 使用 json 格式
5 | 2. 使用数据库存放
6 |
7 | __** 注意:__
8 | 当 `innodb_stats_on_metadata` 打开时,收集参数时会触发收集统计信息的动作, 所以在收集实例信息之前会判断这个参数是否打开,打开就不收集实例信息
9 |
10 | #### 目录结构:
11 | ```
12 | MySQL_Diagnose/
13 | ├── AWR_report ----- 存放已经在生成的 awr 报告
14 | ├── README ----- 使用说明
15 | ├── conf
16 | │ ├── diagnose.cnf ----- 配置文件,用来配置从哪获取被监控机的账号信息
17 | │ └── account_info.json ----- 目标机器信息以 json 格式存放
18 | ├── imgs
19 | │ └── favicon.ico ----- 浏览器头部使用的小图片
20 | ├── lib
21 | │ ├── __init__.py
22 | │ └── funcs.py ----- 公共函数部分
23 | ├── logs
24 | │ └── mysql_diagnose.log ----- 日志文件
25 | ├── machine
26 | │ └── machine_html_result.py ----- 收集机器信息的逻辑代码, 并生成 html 文本
27 | ├── monitor.py ----- 决定要收集的内容, 可以在里面添加和删除要收集的内容
28 | ├── mysql
29 | │ ├── mysql_html_result.py ----- 收集 MySQL 相关信息的逻辑代码, 并生成 html 文本
30 | │ └── sys_variables_status.py ----- 收集的当前库的比较重要的参数信息
31 | ├── mysql_diagnose.py ----- 主文件, 直接运行即可收集信息
32 | ├── requestment.txt ----- 依赖包文件
33 | └── t.py
34 | ```
35 |
36 | #### 准备工作:
37 | - 使用 json 格式时,修改 conf/account_info.json 文件,按下面模板修改
38 | ```
39 | {
40 | "192.168.200.3": {
41 | "host": "1.1.2.3",
42 | "ssh_account": "root",
43 | "ssh_passwd": "123456",
44 | "ssh_port": 22,
45 | "mysql_account": "root",
46 | "mysql_port": 3306,
47 | "mysql_passwd": "123456"
48 | },
49 | "192.168.200.4": {
50 | "host": "1.4.3.4",
51 | "ssh_account": "root",
52 | "ssh_passwd": "123456",
53 | "ssh_port": 22,
54 | "mysql_account": "root",
55 | "mysql_port": 3306,
56 | "mysql_passwd": "123456"
57 | }
58 | }
59 | ```
60 | - 使用数据库方式
61 | - 需要在临时库中创建一个表,用于存放要收集的机器信息,类似下面语句
62 | ```
63 | create table diagnose_account_info(
64 | id int auto_increment primary key,
65 | host varchar(60),
66 | mysql_account varchar(100),
67 | mysql_passwd varchar(100),
68 | mysql_port smallint,
69 | ssh_account varchar(100),
70 | ssh_passwd varchar(100),
71 | ssh_port smallint
72 | );
73 | ```
74 |
75 | - 添加要收集的主机信息
76 | ```
77 | insert into diagnose_account_info(host, mysql_account, mysql_passwd, mysql_port, ssh_account, ssh_passwd, ssh_port)
78 | values
79 | ('192.168.1.4', 'root', '123456', 3306, 'root', 'root', 22),
80 | ('192.168.1.5', 'root', '123456', 3306, 'root', 'root', 22)
81 | ```
82 | __注意:__ mysql 实例账号需要使用 super 权限
83 |
84 |
85 | - 安装依赖包
86 | ` pip3 install requirements.txt`
87 |
88 | - 修改配置文件中的内容
89 | ```
90 | [default]
91 | processing=2 # 并发进程数
92 | host=192.168.200.3 # 库地址
93 | user=hotdb_cloud # 数据库账号
94 | password=hotdb_cloud # 数据库密码
95 | port=3306 # 数据库端口
96 | database=test # 库名
97 | log_level=10 # 日志级别, 10=debug, 20=info, 30=waring, 40=error, 50=critical
98 | type=1 # 目标机器信息存放格式, 1为json, 非1 表示从库表中获取目标机器信息
99 | ```
100 |
101 | ### 运行方式
102 | 进入 MySQL_Diagnose 根目录,执行下面命令即可:
103 | `python3 mysql_diagnose.py`
104 |
105 | ### 流程图
106 | 
107 |
--------------------------------------------------------------------------------
/__pycache__/monitor.cpython-35.pyc:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/thinkdb/MySQL_Diagnose/e37cc20928102c859f0b75dd153726dfae4042fe/__pycache__/monitor.cpython-35.pyc
--------------------------------------------------------------------------------
/conf/account_info.json:
--------------------------------------------------------------------------------
1 | {
2 | "192.168.20.88": {
3 | "host": "192.168.20.88",
4 | "ssh_account": "root",
5 | "ssh_passwd": "123456",
6 | "ssh_port": 22,
7 | "mysql_account": "admin",
8 | "mysql_port": 3306,
9 | "mysql_passwd": "admin"
10 | }
11 | }
--------------------------------------------------------------------------------
/conf/diagnose.cnf:
--------------------------------------------------------------------------------
1 | [default]
2 | processing=2
3 | host=192.168.20.88
4 | user=hotdb_cloud
5 | password=hotdb_cloud
6 | port=3306
7 | database=test
8 | log_level=10
9 | type=1
--------------------------------------------------------------------------------
/imgs/favicon.ico:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/thinkdb/MySQL_Diagnose/e37cc20928102c859f0b75dd153726dfae4042fe/imgs/favicon.ico
--------------------------------------------------------------------------------
/imgs/flow_chart.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/thinkdb/MySQL_Diagnose/e37cc20928102c859f0b75dd153726dfae4042fe/imgs/flow_chart.png
--------------------------------------------------------------------------------
/lib/__init__.py:
--------------------------------------------------------------------------------
1 | #!/bin/env python
2 | # -*- coding:utf8 -*-
--------------------------------------------------------------------------------
/lib/__pycache__/__init__.cpython-35.pyc:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/thinkdb/MySQL_Diagnose/e37cc20928102c859f0b75dd153726dfae4042fe/lib/__pycache__/__init__.cpython-35.pyc
--------------------------------------------------------------------------------
/lib/__pycache__/funcs.cpython-35.pyc:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/thinkdb/MySQL_Diagnose/e37cc20928102c859f0b75dd153726dfae4042fe/lib/__pycache__/funcs.cpython-35.pyc
--------------------------------------------------------------------------------
/lib/funcs.py:
--------------------------------------------------------------------------------
1 | #!/bin/env python
2 | # -*- coding:utf8 -*-
3 | from pymysql.err import DataError
4 | import pymysql
5 | import paramiko
6 | import re
7 | import os
8 | import sys
9 | import time
10 | import configparser
11 | import logging.config
12 |
13 | BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
14 |
15 |
16 | class DBAPI(object):
17 | def __init__(self, host, user, password, port, database=None, auto_commit=0):
18 | self.host = host
19 | try:
20 | self.conn = pymysql.connect(host=self.host, user=user, passwd=password,
21 | port=int(port), charset='utf8mb4',
22 | )
23 | if database:
24 | self.conn.select_db(database)
25 |
26 | if auto_commit:
27 | self.conn.autocommit(auto_commit)
28 | self.cur = self.conn.cursor(pymysql.cursors.DictCursor)
29 | except Exception as e:
30 | Logger().logger(30).error('{ip}: '.format(ip=host) + str(e))
31 | sys.exit(str(e))
32 |
33 | def query(self, sql):
34 | try:
35 | self.cur.execute(sql)
36 | result = self.cur.fetchall()
37 | except Exception as e:
38 | Logger().logger(30).error('{ip}: '.format(ip=self.host) + str(e))
39 | result = e
40 | return result
41 |
42 | def conn_dml(self, sql):
43 | try:
44 | rel = self.cur.execute(sql)
45 | return rel
46 | except Exception as e:
47 | Logger().logger(30).error('{ip}: '.format(ip=self.host) + str(e))
48 | return e
49 |
50 | def dml_commit(self):
51 | self.conn.commit()
52 |
53 | def dml_rollback(self):
54 | self.conn.rollback()
55 |
56 | def close(self):
57 | self.cur.close()
58 | self.conn.close()
59 |
60 |
61 | class RunRomoteCmd(object):
62 | def __init__(self, ip, ssh_user, ssh_passwd, ssh_port):
63 | self.ip = ip
64 | self.user = ssh_user
65 | self.passwd = ssh_passwd
66 | self.port = int(ssh_port)
67 | try:
68 | self.transport = paramiko.Transport(self.ip, self.port)
69 | except Exception as e:
70 | Logger().logger(30).error('{ip}: '.format(ip=self.ip) + str(e))
71 | print(str(e))
72 | self.transport.connect(username=self.user, password=self.passwd)
73 | self.ssh = paramiko.SSHClient()
74 | self.ssh._transport = self.transport
75 |
76 | def run_cmd(self, cmd):
77 | try:
78 | stdin, stdout, stderr = self.ssh.exec_command(cmd)
79 | if len(stderr.read()) == 0:
80 | data = stdout.read()
81 | else:
82 | data = stderr.read()
83 | return data
84 | except Exception as e:
85 | self.close_conn()
86 | Logger().logger(30).error('{ip}: '.format(ip=self.ip) + str(e))
87 | print(str(e))
88 |
89 | def close_conn(self):
90 | self.transport.close()
91 |
92 |
93 | class OsInfo(RunRomoteCmd):
94 | def __init__(self, ip, ssh_user, ssh_passwd, ssh_port):
95 | super(OsInfo, self).__init__(ip, ssh_user, ssh_passwd, ssh_port)
96 | self.kernel_release = None
97 | self.a = None
98 | self.b = None
99 | self.c = None
100 |
101 | def __get_iops(self):
102 | devices = self.run_cmd('cat /proc/diskstats').decode()
103 | io_stat_dict = {}
104 | for item in devices.split('\n')[:-1]:
105 | if re.search('loop', item) or re.search('ram', item) or re.search('sr', item):
106 | pass
107 | else:
108 | line_data = item.split()
109 | if re.search('.\d', line_data[2]):
110 | disk_name = line_data[2]
111 | read_io = line_data[4]
112 | write_io = line_data[8]
113 | if disk_name.startswith('dm'):
114 | dm_num = disk_name.split('-')[1]
115 | pv_data = self.run_cmd('cd /dev/mapper/; dmsetup ls').decode()
116 | for line in pv_data.split('\n')[:-1]:
117 | pv_name = line.split()[0]
118 | pv_num = line.split()[1].split(':')[1].split(')')[0]
119 | if dm_num == pv_num:
120 | io_stat_dict[pv_name] = {'read_io': read_io, 'write_io': write_io}
121 | else:
122 | io_stat_dict[disk_name] = {'read_io': read_io, 'write_io': write_io}
123 | return io_stat_dict
124 |
125 | def get_iops(self, times, interval=1):
126 | if times > 10:
127 | times = 10
128 | new_io_stat_dict = {}
129 | for item in range(times):
130 | if item % 2 == 0:
131 | new_io_stat_dict['class_style'] = 'awrc'
132 | else:
133 | new_io_stat_dict['class_style'] = 'awrnc'
134 |
135 | io_data1 = self.__get_iops()
136 | net_tran1 = self.get_net_tran()
137 | time.sleep(interval)
138 | current_time = time.strftime('%Y-%m-%d %H:%M:%S', time.localtime(time.time()))
139 | net_tran2 = self.get_net_tran()
140 | io_data2 = self.__get_iops()
141 | for keys in net_tran1.keys():
142 | for item in net_tran2.keys():
143 | if keys == item:
144 | for i in net_tran1[keys].keys():
145 | for j in net_tran2[keys].keys():
146 | if i == j:
147 | receive = int(net_tran2[keys]['Receive']) - int(net_tran1[keys]['Receive'])
148 | transmit = int(net_tran2[keys]['Transmit']) - int(net_tran1[keys]['Transmit'])
149 | new_io_stat_dict[keys] = {'Receive': receive, 'Transmit': transmit}
150 |
151 | for keys in io_data2.keys():
152 | for item in io_data1.keys():
153 | if keys == item:
154 | read_io = int(io_data2[keys]['read_io']) - int(io_data1[keys]['read_io'])
155 | write_io = int(io_data2[keys]['write_io']) - int(io_data1[keys]['write_io'])
156 | new_io_stat_dict[keys] = {'write_io': write_io, 'read_io': read_io}
157 |
158 | new_io_stat_dict['time'] = current_time
159 | yield new_io_stat_dict
160 | # new_io_stat_dict = {}
161 |
162 | def get_disk_info(self):
163 | use_stat_dict = {}
164 | data = self.run_cmd("df -TmP")
165 | if len(data) != 0:
166 | disk_data = data.decode().split('\n')
167 | for line in disk_data[1:-1]:
168 | file_system_type = line.split()[1]
169 | total_mb = line.split()[2]
170 | used_mb = line.split()[3]
171 | use_per = line.split()[5].split('%')[0]
172 | avail_mb = line.split()[4]
173 | mount_on = line.split()[6]
174 | mount_disk = line.split()[0]
175 | use_stat_dict[mount_disk] = {"file_system_type": file_system_type,
176 | "total_mb": total_mb,
177 | "used_mb": used_mb,
178 | "use_per": use_per,
179 | "avail_mb": avail_mb,
180 | "mount_on": mount_on
181 | }
182 | data_inode = self.run_cmd("df -iP")
183 | inode = data_inode.decode().split('\n')
184 | for line in inode[1:-1]:
185 | mount_disk = line.split()[0]
186 | inode_per = line.split()[4].split('%')[0]
187 | use_stat_dict[mount_disk]['inode'] = inode_per
188 |
189 | return use_stat_dict
190 |
191 | def get_mem_info(self):
192 | mem_dict = {}
193 | data = self.run_cmd('cat /proc/meminfo').decode()
194 | for line in data.split('\n')[:-1]:
195 | if line.split()[0] in ('MemTotal:', 'MemFree:', 'Buffers:', 'Cached:',
196 | 'SwapCached:', 'SwapTotal:', 'SwapFree:'):
197 | mem_dict[line.split()[0].split(':')[0]] = int(int(line.split()[1])/1024)
198 | free_mem = mem_dict['Buffers'] + mem_dict['Cached'] + mem_dict['MemFree']
199 | mem_use_per = 100 - int(free_mem / mem_dict['MemTotal'] * 100)
200 | mem_dict['mem_use_per'] = mem_use_per
201 | return mem_dict
202 |
203 | def get_cpu_info(self):
204 | cpu_load_dict = {}
205 |
206 | # 获取 cpu 核心数
207 | info_data = self.run_cmd('cat /proc/cpuinfo').decode()
208 | for line in info_data.split('\n')[:-1]:
209 | if line == '':
210 | pass
211 | elif line.split(':')[0].strip() == 'processor':
212 | core_num = int(line.split(':')[1].strip()) + 1
213 | cpu_load_dict["core"] = int(core_num)
214 |
215 | # 获取负载情况
216 | load_data = self.run_cmd('uptime').decode()
217 | for line in load_data.split('\n')[:-1]:
218 | uptime_day = line.split(',')[0].split()[2]
219 | uptime_hour = line.split(',')[1]
220 | load_1 = line.split(':')[-1].split(',')[0]
221 | load_5 = line.split(':')[-1].split(',')[1]
222 | load_15 = line.split(':')[-1].split(',')[2]
223 | uptime = uptime_day + ' days ' + uptime_hour
224 | cpu_load_dict['uptime'] = uptime
225 | cpu_load_dict['load_1'] = float(load_1)
226 | cpu_load_dict['load_5'] = float(load_5)
227 | cpu_load_dict['load_15'] = float(load_15.strip())
228 |
229 | return cpu_load_dict
230 |
231 | def get_net_tran(self):
232 | net_tran = {}
233 | data = self.run_cmd('cat /proc/net/dev').decode()
234 | for line in data.split('\n')[2:-1]:
235 | dev = line.split(':')[0].strip()
236 | if not dev.startswith('lo'):
237 | receive = line.split(':')[1].split()[0]
238 | transmit = line.split(':')[1].split()[8]
239 | net_tran['net_' + dev] = {'Receive': receive, 'Transmit': transmit}
240 | return net_tran
241 |
242 | def get_os_version(self):
243 | version_dict = {}
244 | data = self.run_cmd('uname -a').decode()
245 | version_dict['os_version'] = data.split()[0] + ' ' + data.split()[-2]
246 | version_dict['hostname'] = data.split()[1]
247 | version_dict['kernel_release'] = data.split()[2].split('-')[0]
248 | return version_dict
249 |
250 | def get_cpu_stat(self):
251 | """
252 | CPU times:
253 | (user, nice, system, idle, iowait, irq, softirq [steal, [guest,[guest_nice]]])
254 | Last 3 fields may not be available on all Linux kernel versions.
255 | - user
256 | - nice (UNIX)
257 | - system
258 | - idle
259 | - iowait (Linux)
260 | - irq (Linux, FreeBSD)
261 | - softirq (Linux)
262 | - steal (Linux >= 2.6.11)
263 | - guest (Linux >= 2.6.24)
264 | - guest_nice (Linux >= 3.2.0)
265 | """
266 | if not self.kernel_release:
267 | self.kernel_release = self.get_os_version()['kernel_release']
268 | self.a, self.b, self.c = self.kernel_release.split('.')
269 | cpu_stat = {}
270 | data = self.run_cmd('cat /proc/stat').decode().split('\n')
271 | for item in data:
272 | if re.search('^cpu[0-9]+', item):
273 | cpu_stat_list = item.split()
274 | cpu_stat[cpu_stat_list[0]] = {
275 | 'user': cpu_stat_list[1],
276 | 'nice': cpu_stat_list[2],
277 | 'system': cpu_stat_list[3],
278 | 'idle': cpu_stat_list[4],
279 | 'iowait': cpu_stat_list[5],
280 | 'irq': cpu_stat_list[6],
281 | 'softirq': cpu_stat_list[7]
282 | }
283 | if int(self.a) == 2 and int(self.c) >= 11:
284 | cpu_stat[cpu_stat_list[0]]['steal'] = cpu_stat_list[8]
285 | if int(self.a) == 2 and int(self.c) >= 24:
286 | cpu_stat[cpu_stat_list[0]]['guest'] = cpu_stat_list[9]
287 | if int(self.a) == 3 and int(self.b) >= 2:
288 | cpu_stat[cpu_stat_list[0]]['guest_nice'] = cpu_stat_list[10]
289 | return cpu_stat
290 |
291 |
292 | class MySQLBseInfo(object):
293 | def __init__(self, host, user, passwd, port):
294 | self.host = host
295 | self.user = user
296 | self.passwd = passwd
297 | self.port = int(port)
298 | self.variables_dict = {}
299 | self.status_dict = {}
300 | self.slave_info_dict = {}
301 | self.master_info_dict = {}
302 | self.my_conn = DBAPI(self.host, self.user, self.passwd, self.port)
303 | self.__check_sql_mode()
304 |
305 | def get_global_variables(self, name=None):
306 | """
307 | :param name: str,list or tuple
308 | :return:
309 | """
310 | variables_dict = {}
311 | name_list = []
312 | if not self.variables_dict:
313 | variables_tuple = self.my_conn.query('show global variables')
314 | for items in variables_tuple:
315 | self.variables_dict[items['Variable_name']] = items['Value']
316 | if name:
317 | if isinstance(name, str):
318 | name_list.append(name)
319 | name = tuple(name_list)
320 | else:
321 | name = tuple(name)
322 | for item in name:
323 | if self.variables_dict.get(item):
324 | variables_dict[item] = self.variables_dict[item]
325 | else:
326 | variables_dict[item] = DataError
327 | else:
328 | variables_dict = self.variables_dict
329 | return variables_dict
330 |
331 | def get_global_status(self, name=None, get_diff=None):
332 | """
333 | :param name: str, list or tuple
334 | :param get_diff:
335 | :return:
336 | """
337 | name_list = []
338 | if not self.status_dict:
339 | status_tuple = self.my_conn.query('show global status')
340 | for items in status_tuple:
341 | self.status_dict[items['Variable_name']] = items['Value']
342 | if get_diff:
343 | status_dict_2 = {}
344 | status_tuple = self.my_conn.query('show global status')
345 | for items in status_tuple:
346 | status_dict_2[items['Variable_name']] = items['Value']
347 |
348 | return status_dict_2
349 |
350 | status_dict = {}
351 |
352 | if name:
353 | if isinstance(name, str):
354 | name_list.append(name)
355 | name = tuple(name_list)
356 | else:
357 | name = tuple(name)
358 | for item in name:
359 | if self.status_dict.get(item):
360 | status_dict[item] = self.status_dict[item]
361 | else:
362 | status_dict[item] = DataError
363 | else:
364 | status_dict = self.status_dict
365 | return status_dict
366 |
367 | def get_slave_info(self):
368 | if not self.slave_info_dict:
369 | slave_info_tuple = self.my_conn.query('show slave status')
370 | if slave_info_tuple:
371 | self.slave_info_dict = slave_info_tuple[0]
372 | return self.slave_info_dict
373 |
374 | def get_master_info(self):
375 | if not self.master_info_dict:
376 | self.master_info_dict = self.my_conn.query('show master status')[0]
377 | return self.master_info_dict
378 |
379 | def close(self):
380 | self.my_conn.close()
381 |
382 | def __check_sql_mode(self):
383 | mode_str = ''
384 | sql = "show variables like 'sql_mode'"
385 | ret = self.my_conn.query(sql)
386 | sql_mode_list = ret[0]['Value'].split(',')
387 | if 'ONLY_FULL_GROUP_BY' in sql_mode_list:
388 | sql_mode_list.remove('ONLY_FULL_GROUP_BY')
389 | for item in sql_mode_list:
390 | mode_str += item + ','
391 | mode_str = mode_str[:-1]
392 | self.my_conn.conn_dml("set sql_mode='{mode}'".format(mode=mode_str))
393 |
394 |
395 | class Logger(object):
396 | def logger(self, log_level):
397 | """
398 | logger().level(str(message))
399 | """
400 |
401 | level = logging.INFO
402 |
403 | if log_level == 10:
404 | level = logging.DEBUG
405 | if log_level == 20:
406 | level = logging.INFO
407 | if log_level == 30:
408 | level = logging.WARNING
409 | if log_level == 40:
410 | level = logging.ERROR
411 | if log_level == 50:
412 | level = logging.CRITICAL
413 | logging.config.dictConfig({
414 | 'version': 1,
415 | 'disable_existing_loggers': True,
416 | 'formatters': {
417 | 'verbose': {
418 | 'format': "%(asctime)s - [%(levelname)s] %(message)s",
419 | 'datefmt': "%c"
420 | },
421 | },
422 | 'handlers': {
423 | 'console': {
424 | 'level': 'DEBUG',
425 | 'class': 'logging.StreamHandler',
426 | 'formatter': 'verbose'
427 | },
428 | 'file': {
429 | 'level': 'DEBUG',
430 | 'class': 'logging.handlers.RotatingFileHandler',
431 | 'filename': BASE_DIR + '/logs/mysql_diagnose.log',
432 | 'formatter': 'verbose'
433 | }
434 | },
435 | 'loggers': {
436 | '': {
437 | 'handlers': ['file'],
438 | 'level': level,
439 | },
440 | }
441 | })
442 |
443 | logger1 = logging.getLogger()
444 |
445 | return logger1
446 |
447 |
448 | def get_config():
449 | config = configparser.ConfigParser()
450 | config.read('./conf/diagnose.cnf', encoding='utf-8')
451 | section_has = config.has_section('default')
452 | if not section_has:
453 | sys.exit("Error: The '[default]' not find")
454 | processing = config.get("default", "processing")
455 | host = config.get("default", "host")
456 | user = config.get("default", "user")
457 | password = config.get("default", "password")
458 | port = config.get("default", "port")
459 | database = config.get("default", "database")
460 | log_level = config.get("default", "log_level")
461 | type = config.get("default", "type")
462 |
463 | conf_dict = {
464 | 'processing': processing,
465 | 'user': user,
466 | 'host': host,
467 | 'password': password,
468 | 'port': port,
469 | 'database': database,
470 | 'log_level': log_level,
471 | 'type': type
472 | }
473 | return conf_dict
474 |
--------------------------------------------------------------------------------
/logs/mysql_diagnose.log:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/thinkdb/MySQL_Diagnose/e37cc20928102c859f0b75dd153726dfae4042fe/logs/mysql_diagnose.log
--------------------------------------------------------------------------------
/machine/__pycache__/machine_html_result.cpython-35.pyc:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/thinkdb/MySQL_Diagnose/e37cc20928102c859f0b75dd153726dfae4042fe/machine/__pycache__/machine_html_result.cpython-35.pyc
--------------------------------------------------------------------------------
/machine/machine_html_result.py:
--------------------------------------------------------------------------------
1 | #!/bin/env python
2 | # -*- coding:utf8 -*-
3 |
4 | import time
5 |
6 |
7 | def get_host_info(os_connected_stream):
8 | cpu_stat_dict = {}
9 | cpu_stat_1 = os_connected_stream.get_cpu_stat()
10 | time.sleep(1)
11 | cpu_stat_2 = os_connected_stream.get_cpu_stat()
12 | steal1 = guest1 = guest_nice1 = steal2 = guest2 = guest_nice2 = 0
13 |
14 | class_style = 'awrnc'
15 | for item in cpu_stat_2:
16 | item_info = cpu_stat_2[item]
17 | user2 = int(item_info['user'])
18 | nice2 = int(item_info['nice'])
19 | idle2 = int(item_info['idle'])
20 | iowait2 = int(item_info['iowait'])
21 | irq2 = int(item_info['irq'])
22 | softirq2 = int(item_info['softirq'])
23 | system2 = int(item_info['system'])
24 |
25 | # sleep
26 | user1 = int(cpu_stat_1[item]['user'])
27 | nice1 = int(cpu_stat_1[item]['nice'])
28 | idle1 = int(cpu_stat_1[item]['idle'])
29 | iowait1 = int(cpu_stat_1[item]['iowait'])
30 | irq1 = int(cpu_stat_1[item]['irq'])
31 | softirq1 = int(cpu_stat_1[item]['softirq'])
32 | system1 = int(cpu_stat_1[item]['system'])
33 |
34 | if int(os_connected_stream.a) == 2 and int(os_connected_stream.c) >= 11:
35 | steal2 = int(item_info['steal'])
36 | steal1 = int(cpu_stat_1[item]['steal'])
37 | if int(os_connected_stream.a) == 2 and int(os_connected_stream.c) >= 24:
38 | guest2 = int(item_info['guest'])
39 | guest1 = int(cpu_stat_1[item]['guest'])
40 | if int(os_connected_stream.a) == 3 and int(os_connected_stream.b) >= 2:
41 | guest_nice2 = int(item_info['guest_nice'])
42 | guest_nice1 = int(cpu_stat_1[item]['guest_nice'])
43 |
44 | total_1 = user1 + nice1 + idle1 + iowait1 + irq1 + softirq1 + system1 + steal1 + guest1 + guest_nice1
45 | total_2 = user2 + nice2 + idle2 + iowait2 + irq2 + softirq2 + system2 + steal2 + guest2 + guest_nice2
46 | total = total_2 - total_1
47 | idle = (idle2 - idle1)/total * 100
48 | system = (system2 - system1)/total * 100
49 | user = (user2 - user1)/total * 100
50 | nice = (nice1 - nice2)/total * 100
51 | iowait = (iowait2 - iowait1)/total * 100
52 |
53 | hi = (irq2-irq1)/total * 100
54 | si = (softirq2-softirq1)/total * 100
55 | st = (steal2-steal1)/total * 100
56 |
57 | cpu_stat_dict[item] = {}
58 | cpu_stat_dict[item]['idle'] = idle
59 | cpu_stat_dict[item]['system'] = system
60 | cpu_stat_dict[item]['user'] = user
61 | cpu_stat_dict[item]['nice'] = nice
62 | cpu_stat_dict[item]['iowait'] = iowait
63 | cpu_stat_dict[item]['hi'] = hi
64 | cpu_stat_dict[item]['si'] = si
65 | cpu_stat_dict[item]['st'] = st
66 |
67 | os_version = os_connected_stream.get_os_version()
68 | cpu = os_connected_stream.get_cpu_info()
69 | memory = os_connected_stream.get_mem_info()
70 |
71 | base_info = "