Skip to content

Commit 0a5a705

Browse files
committed
Merge branch 'bugfix/log_tag_change_level' into 'master'
bugfix(log): fix the log tag to update existing rather than add new tag when calling ``esp_log_level_set`` See merge request !1153
2 parents 1c71833 + cfd95b6 commit 0a5a705

File tree

2 files changed

+55
-26
lines changed

2 files changed

+55
-26
lines changed

components/log/include/esp_log.h

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -154,10 +154,15 @@ void esp_log_buffer_char(const char *tag, const void *buffer, uint16_t buff_len)
154154
#endif
155155
#endif
156156

157+
/// macro to output logs in startup code, before heap allocator and syscalls have been initialized. log at ``ESP_LOG_ERROR`` level. @see ``printf``,``ESP_LOGE``
157158
#define ESP_EARLY_LOGE( tag, format, ... ) if (LOG_LOCAL_LEVEL >= ESP_LOG_ERROR) { ets_printf(LOG_FORMAT(E, format), esp_log_timestamp(), tag, ##__VA_ARGS__); }
159+
/// macro to output logs in startup code at ``ESP_LOG_WARN`` level. @see ``ESP_EARLY_LOGE``,``ESP_LOGE``, ``printf``
158160
#define ESP_EARLY_LOGW( tag, format, ... ) if (LOG_LOCAL_LEVEL >= ESP_LOG_WARN) { ets_printf(LOG_FORMAT(W, format), esp_log_timestamp(), tag, ##__VA_ARGS__); }
161+
/// macro to output logs in startup code at ``ESP_LOG_INFO`` level. @see ``ESP_EARLY_LOGE``,``ESP_LOGE``, ``printf``
159162
#define ESP_EARLY_LOGI( tag, format, ... ) if (LOG_LOCAL_LEVEL >= ESP_LOG_INFO) { ets_printf(LOG_FORMAT(I, format), esp_log_timestamp(), tag, ##__VA_ARGS__); }
163+
/// macro to output logs in startup code at ``ESP_LOG_DEBUG`` level. @see ``ESP_EARLY_LOGE``,``ESP_LOGE``, ``printf``
160164
#define ESP_EARLY_LOGD( tag, format, ... ) if (LOG_LOCAL_LEVEL >= ESP_LOG_DEBUG) { ets_printf(LOG_FORMAT(D, format), esp_log_timestamp(), tag, ##__VA_ARGS__); }
165+
/// macro to output logs in startup code at ``ESP_LOG_VERBOSE`` level. @see ``ESP_EARLY_LOGE``,``ESP_LOGE``, ``printf``
161166
#define ESP_EARLY_LOGV( tag, format, ... ) if (LOG_LOCAL_LEVEL >= ESP_LOG_VERBOSE) { ets_printf(LOG_FORMAT(V, format), esp_log_timestamp(), tag, ##__VA_ARGS__); }
162167

163168
#ifndef BOOTLOADER_BUILD
@@ -167,10 +172,21 @@ void esp_log_buffer_char(const char *tag, const void *buffer, uint16_t buff_len)
167172
#define ESP_LOGD( tag, format, ... ) if (LOG_LOCAL_LEVEL >= ESP_LOG_DEBUG) { esp_log_write(ESP_LOG_DEBUG, tag, LOG_FORMAT(D, format), esp_log_timestamp(), tag, ##__VA_ARGS__); }
168173
#define ESP_LOGV( tag, format, ... ) if (LOG_LOCAL_LEVEL >= ESP_LOG_VERBOSE) { esp_log_write(ESP_LOG_VERBOSE, tag, LOG_FORMAT(V, format), esp_log_timestamp(), tag, ##__VA_ARGS__); }
169174
#else
175+
/**
176+
* macro to output logs at ESP_LOG_ERROR level.
177+
*
178+
* @param tag tag of the log, which can be used to change the log level by ``esp_log_level_set`` at runtime.
179+
*
180+
* @see ``printf``
181+
*/
170182
#define ESP_LOGE( tag, format, ... ) ESP_EARLY_LOGE(tag, format, ##__VA_ARGS__)
183+
/// macro to output logs at ``ESP_LOG_WARN`` level. @see ``ESP_LOGE``
171184
#define ESP_LOGW( tag, format, ... ) ESP_EARLY_LOGW(tag, format, ##__VA_ARGS__)
185+
/// macro to output logs at ``ESP_LOG_INFO`` level. @see ``ESP_LOGE``
172186
#define ESP_LOGI( tag, format, ... ) ESP_EARLY_LOGI(tag, format, ##__VA_ARGS__)
187+
/// macro to output logs at ``ESP_LOG_DEBUG`` level. @see ``ESP_LOGE``
173188
#define ESP_LOGD( tag, format, ... ) ESP_EARLY_LOGD(tag, format, ##__VA_ARGS__)
189+
/// macro to output logs at ``ESP_LOG_VERBOSE`` level. @see ``ESP_LOGE``
174190
#define ESP_LOGV( tag, format, ... ) ESP_EARLY_LOGV(tag, format, ##__VA_ARGS__)
175191
#endif // BOOTLOADER_BUILD
176192

components/log/log.c

Lines changed: 39 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@
1313
// limitations under the License.
1414

