]>
Commit | Line | Data |
---|---|---|
1 | /* | |
2 | * SARG Squid Analysis Report Generator http://sarg.sourceforge.net | |
3 | * 1998, 2015 | |
4 | * | |
5 | * SARG donations: | |
6 | * please look at http://sarg.sourceforge.net/donations.php | |
7 | * Support: | |
8 | * http://sourceforge.net/projects/sarg/forums/forum/363374 | |
9 | * --------------------------------------------------------------------- | |
10 | * | |
11 | * This program is free software; you can redistribute it and/or modify | |
12 | * it under the terms of the GNU General Public License as published by | |
13 | * the Free Software Foundation; either version 2 of the License, or | |
14 | * (at your option) any later version. | |
15 | * | |
16 | * This program is distributed in the hope that it will be useful, | |
17 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | |
18 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
19 | * GNU General Public License for more details. | |
20 | * | |
21 | * You should have received a copy of the GNU General Public License | |
22 | * along with this program; if not, write to the Free Software | |
23 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111, USA. | |
24 | * | |
25 | */ | |
26 | ||
27 | #include "include/conf.h" | |
28 | #include "include/defs.h" | |
29 | ||
30 | /* | |
31 | Extract a date range from a squid log file and write it into a separate file. | |
32 | ||
33 | It can optionally convert the date in human readable format. | |
34 | ||
35 | The output can be split by day into separate files. | |
36 | ||
37 | \param arq The squid log file to split. | |
38 | \param df The date format if the date is to be converted in human readable form. Only the first | |
39 | character is taken into account. It can be 'e' for European date format or anything else for | |
40 | US date format. | |
41 | \param dfrom The first date to output in the form (Year*10000+Month*100+Day). | |
42 | \param duntil The last date to output in the form (Year*10000+Month*100+Day). | |
43 | \param convert \c True if the date must be converted into human readable form. | |
44 | \param splitprefix If not empty, the output file is written in separate files (one for each day) and | |
45 | the files are named after the day they contain prefixed with the string contained in this variable. | |
46 | */ | |
47 | void splitlog(const char *arq, char df, int dfrom, int duntil, int convert, const char *splitprefix) | |
48 | { | |
49 | FileObject *fp_in; | |
50 | FILE *fp_ou=NULL; | |
51 | char *buf; | |
52 | char data[30]; | |
53 | char dia[11]; | |
54 | char output_file[MAXLEN]; | |
55 | time_t tt; | |
56 | time_t min_tt; | |
57 | time_t max_tt=0; | |
58 | int idata=0; | |
59 | int autosplit=0; | |
60 | int output_prefix_len=0; | |
61 | int prev_year=0, prev_month=0, prev_day=0; | |
62 | struct tm *t; | |
63 | struct getwordstruct gwarea; | |
64 | longline line; | |
65 | ||
66 | if (splitprefix[0]!='\0') { | |
67 | // '/' + '-YYYY-mm-dd' + '\0' == 13 | |
68 | output_prefix_len=snprintf(output_file,sizeof(output_file)-12,"%s%s",outdir,splitprefix); | |
69 | if (output_prefix_len>=sizeof(output_file)-12) { | |
70 | debuga(__FILE__,__LINE__,_("Path too long: ")); | |
71 | debuga_more("%s%s-YYYY-mm-dd\n",outdir,splitprefix); | |
72 | exit(EXIT_FAILURE); | |
73 | } | |
74 | autosplit=1; | |
75 | } else { | |
76 | fp_ou=stdout; | |
77 | } | |
78 | ||
79 | if(arq[0] == '\0') | |
80 | arq="/var/log/squid/access.log"; | |
81 | ||
82 | if((fp_in=decomp(arq))==NULL) { | |
83 | debuga(__FILE__,__LINE__,_("Cannot open file \"%s\": %s\n"),arq,FileObject_GetLastOpenError()); | |
84 | exit(EXIT_FAILURE); | |
85 | } | |
86 | ||
87 | if ((line=longline_create())==NULL) { | |
88 | debuga(__FILE__,__LINE__,_("Not enough memory to read file \"%s\"\n"),arq); | |
89 | exit(EXIT_FAILURE); | |
90 | } | |
91 | time(&min_tt); | |
92 | ||
93 | while((buf=longline_read(fp_in,line))!=NULL) { | |
94 | getword_start(&gwarea,buf); | |
95 | if (getword(data,sizeof(data),&gwarea,' ')<0) { | |
96 | debuga(__FILE__,__LINE__,_("Invalid date in file \"%s\"\n"),arq); | |
97 | exit(EXIT_FAILURE); | |
98 | } | |
99 | tt=atoi(data); | |
100 | t=localtime(&tt); | |
101 | ||
102 | if(dfrom) { | |
103 | idata=(t->tm_year+1900)*10000+(t->tm_mon+1)*100+t->tm_mday; | |
104 | if(idata < dfrom || idata > duntil) | |
105 | continue; | |
106 | } | |
107 | ||
108 | if (autosplit && (prev_year!=t->tm_year || prev_month!=t->tm_mon || prev_day!=t->tm_mday)) { | |
109 | prev_year=t->tm_year; | |
110 | prev_month=t->tm_mon; | |
111 | prev_day=t->tm_mday; | |
112 | if (fp_ou && fclose(fp_ou)==EOF) { | |
113 | debuga(__FILE__,__LINE__,_("Write error in \"%s\": %s\n"),output_file,strerror(errno)); | |
114 | exit(EXIT_FAILURE); | |
115 | } | |
116 | strftime(output_file+output_prefix_len, sizeof(output_file)-output_prefix_len, "-%Y-%m-%d", t); | |
117 | /* | |
118 | The line must be added to a file we have already created. The file must be created if the date | |
119 | is seen for the first time. The idea is to create the files from scratch if the split is started | |
120 | a second time. | |
121 | */ | |
122 | if ((fp_ou=MY_FOPEN(output_file,(tt>=min_tt && tt<=max_tt) ? "a" : "w"))==NULL) { | |
123 | debuga(__FILE__,__LINE__,_("Cannot open file \"%s\": %s\n"),output_file,strerror(errno)); | |
124 | exit(EXIT_FAILURE); | |
125 | } | |
126 | if (tt<min_tt) min_tt=tt; | |
127 | if (tt>max_tt) max_tt=tt; | |
128 | } | |
129 | ||
130 | if(!convert) { | |
131 | fprintf(fp_ou,"%s %s\n",data,gwarea.current); | |
132 | } else { | |
133 | if (df=='e') | |
134 | strftime(dia, sizeof(dia), "%d/%m/%Y", t); | |
135 | else | |
136 | strftime(dia, sizeof(dia), "%m/%d/%Y", t); | |
137 | ||
138 | fprintf(fp_ou,"%s %02d:%02d:%02d %s\n",dia,t->tm_hour,t->tm_min,t->tm_sec,gwarea.current); | |
139 | } | |
140 | } | |
141 | ||
142 | longline_destroy(&line); | |
143 | if (FileObject_Close(fp_in)) { | |
144 | debuga(__FILE__,__LINE__,_("Read error in \"%s\": %s\n"),arq,FileObject_GetLastCloseError()); | |
145 | exit(EXIT_FAILURE); | |
146 | } | |
147 | if (autosplit && fp_ou) { | |
148 | if (fclose(fp_ou)==EOF) { | |
149 | debuga(__FILE__,__LINE__,_("Write error in \"%s\": %s\n"),output_file,strerror(errno)); | |
150 | exit(EXIT_FAILURE); | |
151 | } | |
152 | } | |
153 | } |