main.c

来自「一百个病毒的源代码 包括熊猫烧香等 极其具有研究价值」· C语言 代码 · 共 586 行

C
586
字号
/*** Modular Logfile Analyzer** Copyright 2000 Jan Kneschke <jan@kneschke.de>**** Homepage: http://www.kneschke.de/projekte/modlogan**    This program is free software; you can redistribute it and/or modify    it under the terms of the GNU General Public License as published by    the Free Software Foundation; either version 2 of the License, or    (at your option) any later version, and provided that the above    copyright and permission notice is included with all distributed    copies of this or derived software.    This program is distributed in the hope that it will be useful,    but WITHOUT ANY WARRANTY; without even the implied warranty of    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the    GNU General Public License for more details.    You should have received a copy of the GNU General Public License    along with this program; if not, write to the Free Software    Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA**** $Id: main.c,v 1.36 2001/01/11 22:19:40 jk Exp $*/#include <libintl.h>#include <locale.h>#include <stdlib.h>#include <stdio.h>#include <time.h>#include <unistd.h>#include <dirent.h>#include <errno.h>#include <string.h>#include <sys/stat.h>#include <sys/time.h>#include "config.h"#ifdef HAVE_GETOPT_H#include <getopt.h>#endif#ifdef HAVE_LIBZ#include <zlib.h>#else #include "zlibwrapper.h"#endif#include "mrecord.h"#include "mstate.h"#include "mlocale.h"#include "mconfig.h"#include "mplugins.h"#include "mdatatypes.h"int history_write(mconfig *conf, mlist *l, char *subpath) {	char filename[255];	gzFile *f;		sprintf(filename, "%s%s%s/modlogan.history%s", 		conf->outputdir ? conf->outputdir : ".", 		subpath ? "/" : "",		subpath ? subpath : "",		".gz");		if (!(f = gzopen(filename, "wb"))) {		return -1;	}		mlist_write(f, l);		gzprintf(f, "# end of history\n");		gzclose(f);		return 0;}int history_read(mconfig *conf, mlist *l, char *subpath) {	char filename[255];	gzFile *f;	data_History *data;		sprintf(filename, "%s%s%s/modlogan.history%s", 		conf->outputdir ? conf->outputdir : ".", 		subpath ? "/" : "",		subpath ? subpath : "",		".gz");		if (!(f = gzopen(filename, "r"))) {		return -1;	}		data = History_init();					while ((data->read(data, f) == 0)) {		if (!data->string) {			break;		}				mlist_insert(l, data);			data = History_init();	}		data->destructor(data);		gzclose(f);		return 0;}void show_version() {	printf("%s %s\n", PACKAGE, VERSION);}void show_header() {	printf("%s %s", PACKAGE, VERSION);#ifdef	NO_PLUGINS	printf(" - static i(%s) p(%s) o(%s)\n", 		INPUT_PLUGIN, 		PROCESSOR_PLUGIN, 		OUTPUT_PLUGIN);#else	printf(" - dynamic\n");#endif}void show_usage() {	show_header();#ifdef HAVE_GETOPT_LONG	printf("Options:\n");	printf(" -c <configfile>    filename of the configfile\n");	printf(" -h --help          this help screen\n");	printf(" -v --version       display version\n");#else	printf("Options:\n");	printf(" -c <configfile>    filename of the configfile\n");	printf(" -h                 this help screen\n");	printf(" -v                 display version\n");#endif};int restore_internal_state (mconfig *conf, mlist *state_list) {	DIR *dir;	int splitter = 0;			/* scan the outputdir for directories */	if ((dir = opendir(conf->outputdir)) == NULL) {		fprintf(stderr, "can't open the outputdir: %s - %s\n", conf->outputdir, strerror(errno));		return -1;	} else {		struct dirent * dent;		while ((dent = readdir(dir))) {			struct stat st;			char *dirname = NULL;					/* skip '.', '..' and hidden directories */			if (*(dent->d_name) == '.') continue;						dirname = malloc(strlen(conf->outputdir)+strlen(dent->d_name)+2);						sprintf(dirname, "%s/%s", conf->outputdir, dent->d_name);						if (stat(dirname, &st)) {				fprintf(stderr, "%s.%d: can't stat the output directory (%s) : %s\n", __FILE__, __LINE__, dirname, strerror(errno));			} else if (S_ISDIR(st.st_mode)) {				mstate *state = NULL;				mlist *hist = mlist_init();				if (conf->debug_level > 1)					fprintf(stderr, "%s.%d: reading statefile from %s\n", __FILE__, __LINE__, dent->d_name);								if (history_read(conf, hist, dent->d_name)) {					mlist_free(hist);					hist = NULL;				}				if (conf->incremental) {					state = mstate_init();								if (mstate_read(conf, state, 0, 0, dent->d_name)) {						mstate_free(state);						state = NULL;					}				}								if (!hist || (conf->incremental && !state)) {					if (hist)	mlist_free(hist);					else fprintf(stderr, "%s\n", _("Reading History file failed"));										if (state)	mstate_free(state);					else if (conf->incremental) fprintf(stderr, "%s\n", _("Reading State file failed"));				} else {					data_State *data = createState(dent->d_name, state, hist);										mlist_insert(state_list, data);										if (conf->debug_level > 2)						fprintf(stderr, "%s.%d: state restored for %s\n", __FILE__, __LINE__, dent->d_name);										splitter = 1;				} 			}						free(dirname);		}		closedir(dir);	}		if (!splitter) {		mstate *state = NULL;		mlist *hist = mlist_init();						if (history_read(conf, hist, NULL)) {			mlist_free(hist);			hist = NULL;		}						if (conf->incremental) {			state = mstate_init();				if (mstate_read(conf, state, 0, 0, NULL)) {				mstate_free(state);				state = NULL;			} else {				splitter = 1;			}		}						if (!hist || !state) {			if (hist)	mlist_free(hist);			else fprintf(stderr, "%s\n", _("Reading History file failed"));			if (state)	mstate_free(state);			else fprintf(stderr, "%s\n", _("Reading State file failed"));		} else {			data_State *data = createState("", state, hist);			mlist_insert(state_list, data);		} 	}		return 0;}typedef struct {	struct timeval start;	struct timeval stop;	long int span;} mtimer;#define MTIMER_START(x)\	gettimeofday(&(x.start), NULL);#define MTIMER_STOP(x)\	gettimeofday(&(x.stop), NULL);#define MTIMER_CALC(x)\	x.span += ((x.stop.tv_sec * 1000 + x.stop.tv_usec / 1000) - (x.start.tv_sec * 1000 + x.start.tv_usec / 1000)); \	#define MTIMER_GET_MSEC(x) \	x.span	#define MTIMER_RESET(x) \	x.span = 0;int main (int argc, char **argv) {	mconfig *conf = NULL;	mlogrec *rec = NULL;	mlist *state_list = NULL;	mlist *l;		int ret, l_month = -1, l_year = -1, l_hour = -1, l_day = -1, i;	char *conf_filename = NULL;	long lines = 0, lines_corrupt = 0, lines_skipped = 0;	int first_valid_line = 0;	struct tm *tm;		time_t l_stamp = -1;	mtimer process_timer, post_process_timer, parse_timer, setup_timer;	#ifdef HAVE_GETOPT_LONG		int option_index = 0;	static struct option long_options[] = {		{"help", 0, NULL, 0},		{"version", 0, NULL, 0},		{NULL, 0, NULL, 0}	};#endif		MTIMER_RESET(process_timer);	MTIMER_RESET(post_process_timer);	MTIMER_RESET(parse_timer);	MTIMER_RESET(setup_timer);	#ifdef HAVE_GETOPT_LONG		while ((i = getopt_long(argc,argv,"c:hv", 		long_options, &option_index)) != -1) {				/* map the long options to the short ones */		if (i == 0) {			switch(option_index) {				case 0: i = 'h'; break;				case 1: i = 'v'; break;				default:					show_usage();					exit( EXIT_FAILURE);			}		}#else	while ((i = getopt(argc,argv,"c:hv")) != EOF) { #endif				switch(i) {			case 'c': 				conf_filename = optarg;				break;			case 'h':				show_usage();				exit( EXIT_SUCCESS);			case 'v':				show_version();				exit( EXIT_SUCCESS);			default:				show_usage();				exit( EXIT_FAILURE);		}	}	show_header();		MTIMER_START(setup_timer);		if (!(conf = mconfig_init(conf_filename))) {		fprintf(stderr, "%s\n", _("Reading Configfile failed"));		return -1;	}		state_list = mlist_init();	rec = mrecord_init();		restore_internal_state(conf, state_list);	if (conf->incremental) {		l = state_list;			while (l) {			data_State *data = l->data;						if (!data) break;						if (data->state->timestamp > l_stamp) {				l_stamp = data->state->timestamp;				l_year = data->state->year-1900;				l_month = data->state->month-1;			}						l = l->next;		}	}		if (l_stamp != -1 && conf->debug_level > 0)		printf("%s %s", _("Starting at"),ctime(&l_stamp));	if (conf->debug_level > 0)			printf("%s\n", _("startup - finished"));		MTIMER_STOP(setup_timer);	MTIMER_CALC(setup_timer);		MTIMER_START(parse_timer);	while ((ret = get_next_record(conf, rec)) != M_RECORD_EOF) {		MTIMER_STOP(parse_timer);		MTIMER_CALC(parse_timer);				MTIMER_START(process_timer);				lines++;		if (ret == M_RECORD_NO_ERROR) {			if (l_month == -1) {				tm = localtime(&(rec->timestamp));				l_month = tm->tm_mon;				l_year = tm->tm_year;				l_stamp = rec->timestamp;				l_hour = tm->tm_hour;			}			if (l_stamp > rec->timestamp) {				if (first_valid_line == 0 && conf->incremental == 1) {					lines_skipped++;					continue;				}				if (conf->debug_level > 2)					fprintf(stderr, "Out of Sequence - ignoring timestamp: %ld > %ld\n", l_stamp, rec->timestamp);								rec->timestamp = l_stamp;			}						tm = localtime(&(rec->timestamp));						if (l_day != tm->tm_mday) {				if (conf->debug_level > 1) {					printf("|-| %02i.%02i.%4i", tm->tm_mday, tm->tm_mon+1, tm->tm_year+1900);					if (conf->debug_level > 1) {						printf(" - %10.2f (%10ld, %4ld, %4ld)",							(lines)/((MTIMER_GET_MSEC(parse_timer)+MTIMER_GET_MSEC(process_timer))/1000.0), 							lines, 							lines_corrupt,							lines_skipped);					}					printf("\n");				}				l_day = tm->tm_mday;			}						if (conf->gen_report_threshold > 0 && 				(lines - lines_corrupt + 1) % conf->gen_report_threshold == 0) {								MTIMER_STOP(process_timer);				MTIMER_CALC(process_timer);																MTIMER_START(post_process_timer);				if (conf->debug_level > 0)					printf("o(t) %s %02i - %04i\n", _("writing month"), l_month+1, l_year+1900);								l = state_list;								while (l) {					data_State *data = l->data;					data_History *histdata = NULL;										if (!data) break;										histdata = createHistory(data->state);									mlist_insert(data->history, histdata);										mstate_write(conf, data->state, M_STATE_WRITE_BY_MONTH, *(data->string) ? data->string : NULL);					history_write(conf, data->history, *(data->string) ? data->string : NULL);										generate_monthly_output(conf, data->state, *(data->string) ? data->string : NULL);					generate_history_output(conf, data->history, *(data->string) ? data->string : NULL);						l = l->next;				}				MTIMER_STOP(post_process_timer);				MTIMER_CALC(post_process_timer);												MTIMER_START(process_timer);			}						if (tm->tm_mon != l_month || tm->tm_year != l_year) {								MTIMER_STOP(process_timer);				MTIMER_CALC(process_timer);								MTIMER_START(post_process_timer);								if (conf->debug_level > 0)					printf("o %s %02i - %04i\n", _("writing month"), l_month+1, l_year+1900);												l = state_list;								while (l) {					data_State *data = l->data;					data_History *histdata = NULL;										if (!data) break;										histdata = createHistory(data->state);									mlist_insert(data->history, histdata);										if (conf->debug_level > 0)						printf("o(t) -- state written: (...)/%s/\n", *(data->string) ? data->string : ".");					mstate_write(conf, data->state, M_STATE_WRITE_BY_MONTH, *(data->string) ? data->string : NULL);										generate_monthly_output(conf, data->state, *(data->string) ? data->string : NULL);										mstate_free(data->state);					data->state = mstate_init();										l = l->next;				}								tm = localtime(&(rec->timestamp));							l_month = tm->tm_mon;				l_year = tm->tm_year;								MTIMER_STOP(post_process_timer);				MTIMER_CALC(post_process_timer);								MTIMER_START(process_timer);			}						insert_record(conf, state_list, rec);						first_valid_line = 1;						l_stamp = rec->timestamp;		} else {			lines_corrupt++;						if (conf->debug_level > 0) {				fprintf (stderr, "%s.%d: parser reported an error in line %ld\n", __FILE__, __LINE__, lines);			}		}		mrecord_free(rec);				rec = mrecord_init();				MTIMER_STOP(process_timer);		MTIMER_CALC(process_timer);				MTIMER_START(parse_timer);	}	MTIMER_STOP(parse_timer);	MTIMER_START(post_process_timer);	if (l_month != -1) {			if (conf->debug_level > 0) 			printf("%s %02i - %04i\n", _("writing month"), l_month+1, l_year+1900);				if (conf->debug_level > 1)			fprintf(stderr, "%s.%d: writing the last month\n", __FILE__, __LINE__ );					l = state_list;						while (l) {			data_State *data = l->data;			data_History *histdata = NULL;								if (!data) break;						if (conf->debug_level > 1)				fprintf(stderr, "%s.%d: subpath = %s\n", __FILE__, __LINE__, data->string);						histdata = createHistory(data->state);							mlist_insert(data->history, histdata);						mstate_write(conf, data->state, M_STATE_WRITE_DEFAULT, *(data->string) ? data->string : NULL);			history_write(conf, data->history, *(data->string) ? data->string : NULL);			generate_monthly_output(conf, data->state, *(data->string) ? data->string : NULL);			generate_history_output(conf, data->history, *(data->string) ? data->string : NULL);			l = l->next;		}	}		MTIMER_STOP(post_process_timer);	MTIMER_CALC(post_process_timer);	mlist_free(state_list);	mrecord_free(rec);		mplugins_free(conf);		if (conf->debug_level > 0) {		printf(" --> Setup       : %10.2fs <--\n", MTIMER_GET_MSEC(setup_timer)/1000.0);		printf(" --> Parse       : %10.2fs <--\n", MTIMER_GET_MSEC(parse_timer)/1000.0);		printf(" --> Process     : %10.2fs <--\n", MTIMER_GET_MSEC(process_timer)/1000.0);		printf(" --> Post-Process: %10.2fs <--\n", MTIMER_GET_MSEC(post_process_timer)/1000.0);				printf("%s: %.2f %s (%ld %s, %ld %s, %ld %s)\n",			_("Throughput"), (lines)/((MTIMER_GET_MSEC(parse_timer)+MTIMER_GET_MSEC(process_timer))/1000.0), 			_("rec/s"),			lines, _("records"), 			lines_corrupt, _("corrupt records"),			lines_skipped, _("skipped records"));	}		mconfig_free(conf);	return 0;}

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?