1515
/*
16-
* Log library implementation notes.
16+
* Log library implementation notes.
1717
*
1818
* Log library stores all tags provided to esp_log_level_set as a linked
1919
* list. See uncached_tag_entry_t structure.
@@ -53,6 +53,7 @@
5353
#include <stdio.h>
5454
#include <assert.h>
5555
#include "esp_log.h"
56+
#include "rom/queue.h"
5657

5758
//print number of bytes per line for esp_log_buffer_char and esp_log_buffer_hex
5859
#define BYTES_PER_LINE 16
@@ -76,14 +77,13 @@ typedef struct {
7677
} cached_tag_entry_t;
7778

7879
typedef struct uncached_tag_entry_{
79-
struct uncached_tag_entry_* next;
80+
SLIST_ENTRY(uncached_tag_entry_) entries;
8081
uint8_t level; // esp_log_level_t as uint8_t
8182
char tag[0]; // beginning of a zero-terminated string
8283
} uncached_tag_entry_t;
8384

8485
static esp_log_level_t s_log_default_level = ESP_LOG_VERBOSE;
85-
static uncached_tag_entry_t* s_log_tags_head = NULL;
86-
static uncached_tag_entry_t* s_log_tags_tail = NULL;
86+
static SLIST_HEAD(log_tags_head , uncached_tag_entry_) s_log_tags = SLIST_HEAD_INITIALIZER(s_log_tags);
8787
static cached_tag_entry_t s_log_cache[TAG_CACHE_SIZE];
8888
static uint32_t s_log_cache_max_generation = 0;
8989
static uint32_t s_log_cache_entry_count = 0;
@@ -122,41 +122,53 @@ void esp_log_level_set(const char* tag, esp_log_level_t level)
122122
return;
123123
}
124124

125-
// allocate new linked list entry and append it to the endo of the list
126-
size_t entry_size = offsetof(uncached_tag_entry_t, tag) + strlen(tag) + 1;
127-
uncached_tag_entry_t* new_entry = (uncached_tag_entry_t*) malloc(entry_size);
128-
if (!new_entry) {
129-
xSemaphoreGive(s_log_mutex);
130-
return;
125+
//searching exist tag
126+
uncached_tag_entry_t *it = NULL;
127+
SLIST_FOREACH( it, &s_log_tags, entries ) {
128+
if ( strcmp(it->tag, tag)==0 ) {
129+
//one tag in the linked list match, update the level
130+
it->level = level;
131+
//quit with it != NULL
132+
break;
133+
}
131134
}
132-
new_entry->next = NULL;
133-
new_entry->level = (uint8_t) level;
134-
strcpy(new_entry->tag, tag);
135-
if (s_log_tags_tail) {
136-
s_log_tags_tail->next = new_entry;
135+
//no exist tag, append new one
136+
if ( it == NULL ) {
137+
// allocate new linked list entry and append it to the head of the list
138+
size_t entry_size = offsetof(uncached_tag_entry_t, tag) + strlen(tag) + 1;
139+
uncached_tag_entry_t* new_entry = (uncached_tag_entry_t*) malloc(entry_size);
140+
if (!new_entry) {
141+
xSemaphoreGive(s_log_mutex);
142+
return;
143+
}
144+
new_entry->level = (uint8_t) level;
145+
strcpy(new_entry->tag, tag);
146+
SLIST_INSERT_HEAD( &s_log_tags, new_entry, entries );
137147
}
138-
s_log_tags_tail = new_entry;
139-
if (!s_log_tags_head) {
140-
s_log_tags_head = new_entry;
148+
149+
//search in the cache and update it if exist
150+
for (int i = 0; i < s_log_cache_entry_count; ++i) {
151+
#ifdef LOG_BUILTIN_CHECKS
152+
assert(i == 0 || s_log_cache[(i - 1) / 2].generation < s_log_cache[i].generation);
153+
#endif
154+
if (s_log_cache[i].tag == tag) {
155+
s_log_cache[i].level = level;
156+
break;
157+
}
141158
}
142159
xSemaphoreGive(s_log_mutex);
143160
}
144161

145162
void clear_log_level_list()
146163
{
147-
for (uncached_tag_entry_t* it = s_log_tags_head; it != NULL; ) {
148-
uncached_tag_entry_t* next = it->next;
149-
free(it);
150-
it = next;
164+
while( !SLIST_EMPTY(&s_log_tags)) {
165+
SLIST_REMOVE_HEAD(&s_log_tags, entries );
151166
}
152-
s_log_tags_tail = NULL;
153-
s_log_tags_head = NULL;
154167
s_log_cache_entry_count = 0;
155168
s_log_cache_max_generation = 0;
156169
#ifdef LOG_BUILTIN_CHECKS
157170
s_log_cache_misses = 0;
158171
#endif
159-
160172
}
161173

162174
void IRAM_ATTR esp_log_write(esp_log_level_t level,
@@ -253,7 +265,8 @@ static inline bool get_uncached_log_level(const char* tag, esp_log_level_t* leve
253265
{
254266
// Walk the linked list of all tags and see if given tag is present in the list.
255267
// This is slow because tags are compared as strings.
256-
for (uncached_tag_entry_t* it = s_log_tags_head; it != NULL; it = it->next) {
268+
uncached_tag_entry_t *it;
269+
SLIST_FOREACH( it, &s_log_tags, entries ) {
257270
if (strcmp(tag, it->tag) == 0) {
258271
*level = it->level;
259272
return true;

0 commit comments

Comments
 (0)