1. 说明:
* ### MQTT Packet Tracing
*
* A feature that can be very useful is printing the MQTT packets that are sent and received. To
* achieve this, use the following environment variable settings:
* @code
MQTT_C_CLIENT_TRACE=ON
MQTT_C_CLIENT_TRACE_LEVEL=PROTOCOL
* @endcode
* The output you should see looks like this:
* @code
20130528 155936.813 3 stdout-subscriber -> CONNECT cleansession: 1 (0)
20130528 155936.813 3 stdout-subscriber <- CONNACK rc: 0
20130528 155936.813 3 stdout-subscriber -> SUBSCRIBE msgid: 1 (0)
20130528 155936.813 3 stdout-subscriber <- SUBACK msgid: 1
20130528 155941.818 3 stdout-subscriber -> DISCONNECT (0)
* @endcode
* where the fields are:
* 1. date
* 2. time
* 3. socket number
* 4. client id
* 5. direction (-> from client to server, <- from server to client)
* 6. packet details
*
* ### Default Level Tracing
2. 在测试的源码中配置以上环境变量
setenv("MQTT_C_CLIENT_TRACE", "ON", 1);
setenv("MQTT_C_CLIENT_TRACE_LEVEL", "ERROR", 1);
setenv("MQTT_C_CLIENT_TRACE_LEVEL", "TRACE_PROTOCOL", 1);
3. MQTT源码是如何对第2中设置的环境变量操作
int Log_initialize(Log_nameValue* info)
{
int rc = -1;
char* envval = NULL;
if ((trace_queue = malloc(sizeof(traceEntry) * trace_settings.max_trace_entries)) == NULL)
return rc;
trace_queue_size = trace_settings.max_trace_entries;
if ((envval = getenv("MQTT_C_CLIENT_TRACE")) != NULL && strlen(envval) > 0)
{
if (strcmp(envval, "ON") == 0 || (trace_destination = fopen(envval, "w")) == NULL)
trace_destination = stdout;
else
{
trace_destination_name = malloc(strlen(envval) + 1);
strcpy(trace_destination_name, envval);
trace_destination_backup_name = malloc(strlen(envval) + 3);
sprintf(trace_destination_backup_name, "%s.0", trace_destination_name);
}
}
if ((envval = getenv("MQTT_C_CLIENT_TRACE_MAX_LINES")) != NULL && strlen(envval) > 0)
{
max_lines_per_file = atoi(envval);
if (max_lines_per_file <= 0)
max_lines_per_file = 1000;
}
if ((envval = getenv("MQTT_C_CLIENT_TRACE_LEVEL")) != NULL && strlen(envval) > 0)
{
if (strcmp(envval, "MAXIMUM") == 0 || strcmp(envval, "TRACE_MAXIMUM") == 0)
trace_settings.trace_level = TRACE_MAXIMUM;
else if (strcmp(envval, "MEDIUM") == 0 || strcmp(envval, "TRACE_MEDIUM") == 0)
trace_settings.trace_level = TRACE_MEDIUM;
else if (strcmp(envval, "MINIMUM") == 0 || strcmp(envval, "TRACE_MEDIUM") == 0)
trace_settings.trace_level = TRACE_MINIMUM;
else if (strcmp(envval, "PROTOCOL") == 0 || strcmp(envval, "TRACE_PROTOCOL") == 0)
trace_output_level = TRACE_PROTOCOL;
else if (strcmp(envval, "ERROR") == 0 || strcmp(envval, "TRACE_ERROR") == 0)
trace_output_level = LOG_ERROR;
}
Log_output(TRACE_MINIMUM, "=========================================================");
Log_output(TRACE_MINIMUM, " Trace Output");
if (info)
{
while (info->name)
{
snprintf(msg_buf, sizeof(msg_buf), "%s: %s", info->name, info->value);
Log_output(TRACE_MINIMUM, msg_buf);
info++;
}
}
#if !defined(WIN32) && !defined(WIN64)
struct stat buf;
if (stat("/proc/version", &buf) != -1)
{
FILE* vfile;
if ((vfile = fopen("/proc/version", "r")) != NULL)
{
int len;
strcpy(msg_buf, "/proc/version: ");
len = strlen(msg_buf);
if (fgets(&msg_buf[len], sizeof(msg_buf) - len, vfile))
Log_output(TRACE_MINIMUM, msg_buf);
fclose(vfile);
}
}
#endif
Log_output(TRACE_MINIMUM, "=========================================================");
return rc;
}
4. 运行第二步中的程序,输出如下格式