ArieGato / serilog-sinks-rabbitmq

Serilog Sink for RabbitMq
Apache License 2.0
53 stars 51 forks source link

Serilog.Sinks.RabbitMQ.RabbitMQClient not properly initialized #91

Closed misky1986 closed 4 years ago

misky1986 commented 5 years ago

Describe the bug Serilog.Sinks.RabbitMQ.RabbitMQClient not properly initialized after I updated Serilog.Sinks.RabbitMQ from version 3.0.0 to version 3.0.3.

Even though I have initialized RabbitMQClientConfiguration as I have done earlier, there seems to be an error in the Serilog.Sinks.RabbitMQ.RabbitMQClient which makes the class not to be initialized properly.

As showed in the section "How to reproduce" I expect the connection should point to the host called "remote-server" but instead in is initialize with the value "localhost" as shown on the two pictures I have attached.

To Reproduce Steps to reproduce the behavior:

  1. Create a Console application in .Net Core or .Net standard
  2. Paste in the following instead of the main method ` static void Main(string[] args) { string UserName = "rabbitmq-test-user"; string Password = "rabbitmq-test-password"; string HostName = "remote-server";
    string routingKey = "testqueue";

        int port = 5672;
    
        Console.WriteLine("Hello this is the sender application!");
    
        var config = new RabbitMQClientConfiguration
        {
            Port = port,
            Username = UserName,
            DeliveryMode = Serilog.Sinks.RabbitMQ.RabbitMQDeliveryMode.Durable,
            Password = Password,
            RouteKey = routingKey                
        };
    
        config.Hostnames.Add(HostName);
    
        Logger logger = new LoggerConfiguration()
            .WriteTo.RabbitMQ((clientConfiguration, sinkConfiguration) =>
            {
                clientConfiguration.From(config);
                sinkConfiguration.TextFormatter = new JsonFormatter();
            })
            .MinimumLevel.Verbose()
            .CreateLogger();
    
        for (int i = 0; i < 4; i++)
        {
            logger.Warning($"{i}. This is a test warning log");
        }
    }

    `

  3. run the application.

Expected behavior No log messages are pushed to the RabbitMQ queue called "testqueue"

Screenshots RabbitMQConnectionFactory-bug RabbitMQ-bug

Operating System and Software (please complete the following information):

madslyng commented 5 years ago

@misky1986 Thank you for the bug.

It seems to be missing a specification of what Exchange you are sending your messages to. You have only specified a routing key, which is what can be used to 'route' messages to a specific queue.

Could that be what is going wrong ?

misky1986 commented 5 years ago

@sonicjolt Your welcome.

And by the way. Thanks a lot for your cool nuget package. It is awesome :)

Yes, maybe I should have written that in the bug description as well. The default behavior in RabbitMQ is, that if you leave the exchange property empty (""), RabbitMQ is going to use the default exchange to bind to the queue. For this to work, it is important that the routing key does match the queue name. In that case the default exchange is used.

I learned about the default exchange behavior at the following link: https://www.rabbitmq.com/tutorials/amqp-concepts.html#exchange-default

I think there is something else that is causing the problem.

madslyng commented 5 years ago

@misky1986 When you are initializing, are you initializing against a host that you know exists ?

dorzeidman commented 4 years ago

Hey @steffenlyng and @misky1986, I tried to help out, the only thing I found that I have to add logger.Dispose() for the message to be sent, can that be the issue here?

cognitive-arch commented 4 years ago

Hey Im facing the same problem. I made a new .net core web project and configured the skin as mentioned in this repo but its not logging anything on RabbitMQ. Im using this version Serilog.Sinks.RabbitMQ:3.0.6.

Below is my configuration.

Logger logger = new LoggerConfiguration()
            .Enrich.FromLogContext()
            .WriteTo.RabbitMQ((clientConfiguration, sinkConfiguration) =>
            {
                clientConfiguration.Port = 5672;
                clientConfiguration.DeliveryMode = RabbitMQDeliveryMode.Durable;
                clientConfiguration.Exchange = "serilog-sink-exchange";
                clientConfiguration.Username = "guest";
                clientConfiguration.Password = "guest";
                clientConfiguration.ExchangeType = "fanout";
                clientConfiguration.Hostnames.Add(HostName);
                sinkConfiguration.TextFormatter = new JsonFormatter();
            }).CreateLogger();

Interesting thing is that when i try to run the given test cases in your provided repository it works fine but not in case of nuget package.

madslyng commented 4 years ago

@cognitive-arch @misky1986 @dorzeidman Thanks all for your feedback - I'll see if I can figure out what is going on, and hopefully find a solution for it.

cognitive-arch commented 4 years ago

Thanks @steffenlyng . Im trying to figure it out too. If i find the solution Ill share here too.

madslyng commented 4 years ago

