using System.Linq; using System.Collections.Generic; using System; using System.Threading.Tasks; using Mogafa.Common; namespace Mogafa.App.LogEvents { public class LogEventReporter : MogafaBase { private static LogEventReporter logEventReporter; private static List pendingEvents = new List(); private readonly List eventReporters; private readonly List intercepts; private readonly List parameterIntercepts; private readonly List abGroups; private readonly List abGroupEventNames; private CommonEventParameter commonEventParameter; private LogEventReporter() { eventReporters = new List(); intercepts = new List(); parameterIntercepts = new List(); abGroups = new List(); abGroupEventNames = new List(); commonEventParameter = new CommonEventParameter(); } public static LogEventReporter Initialize() { return Initialize(null); } public static LogEventReporter Initialize(CommonEventParameter commonEventParameter) { if (logEventReporter == null) { logEventReporter = new LogEventReporter(); } logEventReporter.commonEventParameter = commonEventParameter; if (logEventReporter.commonEventParameter == null) { logEventReporter.commonEventParameter = new CommonEventParameter(); } return logEventReporter; } public static void ChangeEnabledEventNames(string reporterName, params string[] eventNames) { if (logEventReporter == null) { logEventReporter = new LogEventReporter(); } var reporter = logEventReporter.eventReporters.FirstOrDefault(er => er.Name == reporterName); if (reporter == null) { return; } reporter.ChangeEnabledEventNames(eventNames); } public static void AddCommonEventParameter(string parameterName, string value) { if (logEventReporter == null) { logEventReporter = new LogEventReporter(); } if (logEventReporter.commonEventParameter.ContainsKey(parameterName)) { logEventReporter.commonEventParameter.Remove(parameterName); } logEventReporter.commonEventParameter.Add(parameterName, value); foreach (var eventReporter in logEventReporter.eventReporters) { eventReporter.AddCommonEventParameter(parameterName, value); } foreach(var pendingEvent in pendingEvents) { if (!pendingEvent.EventParameters.ContainsKey(parameterName)) { pendingEvent.EventParameters[parameterName] = value; } } } public static void EnableAbGroup(List groups, List eventNames) { if (logEventReporter == null) { logEventReporter = new LogEventReporter(); } foreach (var abGroup in groups) { var old = logEventReporter.abGroups.FirstOrDefault(ab => ab.Name == abGroup.Name); if (old != null) { logEventReporter.abGroups.Remove(old); } logEventReporter.abGroups.Add(abGroup); } foreach (var eventName in eventNames) { if (!logEventReporter.abGroupEventNames.Contains(eventName)) { logEventReporter.abGroupEventNames.Add(eventName); } } } public static void AddParameterIntercept(ILogEventParameterIntercept parameterIntercept) { if (logEventReporter == null) { logEventReporter = new LogEventReporter(); } if (parameterIntercept == null) { return; } var oldIntercept = logEventReporter.parameterIntercepts.FirstOrDefault(i => i.Name == parameterIntercept.Name); if (oldIntercept != null) { logEventReporter.parameterIntercepts.Remove(oldIntercept); } logEventReporter.parameterIntercepts.Add(parameterIntercept); } public static void AddIntercept(ILogEventIntercept intercept) { if (logEventReporter == null) { logEventReporter = new LogEventReporter(); } if (intercept == null) { return; } var oldIntercept = logEventReporter.intercepts.FirstOrDefault(i => i.Name == intercept.Name); if (oldIntercept != null) { logEventReporter.intercepts.Remove(oldIntercept); } logEventReporter.intercepts.Add(intercept); } public static void AddEventReporter(ILogEventReporter eventReporter, List eventNames = null, Dictionary eventNameMap = null, Dictionary eventParameterNameMap = null) { if (eventReporter == null) { return; } if (logEventReporter == null) { logEventReporter = new LogEventReporter(); } logEventReporter.Logger.LogInformation($"Add event reporter, Name:{eventReporter.Name}."); var old = logEventReporter.eventReporters.FirstOrDefault(e => e.Name == eventReporter.Name); if (old != null) { return; } if (eventNameMap == null) { eventNameMap = new Dictionary(); } if (eventParameterNameMap == null) { eventParameterNameMap = new Dictionary(); } eventReporter.Initialize(eventNames, eventNameMap, eventParameterNameMap); foreach (var eventParameter in logEventReporter.commonEventParameter) { eventReporter.AddCommonEventParameter(eventParameter.Key, eventParameter.Value); } logEventReporter.eventReporters.Add(eventReporter); foreach (var pendingEvent in pendingEvents) { logEventReporter.Logger.LogInformation($"Send pending event:{pendingEvent.EventName} to {eventReporter.Name}"); eventReporter.LogEvent(pendingEvent.EventName, pendingEvent.EventParameters); } } public static void ChangeEventNameMap(string reporterName, Dictionary eventNameMap) { if (logEventReporter == null) { logEventReporter = new LogEventReporter(); } var reporter = logEventReporter.eventReporters.FirstOrDefault(er => er.Name == reporterName); if (reporter == null) { return; } reporter.ChangeEventNameMap(eventNameMap); } public static void ChangeEventParameterNameMap(string reporterName, Dictionary eventParameterNameMap) { if (logEventReporter == null) { logEventReporter = new LogEventReporter(); } var reporter = logEventReporter.eventReporters.FirstOrDefault(er => er.Name == reporterName); if (reporter == null) { return; } reporter.ChangeEventParameterNameMap(eventParameterNameMap); } public static async Task LogEvent(string name, Dictionary eventParameters) { if (eventParameters == null) { eventParameters = new Dictionary(); } var clonedEventParameters = new Dictionary(eventParameters); var orderedParameterIntercepts = logEventReporter.parameterIntercepts.OrderBy(i => i.Order); foreach (var parameterIntercept in orderedParameterIntercepts) { var parameters = await parameterIntercept.Execute(name, eventParameters); foreach (var parameter in parameters) { if (clonedEventParameters.ContainsKey(parameter.Key)) { clonedEventParameters[parameter.Key] = parameter.Value; } else { clonedEventParameters.Add(parameter.Key, parameter.Value); } } } if (pendingEvents.Count <= 100) { pendingEvents.Add(new PendingEvent(name, clonedEventParameters)); } if (logEventReporter == null) { //Debug.LogError($"{LogTag}Please invoke LogEventReporter.Initialize first"); return; } logEventReporter.Logger.LogInformation($"Log event: {name}"); Dictionary> events = new Dictionary> { { name, clonedEventParameters } }; var orderedIntercepts = logEventReporter.intercepts.OrderBy(i => i.Order); foreach (var intercept in orderedIntercepts) { var cloneEvents = new Dictionary>(events); foreach (var @event in cloneEvents) { var interceptEvents = await intercept.Execute(@event.Key, @event.Value); foreach (var interceptEvent in interceptEvents) { if (!events.ContainsKey(interceptEvent.Key)) { events.Add(interceptEvent.Key, interceptEvent.Value); } else { var @eventParameter = events[interceptEvent.Key]; foreach (var parameter in interceptEvent.Value) { if (@eventParameter.ContainsKey(parameter.Key)) { continue; } @eventParameter.Add(parameter.Key, parameter.Value); } } } } } foreach (var eventReporter in logEventReporter.eventReporters) { foreach (var @event in events) { try { await eventReporter.LogEvent(@event.Key, @event.Value); } catch (Exception ex) { logEventReporter.Logger.LogError(ex.Message); } } } } } public class PendingEvent { public PendingEvent(string eventName, Dictionary eventParameters) { EventName = eventName; EventParameters = eventParameters; } public string EventName { get; set; } public Dictionary EventParameters { get; set; } } }