3 /* Copyright (C) 2009 Trend Micro Inc.
6 * This program is a free software; you can redistribute it
7 * and/or modify it under the terms of the GNU General Public
8 * License (version 2) as published by the FSF - Free Software
15 #include "analysisd.h"
19 #include "error_messages/error_messages.h"
21 #include "headers/file_op.h"
22 #include "alerts/alerts.h"
24 #include "headers/debug_op.h"
27 char *(weekdays[])={"Sunday","Monday","Tuesday","Wednesday","Thursday",
29 char *(l_month[])={"Jan","Feb","Mar","Apr","May","Jun","Jul","Aug",
30 "Sep","Oct","Nov","Dec"};
36 /* Hour 25 is internally used */
45 int _daily_errors = 0;
48 int percent_diff = 20;
51 char __stats_comment[192];
53 /* Last msgs, to avoid floods */
62 char logfile[OS_FLSIZE +1];
66 /* Creating the path for the logs */
67 snprintf(logfile, OS_FLSIZE,"%s/%d/", STATSAVED, prev_year);
68 if(IsDir(logfile) == -1)
69 if(mkdir(logfile,0770) == -1)
71 merror(MKDIR_ERROR,ARGV0,logfile);
75 snprintf(logfile,OS_FLSIZE,"%s/%d/%s", STATSAVED, prev_year, prev_month);
77 if(IsDir(logfile) == -1)
78 if(mkdir(logfile,0770) == -1)
80 merror(MKDIR_ERROR, ARGV0, logfile);
85 /* Creating the logfile name */
86 snprintf(logfile,OS_FLSIZE,"%s/%d/%s/ossec-%s-%02d.log",
93 flog = fopen(logfile, "a");
96 merror(FOPEN_ERROR, ARGV0, logfile);
100 /* Printing the hourly stats */
103 fprintf(flog,"Hour totals - %d:%d\n", i, _CHour[i]);
106 fprintf(flog,"Total events for day:%d\n", totals);
113 * Return the parameter (event_number + 20 % of it)
114 * If event_number < mindiff, return mindiff
115 * If event_number > maxdiff, return maxdiff
117 int gethour(int event_number)
121 event_diff = (event_number * percent_diff)/100;
125 if(event_diff < mindiff)
126 return(event_number + mindiff);
127 else if(event_diff > maxdiff)
128 return(event_number + maxdiff);
130 return(event_number + event_diff);
134 /* Update_Hour: done daily */
141 /* Print total number of logs received per hour */
153 char _hourly[128]; /* _hourly file */
159 /* If saved hourly = 0, just copy the current hourly rate */
164 _RHour[i]=_CHour[i] + 20;
168 /* If we had too many errors this day */
169 if(_daily_errors >= 3)
171 _RHour[i]=(((3*_CHour[i])+(inter*_RHour[i]))/(inter+3))+25;
176 /* The average is going to be the number of interactions +
177 * the currently hourly rate, divided by 4 */
178 _RHour[i]=((_CHour[i]+(inter*_RHour[i]))/(inter+1))+5;
183 snprintf(_hourly,128,"%s/%d",STATQUEUE,i);
184 fp = fopen(_hourly, "w");
187 fprintf(fp,"%d",_RHour[i]);
193 merror(FOPEN_ERROR, "logstats", _hourly);
196 _CHour[i] = 0; /* Zeroing the currently hour */
206 inter = _CWHour[i][24];
214 if(_CWHour[i][j] == 0)
217 if(_RWHour[i][j] == 0)
218 _RWHour[i][j] = _CWHour[i][j] + 20;
222 if(_daily_errors >= 3)
224 _RWHour[i][j]=(((3*_CWHour[i][j])+(inter*_RWHour[i][j]))/(inter+3))+25;
228 _RWHour[i][j]=((_CWHour[i][j]+(inter*_RWHour[i][j]))/(inter+1))+5;
233 snprintf(_weekly,128,"%s/%d/%d",STATWQUEUE,i,j);
234 fp = fopen(_weekly, "w");
237 fprintf(fp,"%d",_RWHour[i][j]);
242 merror(FOPEN_ERROR, "logstats", _weekly);
254 /* Check Hourly stats */
255 int Check_Hour(Eventinfo *lf)
257 _CHour[__crt_hour]++;
258 _CWHour[__crt_wday][__crt_hour]++;
265 /* checking if any message was already fired for this hour */
266 if((_daily_errors >= 3)||((_fired == 1)&&(_cignorehour == __crt_hour)))
269 else if(_cignorehour != __crt_hour)
271 _cignorehour=__crt_hour;
276 /* checking if passed the threshold */
277 if(_RHour[__crt_hour] != 0)
279 if(_CHour[__crt_hour] > (_RHour[__crt_hour]))
281 if(_CHour[__crt_hour] > (gethour(_RHour[__crt_hour])))
283 /* snprintf will null terminate */
284 snprintf(__stats_comment, 191,
285 "The average number of logs"
286 " between %d:00 and %d:00 is %d. We "
287 "reached %d.",__crt_hour,__crt_hour+1,
288 _RHour[__crt_hour],_CHour[__crt_hour]);
299 /* We need to have at least 3 days of stats */
300 if(_RWHour[__crt_wday][24] <= 2)
303 /* checking for the hour during a specific day of the week */
304 if(_RWHour[__crt_wday][__crt_hour] != 0)
306 if(_CWHour[__crt_wday][__crt_hour] > _RWHour[__crt_wday][__crt_hour])
308 if(_CWHour[__crt_wday][__crt_hour] >
309 gethour(_RWHour[__crt_wday][__crt_hour]))
311 snprintf(__stats_comment, 191,
312 "The average number of logs"
313 " between %d:00 and %d:00 on %s is %d. We"
314 " reached %d.",__crt_hour,__crt_hour+1,
315 weekdays[__crt_wday],
316 _RWHour[__crt_wday][__crt_hour],
317 _CWHour[__crt_wday][__crt_hour]);
329 /* Starting hourly stats and other necessary variables */
336 p = localtime(&c_time);
338 /* Other global variables */
343 thishour = p->tm_hour;
344 prev_year = p->tm_year + 1900;
345 strncpy(prev_month, l_month[p->tm_mon], 3);
346 prev_month[3] = '\0';
349 /* Clearing some memory */
350 memset(__stats_comment, '\0', 192);
353 /* Getting maximum/minimum diffs */
354 maxdiff = getDefine_Int("analysisd",
358 mindiff = getDefine_Int("analysisd",
362 percent_diff = getDefine_Int("analysisd",
363 "stats_percent_diff",
367 /* Last three messages
368 * They are used to keep track of the last
369 * messages received to avoid floods.
376 /* They should not be null */
377 os_strdup(" ", _lastmsg);
378 os_strdup(" ", _prevlast);
379 os_strdup(" ", _pprevlast);
382 /* Creating the stat queue directories */
383 if(IsDir(STATWQUEUE) == -1)
384 if(mkdir(STATWQUEUE,0770) == -1)
386 merror("%s: logstat: Unable to create stat queue: %s",
391 if(IsDir(STATQUEUE) == -1)
392 if(mkdir(STATQUEUE,0770) == -1)
394 merror("%s: logstat: Unable to create stat queue: %s",
399 /* Creating store dir */
400 if(IsDir(STATSAVED) == -1)
401 if(mkdir(STATSAVED,0770) == -1)
403 merror("%s: logstat: Unable to create stat directory: %s",
408 /* Creating hourly directory (24 hour is the stats) */
412 snprintf(_hourly,128,"%s/%d",STATQUEUE,i);
415 if(File_DateofChange(_hourly) < 0)
421 fp = fopen(_hourly, "r");
426 if(fscanf(fp,"%d",&_RHour[i]) <= 0)
436 /* Creating weekly/hourly directories */
440 snprintf(_weekly,128,"%s/%d",STATWQUEUE,i);
441 if(IsDir(_weekly) == -1)
442 if(mkdir(_weekly,0770) == -1)
444 merror("%s: logstat: Unable to create stat queue: %s",
452 snprintf(_weekly,128,"%s/%d/%d",STATWQUEUE,i,j);
453 if(File_DateofChange(_weekly) < 0)
458 fp = fopen(_weekly, "r");
463 if(fscanf(fp,"%d",&_RWHour[i][j]) <= 0)
466 if(_RWHour[i][j] < 0)
477 /* LastMsg_Stats: v0.3: 2006/03/21
478 * v0.3: Some performance fixes (2006/03/21).
480 * check if the message received is repeated. Doing
481 * it to avoid floods from same message.
483 int LastMsg_Stats(char *log)
485 if(strcmp(log,_lastmsg) == 0)
488 else if(strcmp(log,_prevlast) == 0)
491 else if(strcmp(log,_pprevlast) == 0)
497 /* LastMsg_Change: v0.3: 2006/03/21
498 * v0.3: 2006/03/21: Some performance fixes.
500 * If the message is not repeated, rearrange the last
503 void LastMsg_Change(char *log)
505 /* Removing the last one */
508 /* Moving the second to third and the last to second */
509 _pprevlast = _prevlast;
511 _prevlast = _lastmsg;
514 os_strdup(log, _lastmsg);