Skip to content

Commit 44534ce

Browse files
authored
Merge pull request #889 from bazsi/log-msg-memory-accounting-fixes
Log msg memory accounting fixes
2 parents 8d4db0b + b5a707c commit 44534ce

File tree

8 files changed

+61
-135
lines changed

8 files changed

+61
-135
lines changed

lib/logmsg/logmsg-serialize.c

Lines changed: 12 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -511,6 +511,7 @@ gboolean
511511
log_msg_deserialize(LogMessage *self, SerializeArchive *sa)
512512
{
513513
LogMessageSerializationState state = { 0 };
514+
gboolean result = FALSE;
514515

515516
state.sa = sa;
516517
state.msg = self;
@@ -520,7 +521,15 @@ log_msg_deserialize(LogMessage *self, SerializeArchive *sa)
520521
}
521522

522523
if (state.version < LGM_V20)
523-
return _deserialize_message_version_1x(&state);
524-
525-
return _deserialize_message_version_2x(&state);
524+
result = _deserialize_message_version_1x(&state);
525+
else
526+
result = _deserialize_message_version_2x(&state);
527+
528+
self->allocated_bytes = sizeof(LogMessage) +
529+
self->alloc_sdata * sizeof(self->sdata[0]) +
530+
g_sockaddr_len(self->saddr) + g_sockaddr_len(self->daddr) +
531+
(sizeof(self->tags[0]) * self->num_tags) +
532+
(sizeof(self->nodes[0]) * self->num_nodes) +
533+
(self->payload ? nv_table_get_memory_consumption(self->payload) : 0);
534+
return result;
526535
}

lib/logmsg/logmsg.c

Lines changed: 29 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -278,6 +278,13 @@ static StatsCounterItem *count_sdata_updates;
278278
static StatsCounterItem *count_allocated_bytes;
279279
static GPrivate priv_macro_value = G_PRIVATE_INIT(__free_macro_value);
280280

