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

Gelf event handler #1788

Merged
merged 52 commits into from
May 25, 2020
Merged

Gelf event handler #1788

merged 52 commits into from
May 25, 2020

Conversation

mirkobrankovic
Copy link
Contributor

@mirkobrankovic mirkobrankovic commented Sep 21, 2019

Simple TCP/UDP socket event handler to gelf interface.
Config file is simple, you need filter, host, port

events
will look like this in Graylog interface

Still need to think about message structure and custom fields.

1st improvements

compact json

next

finnal version
@lminiero
Copy link
Member

Cool, thanks! You may want to rename this PR to event handler, rather than forwarder, though, as I thought this was media-related.

Being UDP based, how does this handle big events? SDP offer/answers can go way beyond the MTU, and it will be even worse once we merge the unified-plan branch. I'm not familiar with GELF, so I'll look into it and review the code.

@mirkobrankovic
Copy link
Contributor Author

mirkobrankovic commented Sep 22, 2019

Indeed, there is udp chunking with magic number and packet sequence:
https://docs.graylog.org/en/3.1/pages/gelf.html#gelf-via-udp
Need to look at that also.

Looks like I can't change the title, but maybe need to start new PR?
Anyway i will test it in Acceptance and see how it will behave.

Most importantly is that if event handler can't connect to gelf that core and rest of the plugins work normally.

Update: title changed in desktop version

@mirkobrankovic mirkobrankovic changed the title Gelf event udp forwarder Gelf udp event handler Sep 22, 2019
@lminiero
Copy link
Member

lminiero commented Sep 26, 2019

Yep, the chunking part looks useful, and so does compression (but that would be true for other plugins as well, I'll have to check that). Do you plan to add chunking to the PR?

@mirkobrankovic
Copy link
Contributor Author

I will give it a try :D

@mirkobrankovic
Copy link
Contributor Author

mirkobrankovic commented Oct 8, 2019

@lminiero can you help me a bit because I got stuck at this chunking and can't resolve it.
Here is the test I did:
I have a simple server.c listener and client.c that is suppose to take 2404 length SDP and chunk it into 512 bytes packets and send it to server.

You can see the result in this result
So I calculate that I need 4*512 and last 356 length.

  1. Problem is that my "empty" chunk is not empty and reports 518 length at first.
  2. Problem is that first iteration makes a good chunk, except it has additional 6 bytes (for example:L �FE �), but then in second, buf pointer is moved correctly to position 512, but chunk stays the same after strncpy, only those 6 last bytes are removed. Third iteration for chunk var is actually what was suppose to happen in second one.

I'm doing something wrong with this pointer or this 6 bytes are messing everything up, but i'm not sure where they come from.

Hope you have time to help,
Thanks,
Mirko

@lminiero
Copy link
Member

lminiero commented Oct 8, 2019

Probably some strings manipulation error? Sorry, can't look into this right now.

@atoppi
Copy link
Member

atoppi commented Oct 8, 2019

Hi @mirkobrankovic,
your client loop should be like this

    //--------------NETWORK PART---------------------------

    int total = len / MAX_GELF_MSG_LEN + 1;
    fprintf(stderr, "Total packets: %d\n", total);
    fprintf(stderr, "----------------------------------------------------------------------------------------------------------\n");

    int offset = 0;
    int sent = 0;
    char *rnd = randstring(8);

    //fprintf(stderr, "Buffer: %s\n", buffer);

    for (int i = 0; i < total; i++) {
        fprintf(stderr, "Packet No: %d\n", i+1);
        fprintf(stderr, "offset: %d\n", offset);
        
        int bytesToSend = offset + MAX_GELF_MSG_LEN < len ? MAX_GELF_MSG_LEN : len - offset;
        fprintf(stderr, "Bytes to send: %d\n", bytesToSend);
        
        sent = write(sockfd, buf+offset, bytesToSend);
        if (sent < 0) {
            fprintf(stderr, "ERROR writing to socket\n");
            printf(" Value of errno: %s\n ", strerror(errno));
            return 1;
        }
        
        fprintf(stderr, "Bytes sent: %d\n", sent);
        offset += sent;
        fprintf(stderr, "----------------------------------------------------------------------------------------------------------\n");
    }

@mirkobrankovic
Copy link
Contributor Author

@atoppi thanks a lot for pointers :)

@mirkobrankovic mirkobrankovic changed the title Gelf udp event handler Gelf event handler Nov 29, 2019
@mirkobrankovic
Copy link
Contributor Author

TCP is working, now to fix UDP.
I will keep it running on our servers and logging to Graylog to see if something bad will happen :D

@lminiero
Copy link
Member

If this Gelf thing supports gzip, you may want to have a look at the utils I added recently for the purpose, which should help reduce the size of data on UDP (unless Gelf has its own fragmentation mechanisms).

@mirkobrankovic
Copy link
Contributor Author

mirkobrankovic commented Dec 1, 2019

@lminiero thanks I saw it the other day and thought about it.
they do have custom UDP chunking imitating what TCP does, but for compression they do recommend Gzip or Zlib and magic byte is automagically picked up

@mirkobrankovic
Copy link
Contributor Author

TCP compression is not supported cause of the '\0' but for UDP it is possible, just need to see if then I need to stop chunking or not ....

@mirkobrankovic
Copy link
Contributor Author

wow it is all connected :D

@mirkobrankovic
Copy link
Contributor Author

