in source/log_formatter.c [51:187]
int aws_format_standard_log_line(struct aws_logging_standard_formatting_data *formatting_data, va_list args) {
size_t current_index = 0;
/*
* Begin the log line with "[<Log Level>] ["
*/
const char *level_string = NULL;
if (aws_log_level_to_string(formatting_data->level, &level_string)) {
return AWS_OP_ERR;
}
if (formatting_data->total_length == 0) {
return aws_raise_error(AWS_ERROR_INVALID_ARGUMENT);
}
/*
* Use this length for all but the last write, so we guarantee room for the newline even if we get truncated
*/
size_t fake_total_length = formatting_data->total_length - 1;
int log_level_length = snprintf(formatting_data->log_line_buffer, fake_total_length, "[%s] [", level_string);
if (log_level_length < 0) {
return AWS_OP_ERR;
}
current_index = s_advance_and_clamp_index(current_index, log_level_length, fake_total_length);
if (current_index < fake_total_length) {
/*
* Add the timestamp. To avoid copies and allocations, do some byte buffer tomfoolery.
*
* First, make a byte_buf that points to the current position in the output string
*/
struct aws_byte_buf timestamp_buffer = {
.allocator = formatting_data->allocator,
.buffer = (uint8_t *)formatting_data->log_line_buffer + current_index,
.capacity = fake_total_length - current_index,
.len = 0,
};
/*
* Output the current time to the byte_buf
*/
struct aws_date_time current_time;
aws_date_time_init_now(¤t_time);
int result = aws_date_time_to_utc_time_str(¤t_time, formatting_data->date_format, ×tamp_buffer);
if (result != AWS_OP_SUCCESS) {
return aws_raise_error(AWS_ERROR_INVALID_ARGUMENT);
}
current_index = s_advance_and_clamp_index(current_index, (int)timestamp_buffer.len, fake_total_length);
}
if (current_index < fake_total_length) {
/*
* Add thread id and user content separator (" - ")
*/
if (!tl_logging_thread_id.is_valid) {
aws_thread_id_t current_thread_id = aws_thread_current_thread_id();
if (aws_thread_id_t_to_string(current_thread_id, tl_logging_thread_id.repr, AWS_THREAD_ID_T_REPR_BUFSZ)) {
return AWS_OP_ERR;
}
tl_logging_thread_id.is_valid = true;
}
int thread_id_written = snprintf(
formatting_data->log_line_buffer + current_index,
fake_total_length - current_index,
"] [%s] ",
tl_logging_thread_id.repr);
if (thread_id_written < 0) {
return aws_raise_error(AWS_ERROR_INVALID_ARGUMENT);
}
current_index = s_advance_and_clamp_index(current_index, thread_id_written, fake_total_length);
}
if (current_index < fake_total_length) {
/* output subject name */
if (formatting_data->subject_name) {
int subject_written = snprintf(
formatting_data->log_line_buffer + current_index,
fake_total_length - current_index,
"[%s]",
formatting_data->subject_name);
if (subject_written < 0) {
return aws_raise_error(AWS_ERROR_INVALID_ARGUMENT);
}
current_index = s_advance_and_clamp_index(current_index, subject_written, fake_total_length);
}
}
if (current_index < fake_total_length) {
int separator_written =
snprintf(formatting_data->log_line_buffer + current_index, fake_total_length - current_index, " - ");
current_index = s_advance_and_clamp_index(current_index, separator_written, fake_total_length);
}
if (current_index < fake_total_length) {
/*
* Now write the actual data requested by the user
*/
#ifdef _WIN32
int written_count = vsnprintf_s(
formatting_data->log_line_buffer + current_index,
fake_total_length - current_index,
_TRUNCATE,
formatting_data->format,
args);
#else
int written_count = vsnprintf(
formatting_data->log_line_buffer + current_index,
fake_total_length - current_index,
formatting_data->format,
args);
#endif /* _WIN32 */
if (written_count < 0) {
return aws_raise_error(AWS_ERROR_INVALID_ARGUMENT);
}
current_index = s_advance_and_clamp_index(current_index, written_count, fake_total_length);
}
/*
* End with a newline.
*/
int newline_written_count =
snprintf(formatting_data->log_line_buffer + current_index, formatting_data->total_length - current_index, "\n");
if (newline_written_count < 0) {
return aws_raise_error(AWS_ERROR_UNKNOWN); /* we saved space, so this would be crazy */
}
formatting_data->amount_written = current_index + newline_written_count;
return AWS_OP_SUCCESS;
}