1 #include <stdio.h>
2 #include <stdlib.h>
3 #include <string.h>
4 #include <time.h>
5 #include <sys/time.h>
6 #include <errno.h>
7 #include <unistd.h>
8 #include <sys/stat.h>
9 #include <fcntl.h>
10 #include "fastcommon/common_define.h"
11 #include "test_types.h"
12 #include "common_func.h"
13 
14 static int proccess_count;
15 
16 static int combine_stat_overall(int *ptotal_count, int *psuccess_count, int *ptime_used);
17 static int combine_stat_by(const char *file_prefix, EntryStat *stats, const int max_entries, int *entry_count);
18 static void print_stat_by(EntryStat *stats, const int entry_count);
19 
main(int argc,char ** argv)20 int main(int argc, char **argv)
21 {
22 	EntryStat stats[FILE_TYPE_COUNT];
23 	int entry_count;
24 	int time_used;
25 	int total_count;
26 	int success_count;
27 	int i;
28 	int bytes;
29 	int64_t total_bytes;
30 
31 	if (argc < 2)
32 	{
33 		printf("Usage: %s <process_count>\n", argv[0]);
34 		return EINVAL;
35 	}
36 
37 	proccess_count = atoi(argv[1]);
38 	if (proccess_count <= 0)
39 	{
40 		printf("Invalid proccess count: %d\n", proccess_count);
41 		return EINVAL;
42 	}
43 
44 	total_count = 0;
45 	success_count = 0;
46 	time_used = 0;
47 	combine_stat_overall(&total_count, &success_count, &time_used);
48 	printf("total_count=%d, success_count=%d, success ratio: %.2f%% time_used=%ds, avg time used: %dms, QPS=%.2f\n\n",
49 		total_count, success_count, total_count > 0 ? 100.00 * success_count / total_count : 0.00,
50 		time_used, total_count > 0 ? time_used * 1000 / total_count : 0,
51 		time_used == 0 ? 0 : (double)success_count / time_used);
52 
53 	if (combine_stat_by(STAT_FILENAME_BY_FILE_TYPE, stats, FILE_TYPE_COUNT, &entry_count) == 0)
54 	{
55 		printf("file_type total_count success_count time_used(s) avg(ms) QPS success_ratio\n");
56 		print_stat_by(stats, entry_count);
57 		printf("\n");
58 	}
59 
60 	total_bytes = 0;
61 	for (i=0; i<entry_count; i++)
62 	{
63 		if (strcmp(stats[i].id, "5K") == 0)
64 		{
65 			bytes = 5 * 1024;
66 		}
67 		else if (strcmp(stats[i].id, "50K") == 0)
68 		{
69 			bytes = 50 * 1024;
70 		}
71 		else if (strcmp(stats[i].id, "200K") == 0)
72 		{
73 			bytes = 200 * 1024;
74 		}
75 		else if (strcmp(stats[i].id, "1M") == 0)
76 		{
77 			bytes = 1 * 1024 * 1024;
78 		}
79 		else if (strcmp(stats[i].id, "10M") == 0)
80 		{
81 			bytes = 10 * 1024 * 1024;
82 		}
83 		else if (strcmp(stats[i].id, "100M") == 0)
84 		{
85 			bytes = 100 * 1024 * 1024;
86 		}
87 		else
88 		{
89 			bytes = 0;
90 		}
91 
92 		total_bytes += (int64_t)bytes * stats[i].success_count;
93 	}
94 	if (time_used > 0)
95 	{
96 		printf("IO speed = %d KB\n", (int)(total_bytes / (time_used * 1024)));
97 	}
98 
99 	if (combine_stat_by(STAT_FILENAME_BY_STORAGE_IP, stats, FILE_TYPE_COUNT, &entry_count) == 0)
100 	{
101 		printf("ip_addr  total_count success_count time_used(s) avg(ms) QPS success_ratio\n");
102 		print_stat_by(stats, entry_count);
103 		printf("\n");
104 	}
105 
106 	return 0;
107 }
108 
print_stat_by(EntryStat * stats,const int entry_count)109 static void print_stat_by(EntryStat *stats, const int entry_count)
110 {
111 	EntryStat *pEntry;
112 	EntryStat *pEnd;
113 	int seconds;
114 
115 	pEnd = stats + entry_count;
116 	for (pEntry=stats; pEntry<pEnd; pEntry++)
117 	{
118 		seconds = pEntry->time_used / 1000;
119 		printf("%s %d %d %d %d %.2f %.2f\n", pEntry->id, pEntry->total_count,
120 			pEntry->success_count, (int)(pEntry->time_used / 1000),
121 			pEntry->total_count == 0 ? 0 : (int)(pEntry->time_used / pEntry->total_count),
122 			seconds == 0 ? 0 : (double)pEntry->success_count / seconds,
123 			pEntry->total_count > 0 ? 100.00 * pEntry->success_count / pEntry->total_count : 0.00);
124 	}
125 }
126 
combine_stat_by(const char * file_prefix,EntryStat * stats,const int max_entries,int * entry_count)127 static int combine_stat_by(const char *file_prefix, EntryStat *stats, const int max_entries, int *entry_count)
128 {
129 	char filename[64];
130 	FILE *fp;
131 	int proccess_index;
132 	char buff[256];
133 	char id[64];
134 	int64_t time_used;
135 	int total_count;
136 	int success_count;
137 	EntryStat *pEntry;
138 	EntryStat *pEnd;
139 
140 	*entry_count = 0;
141 	memset(stats, 0, sizeof(EntryStat) * max_entries);
142 	for (proccess_index=0; proccess_index<proccess_count; proccess_index++)
143 	{
144 		sprintf(filename, "%s.%d", file_prefix, proccess_index);
145 		if ((fp=fopen(filename, "r")) == NULL)
146 		{
147 			printf("open file %s fail, errno: %d, error info: %s\n",
148 				filename, errno, STRERROR(errno));
149 			return errno != 0 ? errno : EPERM;
150 		}
151 
152 		while (fgets(buff, sizeof(buff), fp) != NULL)
153 		{
154 			if (*buff == '#')
155 			{
156 				continue;
157 			}
158 
159 			if (sscanf(buff, "%s %d %d %"PRId64, id, \
160 				&total_count, &success_count, &time_used) != 4)
161 			{
162 				if (*buff == ' ') //empty id (eg. storage ip)
163 				{
164 					*id = '\0';
165 					if (sscanf(buff+1, "%d %d %"PRId64, \
166 					&total_count, &success_count, &time_used) != 3)
167 					{
168 						printf("sscanf %s fail, errno: %d, error info: %s\n",
169 							filename, errno, STRERROR(errno));
170 		                fclose(fp);
171 						return errno != 0 ? errno : EINVAL;
172 					}
173 				}
174 				else
175 				{
176 					printf("sscanf %s fail, errno: %d, error info: %s\n",
177 						filename, errno, STRERROR(errno));
178 		            fclose(fp);
179 					return errno != 0 ? errno : EINVAL;
180 				}
181 			}
182 
183 			pEnd = stats + (*entry_count);
184 			for (pEntry=stats; pEntry<pEnd; pEntry++)
185 			{
186 				if (strcmp(id, pEntry->id) == 0)
187 				{
188 					break;
189 				}
190 			}
191 
192 			if (pEntry == pEnd) //not found
193 			{
194 				if (*entry_count >= max_entries)
195 				{
196 					printf("entry count: %d >= max entries: %d\n", *entry_count, max_entries);
197 		            fclose(fp);
198 					return ENOSPC;
199 				}
200 
201 				strcpy(pEntry->id, id);
202 				(*entry_count)++;
203 			}
204 
205 			pEntry->total_count += total_count;
206 			pEntry->success_count += success_count;
207 			pEntry->time_used += time_used;
208 		}
209 
210 		fclose(fp);
211 	}
212 
213 	pEnd = stats + (*entry_count);
214 	for (pEntry=stats; pEntry<pEnd; pEntry++)
215 	{
216 		pEntry->time_used /= proccess_count;
217 	}
218 
219 	return 0;
220 }
221 
combine_stat_overall(int * ptotal_count,int * psuccess_count,int * ptime_used)222 static int combine_stat_overall(int *ptotal_count, int *psuccess_count, int *ptime_used)
223 {
224 	char filename[64];
225 	FILE *fp;
226 	int proccess_index;
227 	char buff[256];
228 	int time_used;
229 	int total_count;
230 	int success_count;
231 
232 	*ptotal_count = 0;
233 	*psuccess_count = 0;
234 	*ptime_used = 0;
235 
236 	for (proccess_index=0; proccess_index<proccess_count; proccess_index++)
237 	{
238 		sprintf(filename, "%s.%d", STAT_FILENAME_BY_OVERALL, proccess_index);
239 		if ((fp=fopen(filename, "r")) == NULL)
240 		{
241 			printf("open file %s fail, errno: %d, error info: %s\n",
242 				filename, errno, STRERROR(errno));
243 			return errno != 0 ? errno : EPERM;
244 		}
245 
246 		while (fgets(buff, sizeof(buff), fp) != NULL)
247 		{
248 			if (*buff == '#')
249 			{
250 				continue;
251 			}
252 
253 			if (sscanf(buff, "%d %d %d", &total_count, &success_count, &time_used) != 3)
254 			{
255 				printf("sscanf %s fail, errno: %d, error info: %s\n",
256 					filename, errno, STRERROR(errno));
257 				return errno != 0 ? errno : EINVAL;
258 			}
259 
260 			break;
261 		}
262 
263 		*ptotal_count += total_count;
264 		*psuccess_count += success_count;
265 		*ptime_used += time_used;
266 		fclose(fp);
267 	}
268 
269 	*ptime_used /= proccess_count;
270 
271 	return 0;
272 }
273 
274