Example #1
0
static void
_blackbox_close(int32_t target)
{
	struct qb_log_target *t = qb_log_target_get(target);

	if (t->instance) {
		qb_rb_close(t->instance);
		t->instance = NULL;
	}
}
Example #2
0
static void
_blackbox_reload(int32_t target)
{
	struct qb_log_target *t = qb_log_target_get(target);

	if (t->instance == NULL) {
		return;
	}
	qb_rb_close(t->instance);
	t->instance = qb_rb_open(t->filename, t->size,
				 QB_RB_FLAG_CREATE | QB_RB_FLAG_OVERWRITE, 0);
}
Example #3
0
ssize_t
qb_log_blackbox_write_to_file(const char *filename)
{
	ssize_t written_size = 0;
	struct qb_log_target *t;
	int fd = open(filename, O_CREAT | O_RDWR, 0700);

	if (fd < 0) {
		return -errno;
	}
	t = qb_log_target_get(QB_LOG_BLACKBOX);
	if (t->instance) {
		written_size = qb_rb_write_to_file(t->instance, fd);
	} else {
		written_size = -ENOENT;
	}
	close(fd);

	return written_size;
}
Example #4
0
/* <u32> file lineno
 * <u32> tags
 * <u8> priority
 * <u32> function name length
 * <string> function name
 * <u32> buffer length
 * <string> buffer
 */
static void
_blackbox_vlogger(int32_t target,
		  struct qb_log_callsite *cs, time_t timestamp, va_list ap)
{
	size_t max_size;
	size_t actual_size;
	uint32_t fn_size;
	char *chunk;
	char *msg_len_pt;
	uint32_t msg_len;
	struct qb_log_target *t = qb_log_target_get(target);

	if (t->instance == NULL) {
		return;
	}

	fn_size = strlen(cs->function) + 1;

	actual_size = 4 * sizeof(uint32_t) + sizeof(uint8_t) + fn_size + sizeof(time_t);
	max_size = actual_size + QB_LOG_MAX_LEN;

	chunk = qb_rb_chunk_alloc(t->instance, max_size);

	if (chunk == NULL) {
		/* something bad has happened. abort blackbox logging */
		qb_util_perror(LOG_ERR, "Blackbox allocation error, aborting blackbox log %s", t->filename);
		qb_rb_close(t->instance);
		t->instance = NULL;
		return;
	}

	/* line number */
	memcpy(chunk, &cs->lineno, sizeof(uint32_t));
	chunk += sizeof(uint32_t);

	/* tags */
	memcpy(chunk, &cs->tags, sizeof(uint32_t));
	chunk += sizeof(uint32_t);

	/* log level/priority */
	memcpy(chunk, &cs->priority, sizeof(uint8_t));
	chunk += sizeof(uint8_t);

	/* function name */
	memcpy(chunk, &fn_size, sizeof(uint32_t));
	chunk += sizeof(uint32_t);
	memcpy(chunk, cs->function, fn_size);
	chunk += fn_size;

	/* timestamp */
	memcpy(chunk, &timestamp, sizeof(time_t));
	chunk += sizeof(time_t);

	/* log message length */
	msg_len_pt = chunk;
	chunk += sizeof(uint32_t);

	/* log message */
	msg_len = qb_vsnprintf_serialize(chunk, QB_LOG_MAX_LEN, cs->format, ap);
	if (msg_len >= QB_LOG_MAX_LEN) {
	    chunk = msg_len_pt + sizeof(uint32_t); /* Reset */

	    msg_len = qb_vsnprintf_serialize(chunk, QB_LOG_MAX_LEN,
		"Log message too long to be stored in the blackbox.  "\
		"Maximum is QB_LOG_MAX_LEN" , ap);
	    actual_size += msg_len;
	}

	actual_size += msg_len;

	/* now that we know the length, write it
	 */
	memcpy(msg_len_pt, &msg_len, sizeof(uint32_t));

	(void)qb_rb_chunk_commit(t->instance, actual_size);
}
Example #5
0
/*
 * %n FUNCTION NAME
 * %f FILENAME
 * %l FILELINE
 * %p PRIORITY
 * %t TIMESTAMP
 * %b BUFFER
 * %g SUBSYSTEM
 *
 * any number between % and character specify field length to pad or chop
 */
