0 votes
by (250 points)
edited by

See the problem description below in the answers.

Applies to: Syslog

2 Answers

0 votes
by (72.7k points)
 
Best answer

Thank you for sending us the complete code.

The main issue was that args.Message.ApplicationName.ToString(); raised NullReferenceException on a background task, which stopped execution of the foreach (var args in messageQueue.GetConsumingEnumerable()) loop.

Please note that string properties of the args.Message can be null if the client did not send their value.

I also suggest to put body of the message processing foreach loop into try-catch block and handle errors appropriately.

0 votes
by (72.7k points)

Please clarify what you mean by server gets stuck.

  • You are not able to stop the server? Meaning that you ended in the endless foreach (...GetConsumingEnumerable()) loop?

    • You need to call server.Stop(); and messageQueue.CompleteAdding(); somewhere when you want to stop the server and finish the loop.
  • You are not able to process more messages from some point?

    • I don't know what your replil_syslog_messages.Add(messageModel) and SaveChanges() methods do, but if either of them throws an exception it will lead to exiting the foreach loop = you will stop processing further messages. Here, I would suggest to place body of the loop in the try - catch block.
    • Also please make sure that none of those methods get stuck.
  • You are not able to process any message?

    • Please make sure that if (_entities.SaveChanges().Equals(1)) is passed, no exceptions are thrown and the execution continues to foreach (...GetConsumingEnumerable()) loop.
  • Or something else is happening? Are you getting some errors?

    • Please consider to register the server.ErrorOccurred event as well and handle/log server errors as well.

In any case, it will be very useful if you turn on server logging and examine the log when the server gets stuck. It can be done like this:

var server = new SyslogServer();
server.LogWriter = new Rebex.FileLogWriter(@"c:\data\syslog.log", Rebex.LogLevel.Debug);

Also consider to register the server.MessageReceived event before you call server.Start(); to prevent possible loss of early messages.

by (250 points)
the message queue does show message and count increase, but it does not reach each loop to store the massage.

private async Task LogMessage()
        {
            var messageQueue = new BlockingCollection<SyslogMessageReceivedEventArgs>();
            server.MessageReceived += (s, e) =>
            {
                messageQueue.Add(e);
            };
                foreach (var args in messageQueue.GetConsumingEnumerable())
                {
                    var messageModel = new replil_syslog_messages();

                    messageModel.device_id = args.RemoteEndPoint.Address.ToString();
                    messageModel.message = args.Message.Text.ToString();
                    messageModel.message_category = args.Message.Severity.ToString();
                    messageModel.application_name = args.Message.ApplicationName.ToString();
                    messageModel.severity = args.Message.Severity.ToString();
                    messageModel.processid = args.Message.ProcessId.ToString();
                    messageModel.timestamp = args.ReceivedTime.ToString();

                    _entities.replil_syslog_messages.Add(messageModel);
                    _entities.SaveChanges();
                }
            }
        }
by (72.7k points)
Can you please send us your project to support@rebex.net (or at least a part responsible for Syslog processing).

The provided "private async Task LogMessage()" method implementation does not tell us much - it even does not return Task nor uses await. We need to see your project in wider context.
...