void print_stats(struct list *masters, struct list *foremen, int submitted, int needed, int requested, int connected) { struct timeval tv; struct tm *tm; gettimeofday(&tv, 0); tm = localtime(&tv.tv_sec); int to_connect = submitted - connected; needed = needed > 0 ? needed : 0; requested = requested > 0 ? requested : 0; to_connect = to_connect > 0 ? to_connect : 0; fprintf(stdout, "%04d/%02d/%02d %02d:%02d:%02d: " "|submitted: %d |needed: %d |waiting connection: %d |requested: %d \n", tm->tm_year + 1900, tm->tm_mon + 1, tm->tm_mday, tm->tm_hour, tm->tm_min, tm->tm_sec, submitted, needed, to_connect, requested); int master_count = 0; master_count += masters ? list_size(masters) : 0; master_count += foremen ? list_size(foremen) : 0; if(master_count < 1) { fprintf(stdout, "No change this cycle.\n\n"); return; } int columns = 80; char *column_str = getenv("COLUMNS"); if(column_str) { columns = atoi(column_str); columns = columns < 1 ? 80 : columns; } jx_table_print_header(queue_headers,stdout,columns); struct jx *j; if(masters && list_size(masters) > 0) { list_first_item(masters); while((j = list_next_item(masters))) { if(!using_catalog) { jx_insert_string(j, "name", master_host); } jx_table_print(queue_headers, j, stdout, columns); } } if(foremen && list_size(foremen) > 0) { fprintf(stdout, "foremen:\n"); list_first_item(foremen); while((j = list_next_item(foremen))) { jx_table_print(queue_headers, j, stdout, columns); } } fprintf(stdout, "\n"); fflush(stdout); }
int main(int argc, char *argv[]) { enum { LONGOPT_SERVER_LASTHEARDFROM = INT_MAX-0, LONGOPT_SERVER_PROJECT = INT_MAX-1, LONGOPT_WHERE = INT_MAX-2, }; static const struct option long_options[] = { {"all", no_argument, 0, 'a'}, {"brief", no_argument, 0, 's'}, {"catalog", required_argument, 0, 'c'}, {"debug", required_argument, 0, 'd'}, {"debug-file", required_argument, 0, 'o'}, {"debug-rotate-max", required_argument, 0, 'O'}, {"help", no_argument, 0, 'h'}, {"server-lastheardfrom", required_argument, 0, LONGOPT_SERVER_LASTHEARDFROM}, {"server-project", required_argument, 0, LONGOPT_SERVER_PROJECT}, {"server-space", required_argument, 0, 'A'}, {"timeout", required_argument, 0, 't'}, {"totals", no_argument, 0, 'T'}, {"verbose", no_argument, 0, 'l'}, {"version", no_argument, 0, 'v'}, {"where", required_argument, 0, LONGOPT_WHERE }, {0, 0, 0, 0} }; struct catalog_query *q; struct jx *j; time_t timeout = 60, stoptime; const char *catalog_host = 0; int i; int c; int count = 0; int mode = MODE_TABLE; INT64_T sum_total = 0, sum_avail = 0; const char *filter_name = 0; const char *filter_value = 0; const char *where_expr = "true"; int show_all_types = 0; const char *server_project = NULL; time_t server_lastheardfrom = 0; uint64_t server_avail = 0; debug_config(argv[0]); while((c = getopt_long(argc, argv, "aA:c:d:t:o:O:sTlvh", long_options, NULL)) > -1) { switch (c) { case 'a': show_all_types = 1; break; case 'c': catalog_host = optarg; break; case 'd': debug_flags_set(optarg); break; case 't': timeout = string_time_parse(optarg); break; case 'A': server_avail = string_metric_parse(optarg); break; case 'o': debug_config_file(optarg); break; case 'O': debug_config_file_size(string_metric_parse(optarg)); break; case 'v': cctools_version_print(stdout, argv[0]); return 1; case 's': mode = MODE_SHORT; break; case 'l': mode = MODE_LONG; break; case 'T': mode = MODE_TOTAL; break; case LONGOPT_SERVER_LASTHEARDFROM: server_lastheardfrom = time(0)-string_time_parse(optarg); break; case LONGOPT_SERVER_PROJECT: server_project = xxstrdup(optarg); break; case LONGOPT_WHERE: where_expr = optarg; break; case 'h': default: show_help(argv[0]); return 1; } } cctools_version_debug(D_DEBUG, argv[0]); if(argc - optind == 0) { // fine, keep going } else if((argc - optind) == 1) { filter_name = "name"; filter_value = argv[optind]; } else if((argc - optind) == 2) { filter_name = argv[optind]; filter_value = argv[optind + 1]; } else { show_help(argv[0]); return 1; } stoptime = time(0) + timeout; const char *query_expr; if(show_all_types) { query_expr = where_expr; } else { query_expr = string_format("%s && (type==\"chirp\" || type==\"catalog\")",where_expr); } struct jx *jexpr = jx_parse_string(query_expr); if(!jexpr) { fprintf(stderr,"invalid expression: %s\n",query_expr); return 1; } q = catalog_query_create(catalog_host, 0, jexpr, stoptime); if(!q) { fprintf(stderr, "couldn't query catalog: %s\n", strerror(errno)); return 1; } if(mode == MODE_TABLE) { jx_table_print_header(headers,stdout); } else if(mode==MODE_LONG) { printf("[\n"); } while((j = catalog_query_read(q, stoptime))) { table[count++] = j; } catalog_query_delete(q); qsort(table, count, sizeof(*table), (int (*)(const void *, const void *)) compare_entries); for(i = 0; i < count; i++) { const char *lastheardfrom = jx_lookup_string(table[i], "lastheardfrom"); if (lastheardfrom && (time_t)strtoul(lastheardfrom, NULL, 10) < server_lastheardfrom) continue; const char *avail = jx_lookup_string(table[i], "avail"); if (avail && strtoul(avail, NULL, 10) < server_avail) continue; const char *project = jx_lookup_string(table[i], "project"); if (server_project && (project == NULL || !(strcmp(project, server_project) == 0))) continue; if(filter_name) { const char *v = jx_lookup_string(table[i], filter_name); if(!v || strcmp(filter_value, v)) continue; } if(mode == MODE_SHORT) { const char *t = jx_lookup_string(table[i], "type"); if(t && !strcmp(t, "chirp")) { printf("%s:%d\n", jx_lookup_string(table[i], "name"), (int) jx_lookup_integer(table[i], "port")); } } else if(mode == MODE_LONG) { if(i!=0) printf(",\n"); jx_print_stream(table[i],stdout); } else if(mode == MODE_TABLE) { jx_table_print(headers, table[i], stdout); } else if(mode == MODE_TOTAL) { sum_avail += jx_lookup_integer(table[i], "avail"); sum_total += jx_lookup_integer(table[i], "total"); } } for(i=0;i<count;i++) { jx_delete(table[i]); } if(mode == MODE_TOTAL) { printf("NODES: %4d\n", count); printf("TOTAL: %6sB\n", string_metric(sum_total, -1, 0)); printf("AVAIL: %6sB\n", string_metric(sum_avail, -1, 0)); printf("INUSE: %6sB\n", string_metric(sum_total - sum_avail, -1, 0)); } else if(mode == MODE_TABLE) { jx_table_print_footer(headers,stdout); } else if(mode==MODE_LONG) { printf("\n]\n"); } return 0; }