protected void WriteLogMessage(exDb dbContext, int?_Inbound_Id, int?_Outbound_Id, bool _IsError, string _Message, string _Details) { new LogRecord() { Source = this._Name, HostId = this.HostId, QueueId = this.QueueId, Inbound_Id = _Inbound_Id, Outbound_Id = _Outbound_Id, IsError = _IsError, Message = _Message, Details = _Details } .TryWrite(dbContext); }
void timer_Elapsed(object sender, System.Timers.ElapsedEventArgs e) { if (!Monitor.TryEnter(TimerLock) || ShouldStop) { return; } using (var exdb = new exDb(dbConnStr)) { foreach (var bus in Buses.Where(b => !b.IsConnected)) { new LogRecord() { Source = _Name, HostId = RabbitQueues.FirstOrDefault(q => bus == q.Bus).Host_Id, IsError = true, Message = "Утеряно соединение с сервером RabbitMQ. Выполняются попытки переподключения...", Details = RabbitQueues.FirstOrDefault(q => bus == q.Bus).Host.ConnectionString } .TryWrite(dbConnStr, dbLog); } foreach (var w in workers) { if (!w.IsAlive) { new LogRecord() { Source = _Name, HostId = w.HostId, QueueId = w.QueueId, Message = "Обнаружено непредвиденное завершение обработчика очереди сообщений. Перезапускаем обработчик...", Details = w.QueueFullName } .TryWrite(dbConnStr, dbLog); w.Respawn(); } } } Monitor.Exit(TimerLock); }
private void MessageHandler(Byte[] body, MessageProperties mp, MessageReceivedInfo mi) { using (var exdb = new exDb(dbConnStr)) { exdb.Log = dbLog; new LogRecord() { Source = this._Name, HostId = this.HostId, QueueId = this.QueueId, Message = String.Format("Принято сообщение {0} байт", body.Length), Details = this.QueueFullName } .TryWrite(exdb); var msg = Queue.Base64Data ? Convert.ToBase64String(body) : this.Encoding.GetString(body); var record = new Inbound() { QueueId = this.QueueId, DateReceived = DateTime.Now, Message = msg }; exdb.Inbound.InsertOnSubmit(record); // Rethrow = true. Если не удалось записать сообщение в БД, таск должен упасть, чтобы EasyNetQ не отправил Ack раббиту exdb.TrySubmitChanges(true); new LogRecord() { Source = this._Name, HostId = this.HostId, QueueId = this.QueueId, Inbound_Id = record.Message_Id, Message = String.Format("Записали {0}сообщение в БД", Queue.Base64Data ? "base64 " : ""), Details = String.Format("{0} символов", msg.Length) } .TryWrite(exdb); } }
public void Start() { try { Directory.CreateDirectory(Path.Combine(Path.GetTempPath(), Exchange_Svc.MyServiceName)); } catch (Exception ex) { Trace.TraceWarning("{2}\t{0}: не удалось создать папку логов: {1}", _Name, ex.Message, DateTime.Now); } if (DebugFlag.Enabled) { try { dbLog = new StreamWriter(Path.Combine(Path.GetTempPath(), Exchange_Svc.MyServiceName, "service.dblog")) { AutoFlush = true }; } catch (Exception ex) { Trace.TraceWarning("{2}\t{0}: не удалось создать журнал dblog: {1}", _Name, ex.Message, DateTime.Now); } } Trace.TraceInformation("{1}\t{0}: запускается...", _Name, DateTime.Now); if (dbConnStr == null || String.IsNullOrWhiteSpace(dbConnStr)) { FailStart("Запуск невозможен: строка подключения к БД не может быть пустой"); } using (var SQLconn = new SqlConnection(dbConnStr)) { // Пытаемся подключиться к БД int errorCounter = 0; while (SQLconn.State == ConnectionState.Closed) { try { SQLconn.Open(); } catch (Exception ex) { if (ex is InvalidOperationException) { FailStart("Запуск невозможен: ошибка в строке подключения к БД \"{0}\"", dbConnStr); } else if (errorCounter >= 3) { FailStart("Превышено допустимое количество неудачных попыток подключения к БД. Последняя ошибка: {0}", ex.Message); } else { errorCounter++; Trace.TraceWarning("{1}\tНеудачная попытка подключения к БД: {0}", ex.Message, DateTime.Now); Thread.Sleep(1000); } } } // На этом этапе соединение с БД установлено try { new LogRecord() { Source = _Name, Message = "Успешный запуск, установлено соединение с БД", Details = dbConnStr } .TryWrite(SQLconn, dbLog); } catch (Exception ex) { FailStart("Запуск невозможен: ошибка записи в БД, {0}", ex.Message); } // Получаем список хостов RabbitMQ using (var exdb = new exDb(SQLconn)) { exdb.Log = dbLog; RabbitHosts = exdb.Hosts.Where(h => exdb.Queues.Any(q => q.Host_Id == h.Host_Id)).ToList(); RabbitQueues = exdb.Queues.ToList(); if (RabbitHosts.Count == 0) { var msg = "В таблице Hosts нет активных записей. Остановка службы"; new LogRecord() { Source = _Name, IsError = true, Message = msg } .TryWrite(exdb); FailStart(msg); } } // Подключаемся к хостам RabbitMQ foreach (var host in RabbitHosts) { var rabbit_conn = new ConnectionConfiguration(); rabbit_conn.PrefetchCount = Convert.ToUInt16((host.PrefetchCount > 0) ? host.PrefetchCount : 1); rabbit_conn.PublisherConfirms = true; //r_conn.Port = Convert.ToUInt16((host.Port > 0) ? host.Port : 5671); if (!String.IsNullOrWhiteSpace(host.VirtualHost)) { rabbit_conn.VirtualHost = host.VirtualHost; } if (!String.IsNullOrWhiteSpace(host.Username)) { rabbit_conn.UserName = host.Username; if (!String.IsNullOrWhiteSpace(host.Password)) { rabbit_conn.Password = host.Password; } } var r_host = new HostConfiguration(); r_host.Host = host.Host; r_host.Port = Convert.ToUInt16((host.Port > 0) ? host.Port : host.SslEnabled ? 5671 : 5672); if (host.SslEnabled) { r_host.Ssl.Enabled = true; //r_host.Ssl.ServerName = host.Host; r_host.Ssl.AcceptablePolicyErrors = System.Net.Security.SslPolicyErrors.RemoteCertificateChainErrors | System.Net.Security.SslPolicyErrors.RemoteCertificateNotAvailable | System.Net.Security.SslPolicyErrors.RemoteCertificateNameMismatch; } rabbit_conn.Hosts = new[] { r_host }; new LogRecord() { Source = _Name, HostId = host.Host_Id, Message = String.Format("Подключаемся к {0}серверу RabbitMQ...", host.SslEnabled ? "SSL " : ""), Details = host.ConnectionString } .TryWrite(SQLconn, dbLog); IEasyNetQLogger r_Log = new EasyNetQ.Loggers.NullLogger(); if (DebugFlag.Enabled) { try { r_Log = new RabbitTextLogger(new StreamWriter(Path.Combine(Path.GetTempPath(), Exchange_Svc.MyServiceName, String.Format("rabbit_{0}.log", host.Host_Id))) { AutoFlush = true }); //r_Log = new EasyNetQ.Loggers.ConsoleLogger(); } catch (Exception ex) { Trace.TraceWarning("{4}\t{0}: не удалось создать журнал rabbit_{1} ({2}): {3}", _Name, host.Host_Id, host.ConnectionString, ex.Message, DateTime.Now); } } try { rabbit_conn.Validate(); var bus = RabbitHutch.CreateBus(rabbit_conn, services => services.Register <IEasyNetQLogger>(logger => r_Log)); Buses.Add(bus); foreach (var q in RabbitQueues.Where(q => q.Host_Id == host.Host_Id)) { q.Bus = bus; } for (int i = 0; i < 10; i++) { if (bus.IsConnected) { new LogRecord() { Source = _Name, HostId = host.Host_Id, Message = String.Format("Установлено {0}подключение к RabbitMQ", host.SslEnabled ? "SSL " : ""), Details = host.ConnectionString } .TryWrite(SQLconn, dbLog); break; } Thread.Sleep(10); } } catch (Exception ex) { new LogRecord() { Source = _Name, IsError = true, Message = String.Format("Ошибка при {0}подключении к серверу RabbitMQ: {1}", host.SslEnabled ? "SSL " : "", ex.Message), Details = rabbit_conn.ToString() } .TryWrite(SQLconn, dbLog); } // } } if (Buses.Count == 0) { var msg = "Не удалось подключиться ни к одному из хостов RabbitMQ. Остановка службы"; new LogRecord() { Source = _Name, IsError = true, Message = msg } .TryWrite(SQLconn, dbLog); FailStart(msg); } // Запускаем обработчики очередей workers = new List <Worker>(); foreach (var queue in RabbitQueues.Where(q => q.Bus != null)) { Worker w; if (queue.Direction.Trim() == "In") { w = new Receiver(dbConnStr, (IBus)queue.Bus, queue); } else if (queue.Direction.Trim() == "Out") { w = new Sender(dbConnStr, (IBus)queue.Bus, queue); } else { new LogRecord() { Source = _Name, HostId = queue.Host.Host_Id, QueueId = queue.Queue_Id, IsError = true, Message = String.Format("Неизвестный тип очереди: '{0}'", queue.Direction), Details = queue.Name } .TryWrite(SQLconn, dbLog); continue; } new LogRecord() { Source = _Name, HostId = queue.Host.Host_Id, QueueId = queue.Queue_Id, Message = "Запускаем обработчик очереди сообщений...", Details = w.QueueFullName } .TryWrite(SQLconn, dbLog); w.Run(); workers.Add(w); } timer = new System.Timers.Timer(30000D); timer.AutoReset = true; timer.Elapsed += timer_Elapsed; timer.Start(); #if DEBUG while (!workers.All(w => w.Thread.Join(3000))) { continue; } #endif } }
public override void Start() { var aBus = Bus.Advanced; if (DebugFlag.Enabled) { try { dbLog = new StreamWriter(Path.Combine(Path.GetTempPath(), Exchange_Svc.MyServiceName, String.Format("{0}.dblog", _Name))) { AutoFlush = true }; } catch (Exception ex) { Trace.TraceWarning("{2}\t{0}: не удалось создать журнал dblog: {1}", _Name, ex.Message, DateTime.Now); } } new LogRecord() { Source = this._Name, HostId = this.HostId, QueueId = this.QueueId, Message = "Обработчик отправки сообщений запущен", Details = QueueFullName } .TryWrite(dbConnStr, dbLog); int MsgCounter = 0; int TotalMsgCounter = 0; long BytesProcessed = 0; long TotalBytesProcessed = 0; while (!ShouldStop) { using (var exdb = new exDb(dbConnStr)) { exdb.Log = dbLog; Outbound message; while (!ShouldStop && aBus.IsConnected && null != (message = exdb.Outbound.FirstOrDefault(o => o.QueueId == this.QueueId && o.DateSent == null))) { new LogRecord() { Source = this._Name, HostId = this.HostId, QueueId = this.QueueId, Outbound_Id = message.Message_Id, Message = "Начинаем отправку сообщения...", Details = String.Format("{0} символов", message.Message.Length) } .TryWrite(exdb); byte[] data; //TODO: every xx (1000?) messages do gc.collect(2) to clear LOH try { data = Queue.Base64Data ? Convert.FromBase64String(message.Message) : Encoding.UTF8.GetBytes(message.Message); BytesProcessed += sizeof(byte) * data.Length; TotalBytesProcessed += sizeof(byte) * data.Length; MsgCounter++; TotalMsgCounter++; } catch (Exception ex) { new LogRecord() { Source = this._Name, HostId = this.HostId, QueueId = this.QueueId, Outbound_Id = message.Message_Id, IsError = true, Message = "Ошибка декодирования base64", Details = ex.Message } .TryWrite(exdb); message.ErrorFlag = true; message.DateSent = new DateTime(1900, 1, 1); exdb.TrySubmitChanges(); continue; } if (IntPtr.Size == 4 && BytesProcessed > 3 * (1024 * 1024 * 512)) { LogInfo(exdb, "Forcing GC.Collect(2)", String.Format("Processed {0} messages, {1} MB since last GC. Total {2} messages, {3} MB. Reported GC UsedMem {4} MB" , MsgCounter, BytesProcessed / (1024 * 1024), TotalMsgCounter, TotalBytesProcessed / (1024 * 1024), GC.GetTotalMemory(false) / (1024 * 1024))); // new LogRecord() { // Source = this._Name, // HostId = this.HostId, // QueueId = this.QueueId, // Message = "Forcing GC.Collect(2)", // Details = String.Format("Processed {0} messages, {1} MB since last GC ({2} msgs, {3} MB total). Reported GC UsedMem {4} MB" // ,MsgCounter, BytesProcessed/(1024*1024), TotalMsgCounter, TotalBytesProcessed/(1024*1024), GC.GetTotalMemory(false)/(1024*1024)) } // .TryWrite(exdb); GC.Collect(2); MsgCounter = 0; BytesProcessed = 0; LogInfo(exdb, "Finished GC.Collect(2)", String.Format("Reported GC UsedMem {0} MB", GC.GetTotalMemory(false) / (1024 * 1024))); // new LogRecord() { // Source = this._Name, // HostId = this.HostId, // QueueId = this.QueueId, // Message = "Finished GC.Collect(2)", // Details = String.Format("Reported GC UsedMem {0} MB", GC.GetTotalMemory(false)/(1024*1024)) } // .TryWrite(exdb); } new LogRecord() { Source = this._Name, HostId = this.HostId, QueueId = this.QueueId, Outbound_Id = message.Message_Id, Message = Queue.Base64Data ? "Декодировали base64" : "Сформировали массив байт", Details = String.Format("{0} байт", data.Length) } .TryWrite(exdb); try { var mp = new MessageProperties(); if (!String.IsNullOrWhiteSpace(message.AppMsgId)) { mp.MessageId = message.AppMsgId; } IExchange ex = String.IsNullOrWhiteSpace(this.ExchangeName) ? Exchange.GetDefault() : new Exchange(this.ExchangeName); aBus.Publish(ex, this.QueueName, true, false, mp, data); } catch (Exception ex) { new LogRecord() { Source = this._Name, HostId = this.HostId, QueueId = this.QueueId, Outbound_Id = message.Message_Id, IsError = true, Message = "Ошибка при отправке сообщения", Details = ex.Message } .TryWrite(exdb); Thread.Sleep(PollInterval); continue; } new LogRecord() { Source = this._Name, HostId = this.HostId, QueueId = this.QueueId, Outbound_Id = message.Message_Id, Message = "Сообщение успешно отправлено!", Details = this.QueueFullName } .TryWrite(exdb); message.DateSent = DateTime.Now; exdb.TrySubmitChanges(); } } Thread.Sleep(PollInterval); } // Вышли из главного цикла (ShouldStop = true) new LogRecord() { Source = this._Name, HostId = this.HostId, QueueId = this.QueueId, Message = "Получена команда остановить обработчик. Нормальное завершение работы", Details = QueueFullName } .TryWrite(dbConnStr, dbLog); }
public void LogError(exDb dbContext, string _Message, string _Details, int?msg_Id = null) { WriteLogMessage(dbContext, null, msg_Id, true, _Message, _Details); }
public void LogInfo(exDb dbContext, string _Message, string _Details, int?msg_Id = null) { WriteLogMessage(dbContext, null, msg_Id, false, _Message, _Details); }