#include "gb-include.h" #include "TcpServer.h" #include "HttpServer.h" #include "Pages.h" #include "JobScheduler.h" #include "SafeBuf.h" #include "Profiler.h" static const char *thread_type_name(thread_type_t tt) { switch(tt) { case thread_type_query_coordinator: return "query-coordinator"; case thread_type_query_read: return "query-read"; case thread_type_query_constrain: return "query-constrain"; case thread_type_query_merge: return "query-merge"; case thread_type_query_intersect: return "query-intersect"; case thread_type_query_summary: return "query-summary"; case thread_type_spider_read: return "spider-read"; case thread_type_spider_write: return "spider-write"; case thread_type_spider_filter: return "spider-filter"; case thread_type_spider_query: return "spider-query"; case thread_type_spider_index: return "spider-index"; case thread_type_merge_filter: return "merge-filter"; case thread_type_replicate_write: return "replicate-write"; case thread_type_replicate_read: return "replicate-read"; case thread_type_file_merge: return "file-merge"; case thread_type_file_meta_data: return "file-meta-data"; case thread_type_index_merge: return "index-merge"; case thread_type_index_generate: return "index-generate"; case thread_type_verify_data: return "verify-data"; case thread_type_statistics: return "statistics"; case thread_type_unspecified_io: return "unspecified IO"; case thread_type_generate_thumbnail: return "generate-thumbnail"; case thread_type_config_load: return "config-load"; case thread_type_page_process: return "page-process"; default: return "?"; } } bool sendPageThreads ( TcpSocket *s , HttpRequest *r ) { StackBuf<64*1024> p; g_pages.printAdminTop ( &p , s , r ); std::vector<JobDigest> job_digests = g_jobScheduler.query_job_digests(); int64_t now = gettimeofdayInMilliseconds(); //print summary and count per thread type p.safePrintf("<table %s>", TABLE_STYLE); p.safePrintf(" <tr class=hdrow>\n"); p.safePrintf(" <td colspan=\"1\"><b>Job type</b></td>\n"); p.safePrintf(" <td colspan=\"6\"><b>State</b></td>\n"); p.safePrintf(" </tr>\n"); p.safePrintf(" <tr class=hdrow>\n"); p.safePrintf(" <td colspan=\"1\"></td>\n"); p.safePrintf(" <td colspan=\"2\"><b>Queued</b></td>\n"); p.safePrintf(" <td colspan=\"2\"><b>Running</b></td>\n"); p.safePrintf(" <td colspan=\"2\"><b>Stopped</b></td>\n"); p.safePrintf(" </tr>\n"); p.safePrintf(" <tr class=hdrow>\n"); p.safePrintf(" <td colspan=\"1\"></td>\n"); p.safePrintf(" <td colspan=\"1\"><b>Count</b></td>\n"); p.safePrintf(" <td colspan=\"1\"><b>Avg. time</b></td>\n"); p.safePrintf(" <td colspan=\"1\"><b>Count</b></td>\n"); p.safePrintf(" <td colspan=\"1\"><b>Avg time</b></td>\n"); p.safePrintf(" <td colspan=\"1\"><b>Count</b></td>\n"); p.safePrintf(" <td colspan=\"1\"><b>Avg time</b></td>\n"); p.safePrintf(" </tr>\n"); for(int thread_type=thread_type_query_coordinator; thread_type<=thread_type_generate_thumbnail; thread_type++) { int queued_count=0; uint64_t queued_time=0; int running_count=0; uint64_t running_time=0; int stopped_count=0; uint64_t stopped_time=0; for(const auto &jd : job_digests) { if(jd.thread_type==thread_type) { if(jd.job_state==JobDigest::job_state_queued) { queued_count++; queued_time += (now-jd.queue_enter_time); } if(jd.job_state==JobDigest::job_state_running) { running_count++; running_time += (now-jd.start_time); } if(jd.job_state==JobDigest::job_state_stopped) { stopped_count++; stopped_time += (now-jd.stop_time); } } } p.safePrintf(" <tr bgcolor=#%s>\n",LIGHT_BLUE); p.safePrintf(" <td>%s</td>\n", thread_type_name((thread_type_t)thread_type)); if(queued_count) p.safePrintf(" <td>%d</td><td>%" PRIu64"</td>\n", queued_count, queued_time/queued_count); else p.safePrintf(" <td>-</td><td>-</td>\n"); if(running_count) p.safePrintf(" <td>%d</td><td>%" PRIu64"</td>\n", running_count, running_time/running_count); else p.safePrintf(" <td>-</td><td>-</td>\n"); if(stopped_count) p.safePrintf(" <td>%d</td><td>%" PRIu64"</td>\n", stopped_count, stopped_time/stopped_count); else p.safePrintf(" <td>-</td><td>-</td>\n"); } p.safePrintf("</table><br><br>"); // print details per job p.safePrintf("<table %s>", TABLE_STYLE); p.safePrintf(" <tr class=hdrow>\n"); p.safePrintf(" <td><b>Job type</b></td>\n"); p.safePrintf(" <td><b>Routine</b></td>\n"); p.safePrintf(" <td><b>Queued time</b></td>\n"); p.safePrintf(" <td><b>Running time</b></td>\n"); p.safePrintf(" <td><b>Stopped time</b></td>\n"); p.safePrintf(" </tr>\n"); for(const auto &jd : job_digests) { p.safePrintf(" <tr bgcolor=#%s>\n",LIGHT_BLUE); p.safePrintf(" <td>%s</td>", thread_type_name(jd.thread_type)); p.safePrintf(" <td>%s</td>", g_profiler.getFnName((PTRTYPE)jd.start_routine)); p.safePrintf(" <td>%" PRIu64"</td>", now-jd.queue_enter_time); if(jd.job_state==JobDigest::job_state_running || jd.job_state==JobDigest::job_state_stopped) p.safePrintf(" <td>%" PRIu64"</td>", now-jd.start_time); else p.safePrintf(" <td></td>"); if(jd.job_state==JobDigest::job_state_stopped) p.safePrintf(" <td>%" PRIu64"</td>", now-jd.stop_time); else p.safePrintf(" <td></td>"); p.safePrintf(" </tr>\n"); } p.safePrintf("</table><br><br>"); //print timing / wait time / delay statistics per job type p.safePrintf("<table %s>", TABLE_STYLE); p.safePrintf(" <tr class=hdrow>\n"); p.safePrintf(" <td><b>Job type</b></td>\n"); p.safePrintf(" <td><b>Count</b></td>\n"); p.safePrintf(" <td><b>Time in queue</b></td>\n"); p.safePrintf(" <td><b>Time executing</b></td>\n"); p.safePrintf(" <td><b>Time waiting for cleanup</b></td>\n"); p.safePrintf(" <td><b>Cleanup time</b></td>\n"); p.safePrintf(" </tr>\n"); for(const auto &js : g_jobScheduler.query_job_statistics(true)) { p.safePrintf(" <tr bgcolor=#%s>\n",LIGHT_BLUE); p.safePrintf(" <td>%s</td>", thread_type_name(js.first)); p.safePrintf("<!-- %lu %lu %lu %lu %lu -->\n", js.second.job_count,js.second.queue_time,js.second.running_time,js.second.done_time,js.second.cleanup_time); p.safePrintf(" <td>%lu</td>\n",js.second.job_count); if(js.second.job_count!=0) { p.safePrintf(" <td>%.3f</td>\n", (double)js.second.queue_time/js.second.job_count/1000.0); p.safePrintf(" <td>%.3f</td>\n", (double)js.second.running_time/js.second.job_count/1000.0); p.safePrintf(" <td>%.3f</td>\n", (double)js.second.done_time/js.second.job_count/1000.0); p.safePrintf(" <td>%.3f</td>\n", (double)js.second.cleanup_time/js.second.job_count/1000.0); } else { p.safePrintf(" <td>-</td>\n"); p.safePrintf(" <td>-</td>\n"); p.safePrintf(" <td>-</td>\n"); p.safePrintf(" <td>-</td>\n"); } p.safePrintf(" </tr>\n"); } return g_httpServer.sendDynamicPage ( s , (char*) p.getBufStart() , p.length() ); }