@cognitive-arch I just tested with: https://gist.github.com/steffenlyng/609f91968cfbe7bd867b19fe5a0596b4

Serilog.Sinks.RabbitMq=3.0.6 (based on the nuget package)

And it worked - maybe you can provide some more information about your setup .. I did a fresh install of rabbitmq:

I performed:

  1. choco install rabbitmq
  2. Install RabbitMQ Management Plugin: rabbitmq-plugins enable rabbitmq_management
  3. Added the exchange
  4. Added the queue
  5. Added the binding between exchange and queue
  6. Ran the example from the above Gist

If you follow these steps, are you still not able to get it running ?

madslyng commented 4 years ago

@misky1986 I have created a setup using Serilog.Sinks.RabbitMq 3.0.6 (nuget), and I also tested with v3.0.3 nuget package.

https://gist.github.com/steffenlyng/0a165bbfc4bfc0d6771d48a8d445cd72

I setup rabbitmq as follows:

  1. Clean installation of rabbitmq (see above description in my answerr to @cognitive-arch )
  2. I created a queue called testqueue
  3. Add user called rabbitmq-test-user, with password: rabbitmq-test-password
  4. I Added a permission for the user so it has access
  5. I Ran the gist above

That worked.

Can you try following these instructions ? And let me know.. :)

cognitive-arch commented 4 years ago

@steffenlyng Thanks again for the help. Its working really fine as far as console application concern but not in asp.net core API project.

Here is the sample code with sink configuration and its not logging any error or information into queue .

https://gist.github.com/cognitive-arch/e582fac189fc2fd8d26d4baf121c3e26

I dont know whats wrong with the configuration.

madslyng commented 4 years ago

Based on your example, could you please try:

var loggerFactory = new LoggerFactory();
loggerFactory
  .AddSerilog(logger)
  .AddConsole(LogLevel.Information);

This worked for me, based on your example.

There is a flaw in the documentation in this repository, which says that you can perform:

var logger = new LoggerConfiguration()
    .Enrich.FromLogContext()
    .WriteTo.RabbitMQ((clientConfiguration, sinkConfiguration) => {
        clientConfiguration.Username     = _config["RABBITMQ_USER"];
        clientConfiguration.Password     = _config["RABBITMQ_PASSWORD"];
        clientConfiguration.Exchange     = _config["RABBITMQ_EXCHANGE"];
        clientConfiguration.ExchangeType = _config["RABBITMQ_EXCHANGE_TYPE"];
        clientConfiguration.DeliveryMode = RabbitMQDeliveryMode.Durable;
        clientConfiguration.RouteKey     = "Logs";
        clientConfiguration.Port         = 5672;

        foreach (string hostname in _config["RABBITMQ_HOSTNAMES"]) {
            clientConfiguration.Hostnames.Add(hostname);
        }

        sinkConfiguration.TextFormatter  = new JsonFormatter();
    }).CreateLogger();

and then:

var loggerFactory = new LoggerFactory();
      loggerFactory
        .AddSerilog()
        .AddConsole(LogLevel.Information);
      services.AddSingleton<ILoggerFactory>(loggerFactory);

That is incorrect. Because if you do that, then the logger is simply created in-memory, and never assigned to the LoggerFactory.

You should instead use:

Log.Logger = new LoggerConfiguration()
    .Enrich.FromLogContext()
    .WriteTo.RabbitMQ((clientConfiguration, sinkConfiguration) => {
        clientConfiguration.Username     = _config["RABBITMQ_USER"];
        clientConfiguration.Password     = _config["RABBITMQ_PASSWORD"];
        clientConfiguration.Exchange     = _config["RABBITMQ_EXCHANGE"];
        clientConfiguration.ExchangeType = _config["RABBITMQ_EXCHANGE_TYPE"];
        clientConfiguration.DeliveryMode = RabbitMQDeliveryMode.Durable;
        clientConfiguration.RouteKey     = "Logs";
        clientConfiguration.Port         = 5672;

        foreach (string hostname in _config["RABBITMQ_HOSTNAMES"]) {
            clientConfiguration.Hostnames.Add(hostname);
        }

        sinkConfiguration.TextFormatter  = new JsonFormatter();
    }).CreateLogger();

Notice: Log.Logger = ...

If you do that, then you can use AddSerilog() without the logger

madslyng commented 4 years ago

@misky1986 I am closing this as it seems to be misconfiguration. Based on my trials of yours and @cognitive-arch scenarios I don't see any flaws. Only misinformation in documentation that I have now fixed.

I've tested your examples, and they work.

Please let me know if you continue to experience problems.

cognitive-arch commented 4 years ago

@steffenlyng Thanks its working fine now. Problem was as you mentioned misinformation in documentation and my bad too I forgot the point you mentioned Log.Logger.