Tested all cases and there is the network sniff:
https://pastebin.com/47KqcBus
@lminiero I would like your code x-ray input, I know you have at least 10 improvements :D

@mirkobrankovic
Copy link
Contributor Author

mirkobrankovic commented Apr 1, 2020

I reviewed all 3 segments of the comments and I think I addressed most of them.

This one if puzzling me, what did you mean by this, to decide if message should be sent uncompressed or not?:

				JANUS_LOG(LOG_ERR, "Failed to compress event (%zu bytes)...\n", strlen(message));
				/* Sending message uncompressed */

lminiero on Feb 24 Member
This hasn't been addressed, and I think it's an important point.

Thanks a lot for your time to do this, I really appreciate it.

PS. unfortunately Github is not giving the best user experience with this comment/review/commits all in one thread view

Copy link
Member

@lminiero lminiero left a comment

Choose a reason for hiding this comment

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

Thanks! I added some more notes.

events/janus_gelfevh.c Outdated Show resolved Hide resolved
events/janus_gelfevh.c Show resolved Hide resolved
events/janus_gelfevh.c Show resolved Hide resolved
events/janus_gelfevh.c Outdated Show resolved Hide resolved
events/janus_gelfevh.c Show resolved Hide resolved
@mirkobrankovic
Copy link
Contributor Author

addressed invalid values:

[Fri Apr 24 12:40:31 2020] [janus.eventhandler.gelfevh.jcfg]
[Fri Apr 24 12:40:31 2020]     general: {
[Fri Apr 24 12:40:31 2020]         enabled: true
[Fri Apr 24 12:40:31 2020]         events: all
[Fri Apr 24 12:40:31 2020]         backend: graylog.coligo.com
[Fri Apr 24 12:40:31 2020]         port: 12201
[Fri Apr 24 12:40:31 2020]         protocol: udpp
[Fri Apr 24 12:40:31 2020]         max_message_len: safdsf512
[Fri Apr 24 12:40:31 2020]         compress: false
[Fri Apr 24 12:40:31 2020]         compression: 6
[Fri Apr 24 12:40:31 2020]     }
[Fri Apr 24 12:40:31 2020] [WARN] Missing or invalid transport, using default:UDP
[Fri Apr 24 12:40:31 2020] [WARN] Missing or invalid max_message_len, using default: 500

@lminiero when you get time, can you review new changes ? thanks

Copy link
Member

@lminiero lminiero left a comment

Choose a reason for hiding this comment

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

Thanks! I did another round of review: some are just nits, but there are a couple of things that I think need to be addressed.

events/janus_gelfevh.c Outdated Show resolved Hide resolved
events/janus_gelfevh.c Outdated Show resolved Hide resolved
events/janus_gelfevh.c Outdated Show resolved Hide resolved
events/janus_gelfevh.c Outdated Show resolved Hide resolved
events/janus_gelfevh.c Outdated Show resolved Hide resolved
events/janus_gelfevh.c Outdated Show resolved Hide resolved
events/janus_gelfevh.c Outdated Show resolved Hide resolved
events/janus_gelfevh.c Show resolved Hide resolved
events/janus_gelfevh.c Outdated Show resolved Hide resolved
events/janus_gelfevh.c Show resolved Hide resolved
@mirkobrankovic
Copy link
Contributor Author

@lminiero I refactored tcp send to make sure all bytes are sent, but while debugging I haven't seen sent less then size (every time is sent in one go, even when messages are 2500 chars long), but better to be safe.
Also I needed to add NULL terminator, otherwise it was skipping every second message.

Can you do one more round?

Copy link
Member

@lminiero lminiero left a comment

Choose a reason for hiding this comment

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

Sorry if this took so long, I must have missed your last message, and I came back here after the discussion on the group about that other effort related to GrayLog. I added a few notes: very minor, as you'll see, so I think we're very close to merging (for real this time 😄 ). I'll check how complex installing a Graylog instance for testing is, to see if I can test it myself, but that would be just out of curiosity: you've been using it long enough, so if it works for you, I'm sure it does its job!

events/janus_gelfevh.c Outdated Show resolved Hide resolved
events/janus_gelfevh.c Show resolved Hide resolved
events/janus_gelfevh.c Outdated Show resolved Hide resolved
int offset = 0;
char *rnd = randstring(8);
for (int i = 0; i < total; i++) {
int bytesToSend = offset + max_gelf_msg_len < len ? max_gelf_msg_len : len - offset;
Copy link
Member

Choose a reason for hiding this comment

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

I think it's better to wrap the items with a math operation in brackets, here, or there may be ambiguities: if not for the compiler, for who reads the code for sure.

@lminiero
Copy link
Member

I think this has been around long enough (I see you opened the PR during JanusCon 😱 ), and I think it's fine as it is (I can fix small nits myself, if I find any). Thanks again, merging!

@lminiero lminiero merged commit ea89e24 into meetecho:master May 25, 2020
lminiero added a commit that referenced this pull request May 25, 2020
@lminiero
Copy link
Member

Made some minor changes (mostly code style), and changed the configure to by default compile the module: your patch had maybe in there, but that's actually only supposed to be used when there are dependencies to take into account, and a check later might turn the maybe into a yes. Since your module doesn't depend on any library, it can be a yes right away (unless something else sets it to no).

@mirkobrankovic
Copy link
Contributor Author

Thanks a lot, I have a lot of problems with this VS Code style and auto-correct on different languages :D

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

4 participants