public void Run()
        {
            _rmqConnection = SuperLoggerHelper.GetRmqConnection();
            _rmqChannel    = _rmqConnection.CreateModel();
            _rmqChannel.QueueDeclare(SuperLoggerHelper.QueueName, true, false, false, null);
            //@todo: QueueingBasicConsumer is obsolete and impacts the performance. It has to be replaced
            QueueingBasicConsumer rmqConsumer = new QueueingBasicConsumer();

            _rmqChannel.BasicConsume(SuperLoggerHelper.QueueName, false, rmqConsumer);
            while (Running)
            {
                //@todo: Catch exception from RMQ and reconnect
                //@todo: Add mechanism to deal with bad messages and put the service to sleep in case of RMQ or SQL failures
                BasicDeliverEventArgs message = rmqConsumer.Queue.Dequeue();
                try
                {
                    var body    = message.Body;
                    var payload = Encoding.UTF8.GetString(body);
                    RmqMessageContent  messageContent = JsonConvert.DeserializeObject <RmqMessageContent>(payload);
                    SuperLoggerDbModel dbModel        = new SuperLoggerDbModel();
                    dbModel.AddLogEntry(messageContent.Source,
                                        messageContent.LogType,
                                        messageContent.CorrelationID,
                                        JsonConvert.DeserializeObject <DateTime>(messageContent.CreatedOn),
                                        messageContent.Message,
                                        messageContent.StackTrace,
                                        messageContent.Data);
                    _rmqChannel.BasicAck(message.DeliveryTag, false);
                } catch (Exception ex)
                {
                    _rmqChannel.BasicReject(message.DeliveryTag, true);
                }
            }
        }
        private static RmqMessageContent PrepareMessageContent(string type, string source, string message, string stackTrace, IDictionary <string, string> data)
        {
            RmqMessageContent messageContent = new RmqMessageContent();

            messageContent.LogType       = type;
            messageContent.Source        = source;
            messageContent.Message       = message;
            messageContent.StackTrace    = stackTrace;
            messageContent.Data          = data;
            messageContent.CreatedOn     = JsonConvert.SerializeObject(DateTime.Now.ToUniversalTime());
            messageContent.CorrelationID = CorrelationID;
            return(messageContent);
        }
        private static void SendMessage(string type,
                                        string source,
                                        string message,
                                        string stackTrace,
                                        IDictionary <string, string> data,
                                        bool throwExceptions)
        {
            IConnection rmqConn  = null;
            IModel      rmqModel = null;

            try
            {
                rmqConn  = SuperLoggerHelper.GetRmqConnection();
                rmqModel = rmqConn.CreateModel();
                // @todo: review this
                // This is unecessary and may impact performance. It will require pre rabbit mq configuration to create the Ex
                // Better to move this to a initialization area
                //rmqModel.ExchangeDeclare(SuperLoggerHelper.Exchange, ExchangeType.Direct);
                //rmqModel.QueueDeclare(SuperLoggerHelper.QueueName, true, false, false, null);
                //rmqModel.QueueBind(SuperLoggerHelper.QueueName, SuperLoggerHelper.Exchange, SuperLoggerHelper.RoutingKey, null);
                RmqMessageContent messageContent   = PrepareMessageContent(type, source, message, stackTrace, data);
                string            messageBody      = JsonConvert.SerializeObject(messageContent);
                byte[]            messageBodyBytes = System.Text.Encoding.UTF8.GetBytes(messageBody);
                rmqModel.BasicPublish(SuperLoggerHelper.Exchange, SuperLoggerHelper.RoutingKey, null, messageBodyBytes);
            }
            catch (Exception ex)
            {
                if (throwExceptions)
                {
                    throw;
                }

                // @todo: Add the exception to Event Viewer

                //string source = "Super Logger";
                //string log = "Application";
                //string eventMessage = string.Format("Error: {0} \nStack Trace: {1}", ex.Message, ex.StackTrace);

                //// @todo: This requires admin privilege. Check how to make it always work
                //if (!EventLog.SourceExists(source))
                //    EventLog.CreateEventSource(source, log);
                //EventLog.WriteEntry(source, eventMessage, EventLogEntryType.Error);
            }
            finally
            {
                CloseRmqConnection(rmqConn);
            }
        }