1 /* @(#) $Id: ./src/analysisd/stats.c, 2011/09/08 dcid Exp $
4 /* Copyright (C) 2009 Trend Micro Inc.
7 * This program is a free software; you can redistribute it
8 * and/or modify it under the terms of the GNU General Public
9 * License (version 2) as published by the FSF - Free Software
16 #include "analysisd.h"
20 #include "error_messages/error_messages.h"
22 #include "headers/file_op.h"
23 #include "alerts/alerts.h"
25 #include "headers/debug_op.h"
28 char *(weekdays[])={"Sunday","Monday","Tuesday","Wednesday","Thursday",
30 char *(l_month[])={"Jan","Feb","Mar","Apr","May","Jun","Jul","Aug",
31 "Sep","Oct","Nov","Dec"};
37 /* Hour 25 is internally used */
46 int _daily_errors = 0;
49 int percent_diff = 20;
52 char __stats_comment[192];
54 /* Last msgs, to avoid floods */
63 char logfile[OS_FLSIZE +1];
67 /* Creating the path for the logs */
68 snprintf(logfile, OS_FLSIZE,"%s/%d/", STATSAVED, prev_year);
69 if(IsDir(logfile) == -1)
70 if(mkdir(logfile,0770) == -1)
72 merror(MKDIR_ERROR,ARGV0,logfile);
76 snprintf(logfile,OS_FLSIZE,"%s/%d/%s", STATSAVED, prev_year, prev_month);
78 if(IsDir(logfile) == -1)
79 if(mkdir(logfile,0770) == -1)
81 merror(MKDIR_ERROR, ARGV0, logfile);
86 /* Creating the logfile name */
87 snprintf(logfile,OS_FLSIZE,"%s/%d/%s/ossec-%s-%02d.log",
94 flog = fopen(logfile, "a");
97 merror(FOPEN_ERROR, ARGV0, logfile);
101 /* Printing the hourly stats */
104 fprintf(flog,"Hour totals - %d:%d\n", i, _CHour[i]);
107 fprintf(flog,"Total events for day:%d\n", totals);
114 * Return the parameter (event_number + 20 % of it)
115 * If event_number < mindiff, return mindiff
116 * If event_number > maxdiff, return maxdiff
118 int gethour(int event_number)
122 event_diff = (event_number * percent_diff)/100;
126 if(event_diff < mindiff)
127 return(event_number + mindiff);
128 else if(event_diff > maxdiff)
129 return(event_number + maxdiff);
131 return(event_number + event_diff);
135 /* Update_Hour: done daily */
142 /* Print total number of logs received per hour */
154 char _hourly[128]; /* _hourly file */
160 /* If saved hourly = 0, just copy the current hourly rate */
165 _RHour[i]=_CHour[i] + 20;
169 /* If we had too many errors this day */
170 if(_daily_errors >= 3)
172 _RHour[i]=(((3*_CHour[i])+(inter*_RHour[i]))/(inter+3))+25;
177 /* The average is going to be the number of interactions +
178 * the currently hourly rate, divided by 4 */
179 _RHour[i]=((_CHour[i]+(inter*_RHour[i]))/(inter+1))+5;
184 snprintf(_hourly,128,"%s/%d",STATQUEUE,i);
185 fp = fopen(_hourly, "w");
188 fprintf(fp,"%d",_RHour[i]);
194 merror(FOPEN_ERROR, "logstats", _hourly);
197 _CHour[i] = 0; /* Zeroing the currently hour */
207 inter = _CWHour[i][24];
215 if(_CWHour[i][j] == 0)
218 if(_RWHour[i][j] == 0)
219 _RWHour[i][j] = _CWHour[i][j] + 20;
223 if(_daily_errors >= 3)
225 _RWHour[i][j]=(((3*_CWHour[i][j])+(inter*_RWHour[i][j]))/(inter+3))+25;
229 _RWHour[i][j]=((_CWHour[i][j]+(inter*_RWHour[i][j]))/(inter+1))+5;
234 snprintf(_weekly,128,"%s/%d/%d",STATWQUEUE,i,j);
235 fp = fopen(_weekly, "w");
238 fprintf(fp,"%d",_RWHour[i][j]);
243 merror(FOPEN_ERROR, "logstats", _weekly);
255 /* Check Hourly stats */
256 int Check_Hour(Eventinfo *lf)
258 _CHour[__crt_hour]++;
259 _CWHour[__crt_wday][__crt_hour]++;
266 /* checking if any message was already fired for this hour */
267 if((_daily_errors >= 3)||((_fired == 1)&&(_cignorehour == __crt_hour)))
270 else if(_cignorehour != __crt_hour)
272 _cignorehour=__crt_hour;
277 /* checking if passed the threshold */
278 if(_RHour[__crt_hour] != 0)
280 if(_CHour[__crt_hour] > (_RHour[__crt_hour]))
282 if(_CHour[__crt_hour] > (gethour(_RHour[__crt_hour])))
284 /* snprintf will null terminate */
285 snprintf(__stats_comment, 191,
286 "The average number of logs"
287 " between %d:00 and %d:00 is %d. We "
288 "reached %d.",__crt_hour,__crt_hour+1,
289 _RHour[__crt_hour],_CHour[__crt_hour]);
300 /* We need to have at least 3 days of stats */
301 if(_RWHour[__crt_wday][24] <= 2)
304 /* checking for the hour during a specific day of the week */
305 if(_RWHour[__crt_wday][__crt_hour] != 0)
307 if(_CWHour[__crt_wday][__crt_hour] > _RWHour[__crt_wday][__crt_hour])
309 if(_CWHour[__crt_wday][__crt_hour] >
310 gethour(_RWHour[__crt_wday][__crt_hour]))
312 snprintf(__stats_comment, 191,
313 "The average number of logs"
314 " between %d:00 and %d:00 on %s is %d. We"
315 " reached %d.",__crt_hour,__crt_hour+1,
316 weekdays[__crt_wday],
317 _RWHour[__crt_wday][__crt_hour],
318 _CWHour[__crt_wday][__crt_hour]);
330 /* Starting hourly stats and other necessary variables */
337 p = localtime(&c_time);
339 /* Other global variables */
344 thishour = p->tm_hour;
345 prev_year = p->tm_year + 1900;
346 strncpy(prev_month, l_month[p->tm_mon], 3);
347 prev_month[3] = '\0';
350 /* Clearing some memory */
351 memset(__stats_comment, '\0', 192);
354 /* Getting maximum/minimum diffs */
355 maxdiff = getDefine_Int("analysisd",
359 mindiff = getDefine_Int("analysisd",
363 percent_diff = getDefine_Int("analysisd",
364 "stats_percent_diff",
368 /* Last three messages
369 * They are used to keep track of the last
370 * messages received to avoid floods.
377 /* They should not be null */
378 os_strdup(" ", _lastmsg);
379 os_strdup(" ", _prevlast);
380 os_strdup(" ", _pprevlast);
383 /* Creating the stat queue directories */
384 if(IsDir(STATWQUEUE) == -1)
385 if(mkdir(STATWQUEUE,0770) == -1)
387 merror("%s: logstat: Unable to create stat queue: %s",
392 if(IsDir(STATQUEUE) == -1)
393 if(mkdir(STATQUEUE,0770) == -1)
395 merror("%s: logstat: Unable to create stat queue: %s",
400 /* Creating store dir */
401 if(IsDir(STATSAVED) == -1)
402 if(mkdir(STATSAVED,0770) == -1)
404 merror("%s: logstat: Unable to create stat directory: %s",
409 /* Creating hourly directory (24 hour is the stats) */
413 snprintf(_hourly,128,"%s/%d",STATQUEUE,i);
416 if(File_DateofChange(_hourly) < 0)
422 fp = fopen(_hourly, "r");
427 if(fscanf(fp,"%d",&_RHour[i]) <= 0)
437 /* Creating weekly/hourly directories */
441 snprintf(_weekly,128,"%s/%d",STATWQUEUE,i);
442 if(IsDir(_weekly) == -1)
443 if(mkdir(_weekly,0770) == -1)
445 merror("%s: logstat: Unable to create stat queue: %s",
453 snprintf(_weekly,128,"%s/%d/%d",STATWQUEUE,i,j);
454 if(File_DateofChange(_weekly) < 0)
459 fp = fopen(_weekly, "r");
464 if(fscanf(fp,"%d",&_RWHour[i][j]) <= 0)
467 if(_RWHour[i][j] < 0)
478 /* LastMsg_Stats: v0.3: 2006/03/21
479 * v0.3: Some performance fixes (2006/03/21).
481 * check if the message received is repeated. Doing
482 * it to avoid floods from same message.
484 int LastMsg_Stats(char *log)
486 if(strcmp(log,_lastmsg) == 0)
489 else if(strcmp(log,_prevlast) == 0)
492 else if(strcmp(log,_pprevlast) == 0)
498 /* LastMsg_Change: v0.3: 2006/03/21
499 * v0.3: 2006/03/21: Some performance fixes.
501 * If the message is not repeated, rearrange the last
504 void LastMsg_Change(char *log)
506 /* Removing the last one */
509 /* Moving the second to third and the last to second */
510 _pprevlast = _prevlast;
512 _prevlast = _lastmsg;
515 os_strdup(log, _lastmsg);