示例#1
0
// Background thread for logging
static void log_thread_process(void *arg)
{
	int rv;
	log_entry *entry;
	(void)(arg);
	
	// Signal the init function that the logger thread is ready
	pthread_cond_signal(&wait_log_thread);

	//printf("-- BACKGROUND THREAD STARTED\n");
	for (;;) {
		if (log_lock()) {
			break;
		}
		if (log_qfirst != NULL) {
			rv = 0;
		} else {
			rv = pthread_cond_wait(&queue_data_present, &mutex);
		}
		if (!rv) {
			// Get the next item
			//printf("-- GET ITEM\n");
			entry =  log_entry_pop();
			log_unlock();
			while (entry != NULL) {
				//printf("-- PRINT ITEM\n");
				// Log the type of the thing to log
				log_type(entry->level);
				// Log the timestamp
				log_time(&(entry->tv));
				// Log thread ID:
				log_threadid(entry->thread);
				// Output formatted string
				putc(' ', *log_out);
				set_lvlcolor(entry->level);
				fputs(entry->msg, *log_out);
				// Log function, file and line number
				log_fileline(entry->func, entry->file, entry->line);
				// Log EOL
				log_lineend();
				// Destroy the current instance
				log_entry_destroy(entry);
				
				// Get the next item (if present)
				entry = log_entry_pop();
			}
			if (log_thread_quit) {
				//printf("-- EXIT REQUESTED\n");
				break;
			}
		} else {
			//printf("-- SIGNAL FAILED\n");
			log_unlock();
		}
	}
	//printf("-- BACKGROUND THREAD EXIT\n");
	pthread_exit(NULL);
}
示例#2
0
文件: log.c 项目: dvdhrm/ti-tutorium
int log_set_file(const char *file)
{
	FILE *f, *old;

	if (file) {
		f = fopen(file, "a");
		if (!f) {
			log_err("cannot change log-file to %s (%d): %s",
				file, errno, strerror(errno));
			return -EFAULT;
		}
	} else {
		f = NULL;
		file = "<default>";
	}

	old = NULL;

	log_lock();
	if (log__file != f) {
		log__format(LOG_DEFAULT, LOG_NOTICE,
				"set log-file to %s", file);
		old = log__file;
		log__file = f;
		f = NULL;
	}
	log_unlock();

	if (f)
		fclose(f);
	if (old)
		fclose(old);

	return 0;
}
示例#3
0
文件: log.c 项目: dvdhrm/ti-tutorium
int log_add_filter(const struct log_filter *filter,
			const struct log_config *config)
{
	struct log_dynconf *dconf;
	int ret;

	if (!filter || !config)
		return -EINVAL;

	dconf = malloc(sizeof(*dconf));
	if (!dconf)
		return -ENOMEM;

	memset(dconf, 0, sizeof(*dconf));
	memcpy(&dconf->filter, filter, sizeof(*filter));
	memcpy(&dconf->config, config, sizeof(*config));

	log_lock();
	if (log__dconfig)
		dconf->handle = log__dconfig->handle + 1;
	dconf->next = log__dconfig;
	log__dconfig = dconf;
	ret = dconf->handle;
	log_unlock();

	return ret;
}
示例#4
0
static inline void init_log()
{
	static int init = 0;
	if (init) return;
	init = 1;
	
	// Threading support
	pthread_mutexattr_init(&mutex_atr);
	//pthread_mutexattr_settype(&mutex_atr, PTHREAD_MUTEX_RECURSIVE);
	pthread_mutexattr_settype(&mutex_atr, PTHREAD_MUTEX_RECURSIVE_NP);
	pthread_mutex_init(&mutex, &mutex_atr);
	log_lock();

	// Must be called before localtime_r
	tzset();

	log_setoutput(NULL);
#ifdef LOG_THREADED
	if (pthread_create(&log_thread, NULL, (void *(*)(void *))log_thread_process, NULL)) {
		fprintf(stderr, "LOGGER: ERROR CREATING BACKGROUND THREAD!\n");
		exit(1);
	} else {
		atexit(log_wait_thread);
		logthread_ready();
	}
#endif
	log_unlock();
}
示例#5
0
int vrtpprintf(TURN_LOG_LEVEL level, const char *format, va_list args)
{
	/* Fix for Issue 24, raised by John Selbie: */
#define MAX_RTPPRINTF_BUFFER_SIZE (1024)
	char s[MAX_RTPPRINTF_BUFFER_SIZE+1];
#undef MAX_RTPPRINTF_BUFFER_SIZE

	size_t sz;

	snprintf(s, sizeof(s), "%lu: ",(unsigned long)log_time());
	sz=strlen(s);
	vsnprintf(s+sz, sizeof(s)-1-sz, format, args);
	s[sizeof(s)-1]=0;

	if(to_syslog) {
		syslog(get_syslog_level(level),"%s",s);
	} else {
		log_lock();
		set_rtpfile();
		if(fprintf(_rtpfile,"%s",s)<0) {
			reset_rtpprintf();
		} else if(fflush(_rtpfile)<0) {
			reset_rtpprintf();
		}
		log_unlock();
	}

	return 0;
}
示例#6
0
文件: log.c 项目: dvdhrm/ti-tutorium
void log_set_config(const struct log_config *config)
{
	if (!config)
		return;

	log_lock();
	log__gconfig = *config;
	log_unlock();
}
示例#7
0
void reset_rtpprintf(void)
{
	log_lock();
	if(_rtpfile) {
		if(_rtpfile != stdout)
			fclose(_rtpfile);
		_rtpfile = NULL;
	}
	log_unlock();
}
示例#8
0
static void log_wait_thread()
{
	//printf("Killing threads...\n");
	log_lock();
	log_thread_quit = 1;
	log_unlock();
	pthread_cond_signal(&queue_data_present);

	pthread_join(log_thread, NULL);
	//printf("Threads finished\n");
}
示例#9
0
void set_logfile(const char *fn)
{
	if(fn) {
		log_lock();
		if(strcmp(fn,log_fn_base)) {
			reset_rtpprintf();
			STRCPY(log_fn_base,fn);
		}
		log_unlock();
	}
}
示例#10
0
文件: log.c 项目: dvdhrm/ti-tutorium
void log_clean_filters()
{
	struct log_dynconf *dconf;

	log_lock();
	while ((dconf = log__dconfig)) {
		log__dconfig = dconf->next;
		free(dconf);
	}
	log_unlock();
}
示例#11
0
void log_setoutput(FILE *out)
{
	log_lock();
	if (out == NULL) {
		log_out = NULL;
	} else {
		log_out = &out;
	}
	if (log_out == NULL) {
		log_out = &stdout;
	}
	do_color = isatty(fileno(*log_out));
	log_unlock();
}
示例#12
0
文件: log.c 项目: 939347507/ajvm
void do_log(LOG_LEVEL log_level, char *file_name, char *function,
                int line, char *fmt, ...)
{
        struct tm *log_now;
        time_t log_t;
        va_list arg;
        char tmp[1024];
        char buf[4096];

        assert(log_arg->log_level != LOG_NOLEVEL);
        if (log_level > log_arg->log_level)
                return ;

        va_start(arg, fmt);
        vsprintf(tmp, fmt, arg);
        va_end(arg);

        time(&log_t);
        log_now = localtime(&log_t);
        snprintf(buf, sizeof(buf),
                "%04d-%02d-%02d %02d:%02d:%02d -- %s:%s(%d): %s",
                log_now->tm_year + 1900, log_now->tm_mon + 1,
                log_now->tm_mday, log_now->tm_hour, log_now->tm_min,
                log_now->tm_sec, file_name, function, line, tmp);

        //sync();
        log_lock();
        if (check_log_size() == -1) {
                log_unlock();
                return ;
        }

	fflush(log_arg->log_fp);
        fprintf(log_arg->log_fp, "%s", buf);
        log_unlock();
}
示例#13
0
文件: log.c 项目: dvdhrm/ti-tutorium
void log_submit(const char *file,
		int line,
		const char *func,
		const struct log_config *config,
		const char *subs,
		unsigned int sev,
		const char *format,
		va_list args)
{
	int saved_errno = errno;

	log_lock();
	log__submit(file, line, func, config, subs, sev, format, args);
	log_unlock();

	errno = saved_errno;
}
示例#14
0
static void log_entry_push(log_entry *entry)
{
	log_lock();
	// Add to queue
	entry->next = NULL;

	if (log_qlast != NULL) {
		log_qlast->next = entry;
	}
	log_qlast = entry;

	if (log_qfirst == NULL) {
		log_qfirst = entry;
	}
	log_unlock();
	pthread_cond_signal(&queue_data_present);
}
示例#15
0
void _logout(int lvl, const char *file, int line, const char *func, const char *format, ...)
{
	va_list ap, ap_t;
	char *buf = NULL;
	int ret;
	struct timeval tv;

	//printf("UNTHREADED LOG\n");
	if (lvl > log_level) return;

	// Get the time as soon as possible
	gettimeofday(&tv, NULL);

	// Init the log if needed
	init_log();

	// Format output string
	va_start(ap, format);
	va_copy(ap_t, ap);
	ret = vsnprintf(buf, 0, format, ap_t);
	buf = malloc(ret+1);
	ret = vsnprintf(buf, ret+1, format, ap);
	va_end(ap);

	log_lock();
	// TODO: Queue to background thread
	
	// Log the type of the thing to log
	log_type(lvl);
	// Log the timestamp
	log_time(&tv);
	// Output formatted string
	putc(' ', *log_out);
	set_lvlcolor(lvl);
	fputs(buf, *log_out);
	// Log function, file and line number
	log_fileline(func, file, line);
	// Log EOL
	log_lineend();
	// Unlock the thread
	log_unlock();
	
	// Free the buffer
	if (buf) free(buf);
}
示例#16
0
static log_entry *log_entry_pop()
{
	log_entry *ret = NULL;
	log_lock();

	ret = log_qfirst;
	if (ret != NULL) {
		log_qfirst = ret->next;
		ret->next = NULL;
	} else {
		ret = NULL;
	}
	if (log_qlast == ret) {
		log_qlast = NULL;
	}
	
	log_unlock();
	return ret;
}
示例#17
0
文件: log.c 项目: dvdhrm/ti-tutorium
void log_format(const char *file,
		int line,
		const char *func,
		const struct log_config *config,
		const char *subs,
		unsigned int sev,
		const char *format,
		...)
{
	va_list list;
	int saved_errno = errno;

	va_start(list, format);
	log_lock();
	log__submit(file, line, func, config, subs, sev, format, list);
	log_unlock();
	va_end(list);

	errno = saved_errno;
}
示例#18
0
文件: log.c 项目: 939347507/ajvm
void do_debug(LOG_LEVEL log_level, char *file_name, char *function,
                int line, char *fmt, ...)
{
        va_list arg;
        char tmp[1024];
        char buf[4096];

        assert(log_arg->log_level != LOG_NOLEVEL);
        if (log_level > log_arg->log_level)
                return ;

        va_start(arg, fmt);
        vsprintf(tmp, fmt, arg);
        va_end(arg);

        snprintf(buf, sizeof(buf), "%s:%s(%d): %s", file_name, function, line, tmp);

        log_lock();
        fprintf(stdout, "%s", buf);
        log_unlock();
}
示例#19
0
void rollover_logfile(void)
{
	if(to_syslog || !(log_fn[0]))
		return;

	{
		FILE *f = fopen(log_fn,"r");
		if(!f) {
			fprintf(stderr, "log file is damaged\n");
			reset_rtpprintf();
			TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO, "log file reopened: %s\n", log_fn);
			return;
		} else {
			fclose(f);
		}
	}

	if(simple_log)
		return;

	log_lock();
	if(_rtpfile && log_fn[0] && (_rtpfile != stdout)) {
		char logf[FILE_STR_LEN];

		set_log_file_name(log_fn_base,logf);
		if(strcmp(log_fn,logf)) {
			fclose(_rtpfile);
			log_fn[0]=0;
			_rtpfile = fopen(logf, "w");
			if(_rtpfile) {
				STRCPY(log_fn,logf);
				TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO, "log file opened: %s\n", log_fn);
			} else {
				_rtpfile = stdout;
			}
		}
	}
	log_unlock();
}
示例#20
0
文件: log.c 项目: dvdhrm/ti-tutorium
void log_rm_filter(int handle)
{
	struct log_dynconf *dconf, *i;

	dconf = NULL;

	log_lock();
	if (log__dconfig) {
		if (log__dconfig->handle == handle) {
			dconf = log__dconfig;
			log__dconfig = dconf->next;
		} else for (i = log__dconfig; i->next; i = i->next) {
			dconf = i->next;
			if (dconf->handle == handle) {
				i->next = dconf->next;
				break;
			}
		}
	}
	log_unlock();

	free(dconf);
}
示例#21
0
文件: log.c 项目: 939347507/ajvm
void log_close(void)
{
        log_lock();
        fclose(log_arg->log_fp);
        log_unlock();
}
示例#22
0
APIE process_fork(pid_t *pid) {
	sigset_t oldmask, newmask;
	struct sigaction action;
	int i;

	// block signals now, so that child process can safely disable caller's
	// signal handlers without a race
	sigfillset(&newmask);

	if (pthread_sigmask(SIG_SETMASK, &newmask, &oldmask) != 0) {
		log_error("Could not block signals: %s (%d)",
		          get_errno_name(errno), errno);

		return API_E_INTERNAL_ERROR;
	}

	// ensure to hold the logging mutex, to protect child processes
	// from deadlocking on another thread's inherited mutex state
	log_lock();

	*pid = fork();

	// unlock for both parent and child process
	log_unlock();

	if (*pid < 0) { // error
		pthread_sigmask(SIG_SETMASK, &oldmask, NULL);

		log_error("Could not fork child process: %s (%d)",
		          get_errno_name(errno), errno);

		return API_E_INTERNAL_ERROR;
	} else if (*pid != 0) { // parent
		pthread_sigmask(SIG_SETMASK, &oldmask, NULL);

		return API_E_SUCCESS;
	} else { // child
		// reset all signal handlers from parent so nothing unexpected can
		// happen in the child once signals are unblocked
		action.sa_handler = SIG_DFL;
		action.sa_flags = 0;

		sigemptyset(&action.sa_mask);

		for (i = 1; i < NSIG; ++i) {
			sigaction(i, &action, NULL);
		}

		// unblock all signals in the child
		sigemptyset(&newmask);

		if (pthread_sigmask(SIG_SETMASK, &newmask, NULL) != 0) {
			log_error("Could not unblock signals: %s (%d)",
			          get_errno_name(errno), errno);

			_exit(PROCESS_E_INTERNAL_ERROR);
		}

		return API_E_SUCCESS;
	}
}
示例#23
0
文件: log.c 项目: 939347507/ajvm
int log_init(char *log_path, int log_level, int log_size, int log_num)
{
        char buff[1024];
        char proc_name[64];
        char pwd[1024];

	if (log_level > LOG_NOLEVEL ||
		log_size > MAX_LOG_SIZE ||
		log_num > MAX_LOG_NUM) {
		printf("log argument error.\n");
		return -1;
	}

        memset(proc_name, '\0', 64);
        if (get_process_name(proc_name) == -1)
                return -1;

        if (!getcwd(pwd, 1024))
                return -1;

        log_arg = (LOG_ARG *)malloc(sizeof(LOG_ARG));
        if (!log_arg) {
                fprintf(stderr, "Malloc failed.\n");
                return -1;
        }

        log_arg->log_level = log_level;
        log_arg->log_file_num = log_num;
        log_arg->curr_log_num = 0;

        /* the kernel will write data into memory cache first,
         * using fstat to get the file size is not correctly,
         * To solove this case, it can wait the data until kernel
         * write them to the disk from memory cache, but in order to
         * improve the performance, we just raise the log_size:::-).
         */
        log_arg->log_size = log_size * 1024 * 1024;
        snprintf(log_arg->log_path, 1024, "%s/%d", log_path, getpid());
        pthread_mutex_init(&log_arg->log_lock, NULL);

        if (mkdir(log_arg->log_path, 0700) == -1) {
                perror("mkdir");
                free(log_arg);
                return -1;
        }

        snprintf(buff, sizeof(buff), "%s/log.1", log_arg->log_path);
        strcpy(log_arg->curr_log, buff);

        log_lock();
        log_arg->log_fp = fopen(buff, "w+");
        if (!log_arg->log_fp) {
                perror("fopen");
                log_unlock();
                free(log_arg);
                return -1;
        }
        log_unlock();

        return 0;
}
示例#24
0
void mqueue_start()
{
	char message_buffer[MQUEUE_BUFFER_SIZE];
	
	from_client = mq_open(MQUEUE_SERVER, O_RDONLY | O_EXCL | O_CREAT, S_IRUSR | S_IWUSR, NULL);
	to_client = mq_open(MQUEUE_CLIENT, O_WRONLY | O_EXCL | O_CREAT, S_IWUSR | S_IRUSR, NULL);
	
	if(from_client == -1 || to_client == -1)
	{
	  log_error("Failed to open administration interface, mq_open failed");
	  master_stop();
	}
	
	log_info("Apricot admin interface opened");
	  
	for(;;)
	{
		/* receive a message from the client administration interface */
		if(mq_receive(from_client, message_buffer, MQUEUE_BUFFER_SIZE, NULL) == -1)
		{
		  log_error("mq_receive failed : %s", strerror(errno));
		  continue;
		}
		
		/* process interface request */
		
		if(!strcasecmp(message_buffer, MQUEUE_SEND_LOG))
		{
			FILE * log_file = log_file = fopen(conf.log_file, "r");
			
			if(!log_file)
			{
			  strcpy(message_buffer, MQUEUE_FAIL);
			  send(to_client, message_buffer);
			}
			else
			{
			  while(fgets(message_buffer, MQUEUE_BUFFER_SIZE-1, log_file))
			  {
				send(to_client, message_buffer);
			  }
			  
			  fclose(log_file);
			  strcpy(message_buffer, MQUEUE_OK);
			  send(to_client, message_buffer);
			}
		}
		else if(!strcasecmp(message_buffer, MQUEUE_TRUNCATE_LOG))
		{
			/* to preserve log consistency */
			log_lock();
			truncate(conf.log_file, 0);
			log_unlock();
			
			strcpy(message_buffer, MQUEUE_OK);
			send(to_client, message_buffer);
		}
		else if(!strcasecmp(message_buffer, MQUEUE_STOP_SERVER))
		{	
			log_info("Apricot stop asked by admin interface");
			master_stop();
			exit(EXIT_SUCCESS);
		}
		else if(!strcasecmp(message_buffer, MQUEUE_RESIZE_POOL))
		{
			log_info("Pool resize asked by admin interface");
			
			/* receive a message from the client administration interface */
			if(mq_receive(from_client, message_buffer, MQUEUE_BUFFER_SIZE, NULL) == -1)
			{
			  log_error("mq_receive failed to receive new pool size : %s", strerror(errno));
			  continue;
			}
			
			int new_size;
			
			if(sscanf(message_buffer, "%i", &new_size) != 1 || new_size <= 0)
			{
				log_error("invalid pool size %i received from admin interface", new_size);
				strcpy(message_buffer, MQUEUE_FAIL);
				send(to_client, message_buffer);
				continue;
			}
			
			pool_resize(new_size);
			
			strcpy(message_buffer, MQUEUE_OK);
			send(to_client, message_buffer);
		}
		else
		{
		   	strcpy(message_buffer, MQUEUE_FAIL);
		   	send(to_client, message_buffer);
		}
	}
}