📄 rateup.c
字号:
/* MRTG 2.8.12 -- Rateup ********************* Rateup is a fast add-on to the great MRTG Traffic monitor. It makes the database file updates much faster, and creates the graphic image files, ready for processing by PPMTOGIF. It also reduces memory requirements by a factor of 10, and increases the speed of updates by a factor of at least 10. This makes it feasible to run mrtg every 5 minutes. rateup attempts to compensate for missed updates by repeating the last sample, and also tries to catch bad update times. The .log file stores real history every five minutes for 31 hours, then 'compresses' the history into 30 minute samples for a week, then 2-hour samples for 31 days, then daily samples for two years. This ensures that the log files don't grow in size. The log files are a slightly different format, but convert.perl will fix that for you. Enjoy! Dave Rand dlr@bungi.com 04/26/99 - There was some compilation bug under Watcom 10.6 which was fixed when recompiled with VC++ 6.0 Alexandre Steinberg steinberg@base.com.br*/#include <stdlib.h>#include <string.h>/* VC++ does not have unistd.h */#ifndef WIN32#include <unistd.h>#endif#include <limits.h>#include <stdio.h>#include <time.h>#include <math.h>#include <ctype.h>#ifndef GFORM_GD#define GFORM_GD gdImagePng #endif/* BSDI 2.0.1 does not have malloc.h */#if !defined(bsdi) && !defined(__FreeBSD__) && !defined(__OpenBSD__)#include <malloc.h>#endif/* WATCOM C/C++ 10.6 under Win95/NT *//* VC++ 6.0 under Win95/NT */#if defined(__WATCOMC__) || defined(WIN32)#include <string.h>#include <sys\types.h>#include <direct.h>#include <io.h>#endif#include <gd.h>#include <gdfonts.h>char *VERSION = "2.8.12";char *program,*router,*routerpath;int histvalid;int dorelpercent = 0;int transparent = 0;int unknaszero = 0;time_t NOW;char *short_si[] = {"","k","M","G","T"};char *longup = NULL;char *shortup = NULL;char weekformat = 'W'; /* strftime() fmt char for week # */#define DAY_COUNT (600) /* 400 samples is 33.33 hours */#define DAY_SAMPLE (5*60) /* Sample every 5 minutes */#define WEEK_COUNT (600) /* 400 samples is 8.33 days */#define WEEK_SAMPLE (30*60) /* Sample every 30 minutes */#define MONTH_COUNT (600) /* 400 samples is 33.33 days */#define MONTH_SAMPLE (2*60*60) /* Sample every 2 hours */#define YEAR_COUNT (2 * 366) /* 1 sample / day, 366 days, 2 years */#define YEAR_SAMPLE (24*60*60) /* Sample every 24 hours *//* One 'rounding error' per sample period, so add 4 to total and for good mesure we take 10 :-) */#define MAX_HISTORY (DAY_COUNT+WEEK_COUNT+MONTH_COUNT+YEAR_COUNT+10)/* These are the colors used for the variouse parts of the graph *//* the format is Red,Green,Blue */#define c_blank 245,245,245#define c_light 194,194,194#define c_dark 100,100,100#define c_major 255,0,0#define c_in 0,235,12#define c_out 0,94,255#define c_grid 0,0,0#define c_inm 0,166,33#define c_outm 255,0,255#define c_outp 239,159,79int col_in[3];int col_out[3];int col_inm[3];int col_outm[3];int col_outp[3];long kilo = (long)1000;char* kMG = (char*) NULL;char* kMGcopy = (char*) NULL; /* JML bugfix */int kMGnumber = 0;#define MAXL 200 /* Maximum length of last in & out fields */struct HISTORY { time_t time; unsigned long in, out, percent, inmax, outmax;} *history;int Mh;struct LAST { time_t time; char in[MAXL],out[MAXL];} last;#if !defined(__WATCOMC__) && !defined(WIN32)#define max(a,b) ((a) > (b) ? (a) : (b))#define min(a,b) ((a) < (b) ? (a) : (b))#endif/*notes about the NEXT macro ....* position n to the entry in the history array so that NOW is between history[n] and history[n+1]* calculate the interval according to steptime and position of now within the history array.for debuging fprintf (stderr,"NOW: %8lu ST: %4lu N: %4u HTN: %8lu HTN+1: %8lu IV: %6.0f\n", \ now,steptime,n,history[n].time, history[n+1].time, interval);\*/#define NEXT(steptime) \ inmax = outmax = avc = 0; \ inr = outr = 0.0;\ nextnow = now - steptime;\ if (now == history[n].time && \ n<histvalid && \ nextnow == history[n+1].time) { \ inr = (double) history[n].in;\ outr = (double) history[n].out;\ inmax = history[n].inmax;\ outmax = history[n].outmax;\ n++;\ } else {\ if (now > history[n].time) {\ fprintf(stderr,"ERROR: Rateup is trying to read ahead of the available data\n");\ } else {\ while (now <= history[n+1].time && n < histvalid){n++;}\ do {\ if (now >= history[n].time) {\ if (nextnow <= history[n+1].time) {\ interval = history[n].time - history[n+1].time;\ } else {\ interval = history[n].time - nextnow;\ }\ } else {\ if (nextnow > history[n+1].time) {\ interval = steptime;\ } else {\ interval = now - history[n+1].time;\ }\ }\ inr += (double) history[n].in * interval;\ outr += (double) history[n].out * interval;\ avc += interval;\ inmax = max(inmax, history[n].inmax);\ outmax = max(outmax,history[n].outmax);\ if (nextnow <= history[n+1].time) n++; else break;\ } while (n < histvalid && nextnow < history[n].time);\\ if (avc != steptime) {\ fprintf(stderr,"ERROR: StepTime does not match Avc %8lu. Please Report this.\n", avc);\ }\\ inr /= avc; outr /= avc;\ }\ } void image(file,maxvi,maxvo,maxx,maxy,xscale,yscale,growright,step, bits, ytics, yticsf, peak)char *file;long maxvi,maxvo;long maxx;unsigned long maxy,growright,step,bits;double xscale,yscale;int ytics;double yticsf;int peak;{ FILE *fo; int i,x,y,n,type; long maxv; unsigned long origmaxvi, origmaxvo,maxs, avc, inmax, outmax; double inr, outr,muli, interval; time_t now,onow,nextnow; struct tm *tm; char *graph_label[600]; char ylab[30]; /* scaling helpers */ long maxv_q; unsigned long valsamp,maxin,maxout,digits,maxpercent=0; unsigned long sca_ten,sca_hun,nmax_q; double avin, avout,latestout=0,latestin=0,nmax,avpercent=0,latestpercent=0; double nex_ten,nex_hun,nex_rnd; double sca_max_q,dummy; double percent; char *short_si_out; struct HISTORY *lhist; /* ################################################# */ /* Some general definitions for the graph generation */#define XSIZE (unsigned long)((maxx*xscale)+100+dorelpercent*30)#define YSIZE (unsigned long)((maxy*yscale)+35) /* position the graph */#define ytr(y) (unsigned long)(maxy*yscale+14-((y)*yscale)) /* translate x/y coord into graph coord */#define xtr(x) (unsigned long)((growright) ? (maxx*xscale+81-((x)*xscale)) : (81+((x)*xscale))) /* ################################################# */ /* GD LIB declarations */ /* Declare the image */ gdImagePtr graph,brush_out,brush_outm,brush_outp; /* Declare color indexes */ int i_light,i_dark,i_blank, i_major, i_in, i_out, i_grid, i_inm, i_outm; int i_outp, i_outpg; /* Dotted style */ int styleDotted[3]; /* multiplicator for bits/bytes */ muli = 7*bits+1; maxvi *= muli; maxvo *= muli; origmaxvi = labs(maxvi); origmaxvo = labs(maxvo); maxv = max(maxvi,maxvo); if (step > MONTH_SAMPLE) { type = 4; now = (long)(NOW / YEAR_SAMPLE)*YEAR_SAMPLE; } else if (step > WEEK_SAMPLE) { type = 3; now = (long)(NOW / MONTH_SAMPLE)*MONTH_SAMPLE; } else if (step > DAY_SAMPLE) { type = 2; now = (long)(NOW / WEEK_SAMPLE)*WEEK_SAMPLE; } else { type = 1; now = (long)(NOW / DAY_SAMPLE)*DAY_SAMPLE; } if ((lhist = calloc(1,sizeof(struct HISTORY) * maxx)) == NULL) { fprintf(stderr,"Rateup ERROR: Out of memory in graph creation\n"); exit(1); } onow = now; avin = avout = 0.0; inmax = outmax = maxin = maxout = 0; valsamp =0; for (maxs = 0,n=0,x=0; x<maxx; x++) { NEXT(step); /*scale with muli */ inr *=muli; outr *=muli; inmax *=muli; outmax *=muli; /* ignore times when we have not sampled */ if(inr>0 || outr>0) valsamp++; if (x==0) {latestin=inr;latestout=outr;if (outr) {latestpercent=inr*(double)100./outr;}} avin += inr; avout += outr; if (peak) { maxin = max(maxin,inmax); maxout = max(maxout,outmax); maxs = max(maxs,inmax); maxs = max(maxs,outmax); } else { maxin = max(maxin,inr); maxout = max(maxout,outr); maxs = max(maxs,inr); maxs = max(maxs,outr); } if (dorelpercent && outr) { dummy = (double)100.*inr/outr; maxpercent = max(dummy,maxpercent); } now -= step; } if (dorelpercent) { if (avout && valsamp) { avpercent = (double)100.*avin/avout; } else { avpercent = 0; } } if (valsamp) { avin /= valsamp; avout /= valsamp; } printf("%lu\n",(unsigned long)(maxin/muli)); printf("%lu\n",(unsigned long)(maxout/muli)); if (dorelpercent) { printf("%lu\n",(unsigned long)(maxpercent)); } printf("%lu\n",(unsigned long)(avin/muli)); printf("%lu\n",(unsigned long)(avout/muli)); if (dorelpercent) { printf("%lu\n",(unsigned long)(avpercent)); } printf("%lu\n",(unsigned long)(latestin/muli)); printf("%lu\n",(unsigned long)(latestout/muli)); if (dorelpercent) { printf("%lu\n",(unsigned long)(latestpercent)); } if (maxv<0 || maxv < maxs) {maxv = maxs;} now = onow; if (maxv <= 0) maxv = 1; if (kMG) { char *string = kMG; kMGnumber = 0; while (strchr(string, ',')) { string = strchr(string, ',')+1; kMGnumber++; } } else { kMGnumber = 4; } /* mangle the 0.25*maxv value so, that we get a number with either */ /* one or two digits != 0 and these digits should be at the */ /* start of the number ... */ /* the ceil compensates for rounding with small numbers */ maxv_q = ceil((double)maxv / (double) ytics); /* int */ digits = 0; { double number = (double)maxv_q;/* while (number/(double) kilo >= (double)kilo && digits<kMGnumber*3) {*/ while (number >= (double)kilo && digits<kMGnumber*3) { number /= (double) kilo; digits += 3; } sca_max_q = (double) ( (int) ( ( (double)100.*(double)number )/ (pow((double)10.,(double)(int)(log10((double)number)))) +(double)9.999) / (int)10) /(double)10 *(pow((double)10.,(double)(int)(log10((double)number)))); } if (kMG) { int count = (int)digits; short_si_out = kMGcopy; /* JML bugfix */ strcpy(kMGcopy,kMG); /* JML bugfix */ while (count >= 3) { count -= 3; short_si_out = strchr(short_si_out, ',')+1; } if (strchr(short_si_out, ',')) { *((char*)strchr(short_si_out, ',')) = '\0'; } } else { short_si_out = short_si[min(digits/3,kMGnumber)]; } if (maxv_q) { digits = log10((double)maxv_q); } else { digits=0; } sca_ten = maxv_q / pow(10.0,(double)digits); sca_hun = maxv_q / pow(10.0,(double)digits-1); nex_rnd = (sca_hun) * pow(10.0,(double)digits-1); nex_ten = (sca_ten+1) * pow(10.0,(double)digits); nex_hun = (sca_hun+1) * pow(10.0,(double)digits-1); if (nex_ten <= (1.1 * maxv_q)) { nmax_q = nex_ten; } else if (maxv_q == nex_rnd) { nmax_q = nex_rnd; } else { nmax_q = nex_hun; } sca_max_q = nmax_q/(pow(10.0,(double)((int)(digits/3))*3)); nmax=sca_max_q*ytics*(pow((double)kilo,(double)((int)(digits/3)))); if (nmax < 1.) {nmax=1.;} for (n=0,x=0; x<maxx; x++) { lhist[x].time = 0; graph_label[x] = NULL; tm = localtime(&history[n].time); switch(type){ default: case 1: if (tm->tm_min < 5) { lhist[x].time |= 1; if (tm->tm_hour == 0) lhist[x].time |= 2; } if ((tm->tm_min < 5) && (tm->tm_hour % 2 == 0)) { if ((graph_label[x] = calloc(1,sizeof(char) * 4)) == NULL) { fprintf(stderr,"Rateup ERROR: Out of memory in graph labeling\n"); exit(0); } else { sprintf(graph_label[x],"%i",tm->tm_hour); } } break; case 2: if (tm->tm_min < 30 && tm->tm_hour == 0) { lhist[x].time |= 1; if (tm->tm_wday == 1) lhist[x].time |= 2; } /* fprintf(stderr,"x: %i, min:%i, hour:%i day: %i\n", x,tm->tm_min,tm->tm_hour,tm->tm_wday); */ if ((tm->tm_min < 30) && (tm->tm_hour == 12)) { if ((graph_label[x] = calloc(1,sizeof(char) * 5)) == NULL) { fprintf(stderr,"Rateup ERROR: Out of memory in graph labeling\n"); exit(0); } else { strftime(graph_label[x],4,"%a",tm); } } break; case 3: if (tm->tm_hour < 2) { if (tm->tm_wday == 1) lhist[x].time |= 1; if (tm->tm_mday == 1) lhist[x].time |= 2; } /* label goes to thursday noon */ if ((tm->tm_hour > 10) && (tm->tm_hour <= 12) && (tm->tm_wday == 4)) { if ((graph_label[x] = calloc(1,sizeof(char) * 16)) == NULL) { fprintf(stderr,"Rateup ERROR: Out of memory in graph labeling\n"); exit(0); } else { char fmtbuf[10]; sprintf (fmtbuf, "Week %%%c", weekformat); strftime(graph_label[x],8,fmtbuf, tm); } }
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -