Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Trim large messages #2644

Merged
merged 13 commits into from Apr 10, 2019
Merged

Trim large messages #2644

merged 13 commits into from Apr 10, 2019

Conversation

szemere
Copy link
Collaborator

@szemere szemere commented Mar 22, 2019

Add the trim-large-messages option to the logproto-framed-server. (syslog source driver)

Without trimming, the framed server simply drops oversized messages (>log_msg_size) and closes the incoming connection.
With trim-large-messages enabled, framed server will create a log message from the first (log_msg_size sized) part of the message, and ignores the rest of it. The communication will continue uniterrupted with the following message.

TODO:

  • The trim action can be propagated back towards LogReader via LogTransportAuxData, and can be marked on the new log message i.e. with a tag. But I don't like the idea, that LogReader has to deal with a property from one specific protocol.

@kira-syslogng
Copy link
Contributor

Build FAILURE

@szemere szemere changed the title [WIP] Trim large messages Trim large messages Apr 1, 2019
@szemere szemere marked this pull request as ready for review April 1, 2019 05:37
@kira-syslogng
Copy link
Contributor

Build SUCCESS

@bazsi
Copy link
Collaborator

bazsi commented Apr 1, 2019

This pull request introduces 1 alert when merging 0efdf2c3313ae1bad02dbe90a5d5fe160d92ecb6 into b1620af - view on LGTM.com

new alerts:

  • 1 for Use of goto

Comment posted by LGTM.com

@kira-syslogng
Copy link
Contributor

Build FAILURE

@kira-syslogng
Copy link
Contributor

Build SUCCESS

@furiel
Copy link
Collaborator

furiel commented Apr 3, 2019

Could you cover the case with unit test when a small message and a large message is available in the buffer, and the large message is not truncated below max_msg_size?
Something like:

max_msg_size: 10
kernel buffer: single read: 2 ab16 0123456789ABCDEF
expected behaviour:
msg_1: ab
msg_2: 0123456789 (and not 012)

lib/logproto/logproto-framed-server.c Show resolved Hide resolved
lib/logproto/logproto-framed-server.c Outdated Show resolved Hide resolved
lib/logproto/logproto-framed-server.c Outdated Show resolved Hide resolved
lib/logproto/logproto-framed-server.c Outdated Show resolved Hide resolved
furiel
furiel previously approved these changes Apr 4, 2019
Copy link
Collaborator

@furiel furiel left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks!

@kira-syslogng
Copy link
Contributor

Build FAILURE

@szemere
Copy link
Collaborator Author

szemere commented Apr 4, 2019

@kira-syslogng retest this please

@kira-syslogng
Copy link
Contributor

Build SUCCESS

@lbudai
Copy link
Collaborator

lbudai commented Apr 4, 2019

note to your ToDo: aux (or ancillary) data is a transport functionality(credentials, peer addr, pid, etc...), trim is a proto functionality.
Mixing them ends up in a layering violation, so do not extend LogTransportAuxData with proto related state/information.

lbudai
lbudai previously requested changes Apr 4, 2019
Copy link
Collaborator

@lbudai lbudai left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Note:
I'm not sure if it's not possible to minimize the state machine.

lib/cfg-parser.c Outdated Show resolved Hide resolved
lib/logproto/logproto-framed-server.c Show resolved Hide resolved
@lbudai
Copy link
Collaborator

lbudai commented Apr 4, 2019

@szemere : and one more note to the other topic (the tagging issue): maybe it is time to modify the fetch method: what if we create a LogMessage object instead of 'returning' raw string buffer?

additionally corrected some nearby indentations

Signed-off-by: Laszlo Szemere <laszlo.szemere@balabit.com>
The framed server has never supported the encoding option, thus
  init_buffer_size == max_buffer_size == max_msg_size

Signed-off-by: Laszlo Szemere <laszlo.szemere@balabit.com>
As a preparation to make log_proto_framed_server_fetch states more
independent from each other (will be easier to introduce a new state)
eliminated the try_read variable with some code duplication.

Signed-off-by: Laszlo Szemere <laszlo.szemere@balabit.com>
Implementing the "trim_large_messages" option. (Currently
aligning with the logic of log_proto_framed_server_fetch,
with lots of goto statements and code duplication.)

Signed-off-by: Laszlo Szemere <laszlo.szemere@balabit.com>
in log_proto_framed_server_fetch into enums and continue statements

Signed-off-by: Laszlo Szemere <laszlo.szemere@balabit.com>
@kira-syslogng
Copy link
Contributor

Build SUCCESS

