예제 #1
0
파일: log.c 프로젝트: jkadlec/knot
static int emit_log_msg(int level, const char *zone, size_t zone_len, const char *msg)
{
	rcu_read_lock();
	struct log_sink *log = s_log;
	if(!log_isopen()) {
		rcu_read_unlock();
		return KNOT_ERROR;
	}

	int ret = 0;
	uint8_t *f = facility_at(log, LOGT_SYSLOG);
	logsrc_t src = zone ? LOG_ZONE : LOG_SERVER;

	// Syslog
	if (facility_levels(f, src) & LOG_MASK(level)) {
#ifdef ENABLE_SYSTEMD
		char *zone_fmt = zone ? "ZONE=%.*s" : NULL;
		sd_journal_send("PRIORITY=%d", level,
		                "MESSAGE=%s", msg,
		                zone_fmt, zone_len, zone,
		                NULL);
#else
		syslog(level, "%s", msg);
#endif
		ret = 1; // To prevent considering the message as ignored.
	}

	// Convert level to mask
	level = LOG_MASK(level);

	/* Prefix date and time. */
	char tstr[LOG_BUFLEN] = {0};
	struct tm lt;
	struct timeval tv;
	gettimeofday(&tv, NULL);
	time_t sec = tv.tv_sec;
	if (localtime_r(&sec, &lt) != NULL) {
		strftime(tstr, sizeof(tstr), KNOT_LOG_TIME_FORMAT " ", &lt);
	}

	// Log streams
	for (int i = LOGT_STDERR; i < LOGT_FILE + log->file_count; ++i) {

		// Check facility levels mask
		f = facility_at(log, i);
		if (facility_levels(f, src) & level) {

			// Select stream
			FILE *stream;
			switch(i) {
			case LOGT_STDERR: stream = stderr; break;
			case LOGT_STDOUT: stream = stdout; break;
			default: stream = log->file[i - LOGT_FILE]; break;
			}

			// Print
			ret = fprintf(stream, "%s%s\n", tstr, msg);
			if (stream == stdout) {
				fflush(stream);
			}
		}
	}

	rcu_read_unlock();

	if (ret < 0) {
		return KNOT_EINVAL;
	}

	return ret;
}
예제 #2
0
파일: log.c 프로젝트: dnstap/knot
static int _log_msg(logsrc_t src, int level, const char *msg)
{
	if(!log_isopen()) {
		return KNOT_ERROR;
	}

	int ret = 0;
	uint8_t *f = facility_at(LOGT_SYSLOG);

	// Syslog
	if (facility_levels(f, src) & LOG_MASK(level)) {
		syslog(level, "%s", msg);
		ret = 1; // To prevent considering the message as ignored.
	}

	// Convert level to mask
	level = LOG_MASK(level);

	/* Prefix date and time. */
	char tstr[128] = {0};
	int tlen = 0;
	struct tm lt;
	struct timeval tv;
	gettimeofday(&tv, NULL);
	time_t sec = tv.tv_sec;
	if (localtime_r(&sec, &lt) != NULL) {
		bool precise = false;

#ifdef ENABLE_MICROSECONDS_LOG
		precise = true;
#endif /* ENABLE_MICROSECONDS_LOG */

		tlen = strftime(tstr, sizeof(tstr), KNOT_LOG_TIME_FORMAT " ", &lt);

		if (precise && tlen > 0) {
			char pm = (lt.tm_gmtoff > 0) ? '+' : '-';
			snprintf(tstr + tlen - 1, sizeof(tstr) - tlen + 1,
			         ".%.6lu%c%.2u:%.2u ",
			         (unsigned long)tv.tv_usec, pm,
			         (unsigned int)lt.tm_gmtoff / 3600,
			         (unsigned int)(lt.tm_gmtoff / 60) % 60);
		}
	}

	// Log streams
	for (int i = LOGT_STDERR; i < LOGT_FILE + LOG_FDS_OPEN; ++i) {

		// Check facility levels mask
		f = facility_at(i);
		if (facility_levels(f, src) & level) {

			// Select stream
			FILE *stream;
			switch(i) {
			case LOGT_STDERR: stream = stderr; break;
			case LOGT_STDOUT: stream = stdout; break;
			default: stream = LOG_FDS[i - LOGT_FILE]; break;
			}

			// Print
			ret = fprintf(stream, "%s%s", tstr, msg);
			if (stream == stdout) {
				fflush(stream);
			}
		}
	}

	if (ret < 0) {
		return KNOT_EINVAL;
	}

	return ret;
}