281+
static inline void
282+
log_msg_update_allocation(LogMessage *self, gssize delta)
283+
{
284+
self->allocated_bytes += delta;
285+
stats_counter_add(count_allocated_bytes, delta);
286+
}
287+
281288
static void
282289
log_msg_update_sdata_slow(LogMessage *self, NVHandle handle, const gchar *name, gssize name_len)
283290
{
@@ -327,8 +334,7 @@ log_msg_update_sdata_slow(LogMessage *self, NVHandle handle, const gchar *name,
327334
self->alloc_sdata = alloc_sdata;
328335
if (self->sdata)
329336
{
330-
self->allocated_bytes += ((self->alloc_sdata - old_alloc_sdata) * sizeof(self->sdata[0]));
331-
stats_counter_add(count_allocated_bytes, (self->alloc_sdata - old_alloc_sdata) * sizeof(self->sdata[0]));
337+
log_msg_update_allocation(self, ((self->alloc_sdata - old_alloc_sdata) * sizeof(self->sdata[0])));
332338
}
333339
/* ok, we have our own SDATA array now which has at least one free slot */
334340

@@ -577,8 +583,7 @@ log_msg_set_value_with_type(LogMessage *self, NVHandle handle,
577583
{
578584
self->payload = nv_table_clone(self->payload, name_len + value_len + 2);
579585
log_msg_set_flag(self, LF_STATE_OWN_PAYLOAD);
580-
self->allocated_bytes += self->payload->size;
581-
stats_counter_add(count_allocated_bytes, self->payload->size);
586+
log_msg_update_allocation(self, self->payload->size);
582587
}
583588

584589
/* we need a loop here as a single realloc may not be enough. Might help
@@ -598,8 +603,7 @@ log_msg_set_value_with_type(LogMessage *self, NVHandle handle,
598603
break;
599604
}
600605
guint32 new_size = self->payload->size;
601-
self->allocated_bytes += (new_size - old_size);
602-
stats_counter_add(count_allocated_bytes, new_size-old_size);
606+
log_msg_update_allocation(self, (new_size - old_size));
603607
stats_counter_inc(count_payload_reallocs);
604608
}
605609

@@ -650,8 +654,7 @@ log_msg_unset_value(LogMessage *self, NVHandle handle)
650654
break;
651655
}
652656
guint32 new_size = self->payload->size;
653-
self->allocated_bytes += (new_size - old_size);
654-
stats_counter_add(count_allocated_bytes, new_size-old_size);
657+
log_msg_update_allocation(self, (new_size - old_size));
655658
stats_counter_inc(count_payload_reallocs);
656659
}
657660

@@ -932,6 +935,7 @@ log_msg_set_tag_by_id_onoff(LogMessage *self, LogTagId id, gboolean on)
932935
if (!log_msg_chk_flag(self, LF_STATE_OWN_TAGS) && self->num_tags)
933936
{
934937
self->tags = g_memdup2(self->tags, sizeof(self->tags[0]) * self->num_tags);
938+
log_msg_update_allocation(self, sizeof(self->tags[0]) * self->num_tags);
935939
}
936940
log_msg_set_flag(self, LF_STATE_OWN_TAGS);
937941

@@ -961,6 +965,7 @@ log_msg_set_tag_by_id_onoff(LogMessage *self, LogTagId id, gboolean on)
961965
self->tags = g_realloc(self->tags, sizeof(self->tags[0]) * self->num_tags);
962966
else
963967
self->tags = g_malloc(sizeof(self->tags[0]) * self->num_tags);
968+
log_msg_update_allocation(self, (self->num_tags - old_num_tags) * sizeof(self->tags[0]));
964969
memset(&self->tags[old_num_tags], 0, (self->num_tags - old_num_tags) * sizeof(self->tags[0]));
965970

966971
if (inline_tags)
@@ -1277,9 +1282,14 @@ log_msg_set_saddr(LogMessage *self, GSockAddr *saddr)
12771282
void
12781283
log_msg_set_saddr_ref(LogMessage *self, GSockAddr *saddr)
12791284
{
1285+
gssize old_len = 0;
12801286
if (log_msg_chk_flag(self, LF_STATE_OWN_SADDR))
1281-
g_sockaddr_unref(self->saddr);
1287+
{
1288+
old_len = g_sockaddr_len(self->saddr);
1289+
g_sockaddr_unref(self->saddr);
1290+
}
12821291
self->saddr = saddr;
1292+
log_msg_update_allocation(self, (gssize) g_sockaddr_len(self->saddr) - old_len);
12831293
self->flags |= LF_STATE_OWN_SADDR;
12841294
}
12851295

@@ -1292,9 +1302,14 @@ log_msg_set_daddr(LogMessage *self, GSockAddr *daddr)
12921302
void
12931303
log_msg_set_daddr_ref(LogMessage *self, GSockAddr *daddr)
12941304
{
1305+
gssize old_len = 0;
12951306
if (log_msg_chk_flag(self, LF_STATE_OWN_DADDR))
1296-
g_sockaddr_unref(self->daddr);
1307+
{
1308+
old_len = g_sockaddr_len(self->daddr);
1309+
g_sockaddr_unref(self->daddr);
1310+
}
12971311
self->daddr = daddr;
1312+
log_msg_update_allocation(self, (gssize) g_sockaddr_len(self->daddr) - old_len);
12981313
self->flags |= LF_STATE_OWN_DADDR;
12991314
}
13001315

@@ -1392,8 +1407,7 @@ log_msg_alloc(gsize payload_size)
13921407
msg->payload = nv_table_init_borrowed(((gchar *) msg) + payload_ofs, payload_space, LM_V_MAX);
13931408

13941409
msg->num_nodes = nodes;
1395-
msg->allocated_bytes = alloc_size + payload_space;
1396-
stats_counter_add(count_allocated_bytes, msg->allocated_bytes);
1410+
log_msg_update_allocation(msg, alloc_size);
13971411
return msg;
13981412
}
13991413

@@ -1444,9 +1458,10 @@ log_msg_alloc_clone(LogMessage *original)
14441458
msg = g_malloc(alloc_size);
14451459

14461460
memcpy(msg, original, sizeof(*msg));
1461+
msg->allocated_bytes = 0;
14471462
msg->num_nodes = nodes;
1448-
msg->allocated_bytes = alloc_size;
1449-
stats_counter_add(count_allocated_bytes, msg->allocated_bytes);
1463+
log_msg_update_allocation(msg, alloc_size);
1464+
14501465
return msg;
14511466
}
14521467

@@ -2110,20 +2125,6 @@ log_msg_lookup_time_stamp_name(const gchar *name)
21102125
return -1;
21112126
}
21122127

2113-
gssize
2114-
log_msg_get_size(LogMessage *self)
2115-
{
2116-
if (!self)
2117-
return 0;
2118-
2119-
return
2120-
sizeof(LogMessage) + // msg.static fields
2121-
+ self->alloc_sdata * sizeof(self->sdata[0]) +
2122-
g_sockaddr_len(self->saddr) + g_sockaddr_len(self->daddr) +
2123-
((self->num_tags) ? sizeof(self->tags[0]) * self->num_tags : 0) +
2124-
nv_table_get_memory_consumption(self->payload); // msg.payload (nvtable)
2125-
}
2126-
21272128
#ifdef __linux__
21282129

21292130
const gchar *

lib/logmsg/logmsg.h

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -638,7 +638,11 @@ void log_msg_registry_foreach(GHFunc func, gpointer user_data);
638638

639639
gint log_msg_lookup_time_stamp_name(const gchar *name);
640640

641-
gssize log_msg_get_size(LogMessage *self);
641+
static inline gsize
642+
log_msg_get_size(LogMessage *self)
643+
{
644+
return self->allocated_bytes;
645+
}
642646

643647
#define evt_tag_msg_reference(msg) \
644648
evt_tag_printf("msg", "%p", (msg)), \
@@ -661,4 +665,6 @@ evt_tag_msg_value_name(const gchar *name, NVHandle value_handle)
661665
return evt_tag_str(name, value_name);
662666
}
663667

668+
extern gint logmsg_queue_node_max;
669+
664670
#endif

lib/logmsg/nvtable.h

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -463,9 +463,7 @@ nv_table_get_ofs_for_an_entry(NVTable *self, NVEntry *entry)
463463
static inline gssize
464464
nv_table_get_memory_consumption(NVTable *self)
465465
{
466-
return sizeof(*self)+
467-
self->num_static_entries*sizeof(self->static_entries[0])+
468-
self->used;
466+
return self->size;
469467
}
470468

471469
#endif

lib/logmsg/tests/test_log_message.c

Lines changed: 0 additions & 97 deletions
Original file line numberDiff line numberDiff line change
@@ -768,103 +768,6 @@ Test(log_message, test_clear_matches_call_resets_all_matches_to_unset)
768768
log_msg_unref(msg);
769769
}
770770

771-
#define DEFUN_KEY_VALUE(name, key, value, size) \
772-
gchar name ## _key[size]; \
773-
gchar name ## _value[size]; \
774-
name ## _key[size-1] = name ## _value[size-1] = 0; \
775-
memset(name ## _key, key, sizeof(name ##_key)-1); \
776-
memset(name ## _value, value, sizeof(name ##_value)-1); \
777-
778-
779-
typedef struct
780-
{
781-
gssize nvtable_size_old;
782-
gssize nvtable_size_new;
783-
gssize msg_size_old;
784-
gssize msg_size_new;
785-
} sizes_t;
786-
787-
static sizes_t
788-
add_key_value(LogMessage *msg, gchar *key, gchar *value)
789-
{
790-
sizes_t sizes;
791-
sizes.msg_size_old = log_msg_get_size(msg);
792-
sizes.nvtable_size_old = nv_table_get_memory_consumption(msg->payload);
793-
log_msg_set_value_by_name(msg, key, value, -1);
794-
sizes.nvtable_size_new = nv_table_get_memory_consumption(msg->payload);
795-
sizes.msg_size_new = log_msg_get_size(msg);
796-
return sizes;
797-
}
798-
799-
800-
static void
801-
test_with_sdata(LogMessage *msg, guint32 old_msg_size)
802-
{
803-
sizes_t sizes;
804-
gchar key[] = ".SDATA.**";
805-
gchar value[] = "AAAAAAA";
806-
807-
guint32 single_sdata_kv_size;
808-
guint32 sdata_payload_array_size;
809-
810-
const char iter_length = 17;
811-
812-
for (char i = 0; i < iter_length; i++)
813-
{
814-
g_snprintf(key, sizeof(key), ".SDATA.%02d", i);
815-
sizes = add_key_value(msg, key, value);
816-
817-
single_sdata_kv_size = NV_ENTRY_DIRECT_HDR + NV_TABLE_BOUND(strlen(key)+1 + strlen(value)+1);
818-
819-
/* i+1 is stored, but the sdata array size is calculated when adding the i-th */
820-
sdata_payload_array_size = STRICT_ROUND_TO_NEXT_EIGHT(i) * sizeof(msg->sdata[0]);
821-
cr_assert_eq(old_msg_size + (i+1) * single_sdata_kv_size + sdata_payload_array_size, sizes.msg_size_new);
822-
}
823-
}
824-
825-
#define SMALL_LENGTH 10
826-
#define LARGE_LENGTH 256
827-
828-
Test(log_message, test_message_size)
829-
{
830-
LogMessage *msg = log_msg_new_empty();
831-
832-
sizes_t sizes;
833-
834-
DEFUN_KEY_VALUE(small, 'C', 'D', SMALL_LENGTH);
835-
sizes = add_key_value(msg, small_key, small_value);
836-
// (SMALL_LENGTH-1)*'C'+'\0' + (SMALL_LENGTH-1)*'D'+'\0'
837-
guint32 entry_size = NV_ENTRY_DIRECT_HDR + NV_TABLE_BOUND(SMALL_LENGTH + SMALL_LENGTH);
838-
cr_assert_eq(sizes.nvtable_size_old + entry_size, sizes.nvtable_size_new);
839-
cr_assert_eq(sizes.msg_size_old + entry_size, sizes.msg_size_new); // Size increased because of nvtable
840-
841-
guint32 msg_size = sizes.msg_size_new;
842-
log_msg_set_tag_by_name(msg, "test_tag_storage");
843-
cr_assert(log_msg_is_tag_by_name(msg, "test_tag_storage"));
844-
cr_assert_eq(msg_size, log_msg_get_size(msg)); // Tag is not increased until tag id 65
845-
846-
char *tag_name = strdup("00tagname");
847-
// (*8 to convert to bits) + no need plus 1 bcause we already added one tag: test_tag_storage
848-
for (int i = 0; i < GLIB_SIZEOF_LONG*8; i++)
849-
{
850-
sprintf(tag_name, "%dtagname", i);
851-
log_msg_set_tag_by_name(msg, tag_name);
852-
}
853-
free(tag_name);
854-
cr_assert_eq(msg_size + 2*GLIB_SIZEOF_LONG, log_msg_get_size(msg));
855-
856-
857-
DEFUN_KEY_VALUE(big, 'A', 'B', LARGE_LENGTH);
858-
sizes = add_key_value(msg, big_key, big_value); // nvtable is expanded
859-
entry_size = NV_ENTRY_DIRECT_HDR + NV_TABLE_BOUND(LARGE_LENGTH + LARGE_LENGTH);
860-
cr_assert_eq(sizes.nvtable_size_old + entry_size, sizes.nvtable_size_new); // but only increased by the entry
861-
cr_assert_eq(sizes.msg_size_old + entry_size, sizes.msg_size_new); // nvtable is doubled
862-
863-
test_with_sdata(msg, sizes.msg_size_new);
864-
865-
log_msg_unref(msg);
866-
}
867-
868771
Test(log_message, when_get_indirect_value_with_null_value_len_abort_instead_of_sigsegv, .signal=SIGABRT)
869772
{
870773
LogMessageTestParams *params = log_message_test_params_new();

modules/diskq/tests/test_diskq.c

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -579,6 +579,11 @@ setup(void)
579579
configuration->stats_options.level = 1;
580580

581581
cr_assert(cfg_init(configuration));
582+
583+
/* we bump the number so our tests do not increase it as we send/receive
584+
* messages. This makes the size of a LogMessage stable, thus we can
585+
* check stats counters */
586+
logmsg_queue_node_max = 10;
582587
}
583588

584589
static void

news/bugfix-889.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
Make message memory usage metrics more accurate: AxoSyslog keeps track of
2+
memory usage by messages both globally and on a per queue basis. The
3+
accounting behind those metrics were inaccurate, the value shown being
4+
smaller than the actual memory use. These inaccuracies were fixed.

tests/light/functional_tests/destination_drivers/network_destination/disk_buffer/helper_functions.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -154,7 +154,7 @@ def set_expected_metrics_state_when_sending_more_logs_than_buffer_can_handle_wit
154154
"syslogng_disk_queue_disk_allocated_bytes",
155155
"syslogng_disk_queue_disk_usage_bytes",
156156
"syslogng_disk_queue_events",
157-
"syslogng_disk_queue_memory_usage_bytes",
157+
# "syslogng_disk_queue_memory_usage_bytes",
158158
"messages_in_disk_buffer",
159159
],
160160
)
@@ -173,7 +173,7 @@ def set_expected_metrics_state_when_sending_more_logs_than_buffer_can_handle_wit
173173
syslogng_disk_queue_disk_allocated_bytes=1048576,
174174
syslogng_disk_queue_disk_usage_bytes=1044480,
175175
syslogng_disk_queue_events=frontCache_size + qdisk_size,
176-
syslogng_disk_queue_memory_usage_bytes=764000,
176+
# syslogng_disk_queue_memory_usage_bytes=764000,
177177
messages_in_disk_buffer=qdisk_size,
178178
),
179179
after=BufferState(
@@ -184,7 +184,7 @@ def set_expected_metrics_state_when_sending_more_logs_than_buffer_can_handle_wit
184184
syslogng_disk_queue_disk_allocated_bytes=1048576,
185185
syslogng_disk_queue_disk_usage_bytes=0,
186186
syslogng_disk_queue_events=0,
187-
syslogng_disk_queue_memory_usage_bytes=0,
187+
# syslogng_disk_queue_memory_usage_bytes=0,
188188
messages_in_disk_buffer=0,
189189
),
190190
)

0 commit comments

Comments
 (0)