diff options
| author | Roy Ben-Shabat <Roy@Twine-s.com> | 2018-05-27 19:33:15 +0300 |
|---|---|---|
| committer | Roy Ben-Shabat <Roy@Twine-s.com> | 2018-05-27 19:33:15 +0300 |
| commit | e571f20e27c4fca6bb6efe03d6427a1f332f9830 (patch) | |
| tree | b16041b76ea3b4e8368039c9396f9bbf9624dcc2 /Software/Visual_Studio/PPC/Tango.PPC.Common/EventLogging | |
| parent | 157e0685abb2e7b22b6584cdc7d6f5838ed0a808 (diff) | |
| download | Tango-e571f20e27c4fca6bb6efe03d6427a1f332f9830.tar.gz Tango-e571f20e27c4fca6bb6efe03d6427a1f332f9830.zip | |
Working on panel pc.
Diffstat (limited to 'Software/Visual_Studio/PPC/Tango.PPC.Common/EventLogging')
| -rw-r--r-- | Software/Visual_Studio/PPC/Tango.PPC.Common/EventLogging/DefaultEventLogger.cs | 331 | ||||
| -rw-r--r-- | Software/Visual_Studio/PPC/Tango.PPC.Common/EventLogging/IEventLogger.cs | 64 |
2 files changed, 395 insertions, 0 deletions
diff --git a/Software/Visual_Studio/PPC/Tango.PPC.Common/EventLogging/DefaultEventLogger.cs b/Software/Visual_Studio/PPC/Tango.PPC.Common/EventLogging/DefaultEventLogger.cs new file mode 100644 index 000000000..2675fa1fa --- /dev/null +++ b/Software/Visual_Studio/PPC/Tango.PPC.Common/EventLogging/DefaultEventLogger.cs @@ -0,0 +1,331 @@ +using Google.Protobuf; +using System; +using System.Collections.Concurrent; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading; +using System.Threading.Tasks; +using Tango.BL; +using Tango.BL.Entities; +using Tango.BL.Enumerations; +using Tango.Core; +using Tango.Integration.Services; +using Tango.PMR.Diagnostics; +using Tango.Integration.Operation; +using Tango.PPC.Common.Application; +using Tango.PPC.Common.Authentication; + +namespace Tango.PPC.Common.EventLogging +{ + /// <summary> + /// Represents the default database events logger. + /// </summary> + /// <seealso cref="IEventLogger" /> + public class DefaultEventLogger : ExtendedObject, IEventLogger + { + private ObservablesContext _db; + private Thread _logThread; + private ConcurrentQueue<MachinesEvent> _events; + private IPPCApplicationManager _application; + private IAuthenticationProvider _authentication; + private Dictionary<EventTypes, BL.Entities.EventType> _eventTypesGuids; + private String _hostName; + private bool _isInitialized; + private List<MachinesEvent> _pendingEvents; + + #region Events + + /// <summary> + /// Occurs when a new machine event has been logged. + /// </summary> + public event EventHandler<MachinesEvent> NewLog; + + #endregion + + #region Constructors + + /// <summary> + /// Initializes a new instance of the <see cref="DefaultEventLogger"/> class. + /// </summary> + /// <param name="applicationManager">The application manager.</param> + /// <param name="authenticationProvider">The authentication provider.</param> + public DefaultEventLogger(IPPCApplicationManager applicationManager, IAuthenticationProvider authenticationProvider) + { + _hostName = Environment.MachineName; + + _events = new ConcurrentQueue<MachinesEvent>(); + _pendingEvents = new List<MachinesEvent>(); + + _eventTypesGuids = new Dictionary<EventTypes, BL.Entities.EventType>(); + + _application = applicationManager; + _authentication = authenticationProvider; + _logThread = new Thread(LogThreadMethod); + _logThread.IsBackground = true; + _logThread.Start(); + + _application.ConnectedMachineChanged += _application_ConnectedMachineChanged; + } + + #endregion + + #region Private Methods + + private void Init() + { + if (!_isInitialized) + { + try + { + _db = ObservablesContext.CreateDefault(); + _db.Configuration.LazyLoadingEnabled = false; + + _db.ActionTypes.ToList(); + _db.EventTypesActions.ToList(); + _db.EventTypesCategories.ToList(); + _db.EventTypesGroups.ToList(); + _db.EventTypes.ToList(); + + foreach (var type in _db.EventTypes) + { + _eventTypesGuids.Add((EventTypes)type.Code, type); + } + + _isInitialized = true; + } + catch + { + _isInitialized = false; + } + } + } + + #endregion + + #region Event Handlers + + /// <summary> + /// Handle the application manager connected machine changed event. + /// </summary> + /// <param name="sender">The sender.</param> + /// <param name="machine">The machine.</param> + private void _application_ConnectedMachineChanged(object sender, IMachineOperator machine) + { + if (machine != null) + { + if (machine.MachineEventsStateProvider != null) + { + machine.MachineEventsStateProvider.NewEvents -= MachineEventsStateProvider_NewEvents; + machine.MachineEventsStateProvider.NewEvents += MachineEventsStateProvider_NewEvents; + machine.MachineEventsStateProvider.EventsResolved -= MachineEventsStateProvider_EventsResolved; + machine.MachineEventsStateProvider.EventsResolved += MachineEventsStateProvider_EventsResolved; + } + + machine.RequestSent -= Machine_RequestSent; + machine.RequestFailed -= Machine_RequestFailed; + machine.ResponseReceived -= Machine_ResponseReceived; + + machine.RequestSent += Machine_RequestSent; + machine.RequestFailed += Machine_RequestFailed; + machine.ResponseReceived += Machine_ResponseReceived; + } + } + + /// <summary> + /// Handles the RequestSent event of the connected machine. + /// </summary> + /// <param name="sender">The sender.</param> + /// <param name="message">The message.</param> + private void Machine_RequestSent(object sender, IMessage message) + { + Log(EventTypes.RequestSent, String.Format("Sending request '{0}'...{1}{2}", message.GetType().Name, Environment.NewLine, message.ToJsonString())); + } + + /// <summary> + /// Handles the RequestFailed event of the connected machine. + /// </summary> + /// <param name="sender">The source of the event.</param> + /// <param name="e">The <see cref="RequestFailedEventArgs"/> instance containing the event data.</param> + private void Machine_RequestFailed(object sender, RequestFailedEventArgs e) + { + Log(EventTypes.RequestFailed, String.Format("Request failed '{0}'...{1}{2}{1}{3}", e.Message.GetType().Name, Environment.NewLine, e.Message.ToJsonString(), e.Exception.ToString())); + } + + /// <summary> + /// Handles the ResponseReceived event of the connected machine. + /// </summary> + /// <param name="sender">The sender.</param> + /// <param name="message">The message.</param> + private void Machine_ResponseReceived(object sender, IMessage message) + { + Log(EventTypes.ResponseReceived, String.Format("Response received '{0}'...{1}{2}", message.GetType().Name, Environment.NewLine, message.ToJsonString())); + } + + /// <summary> + /// Handles the connected machine events state provider NewEvents event. + /// </summary> + /// <param name="sender">The sender.</param> + /// <param name="events">The events.</param> + private void MachineEventsStateProvider_NewEvents(object sender, IEnumerable<MachinesEvent> events) + { + foreach (var ev in events) + { + Log(ev); + } + } + + /// <summary> + /// Handles the connected machine events state provider EventsResolved event. + /// </summary> + /// <param name="sender">The sender.</param> + /// <param name="events">The events.</param> + private void MachineEventsStateProvider_EventsResolved(object sender, IEnumerable<MachinesEvent> events) + { + foreach (var ev in events) + { + Log(String.Format("Event '{0}' resolved.", ev.EventType.Name)); + } + } + + #endregion + + #region Logging + + /// <summary> + /// Logs the specified machine event. + /// </summary> + /// <param name="machineEvent">The machine event.</param> + public void Log(MachinesEvent machineEvent) + { + machineEvent.HostName = _hostName; + machineEvent.EventType = _eventTypesGuids[machineEvent.Type]; + + if (_application.ConnectedMachine == null || _authentication.CurrentUser == null) + { + _pendingEvents.Add(machineEvent); + } + else + { + if (_pendingEvents.Count > 0) + { + var pending = _pendingEvents.ToList(); + _pendingEvents.Clear(); + + foreach (var ev in pending) + { + Log(ev); + } + } + + LogManager.Log("Logging event " + machineEvent.EventType.Name + " - " + machineEvent.Description); + machineEvent.MachineGuid = _application.ConnectedMachine.Machine.Guid; + machineEvent.UserGuid = _authentication.CurrentUser.Guid; + machineEvent.User = _authentication.CurrentUser; + _events.Enqueue(machineEvent); + NewLog?.Invoke(this, machineEvent); + } + } + + /// <summary> + /// Logs the specified event type. + /// </summary> + /// <param name="eventType">Type of the event.</param> + /// <param name="message">The message.</param> + public void Log(EventTypes eventType, string message) + { + Init(); + + MachinesEvent machineEvent = new MachinesEvent(); + machineEvent.DateTime = DateTime.UtcNow; + machineEvent.Description = message; + machineEvent.EventType = _eventTypesGuids[eventType]; + machineEvent.EventTypeGuid = machineEvent.EventType.Guid; + + Log(machineEvent); + } + + /// <summary> + /// Logs the specified hardware event. + /// </summary> + /// <param name="hardwareEvent">The hardware event.</param> + public void Log(Event hardwareEvent) + { + Log((EventTypes)hardwareEvent.Type, hardwareEvent.Message); + } + + /// <summary> + /// Logs the specified exception using the <see cref="EventTypes.ApplicationException"/>. + /// </summary> + /// <param name="exception">The exception.</param> + public void Log(Exception exception) + { + Log(EventTypes.ApplicationException, exception.ToString()); + } + + /// <summary> + /// Logs the specified exception using the <see cref="EventTypes.ApplicationException" />. + /// </summary> + /// <param name="exception">The exception.</param> + /// <param name="description"></param> + public void Log(Exception exception, string description) + { + Log(EventTypes.ApplicationException, description + Environment.NewLine + exception.ToString()); + } + + /// <summary> + /// Logs the specified message using the <see cref="EventTypes.ApplicationInformation"/>. + /// </summary> + /// <param name="message">The message.</param> + public void Log(String message) + { + Log(EventTypes.ApplicationInformation, message); + } + + /// <summary> + /// Logging thread loop. + /// </summary> + private void LogThreadMethod() + { + while (true) + { + FlushAll(); + Thread.Sleep(5000); + } + } + + /// <summary> + /// Immediately saves all pending events to database. + /// </summary> + public void FlushAll() + { + bool _saveChanges = false; + + while (_events.Count > 0) + { + MachinesEvent ev = null; + + if (_events.TryDequeue(out ev)) + { + ev.User = null; + _db.MachinesEvents.Add(ev); + _saveChanges = true; + } + } + + if (_saveChanges) + { + try + { + _db.SaveChanges(); + } + catch (Exception ex) + { + LogManager.Log(ex, "Error saving machine event to database."); + } + } + } + + #endregion + } +} diff --git a/Software/Visual_Studio/PPC/Tango.PPC.Common/EventLogging/IEventLogger.cs b/Software/Visual_Studio/PPC/Tango.PPC.Common/EventLogging/IEventLogger.cs new file mode 100644 index 000000000..f7eadac1e --- /dev/null +++ b/Software/Visual_Studio/PPC/Tango.PPC.Common/EventLogging/IEventLogger.cs @@ -0,0 +1,64 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using Tango.BL.Entities; +using Tango.BL.Enumerations; +using Tango.PMR.Diagnostics; + +namespace Tango.PPC.Common.EventLogging +{ + /// <summary> + /// Represents a database events logger. + /// </summary> + public interface IEventLogger + { + /// <summary> + /// Occurs when a new machine event has been logged. + /// </summary> + event EventHandler<MachinesEvent> NewLog; + + /// <summary> + /// Logs the specified machine event. + /// </summary> + /// <param name="machineEvent">The machine event.</param> + void Log(MachinesEvent machineEvent); + + /// <summary> + /// Logs the specified event type. + /// </summary> + /// <param name="eventType">Type of the event.</param> + /// <param name="message">The message.</param> + void Log(EventTypes eventType, String message); + + /// <summary> + /// Logs the specified hardware event. + /// </summary> + /// <param name="hardwareEvent">The hardware event.</param> + void Log(Event hardwareEvent); + + /// <summary> + /// Logs the specified exception using the <see cref="EventTypes.ApplicationException"/>. + /// </summary> + /// <param name="exception">The exception.</param> + void Log(Exception exception); + + /// <summary> + /// Logs the specified exception using the <see cref="EventTypes.ApplicationException"/>. + /// </summary> + /// <param name="exception">The exception.</param> + void Log(Exception exception, String description); + + /// <summary> + /// Logs the specified message using the <see cref="EventTypes.ApplicationInformation"/>. + /// </summary> + /// <param name="message">The message.</param> + void Log(String message); + + /// <summary> + /// Immediately saves all pending events to database. + /// </summary> + void FlushAll(); + } +} |
