private static void AggregateSum(string basePropertyName, ActionPropertyBag targetAction, ConcurrentDictionary <string, long> childMap) { string fullPropertyname = basePropertyName + ActionPropertyNames.SumConstStrSuffix; if (ShouldAggregateProperty <long>(fullPropertyname, childMap, out long childValue)) { targetAction.Sum(fullPropertyname, childValue); } }
private static void AggregateMin(string basePropertyName, ActionPropertyBag targetAction, ConcurrentDictionary <string, int> childMap) { string fullPropertyname = basePropertyName + ActionPropertyNames.MinConstStrSuffix; if (ShouldAggregateProperty <int>(fullPropertyname, childMap, out int childValue)) { targetAction.Min(fullPropertyname, childValue); } }
private void SetScopesProperty(ActionPropertyBag propertyBag, IEnumerable <string> scopes) { // TODO(mats): how is this supposed to work? Should we get multiple properties somehow, one per scope? or do we send up all scopes in a space-delimited string (will make querying hard on the backend) foreach (string scope in scopes) { if (_telemetryAllowedScopes.Contains(scope)) { propertyBag.Add(ActionPropertyNames.ScopeConstStrKey, scope); } else if (!string.IsNullOrEmpty(scope)) { propertyBag.Add(ActionPropertyNames.ScopeConstStrKey, "ScopeRedacted"); } } }
private void EndGenericAction(string actionId, string outcome, ErrorSource errorSource, string error, string errorDescription, string accountCid) { if (string.IsNullOrEmpty(actionId)) { // This is an invalid action; we do not want to upload it. _errorStore.ReportError("Tried to end an action with an empty actionId", ErrorType.Action, ErrorSeverity.Warning); return; } ActionPropertyBag propertyBag = GetActionPropertyBagFromId(actionId); if (propertyBag == null) { _errorStore.ReportError("Trying to end an action that doesn't exist or was already uploaded", ErrorType.Action, ErrorSeverity.Warning); return; } if (propertyBag.ReadyForUpload) { return; } int startingCount = 1; var endTime = DateTime.UtcNow; propertyBag.Add(ActionPropertyNames.OutcomeConstStrKey, outcome); propertyBag.Add(ActionPropertyNames.FailureSourceConstStrKey, MatsConverter.AsString(errorSource)); propertyBag.Add(ActionPropertyNames.FailureConstStrKey, error); propertyBag.Add(ActionPropertyNames.FailureDescriptionConstStrKey, errorDescription); propertyBag.Add(ActionPropertyNames.EndTimeConstStrKey, DateTimeUtils.GetMillisecondsSinceEpoch(endTime)); // propertyBag->Add(ActionPropertyNames::getAccountIdConstStrKey(), accountCid); Commenting this out for GDPR reasons; once pipeline supports this we can upload again. propertyBag.Add(ActionPropertyNames.CountConstStrKey, startingCount); PopulateDuration(propertyBag); //Check if should aggregate here var contents = propertyBag.GetContents(); if (_eventFilter.ShouldAggregateAction(contents)) { EndAggregatedAction(actionId, propertyBag); } else { propertyBag.ReadyForUpload = true; } }
/// <summary> /// Returns true if the actions are the same, either are ready for upload, and either is not aggregable. /// This is used to determine whether or not we should aggregate this particular property bag of event data. /// </summary> /// <param name="action1"></param> /// <param name="action2"></param> /// <returns></returns> public static bool IsEquivalentClass(ActionPropertyBag action1, ActionPropertyBag action2) { if (action1 == action2 || action1.ReadyForUpload || action2.ReadyForUpload || !action1.IsAggregable || !action2.IsAggregable) { return(false); } var contents1 = action1.GetContents(); var contents2 = action2.GetContents(); var v = GetComparisonStringProperties(); foreach (string s in v) { if (!IsPropertyEquivalent(s, contents1.StringProperties, contents2.StringProperties)) { return(false); } } return(true); }
public static void AggregateActions(ActionPropertyBag targetAction, ActionPropertyBag childAction) { targetAction.IncrementCount(); targetAction.Sum(ActionPropertyNames.CountConstStrKey, 1); var childContents = childAction.GetContents(); foreach (string s in GetIntAggregationProperties()) { AggregateMax(s, targetAction, childContents.IntProperties); AggregateMin(s, targetAction, childContents.IntProperties); AggregateSum(s, targetAction, childContents.IntProperties); } foreach (string s in GetInt64AggregationProperties()) { AggregateMax(s, targetAction, childContents.Int64Properties); AggregateMin(s, targetAction, childContents.Int64Properties); AggregateSum(s, targetAction, childContents.Int64Properties); } }
private void EndAggregatedAction(string actionId, ActionPropertyBag propertyBag) { lock (_lockActionIdToPropertyBag) { propertyBag.IsAggregable = true; bool shouldRemove = false; foreach (var targetPropertyBag in _actionIdToPropertyBag.Values) { if (ActionComparer.IsEquivalentClass(targetPropertyBag, propertyBag)) { ActionAggregator.AggregateActions(targetPropertyBag, propertyBag); shouldRemove = true; break; } } if (shouldRemove) { _actionIdToPropertyBag.Remove(actionId); } } }
private ActionArtifacts CreateGenericAction(MatsScenario scenario, string correlationId, ActionType actionType) { string actionId = MatsId.Create(); MatsAction action = new MatsAction(actionId, scenario, correlationId); string corrIdTrim = correlationId.TrimCurlyBraces(); var propertyBag = new ActionPropertyBag(_errorStore); var startTimePoint = DateTime.UtcNow; propertyBag.Add(ActionPropertyNames.UploadIdConstStrKey, MatsId.Create()); propertyBag.Add(ActionPropertyNames.ActionTypeConstStrKey, MatsConverter.AsString(actionType)); propertyBag.Add(ScenarioPropertyNames.IdConstStrKey, scenario?.ScenarioId); propertyBag.Add(ActionPropertyNames.CorrelationIdConstStrKey, corrIdTrim); propertyBag.Add(ActionPropertyNames.StartTimeConstStrKey, DateTimeUtils.GetMillisecondsSinceEpoch(startTimePoint)); lock (_lockActionIdToPropertyBag) { _actionIdToPropertyBag[actionId] = propertyBag; } return(new ActionArtifacts(action, propertyBag)); }
private void PopulateDuration(ActionPropertyBag propertyBag) { var contents = propertyBag.GetContents(); long startTime; long endTime; if (!contents.Int64Properties.TryGetValue(ActionPropertyNames.StartTimeConstStrKey, out startTime)) { _errorStore.ReportError("Could not retrieve start time for duration calculation.", ErrorType.Action, ErrorSeverity.LibraryError); return; } if (!contents.Int64Properties.TryGetValue(ActionPropertyNames.EndTimeConstStrKey, out endTime)) { _errorStore.ReportError("Could not retrieve end time for duration calculation.", ErrorType.Action, ErrorSeverity.LibraryError); return; } long duration = endTime - startTime; propertyBag.Add(ActionPropertyNames.DurationConstStrKey + ActionPropertyNames.SumConstStrSuffix, duration); propertyBag.Add(ActionPropertyNames.DurationConstStrKey + ActionPropertyNames.MaxConstStrSuffix, duration); propertyBag.Add(ActionPropertyNames.DurationConstStrKey + ActionPropertyNames.MinConstStrSuffix, duration); }