in v2/src/log_sink_callback.c [73:176]
static void log_sink_callback_log(LOG_LEVEL log_level, LOG_CONTEXT_HANDLE log_context, const char* file, const char* func, int line, const char* message_format, va_list args)
{
if (message_format == NULL)
{
/* Codes_SRS_LOG_SINK_CALLBACK_42_006: [ If message_format is NULL, log_sink_callback.log shall call the log_callback with an error message and return. ]*/
log_sink_callback_callback(log_sink_callback_context, LOG_LEVEL_CRITICAL, error_string_invalid_args);
}
else
{
if (log_level > log_sink_callback_max_level)
{
/* Codes_SRS_LOG_SINK_CALLBACK_42_020: [ If log_level is greater than the maximum level set by log_sink_callback_set_max_level, then log_sink_callback.log shall return without calling the log_callback. ]*/
}
else
{
/* Codes_SRS_LOG_SINK_CALLBACK_42_016: [ log_sink_callback.log shall include at most LOG_MAX_MESSAGE_LENGTH characters including the null terminator in the callback argument (the rest of the context shall be truncated). ]*/
char temp[LOG_MAX_MESSAGE_LENGTH];
char* buffer = temp;
size_t buffer_size = sizeof(temp);
/* Codes_SRS_LOG_SINK_CALLBACK_42_007: [ log_sink_callback.log shall obtain the time by calling time. ]*/
time_t t = time(NULL);
/* Codes_SRS_LOG_SINK_CALLBACK_42_008: [ log_sink_callback.log shall write the time to string by calling ctime. ]*/
/* Codes_SRS_LOG_SINK_CALLBACK_42_010: [ If the call to time fails then log_sink_callback.log shall format the time as NULL. ]*/
char* ctime_result = (t == (time_t)-1) ? NULL : ctime(&t);
/* Codes_SRS_LOG_SINK_CALLBACK_42_009: [ log_sink_callback.log shall create a line in the format: Time: {formatted time} File:{file}:{line} Func:{func} {optional context information} {formatted message}. ]*/
int snprintf_result = snprintf(buffer, buffer_size, "Time:%.24s File:%s:%d Func:%s",
/* Codes_SRS_LOG_SINK_CALLBACK_42_011: [ If the call to ctime fails then log_sink_callback.log shall format the time as NULL. ]*/
MU_P_OR_NULL(ctime_result),
MU_P_OR_NULL(file),
line,
MU_P_OR_NULL(func));
if (snprintf_result < 0)
{
/* Codes_SRS_LOG_SINK_CALLBACK_42_017: [ If any encoding error occurs during formatting of the line (i.e. if any printf class functions fails), log_sink_callback.log shall call the log_callback with Error formatting log line and return. ]*/
log_sink_callback_callback(log_sink_callback_context, LOG_LEVEL_CRITICAL, error_string);
}
else
{
bool error = false;
snprintf_result = MIN(snprintf_result, (int)buffer_size);
buffer += snprintf_result;
buffer_size -= snprintf_result;
/* Codes_SRS_LOG_SINK_CALLBACK_42_012: [ If log_context is non-NULL: ]*/
if (log_context != NULL)
{
/* Codes_SRS_LOG_SINK_CALLBACK_42_013: [ log_sink_callback.log shall call log_context_get_property_value_pair_count to obtain the count of properties. ]*/
size_t property_value_pair_count = log_context_get_property_value_pair_count(log_context);
/* Codes_SRS_LOG_SINK_CALLBACK_42_014: [ log_sink_callback.log shall call log_context_get_property_value_pairs to obtain the properties. ]*/
const LOG_CONTEXT_PROPERTY_VALUE_PAIR* property_value_pairs = log_context_get_property_value_pairs(log_context);
/* Codes_SRS_LOG_SINK_CALLBACK_42_015: [ log_sink_callback.log shall call log_context_property_to_string to write the properties to the string buffer. ]*/
int log_n_properties_result = log_context_property_to_string(buffer, buffer_size, property_value_pairs, property_value_pair_count); // lgtm[cpp/unguardednullreturndereference] Tests and code review ensure that NULL access cannot happen
if (log_n_properties_result < 0)
{
/* Codes_SRS_LOG_SINK_CALLBACK_42_017: [ If any encoding error occurs during formatting of the line (i.e. if any printf class functions fails), log_sink_callback.log shall call the log_callback with Error formatting log line and return. ]*/
error = true;
}
else
{
log_n_properties_result = MIN(log_n_properties_result, (int)buffer_size);
buffer += log_n_properties_result;
buffer_size -= log_n_properties_result;
}
}
if (!error)
{
if (buffer_size > 1)
{
*buffer = ' ';
buffer++;
buffer_size--;
int vsnprintf_result = vsnprintf(buffer, buffer_size, message_format, args);
if (vsnprintf_result < 0)
{
/* Codes_SRS_LOG_SINK_CALLBACK_42_017: [ If any encoding error occurs during formatting of the line (i.e. if any printf class functions fails), log_sink_callback.log shall call the log_callback with Error formatting log line and return. ]*/
error = true;
}
else
{
// all ok
}
}
}
if (error)
{
log_sink_callback_callback(log_sink_callback_context, LOG_LEVEL_CRITICAL, error_string);
}
else
{
/* Codes_SRS_LOG_SINK_CALLBACK_42_018: [ log_sink_callback.log shall call log_callback with its context, log_level, and the formatted message. ]*/
log_sink_callback_callback(log_sink_callback_context, log_level, temp);
}
}
}
}
}