Всем доброго утра , дня и ночи !
Пишу порогу по анлизу squid лога на си. Сталкнулся вот с такой проблемкой.
Делаю access.log 100mb и натравливаю мою программку на этот лог, она его лопатит секунд 35,40 но при этом приличная нагрузка на CPU от 80 до 99,9.
Вот мой кодинг:
void open_file();
void open_files_otbor_dannuh();//===================================================================
void open_files_otbor_dannuh()
{
time_t now;
char dte[30];
now = time(NULL);
strcpy(dte,ctime(&now));
printf("%s",dte);
}//====================================================================
void open_file()
{
FILE *fp;
FILE *fd;
char *date;
char *ishod_traf;
char *ip;
char *tcp_miss;
char *vhodychiy_traf;
char *tip_pered;
char *http_url;
char *musor_1;
char *musor_2;
char *musor_3;int i,d;
char *new_date;
if((fp=fopen("access.log", "r"))==NULL)
{
printf("Error fopen files");
exit(1);
}
if((fd=fopen("access.sort", "w+"))==NULL)
{
printf("Error fopen files");
exit(1);
}while(fp){
http_url=(char *) malloc(1000);
tcp_miss=(char *) malloc(100);
new_date=(char *) malloc(100);
ishod_traf=(char *) malloc(100);
ip=(char *) malloc(100);
vhodychiy_traf=(char *) malloc(100);
tip_pered=(char *) malloc(100);
musor_1=(char *) malloc(100);
musor_2=(char *) malloc(100);
musor_3=(char *) malloc(100);
date=(char *) malloc(100);if(fscanf(fp,"%s %s %s %s %s %s %s %s %s %s\n", date,ishod_traf,ip,tcp_miss,vhodychiy_traf, tip_pered,http_url, musor_1
d=atoi(date);
strncpy(new_date, ctime(&d),24);
fprintf(fd,"%s %s %s %s %s\n",new_date, ishod_traf,ip,vhodychiy_traf, http_url);free(http_url);
free(tcp_miss);
free(new_date);
free(date);
free(ip);
free(ishod_traf);
free(vhodychiy_traf);
free(tip_pered);
free(musor_1);
free(musor_2);
free(musor_3);}else{
exit(1);
}
}
fclose(fd);
fclose(fp);
}
//====================================================================
int main(void)
{
open_file();
return 0;
}Проверял существенная нагрузка возникает при записи в fd;
Ответе я чувствую что это не правильно!!!Есть такой вариант но я не знаю логичный он или нет
1) Поставить sleep(5) в цикле но тогда увиличивается время выполнения
и надо дописывать в файл а не перезаписывать. Как в си дописывать в файл (w+)?--;2) Делать это в другом потоке но я не знаю как, и что может из этого вытекать .
Люди посаветуйте плиз!!!
>Ответе я чувствую что это не правильно!!!
>
>Есть такой вариант но я не знаю логичный он или нет
>1) Поставить sleep(5) в цикле но тогда увиличивается время выполненияпопробуй usleep()
>и надо дописывать в файл а не перезаписывать. Как в си дописывать
>в файл (w+)?--;"a"
а, собственно, в чем проблема?
любая программа нагружет CPU, он для того и предназначен - программы выполнять...если эта нагрузка мешает чему-то еще, то понизь приоритет своего процесса.
например, командой nice...
огромное всем спосибо я разобрался!
>Всем доброго утра , дня и ночи !
>Пишу порогу по анлизу squid лога на си. Сталкнулся вот с
>такой проблемкой.С твоим кодом будут проблемы покруче, чем затраты временные :))
Например, здесь:
> http_url=(char *) malloc(1000);
> tcp_miss=(char *) malloc(100);
> new_date=(char *) malloc(100);
> ishod_traf=(char *) malloc(100);
> ip=(char *) malloc(100);
> vhodychiy_traf=(char *) malloc(100);
> tip_pered=(char *) malloc(100);
> musor_1=(char *) malloc(100);
> musor_2=(char *) malloc(100);
> musor_3=(char *) malloc(100);
> date=(char *) malloc(100);
> if(fscanf(fp,"%s %s %s %s %s %s %s %s %s %s\n",Надеюсь, не надо объяснять, что будет с твоей прогой, если длина поля, например, http_url, будет несколько больше 1000 символов? Это называется buffer overflow :)
Такой подход, в принципе, является ущербным, тк сколько бы ты памяти не выделил, всегда найдется запись, которая не влезет в этот буфер.
Я сам делал аналогичную вещь - переливалку access.log-а в БД для учета проксевого траффика. Сначала использовал аналогичный подход, но потом, заколебавшись менять BUFSIZE после после очередного перебора (жизнь показала, что и 64К иногда мало!), взял и полностью переписал парсер на С++, с использованием stl-евской std::string для загрузки полей, и оstrstream для формирования sql-запроса для заталкивания порции данных в БД.
Конечно, парсер стал менее эффективным, но зато он стал непробиваемым.Да, а что касается самой задачи разбора пользовательской статистики сквида, то считаю наиболее оптимальным вариантом использовать СУБДшку для хранения и обработки логов.
Что я и реализовал у себя в фирме. И теперь с ехидством смотрю на форумные посты типа "Помогите! У меня SARG не запускается/валится/не генерит отчеты" :)
Думаю, может затеять open-source проект на эту тему?Удачи!