1 /**
2 * Copyright (C) 2008 Happy Fish / YuQing
3 *
4 * FastDFS may be copied only under the terms of the GNU General
5 * Public License V3, which may be found in the FastDFS source kit.
6 * Please visit the FastDFS Home Page http://www.fastken.com/ for more detail.
7 **/
8 
9 #include <stdio.h>
10 #include <string.h>
11 #include <stdlib.h>
12 #include <errno.h>
13 #include <fcntl.h>
14 #include "tracker_dump.h"
15 #include "fastcommon/shared_func.h"
16 #include "fastcommon/sched_thread.h"
17 #include "fastcommon/logger.h"
18 #include "fastcommon/hash.h"
19 #include "fastcommon/connection_pool.h"
20 #include "fdfs_global.h"
21 #include "tracker_global.h"
22 #include "tracker_mem.h"
23 #include "tracker_service.h"
24 #include "tracker_relationship.h"
25 #include "fdfs_shared_func.h"
26 
27 static int fdfs_dump_storage_stat(FDFSStorageDetail *pServer,
28 		char *buff, const int buffSize);
29 
fdfs_dump_group_stat(FDFSGroupInfo * pGroup,char * buff,const int buffSize)30 static int fdfs_dump_group_stat(FDFSGroupInfo *pGroup, char *buff, const int buffSize)
31 {
32 	char szLastSourceUpdate[32];
33 	char szLastSyncUpdate[32];
34 	char szSyncedTimestamp[32];
35 	int total_len;
36 	FDFSStorageDetail **ppServer;
37 	FDFSStorageDetail **ppServerEnd;
38 	int i;
39 	int j;
40 
41 	total_len = snprintf(buff, buffSize,
42 		"group_name=%s\n"
43 		"total_mb=%"PRId64"\n"
44 		"free_mb=%"PRId64"\n"
45 		"alloc_size=%d\n"
46 		"server count=%d\n"
47 		"active server count=%d\n"
48 		"storage_port=%d\n"
49 		"storage_http_port=%d\n"
50 		"current_read_server=%d\n"
51 		"current_write_server=%d\n"
52 		"store_path_count=%d\n"
53 		"subdir_count_per_path=%d\n"
54 		"current_trunk_file_id=%d\n"
55 		"pStoreServer=%s\n"
56 		"pTrunkServer=%s\n"
57 		"last_trunk_server_id=%s\n"
58 		"chg_count=%d\n"
59 		"trunk_chg_count=%d\n"
60 		"last_source_update=%s\n"
61 		"last_sync_update=%s\n",
62 		pGroup->group_name,
63 		pGroup->total_mb,
64 		pGroup->free_mb,
65 		pGroup->alloc_size,
66 		pGroup->count,
67 		pGroup->active_count,
68 		pGroup->storage_port,
69 		pGroup->storage_http_port,
70 		pGroup->current_read_server,
71 		pGroup->current_write_server,
72 		pGroup->store_path_count,
73 		pGroup->subdir_count_per_path,
74 		pGroup->current_trunk_file_id,
75 		pGroup->pStoreServer != NULL ? FDFS_CURRENT_IP_ADDR(pGroup->pStoreServer) : "",
76 		pGroup->pTrunkServer != NULL ? FDFS_CURRENT_IP_ADDR(pGroup->pTrunkServer) : "",
77 		pGroup->last_trunk_server_id,
78 		pGroup->chg_count,
79 		pGroup->trunk_chg_count,
80 		formatDatetime(pGroup->last_source_update,
81 			"%Y-%m-%d %H:%M:%S",
82 			szLastSourceUpdate, sizeof(szLastSourceUpdate)),
83 		formatDatetime(pGroup->last_sync_update,
84 			"%Y-%m-%d %H:%M:%S",
85 			szLastSyncUpdate, sizeof(szLastSyncUpdate))
86 	);
87 
88 	total_len += snprintf(buff + total_len, buffSize - total_len,
89 		"total server count=%d\n", pGroup->count);
90 	ppServerEnd = pGroup->all_servers + pGroup->count;
91 	for (ppServer=pGroup->all_servers; ppServer<ppServerEnd; ppServer++)
92 	{
93 		total_len += snprintf(buff + total_len, buffSize - total_len,
94 			"\t%s\n", FDFS_CURRENT_IP_ADDR(*ppServer));
95 	}
96 
97 	total_len += snprintf(buff + total_len, buffSize - total_len,
98 		"\nactive server count=%d\n", pGroup->active_count);
99 	ppServerEnd = pGroup->active_servers + pGroup->active_count;
100 	for (ppServer=pGroup->active_servers; ppServer<ppServerEnd; ppServer++)
101 	{
102 		total_len += snprintf(buff + total_len, buffSize - total_len,
103 			"\t%s\n", FDFS_CURRENT_IP_ADDR(*ppServer));
104 	}
105 
106 #ifdef WITH_HTTPD
107 	total_len += snprintf(buff + total_len, buffSize - total_len,
108 		"\nhttp active server count=%d\n"
109 		"current_http_server=%d\n",
110 		pGroup->http_server_count,
111 		pGroup->current_http_server);
112 
113 	ppServerEnd = pGroup->http_servers + pGroup->http_server_count;
114 	for (ppServer=pGroup->http_servers; ppServer<ppServerEnd; ppServer++)
115 	{
116 		total_len += snprintf(buff + total_len, buffSize - total_len,
117 			"\t%s\n", (*ppServer)->ip_addr);
118 	}
119 #endif
120 
121 	ppServerEnd = pGroup->sorted_servers + pGroup->count;
122 	for (ppServer=pGroup->sorted_servers; ppServer<ppServerEnd; ppServer++)
123 	{
124 		total_len += snprintf(buff + total_len, buffSize - total_len,
125 				"\nHost %d.\n",
126 				(int)(ppServer - pGroup->sorted_servers) + 1);
127 		total_len += fdfs_dump_storage_stat(*ppServer, buff + total_len,
128 				 buffSize - total_len);
129 	}
130 
131 	total_len += snprintf(buff + total_len, buffSize - total_len,
132 			"\nsynced timestamp table:\n");
133 	for (i=0; i<pGroup->count; i++)
134 	{
135 	for (j=0; j<pGroup->count; j++)
136 	{
137 		if (i == j)
138 		{
139 			continue;
140 		}
141 
142 		total_len += snprintf(buff + total_len, buffSize - total_len,
143 				"\t%s => %s: %s\n",
144 				FDFS_CURRENT_IP_ADDR(pGroup->all_servers[i]),
145 				FDFS_CURRENT_IP_ADDR(pGroup->all_servers[j]),
146 				formatDatetime(pGroup->last_sync_timestamps[i][j],
147 					"%Y-%m-%d %H:%M:%S",
148 					szSyncedTimestamp,
149 					sizeof(szSyncedTimestamp))
150 				);
151 	}
152 	}
153 
154 	total_len += snprintf(buff + total_len, buffSize - total_len,
155 			"\n\n");
156 	return total_len;
157 }
158 
fdfs_dump_storage_stat(FDFSStorageDetail * pServer,char * buff,const int buffSize)159 static int fdfs_dump_storage_stat(FDFSStorageDetail *pServer,
160 		char *buff, const int buffSize)
161 {
162 	char szJoinTime[32];
163 	char szUpTime[32];
164 	char szLastHeartBeatTime[32];
165 	char szSrcUpdTime[32];
166 	char szSyncUpdTime[32];
167 	char szSyncedTimestamp[32];
168 	char szSyncUntilTimestamp[32];
169 	int i;
170 	int total_len;
171 
172 	total_len = snprintf(buff, buffSize,
173 		"ip_addr=%s\n"
174 		"version=%s\n"
175 		"status=%d\n"
176 		"domain_name=%s\n"
177 		"sync_src_server=%s\n"
178 		"sync_until_timestamp=%s\n"
179 		"join_time=%s\n"
180 		"up_time=%s\n"
181 		"total_mb=%"PRId64" MB\n"
182 		"free_mb=%"PRId64" MB\n"
183 		"changelog_offset=%"PRId64"\n"
184 		"store_path_count=%d\n"
185 		"storage_port=%d\n"
186 		"storage_http_port=%d\n"
187 		"subdir_count_per_path=%d\n"
188 		"upload_priority=%d\n"
189 		"current_write_path=%d\n"
190 		"chg_count=%d\n"
191 #ifdef WITH_HTTPD
192 		"http_check_last_errno=%d\n"
193 		"http_check_last_status=%d\n"
194 		"http_check_fail_count=%d\n"
195 		"http_check_error_info=%s\n"
196 #endif
197 
198 		"total_upload_count=%"PRId64"\n"
199 		"success_upload_count=%"PRId64"\n"
200 		"total_set_meta_count=%"PRId64"\n"
201 		"success_set_meta_count=%"PRId64"\n"
202 		"total_delete_count=%"PRId64"\n"
203 		"success_delete_count=%"PRId64"\n"
204 		"total_download_count=%"PRId64"\n"
205 		"success_download_count=%"PRId64"\n"
206 		"total_get_meta_count=%"PRId64"\n"
207 		"success_get_meta_count=%"PRId64"\n"
208 		"total_create_link_count=%"PRId64"\n"
209 		"success_create_link_count=%"PRId64"\n"
210 		"total_delete_link_count=%"PRId64"\n"
211 		"success_delete_link_count=%"PRId64"\n"
212 		"last_source_update=%s\n"
213 		"last_sync_update=%s\n"
214 		"last_synced_timestamp=%s\n"
215 		"last_heart_beat_time=%s\n",
216 		FDFS_CURRENT_IP_ADDR(pServer),
217 		pServer->version,
218 		pServer->status,
219 		pServer->domain_name,
220 		pServer->psync_src_server != NULL ?
221 		FDFS_CURRENT_IP_ADDR(pServer->psync_src_server) : "",
222 		formatDatetime(pServer->sync_until_timestamp,
223 			"%Y-%m-%d %H:%M:%S",
224 			szSyncUntilTimestamp, sizeof(szSyncUntilTimestamp)),
225 		formatDatetime(pServer->join_time,
226 			"%Y-%m-%d %H:%M:%S",
227 			szJoinTime, sizeof(szJoinTime)),
228 		formatDatetime(pServer->up_time,
229 			"%Y-%m-%d %H:%M:%S",
230 			szUpTime, sizeof(szUpTime)),
231 		pServer->total_mb,
232 		pServer->free_mb,
233 		pServer->changelog_offset,
234 		pServer->store_path_count,
235 		pServer->storage_port,
236 		pServer->storage_http_port,
237 		pServer->subdir_count_per_path,
238 		pServer->upload_priority,
239 		pServer->current_write_path,
240 		pServer->chg_count,
241 #ifdef WITH_HTTPD
242 		pServer->http_check_last_errno,
243 		pServer->http_check_last_status,
244 		pServer->http_check_fail_count,
245 		pServer->http_check_error_info,
246 #endif
247 		pServer->stat.total_upload_count,
248 		pServer->stat.success_upload_count,
249 		pServer->stat.total_set_meta_count,
250 		pServer->stat.success_set_meta_count,
251 		pServer->stat.total_delete_count,
252 		pServer->stat.success_delete_count,
253 		pServer->stat.total_download_count,
254 		pServer->stat.success_download_count,
255 		pServer->stat.total_get_meta_count,
256 		pServer->stat.success_get_meta_count,
257 		pServer->stat.total_create_link_count,
258 		pServer->stat.success_create_link_count,
259 		pServer->stat.total_delete_link_count,
260 		pServer->stat.success_delete_link_count,
261 		formatDatetime(pServer->stat.last_source_update,
262 			"%Y-%m-%d %H:%M:%S",
263 			szSrcUpdTime, sizeof(szSrcUpdTime)),
264 		formatDatetime(pServer->stat.last_sync_update,
265 			"%Y-%m-%d %H:%M:%S",
266 			szSyncUpdTime, sizeof(szSyncUpdTime)),
267 		formatDatetime(pServer->stat.last_synced_timestamp,
268 			"%Y-%m-%d %H:%M:%S",
269 			szSyncedTimestamp, sizeof(szSyncedTimestamp)),
270 		formatDatetime(pServer->stat.last_heart_beat_time,
271 			"%Y-%m-%d %H:%M:%S",
272 			szLastHeartBeatTime, sizeof(szLastHeartBeatTime))
273 	);
274 
275 	for (i=0; i<pServer->store_path_count; i++)
276 	{
277 		total_len += snprintf(buff + total_len, buffSize - total_len,
278 			"disk %d: total_mb=%"PRId64" MB, "
279 			"free_mb=%"PRId64" MB\n",
280 			i+1, pServer->path_total_mbs[i],
281 			pServer->path_free_mbs[i]);
282 	}
283 
284 	return total_len;
285 }
286 
fdfs_dump_global_vars(char * buff,const int buffSize)287 static int fdfs_dump_global_vars(char *buff, const int buffSize)
288 {
289 	int total_len;
290 	char reserved_space_str[32];
291     char *p;
292 
293 	total_len = snprintf(buff, buffSize,
294 		"g_fdfs_connect_timeout=%ds\n"
295 		"g_fdfs_network_timeout=%ds\n"
296 		"g_fdfs_base_path=%s\n"
297 		"g_fdfs_version=%d.%02d\n"
298 		"g_continue_flag=%d\n"
299 		"g_schedule_flag=%d\n"
300 		"g_server_port=%d\n"
301 		"g_max_connections=%d\n"
302 		"g_tracker_thread_count=%d\n"
303 		"g_sync_log_buff_interval=%ds\n"
304 		"g_check_active_interval=%ds\n"
305 		"g_storage_stat_chg_count=%d\n"
306 		"g_storage_sync_time_chg_count=%d\n"
307 		"g_storage_reserved_space=%s\n"
308 		"g_allow_ip_count=%d\n"
309 		"g_run_by_group=%s\n"
310 		"g_run_by_user=%s\n"
311 		"g_storage_ip_changed_auto_adjust=%d\n"
312 		"g_thread_stack_size=%d\n"
313 		"if_use_trunk_file=%d\n"
314 		"slot_min_size=%d\n"
315 		"slot_max_size=%d MB\n"
316 		"trunk_file_size=%d MB\n"
317 		"g_changelog_fsize=%"PRId64"\n"
318 		"g_storage_sync_file_max_delay=%ds\n"
319 		"g_storage_sync_file_max_time=%ds\n"
320 		"g_up_time=%d\n"
321 		"g_tracker_last_status.up_time=%d\n"
322 		"g_tracker_last_status.last_check_time=%d\n"
323 		"g_if_leader_self=%d\n"
324 		"g_next_leader_index=%d\n"
325 		"g_tracker_leader_chg_count=%d\n"
326 		"g_trunk_server_chg_count=%d\n"
327 		"g_use_connection_pool=%d\n"
328 		"g_connection_pool_max_idle_time=%d\n"
329 		"connection_pool_conn_count=%d\n"
330 	#ifdef WITH_HTTPD
331 		"g_http_params.disabled=%d\n"
332 		"g_http_params.anti_steal_token=%d\n"
333 		"g_http_params.server_port=%d\n"
334 		"g_http_params.content_type_hash item count=%d\n"
335 		"g_http_params.anti_steal_secret_key length=%d\n"
336 		"g_http_params.token_check_fail_buff length=%d\n"
337 		"g_http_params.default_content_type=%s\n"
338 		"g_http_params.token_check_fail_content_type=%s\n"
339 		"g_http_params.token_ttl=%d\n"
340 		"g_http_check_interval=%d\n"
341 		"g_http_check_type=%d\n"
342 		"g_http_check_uri=%s\n"
343 		"g_http_servers_dirty=%d\n"
344 	#endif
345 	#if defined(DEBUG_FLAG) && defined(OS_LINUX)
346 		"g_exe_name=%s\n"
347 	#endif
348 		, g_fdfs_connect_timeout
349 		, g_fdfs_network_timeout
350 		, g_fdfs_base_path
351 		, g_fdfs_version.major, g_fdfs_version.minor
352 		, g_continue_flag
353 		, g_schedule_flag
354 		, g_server_port
355 		, g_max_connections
356 		, g_tracker_thread_count
357 		, g_sync_log_buff_interval
358 		, g_check_active_interval
359 		, g_storage_stat_chg_count
360 		, g_storage_sync_time_chg_count
361 		, fdfs_storage_reserved_space_to_string( \
362 		    &g_storage_reserved_space, reserved_space_str) \
363 		, g_allow_ip_count
364 		, g_run_by_group
365 		, g_run_by_user
366 		, g_storage_ip_changed_auto_adjust
367 		, g_thread_stack_size
368 		, g_if_use_trunk_file
369 		, g_slot_min_size
370 		, g_slot_max_size / FDFS_ONE_MB
371 		, g_trunk_file_size / FDFS_ONE_MB
372 		, g_changelog_fsize
373 		, g_storage_sync_file_max_delay
374 		, g_storage_sync_file_max_time
375 		, (int)g_up_time
376 		, (int)g_tracker_last_status.up_time
377 		, (int)g_tracker_last_status.last_check_time
378 		, g_if_leader_self
379 		, g_next_leader_index
380 		, g_tracker_leader_chg_count
381 		, g_trunk_server_chg_count
382 		, g_use_connection_pool
383 		, g_connection_pool_max_idle_time
384 		, g_use_connection_pool ? conn_pool_get_connection_count( \
385 			&g_connection_pool) : 0
386 	#ifdef WITH_HTTPD
387 		, g_http_params.disabled
388 		, g_http_params.anti_steal_token
389 		, g_http_params.server_port
390 		, hash_count(&(g_http_params.content_type_hash))
391 		, g_http_params.anti_steal_secret_key.length
392 		, g_http_params.token_check_fail_buff.length
393 		, g_http_params.default_content_type
394 		, g_http_params.token_check_fail_content_type
395 		, g_http_params.token_ttl
396 		, g_http_check_interval
397 		, g_http_check_type
398 		, g_http_check_uri
399 		, g_http_servers_dirty
400 	#endif
401 
402 	#if defined(DEBUG_FLAG) && defined(OS_LINUX)
403 		, g_exe_name
404 	#endif
405 	);
406 
407     if (total_len < buffSize - 1)
408     {
409         *(buff + total_len++) = '\n';
410     }
411     p = buff + total_len;
412     local_host_ip_addrs_to_string(p, buffSize - total_len);
413     total_len += strlen(p);
414     if (total_len < buffSize - 1)
415     {
416         *(buff + total_len++) = '\n';
417     }
418     *(buff + total_len) = '\0';
419 
420 	return total_len;
421 }
422 
fdfs_dump_tracker_servers(char * buff,const int buffSize)423 static int fdfs_dump_tracker_servers(char *buff, const int buffSize)
424 {
425 	int total_len;
426 	TrackerServerInfo *pTrackerServer;
427 	TrackerServerInfo *pTrackerEnd;
428     char ip_str[256];
429 
430 	total_len = snprintf(buff, buffSize, \
431 		"g_tracker_servers.server_count=%d, " \
432 		"g_tracker_servers.leader_index=%d\n", \
433 		g_tracker_servers.server_count, \
434 		g_tracker_servers.leader_index);
435 	if (g_tracker_servers.server_count == 0)
436 	{
437 		return total_len;
438 	}
439 
440 	pTrackerEnd = g_tracker_servers.servers + g_tracker_servers.server_count;
441 	for (pTrackerServer=g_tracker_servers.servers; \
442 		pTrackerServer<pTrackerEnd; pTrackerServer++)
443 	{
444         fdfs_server_info_to_string(pTrackerServer, ip_str, sizeof(ip_str));
445 
446 		total_len += snprintf(buff + total_len, buffSize - total_len,
447 			"\t%d. tracker server=%s:%d\n", \
448 			(int)(pTrackerServer - g_tracker_servers.servers) + 1, \
449 			ip_str, pTrackerServer->connections[0].port);
450 	}
451 
452 	return total_len;
453 }
454 
fdfs_dump_groups_info(char * buff,const int buffSize)455 static int fdfs_dump_groups_info(char *buff, const int buffSize)
456 {
457 	int total_len;
458 
459 	total_len = snprintf(buff, buffSize,
460 		"group count=%d\n"
461 		"group alloc_size=%d\n"
462 		"store_lookup=%d\n"
463 		"store_server=%d\n"
464 		"download_server=%d\n"
465 		"store_path=%d\n"
466 		"store_group=%s\n"
467 		"pStoreGroup=%s\n"
468 		"current_write_group=%d\n",
469 		g_groups.count,
470 		g_groups.alloc_size,
471 		g_groups.store_lookup,
472 		g_groups.store_server,
473 		g_groups.download_server,
474 		g_groups.store_path,
475 		g_groups.store_group,
476 		g_groups.pStoreGroup != NULL ?
477 			g_groups.pStoreGroup->group_name : "",
478 		g_groups.current_write_group
479 	);
480 
481 	return total_len;
482 }
483 
484 #define WRITE_TO_FILE(fd, buff, len) \
485 	if (write(fd, buff, len) != len) \
486 	{ \
487 		logError("file: "__FILE__", line: %d, " \
488 			"write to file %s fail, errno: %d, error info: %s", \
489 			__LINE__, filename, errno, STRERROR(errno)); \
490 		result = errno; \
491 		break; \
492 	}
493 
fdfs_dump_tracker_global_vars_to_file(const char * filename)494 int fdfs_dump_tracker_global_vars_to_file(const char *filename)
495 {
496 	char buff[16 * 1024];
497 	char szCurrentTime[32];
498 	int len;
499 	int result;
500 	int fd;
501 	FDFSGroupInfo **ppGroup;
502 	FDFSGroupInfo **ppGroupEnd;
503 
504 	fd = open(filename, O_WRONLY | O_CREAT | O_APPEND, 0644);
505 	if (fd < 0)
506 	{
507 		logError("file: "__FILE__", line: %d, "
508 			"open file %s fail, errno: %d, error info: %s",
509 			__LINE__, filename, errno, STRERROR(errno));
510 		return errno;
511 	}
512 
513 	do
514 	{
515 		result = 0;
516 		formatDatetime(g_current_time, "%Y-%m-%d %H:%M:%S",
517 				szCurrentTime, sizeof(szCurrentTime));
518 
519 		len = sprintf(buff, "\n====time: %s  DUMP START====\n",
520 				szCurrentTime);
521 		WRITE_TO_FILE(fd, buff, len)
522 
523 		len = fdfs_dump_global_vars(buff, sizeof(buff));
524 		WRITE_TO_FILE(fd, buff, len)
525 
526 		len = fdfs_dump_tracker_servers(buff, sizeof(buff));
527 		WRITE_TO_FILE(fd, buff, len)
528 
529 		len = fdfs_dump_groups_info(buff, sizeof(buff));
530 		WRITE_TO_FILE(fd, buff, len)
531 
532 		len = sprintf(buff, "\ngroup name list:\n");
533 		WRITE_TO_FILE(fd, buff, len)
534 		len = 0;
535 		ppGroupEnd = g_groups.groups + g_groups.count;
536 		for (ppGroup=g_groups.groups; ppGroup<ppGroupEnd; ppGroup++)
537 		{
538 			len += sprintf(buff+len, "\t%s\n", (*ppGroup)->group_name);
539 		}
540 		len += sprintf(buff+len, "\n");
541 		WRITE_TO_FILE(fd, buff, len)
542 
543 		ppGroupEnd = g_groups.sorted_groups + g_groups.count;
544 		for (ppGroup=g_groups.sorted_groups; ppGroup<ppGroupEnd; ppGroup++)
545 		{
546 			len = sprintf(buff, "\nGroup %d.\n",
547 				(int)(ppGroup - g_groups.sorted_groups) + 1);
548 			WRITE_TO_FILE(fd, buff, len)
549 
550 			len = fdfs_dump_group_stat(*ppGroup, buff, sizeof(buff));
551 			WRITE_TO_FILE(fd, buff, len)
552 		}
553 
554 		len = sprintf(buff, "\n====time: %s  DUMP END====\n\n",
555 				szCurrentTime);
556 		WRITE_TO_FILE(fd, buff, len)
557 	} while(0);
558 
559 	close(fd);
560 
561 	return result;
562 }
563 
564