/* running in print live mode */ void running_print_live() {//实时隔一会打印一行数据。 int print_num = 1, re_p_hdr = 0; collect_record(); /* print header */ print_header(); /* set struct module fields */ init_module_fields(); /* skip first record */ if (collect_record_stat() == 0) { do_debug(LOG_INFO, "collect_record_stat warn\n"); } sleep(conf.print_interval); /* print live record */ while (1) { collect_record();//调用各个模块的回调函数,获取一次当前的数据,字符串形式保存在mod->record中。 if (!((print_num) % DEFAULT_PRINT_NUM) || re_p_hdr) { /* get the header will print every DEFAULT_PRINT_NUM */ print_header(); re_p_hdr = 0; print_num = 1; } if (!collect_record_stat()) {//解析mod->record里面的数据,放入st_array中,以备打印 re_p_hdr = 1; continue; } /* print current time */ print_current_time(); print_record();//打印st_array里面的数据 print_num++; /* sleep every interval */ sleep(conf.print_interval);//睡会。 } }
/* running in print live mode */ void running_print_live() { int print_num = 1, re_p_hdr = 0; collect_record(); /* print header */ print_header(); /* set struct module fields */ init_module_fields(); /* skip first record */ if (collect_record_stat() == 0) { do_debug(LOG_INFO, "collect_record_stat warn\n"); } sleep(conf.print_interval); /* print live record */ while (1) { collect_record(); if (!((print_num) % DEFAULT_PRINT_NUM) || re_p_hdr) { /* get the header will print every DEFAULT_PRINT_NUM */ print_header(); re_p_hdr = 0; print_num = 1; } if (!collect_record_stat()) { re_p_hdr = 1; continue; } /* print current time */ print_current_time(); print_record(); print_num++; /* sleep every interval */ sleep(conf.print_interval); } }
void running_check(int check_type) { int total_num=0, i, j, k; FILE *fp; char line[2][LEN_10240]; char filename[LEN_128] = {0}; char tmp[9][LEN_256]; char check[LEN_10240] = {0}; char host_name[LEN_64] = {0}; struct module *mod = NULL; double *st_array; /* get hostname */ if (0 != gethostname(host_name, sizeof(host_name))) { do_debug(LOG_FATAL, "tsar -check: gethostname err, errno=%d", errno); } i = 0; while (host_name[i]) { if (!isprint(host_name[i++])) { host_name[i-1] = '\0'; break; } } memset(tmp, 0, 9 * LEN_256); sprintf(check, "%s\ttsar\t", host_name); sprintf(filename, "%s", conf.output_file_path); fp = fopen(filename, "r"); if (!fp) { do_debug(LOG_FATAL, "unable to open the log file %s.\n", filename); } /* get file len */ memset(&line[0], 0, LEN_10240); total_num =0; /* find two \n from end*/ if (fseek(fp, -1, SEEK_END) != 0) { do_debug(LOG_FATAL, "fseek error:%s", strerror(errno)); } while (1) { if (fgetc(fp) == '\n') { ++total_num; } if (total_num == 3) { break; } if (fseek(fp, -2, SEEK_CUR) != 0) { /* just 1 or 2 line, goto file header */ if (fseek(fp, 0, SEEK_SET) != 0) { do_debug(LOG_FATAL, "fseek error:%s", strerror(errno)); } break; } } /*FIX ME*/ if (total_num == 0) { if (fclose(fp) < 0) { do_debug(LOG_FATAL, "fclose error:%s", strerror(errno)); } memset(filename, 0, sizeof(filename)); sprintf(filename, "%s.1", conf.output_file_path); fp = fopen(filename, "r"); if (!fp) { do_debug(LOG_FATAL, "unable to open the log file %s.\n", filename); } total_num = 0; memset(&line[0], 0, 2 * LEN_10240); /* count tsar.data.1 lines */ if (fseek(fp, -1, SEEK_END) != 0) { do_debug(LOG_FATAL, "fseek error:%s", strerror(errno)); } while (1) { if (fgetc(fp) == '\n') { ++total_num; } if (total_num == 3) { break; } if (fseek(fp, -2, SEEK_CUR) != 0) { if (fseek(fp, 0, SEEK_SET) != 0) { do_debug(LOG_FATAL, "fseek error:%s", strerror(errno)); } break; } } if (total_num < 2) { do_debug(LOG_FATAL, "not enough lines at log file %s.\n", filename); } memset(&line[0], 0, LEN_10240); if (!fgets(line[0], LEN_10240, fp)) { do_debug(LOG_FATAL, "fgets error:%s", strerror(errno)); } memset(&line[1], 0, LEN_10240); if (!fgets(line[1], LEN_10240, fp)) { do_debug(LOG_FATAL, "fgets error:%s", strerror(errno)); } } else if (total_num == 1) { memset(&line[1], 0, LEN_10240); if (!fgets(line[1], LEN_10240, fp)) { do_debug(LOG_FATAL, "fgets error:%s", strerror(errno)); } if (fclose(fp) < 0) { do_debug(LOG_FATAL, "fclose error:%s", strerror(errno)); } sprintf(filename, "%s.1", conf.output_file_path); fp = fopen(filename, "r"); if (!fp) { do_debug(LOG_FATAL, "unable to open the log file %s\n", filename); } total_num = 0; /* go to the start of the last line at tsar.data.1 */ if (fseek(fp, -1, SEEK_END) != 0) { do_debug(LOG_FATAL, "fseek error:%s", strerror(errno)); } while (1) { if (fgetc(fp) == '\n') { ++total_num; } /* find the sencond \n from the end, read fp point to the last line */ if (total_num == 2) { break; } if (fseek(fp, -2, SEEK_CUR) != 0) { if (fseek(fp, 0, SEEK_SET) != 0) { do_debug(LOG_FATAL, "fseek error:%s", strerror(errno)); } break; } } if (total_num < 1) { do_debug(LOG_FATAL, "not enough lines at log file %s\n", filename); } memset(&line[0], 0, LEN_10240); if (!fgets(line[0], LEN_10240, fp)) { do_debug(LOG_FATAL, "fgets error:%s", strerror(errno)); } } else { memset(&line[0], 0, LEN_10240); if (!fgets(line[0], LEN_10240, fp)) { do_debug(LOG_FATAL, "fgets error:%s", strerror(errno)); } memset(&line[1], 0, LEN_10240); if (!fgets(line[1], LEN_10240, fp)) { do_debug(LOG_FATAL, "fgets error:%s", strerror(errno)); } } /* set struct module fields */ init_module_fields(); /* read one line to init module parameter */ read_line_to_module_record(line[0]); collect_record_stat(); read_line_to_module_record(line[1]); collect_record_stat(); /*display check detail*/ /* ---------------------------RUN_CHECK_NEW--------------------------------------- */ if (check_type == RUN_CHECK_NEW) { printf("%s\ttsar\t", host_name); for (i = 0; i < statis.total_mod_num; i++) { mod = &mods[i]; if (!mod->enable) { continue; } struct mod_info *info = mod->info; /* get mod name */ char *mod_name = strstr(mod->opt_line, "--"); if (mod_name) { mod_name += 2; } char opt[LEN_128] = {0}; char *n_record = strdup(mod->record); char *token = strtok(n_record, ITEM_SPLIT); char *s_token; for (j = 0; j < mod->n_item; j++) { memset(opt, 0, sizeof(opt)); if (token) { s_token = strstr(token, ITEM_SPSTART); if (s_token) { strncat(opt, token, s_token - token); strcat(opt, ":"); } } st_array = &mod->st_array[j * mod->n_col]; for (k=0; k < mod->n_col; k++) { if (mod->spec) { if (!st_array || !mod->st_flag) { if (((DATA_SUMMARY == conf.print_mode) && (SPEC_BIT == info[k].summary_bit)) || ((DATA_DETAIL == conf.print_mode) && (SPEC_BIT == info[k].summary_bit))) { printf("%s:%s%s=-%s", mod_name, opt, trim(info[k].hdr, LEN_128), " "); } } else { if (((DATA_SUMMARY == conf.print_mode) && (SPEC_BIT == info[k].summary_bit)) || ((DATA_DETAIL == conf.print_mode) && (SPEC_BIT == info[k].summary_bit))) { printf("%s:%s%s=", mod_name, opt, trim(info[k].hdr, LEN_128)); printf("%0.1f ", st_array[k]); } } } else { if (!st_array || !mod->st_flag) { if (((DATA_SUMMARY == conf.print_mode) && (SUMMARY_BIT == info[k].summary_bit)) || ((DATA_DETAIL == conf.print_mode) && (HIDE_BIT != info[k].summary_bit))) { printf("%s:%s%s=-%s", mod_name, opt, trim(info[k].hdr, LEN_128), " "); } } else { if (((DATA_SUMMARY == conf.print_mode) && (SUMMARY_BIT == info[k].summary_bit)) || ((DATA_DETAIL == conf.print_mode) && (HIDE_BIT != info[k].summary_bit))) { printf("%s:%s%s=", mod_name, opt, trim(info[k].hdr, LEN_128)); printf("%0.1f ", st_array[k]); } } } } if (token) { token = strtok(NULL, ITEM_SPLIT); } } if (n_record) { free(n_record); n_record = NULL; } } printf("\n"); if (fclose(fp) < 0) { do_debug(LOG_FATAL, "fclose error:%s", strerror(errno)); } fp = NULL; return; } #ifdef OLDTSAR /*tsar -check output similar as: v014119.cm3 tsar apache/qps=5.35 apache/rt=165.89 apache/busy=2 apache/idle=148 cpu=3.58 mem=74.93% load1=0.22 load5=0.27 load15=0.20 xvda=0.15 ifin=131.82 ifout=108.86 TCPretr=0.12 df/=4.04% df/home=10.00% df/opt=71.22% df/tmp=2.07% df/usr=21.27% df/var=5.19% */ /* ------------------------------RUN_CHECK------------------------------------------- */ if (check_type == RUN_CHECK) { for (i = 0; i < statis.total_mod_num; i++) { mod = &mods[i]; if (!mod->enable){ continue; } if (!strcmp(mod->name, "mod_apache")) { for (j = 0; j < mod->n_item; j++) { st_array = &mod->st_array[j * mod->n_col]; if (!st_array || !mod->st_flag) { sprintf(tmp[0], " apache/qps=- apache/rt=- apache/busy=- apache/idle=-"); } else { sprintf(tmp[0], " apache/qps=%0.2f apache/rt=%0.2f apache/busy=%0.0f apache/idle=%0.0f", st_array[0], st_array[1], st_array[3], st_array[4]); } } } if (!strcmp(mod->name, "mod_cpu")) { for (j = 0; j < mod->n_item; j++) { st_array = &mod->st_array[j * mod->n_col]; if (!st_array || !mod->st_flag) { sprintf(tmp[1], " cpu=-"); } else { sprintf(tmp[1], " cpu=%0.2f", st_array[5]); } } } if (!strcmp(mod->name, "mod_mem")) { for (j = 0; j < mod->n_item; j++) { st_array = &mod->st_array[j * mod->n_col]; if (!st_array || !mod->st_flag) { sprintf(tmp[2], " mem=-"); } else { sprintf(tmp[2], " mem=%0.2f%%", st_array[5]); } } } if (!strcmp(mod->name, "mod_load")) { for (j = 0; j < mod->n_item; j++) { st_array = &mod->st_array[j * mod->n_col]; if (!st_array || !mod->st_flag) { sprintf(tmp[3], " load1=- load5=- load15=-"); } else { sprintf(tmp[3], " load1=%0.2f load5=%0.2f load15=%0.2f", st_array[0], st_array[1], st_array[2]); } } } if (!strcmp(mod->name, "mod_io")) { char opt[LEN_128] = {0}; char item[LEN_128] = {0}; char *n_record = strdup(mod->record); char *token = strtok(n_record, ITEM_SPLIT); char *s_token; for (j = 0; j < mod->n_item; j++) { s_token = strstr(token, ITEM_SPSTART); if (s_token) { memset(opt, 0, sizeof(opt)); strncat(opt, token, s_token - token); st_array = &mod->st_array[j * mod->n_col]; if (!st_array || !mod->st_flag) { sprintf(item, " %s=-", opt); } else { sprintf(item, " %s=%0.2f", opt, st_array[10]); } strcat(tmp[4], item); } token = strtok(NULL, ITEM_SPLIT); } if (n_record) { free(n_record); n_record = NULL; } } if (!strcmp(mod->name, "mod_traffic")) { for (j = 0; j < mod->n_item; j++) { st_array = &mod->st_array[j * mod->n_col]; if (!st_array || !mod->st_flag) { sprintf(tmp[5], " ifin=- ifout=-"); } else { sprintf(tmp[5], " ifin=%0.2f ifout=%0.2f", st_array[0] / 1000, st_array[1] / 1000); } } } if (!strcmp(mod->name, "mod_tcp")) { for (j = 0; j < mod->n_item; j++) { st_array = &mod->st_array[j * mod->n_col]; if (!st_array || !mod->st_flag) { sprintf(tmp[6], " TCPretr=-"); } else { sprintf(tmp[6], " TCPretr=%0.2f", st_array[4]); } } } if (!strcmp(mod->name, "mod_partition")) { char opt[LEN_128] = {0}; char item[LEN_128] = {0}; char *n_record = strdup(mod->record); char *token = strtok(n_record, ITEM_SPLIT); char *s_token; for (j = 0; j < mod->n_item; j++) { s_token = strstr(token, ITEM_SPSTART); if (s_token) { memset(opt, 0, sizeof(opt)); strncat(opt, token, s_token - token); st_array = &mod->st_array[j * mod->n_col]; if (!st_array || !mod->st_flag) { sprintf(item, " df%s=-", opt); } else { sprintf(item, " df%s=%0.2f%%", opt, st_array[3]); } strcat(tmp[7], item); } token = strtok(NULL, ITEM_SPLIT); } if (n_record) { free(n_record); n_record = NULL; } } if (!strcmp(mod->name, "mod_nginx")){ for (j = 0; j < mod->n_item; j++) { st_array = &mod->st_array[j * mod->n_col]; if (!st_array || !mod->st_flag) { sprintf(tmp[8], " nginx/qps=- nginx/rt=-"); } else { sprintf(tmp[8], " nginx/qps=%0.2f nginx/rt=%0.2f", st_array[7], st_array[8]); } } } } for (j = 0; j < 9; j++) { strcat(check, tmp[j]); } printf("%s\n", check); if (fclose(fp) < 0) { do_debug(LOG_FATAL, "fclose error:%s", strerror(errno)); } fp = NULL; } #endif }
/* * init_running_print, if sucess then return fp, else return NULL */ FILE * init_running_print() { int i=0, k=0; FILE *fp, *fptmp; char line[LEN_10240] = {0}; char filename[LEN_128] = {0}; /* will print tail*/ conf.print_tail = 1; fp = fopen(conf.output_file_path, "r");//读取/var/log/tsar.data文件 if (!fp) { do_debug(LOG_FATAL, "unable to open the log file %s\n", conf.output_file_path); } /*log number to use for print*/ conf.print_file_number = -1; /* find start offset will print from tsar.data */ k=find_offset_from_start(fp, i);//在tsar.data文件中,用二分查找,找出要开始打印的行的位置放在print_file_number。 if (k == 1) {//如果返回1,代表当前的文件里面没有数据,数据在后面的文件中。用同样的方法扫描后面的文件。 /*find all possible record*/ for (i=1; ; i++) { memset(filename, 0, sizeof(filename)); sprintf(filename, "%s.%d", conf.output_file_path, i); fptmp = fopen(filename, "r"); if (!fptmp) { conf.print_file_number = i - 1; break; } k=find_offset_from_start(fptmp, i); if (k==0 || k==4) { if (fclose(fp) < 0) { do_debug(LOG_FATAL, "fclose error:%s", strerror(errno)); } fp=fptmp; break; } if (k== 2) { if (fseek(fp, 0, SEEK_SET) != 0) { do_debug(LOG_FATAL, "fseek error:%s", strerror(errno)); } if (fclose(fptmp) < 0) { do_debug(LOG_FATAL, "fclose error:%s", strerror(errno)); } break; } if (k == 1) { if (fclose(fp) < 0) { do_debug(LOG_FATAL, "fclose error:%s", strerror(errno)); } fp=fptmp; continue; } if (k == 5 || k == 6) { do_debug(LOG_FATAL, "log format error or find_offset_from_start have a bug. error code=%d\n", k); } } } if (k == 5 || k == 6) { do_debug(LOG_FATAL, "log format error or find_offset_from_start have a bug. error code=%d\n", k); } /* get record */ if (!fgets(line, LEN_10240, fp)) { do_debug(LOG_FATAL, "can't get enough log info\n"); } /* read one line to init module parameter */ read_line_to_module_record(line);//读取一行数据到每个模块的mod->record /* print header */ print_header();//打印头部信息 /* set struct module fields */ init_module_fields(); set_record_time(line);//更新conf.print_interval的间隔时间 return fp; }
/* get data from tsar.data */ int get_st_array_from_file(int have_collect) { int i, ret = 0; char pre_line[LEN_10240] = {0}; char line[LEN_10240] = {0}; char detail[LEN_1024] = {0}; char pre_time[32] = {0}; char *s_token; FILE *fp; struct module *mod; if (!have_collect) { collect_record(0); } /* update module parameter */ conf.print_merge = MERGE_ITEM; sprintf(line, "%ld", statis.cur_time); for (i = 0; i < statis.total_mod_num; i++) { mod = &mods[i]; if (mod->enable && strlen(mod->record)) { memset(&detail, 0, sizeof(detail)); /* save collect data to output_file */ sprintf(detail, "%s%s%s%s", SECTION_SPLIT, mod->opt_line, STRING_SPLIT, mod->record); strcat(line, detail); } } if (strlen(line)) { strcat(line, "\n"); } /* if fopen PRE_RECORD_FILE sucess then store data to pre_record */ if ((fp = fopen(PRE_RECORD_FILE, "r"))) { if (!fgets(pre_line, LEN_10240, fp)) { if (fclose(fp) < 0) { do_debug(LOG_FATAL, "fclose error:%s", strerror(errno)); } ret = -1; goto out; } } else { ret = -1; goto out; } /* set print_interval */ s_token = strstr(pre_line, SECTION_SPLIT); if (!s_token) { ret = -1; goto out; } memcpy(pre_time, pre_line, s_token - pre_line); if (!(conf.print_interval = statis.cur_time - atol(pre_time))) { goto out; } /* read pre_line to mod->record and store to pre_array */ read_line_to_module_record(pre_line); init_module_fields(); collect_record_stat(); /* read cur_line and stats operation */ read_line_to_module_record(line); collect_record_stat(); ret = 0; out: /* store current record to PRE_RECORD_FILE */ if ((fp = fopen(PRE_RECORD_FILE, "w"))) { strcat(line, "\n"); if (fputs(line, fp) < 0) { do_debug(LOG_ERR, "fputs error:%s", strerror(errno)); } if (fclose(fp) < 0) { do_debug(LOG_FATAL, "fclose error:%s", strerror(errno)); } chmod(PRE_RECORD_FILE, 0666); } return ret; }
/* * init_running_print, if sucess then return fp, else return NULL */ FILE *init_running_print() { int i=0,k=0; FILE *fp,*fptmp; char line[LEN_10240] = {0}; char filename[LEN_128] = {0}; /* will print tail*/ conf.print_tail = 1; fp = fopen(conf.output_file_path, "r"); if (!fp){ do_debug(LOG_FATAL, "unable to open the log file %s\n",conf.output_file_path); } /*log number to use for print*/ conf.print_file_number = -1; /* find start offset will print from tsar.data */ k=find_offset_from_start(fp,i); if(k==1){ /*find all possible record*/ for(i=1;;i++){ memset(filename,0,sizeof(filename)); sprintf(filename,"%s.%d",conf.output_file_path,i); fptmp = fopen(filename, "r"); if(!fptmp){ conf.print_file_number = i - 1; break; } k=find_offset_from_start(fptmp,i); if(k==0 || k==4){ fclose(fp); fp=fptmp; break; } if(k==2){ fseek(fp,0,SEEK_SET); fclose(fptmp); break; } if(k==1){ fclose(fp); fp=fptmp; continue; } if(k==5 || k==6){ do_debug(LOG_FATAL, "log format error or find_offset_from_start have a bug. error code=%d\n",k); } } } if(k==5 || k==6){ do_debug(LOG_FATAL, "log format error or find_offset_from_start have a bug. error code=%d\n",k); } /* get record */ if (!fgets(line, LEN_10240, fp)) { do_debug(LOG_FATAL, "can't get enough log info\n"); } /* read one line to init module parameter */ read_line_to_module_record(line); /* print header */ print_header(); /* set struct module fields */ init_module_fields(); set_record_time(line); return fp; }
int get_st_array_from_file() { struct module *mod; int i, ret; char pre_line[LEN_4096] = {0}; char line[LEN_4096] = {0}; char detail[LEN_1024] = {0}; char pre_time[32] = {0}; char *s_token; FILE *fp; sprintf(line, "%ld", statis.cur_time); for (i = 0; i < statis.total_mod_num; i++) { mod = &mods[i]; if (mod->enable && strlen(mod->record)) { memset(&detail, 0, sizeof(detail)); /* save collect data to output_file */ sprintf(detail, "%s%s%s%s", SECTION_SPLIT, mod->opt_line, STRING_SPLIT, mod->record); strcat(line, detail); } } strcat(line,"\n"); /* if fopen PRE_RECORD_FILE sucess then store data to pre_record */ if ((fp = fopen(PRE_RECORD_FILE, "r"))) { if (!fgets(pre_line, LEN_4096, fp)) { fclose(fp); ret = -1; goto out; } } else { ret = -1; goto out; } /* set print_interval */ s_token = strstr(pre_line, SECTION_SPLIT); if (!s_token) { ret = -1; goto out; } memcpy(pre_time, pre_line, s_token - pre_line); if (!(conf.print_interval = statis.cur_time - strtol(pre_time,NULL,0))) goto out; /* read pre_line to mod->record and store to pre_array */ read_line_to_module_record(pre_line); init_module_fields(); if(collect_record_stat() == 0) do_debug(LOG_INFO, "collect_record_stat warn\n"); /* read cur_line and stats operation */ read_line_to_module_record(line); if(collect_record_stat() == 0) do_debug(LOG_INFO, "collect_record_stat warn\n"); ret = 0; out: /* store current record to PRE_RECORD_FILE */ if ((fp = fopen(PRE_RECORD_FILE, "w"))) { strcat(line,"\n"); if(fputs(line, fp) < 0) do_debug(LOG_WARN, "write line error\n"); fclose(fp); if(chmod(PRE_RECORD_FILE, 0666) < 0) do_debug(LOG_WARN, "chmod file %s error\n",PRE_RECORD_FILE); } return ret; }