void
qb_log_target_format(int32_t target,
		     struct qb_log_callsite *cs,
		     time_t current_time,
		     const char *formatted_message, char *output_buffer)
{
	char tmp_buf[128];
	struct tm tm_res;
	unsigned int format_buffer_idx = 0;
	unsigned int output_buffer_idx = 0;
	size_t cutoff;
	uint32_t len;
	int ralign;
	int c;
	struct qb_log_target *t = qb_log_target_get(target);

	if (t->format == NULL) {
		return;
	}

	while ((c = t->format[format_buffer_idx])) {
		cutoff = 0;
		ralign = 0;
		if (c != '%') {
			output_buffer[output_buffer_idx++] = c;
			format_buffer_idx++;
		} else {
			const char *p;

			format_buffer_idx += 1;
			if (t->format[format_buffer_idx] == '-') {
				ralign = 1;
				format_buffer_idx += 1;
			}

			if (isdigit(t->format[format_buffer_idx])) {
				cutoff = atoi(&t->format[format_buffer_idx]);
			}
			while (isdigit(t->format[format_buffer_idx])) {
				format_buffer_idx += 1;
			}

			switch (t->format[format_buffer_idx]) {
			case 'g':
				if (_user_tags_stringify_fn) {
					p = _user_tags_stringify_fn(cs->tags);
				} else {
					p = "";
				}
				break;

			case 'n':
				p = cs->function;
				break;

			case 'f':
#ifdef BUILDING_IN_PLACE
				p = cs->filename;
#else
				p = strrchr(cs->filename, '/');
				if (p == NULL) {
					p = cs->filename;
				} else {
					p++; /* move past the "/" */
				}
#endif /* BUILDING_IN_PLACE */
				break;

			case 'l':
				snprintf(tmp_buf, 30, "%d", cs->lineno);
				p = tmp_buf;
				break;

			case 't':
				(void)localtime_r(&current_time, &tm_res);
				snprintf(tmp_buf, TIME_STRING_SIZE,
					 "%s %02d %02d:%02d:%02d",
					 log_month_name[tm_res.tm_mon],
					 tm_res.tm_mday, tm_res.tm_hour,
					 tm_res.tm_min, tm_res.tm_sec);
				p = tmp_buf;
				break;

			case 'b':
				p = formatted_message;
				break;

			case 'p':
				if (cs->priority > LOG_TRACE) {
					p = prioritynames[LOG_TRACE].c_name;
				} else {
					p = prioritynames[cs->priority].c_name;
				}
				break;

			default:
				p = "";
				break;
			}
			len = _strcpy_cutoff(output_buffer + output_buffer_idx,
					     p, cutoff, ralign,
					     (QB_LOG_MAX_LEN -
					      output_buffer_idx));
			output_buffer_idx += len;
			format_buffer_idx += 1;
		}
		if (output_buffer_idx >= QB_LOG_MAX_LEN - 1) {
			break;
		}
	}

	if (output_buffer[output_buffer_idx - 1] == '\n') {
		output_buffer[output_buffer_idx - 1] = '\0';
	} else {
		output_buffer[output_buffer_idx] = '\0';
	}
}
Example #6
0
/*
 * This function will do static formatting (for things that don't
 * change on each log message).
 *
 * %P PID
 * %N name passed into qb_log_init
 * %H hostname
 *
 * any number between % and character specify field length to pad or chop
 */
void
qb_log_target_format_static(int32_t target, const char * format,
			    char *output_buffer)
{
	char tmp_buf[255];
	unsigned int format_buffer_idx = 0;
	unsigned int output_buffer_idx = 0;
	size_t cutoff;
	uint32_t len;
	int ralign;
	int c;
	struct qb_log_target *t = qb_log_target_get(target);

	if (format == NULL) {
		return;
	}

	while ((c = format[format_buffer_idx])) {
		cutoff = 0;
		ralign = 0;
		if (c != '%') {
			output_buffer[output_buffer_idx++] = c;
			format_buffer_idx++;
		} else {
			const char *p;
			unsigned int percent_buffer_idx = format_buffer_idx;

			format_buffer_idx += 1;
			if (format[format_buffer_idx] == '-') {
				ralign = 1;
				format_buffer_idx += 1;
			}

			if (isdigit(format[format_buffer_idx])) {
				cutoff = atoi(&format[format_buffer_idx]);
			}
			while (isdigit(format[format_buffer_idx])) {
				format_buffer_idx += 1;
			}

			switch (format[format_buffer_idx]) {
			case 'P':
				snprintf(tmp_buf, 30, "%d", getpid());
				p = tmp_buf;
				break;

			case 'N':
				p = t->name;
				break;

			case 'H':
				if (gethostname(tmp_buf, 255) == 0) {
					tmp_buf[254] = '\0';
				} else {
					(void)strlcpy(tmp_buf, "localhost", 255);
				}
				p = tmp_buf;
				break;

			default:
				p = &format[percent_buffer_idx];
				cutoff = (format_buffer_idx - percent_buffer_idx + 1);
				ralign = 0;
				break;
			}
			len = _strcpy_cutoff(output_buffer + output_buffer_idx,
					     p, cutoff, ralign,
					     (QB_LOG_MAX_LEN -
					      output_buffer_idx));
			output_buffer_idx += len;
			format_buffer_idx += 1;
		}
		if (output_buffer_idx >= QB_LOG_MAX_LEN - 1) {
			break;
		}
	}

	output_buffer[output_buffer_idx] = '\0';
}