MrAnno
MrAnno previously requested changes Apr 5, 2019
lib/logproto/logproto-framed-server.c Show resolved Hide resolved
lib/logproto/logproto-framed-server.c Outdated Show resolved Hide resolved
lib/logproto/logproto-framed-server.c Outdated Show resolved Hide resolved
lib/logproto/logproto-framed-server.c Outdated Show resolved Hide resolved
lib/logproto/logproto-framed-server.c Outdated Show resolved Hide resolved
lib/logproto/logproto-framed-server.c Outdated Show resolved Hide resolved
lib/logproto/logproto-framed-server.c Show resolved Hide resolved
lib/logproto/logproto-framed-server.c Outdated Show resolved Hide resolved
lib/logproto/logproto-framed-server.c Outdated Show resolved Hide resolved
lib/logproto/logproto-framed-server.c Outdated Show resolved Hide resolved
On caller side we are only interested in the case when we were
able to fetch any data from the input. Before this change EAGAIN
was masked with LPS_SUCCESS, giving mixed results on caller side.

Signed-off-by: Laszlo Szemere <laszlo.szemere@balabit.com>
With the previous change of log_proto_framed_server_fetch_data, it
was easier to create "read" states in log_proto_framed_server_fetch.

By separating the "read" and "extract" steps, eliminated the code
duplications caused by the "extract -> read -> extract" logic.

Extract state will jump into read, if there is not enough data to
finish. Read state will return LPS_SUCCESS, and continue later
if there is nothing to read.

Signed-off-by: Laszlo Szemere <laszlo.szemere@balabit.com>
From now on frame header reading will ensure that there is enough
space in the buffer for reading the frame header. (With a low
chance of unsuccessfull parsing atempt.)
And with the knowledge of the actual frame_len it will also make
sure that later, there will be enough room for the message.

Signed-off-by: Laszlo Szemere <laszlo.szemere@balabit.com>
@kira-syslogng
Copy link
Contributor

Build SUCCESS

@Kokan Kokan added this to the syslog-ng-3.21 milestone Apr 8, 2019
@kira-syslogng
Copy link
Contributor

Build FAILURE

@MrAnno MrAnno dismissed their stale review April 8, 2019 07:36

I'm dismissing my review because I'm feeling sick and don't want to block the PR. Thanks for addressing my notes!

@kira-syslogng
Copy link
Contributor

Build FAILURE

@szemere
Copy link
Collaborator Author

szemere commented Apr 8, 2019

@kira-syslogng retest this please

@kira-syslogng
Copy link
Contributor

Build SUCCESS

szemere and others added 5 commits April 8, 2019 16:33
from the state machine in log_proto_framed_server_fetch

Signed-off-by: Laszlo Szemere <laszlo.szemere@balabit.com>
split into smaller methods, each state got a separate method

Signed-off-by: Laszlo Budai <stentor.bgyk@gmail.com>
Signed-off-by: Laszlo Budai <stentor.bgyk@gmail.com>
Signed-off-by: Laszlo Budai <stentor.bgyk@gmail.com>
to prevent the starvation of other sources.

Signed-off-by: Laszlo Szemere <laszlo.szemere@balabit.com>
@@ -99,6 +101,9 @@ log_proto_framed_server_fetch_data(LogProtoFramedServer *self, gboolean *may_rea
if (!(*may_read))
return FALSE;

if (self->fetch_counter++ >= MAX_FETCH_COUNT)
return FALSE;
Copy link
Collaborator

@MrAnno MrAnno Apr 8, 2019

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think this is not necessary.
I just read about this yesterday, every edge-triggered server works like this: they have to read until EAGAIN is returned, and server programs usually do not deal with the possibility of starvation on this level.

In theory, starvation is possible in case of super-fast senders, but this is not a real-world scenario in my opinion.
The same question has been asked on the nginx forum a few years ago:
https://forum.nginx.org/read.php?29,250351,250360#msg-250360

When an in-memory loopback interface is used, it might be possible to reproduce a starvation problem, but in case of real network connections or files, the order of magnitude of reading from a memory buffer is different than the speed of those devices, so the problem does not really exist (unless the CPU has a very high load).

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

However, if we really want to care with this case, our other proto server implementations have to be adjusted as well.

Fortunately, epoll uses round robin, so the concept will actually work:

If more than maxevents file descriptors are ready when epoll_wait()
is called, then successive epoll_wait() calls will round robin
through the set of ready file descriptors. This behavior helps avoid
starvation scenarios, where a process fails to notice that additional
file descriptors are ready because it focuses on a set of file
descriptors that are already known to be ready.

Note: We have log-msg-size and log-iw-size, they can avoid starvation together with our flow-control mechanism even if flags(flow-control) is not set (but this is on a different level).

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

MAX_FETCH_COUNT adds back the old try try_read logic in a much cleaner way. Removing this patch did not really change our performance numbers, so I'm approving the PR.

@kira-syslogng
Copy link
Contributor

Build SUCCESS

@szemere szemere added the user-visible-feature User visible feature label Apr 9, 2019
@pzoleex
Copy link
Collaborator

pzoleex commented Apr 9, 2019

@kira-syslogng test this please test branch=pzolee-trim-large-messages;

@kira-syslogng
Copy link
Contributor

Build SUCCESS

@alltilla alltilla merged commit 48624ed into syslog-ng:master Apr 10, 2019
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
user-visible-feature User visible feature
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

9 participants