public static string ParseEffectiveUsername(this QueryBeginEvent beginEvent) { XmlDocument xd = new XmlDocument(); xd.LoadXml(beginEvent.RequestProperties); XmlNamespaceManager nsmgr = new XmlNamespaceManager(xd.NameTable); nsmgr.AddNamespace("x", xd.DocumentElement.NamespaceURI); var effNode = xd.SelectSingleNode("x:PropertyList/x:EffectiveUserName", nsmgr); var effName = effNode?.InnerText ?? string.Empty; return(effName); }
public void ParsePropertiesWithoutEffectiveUserTest() { var props = @"<PropertyList xmlns=""urn:schemas-microsoft-com:xml-analysis""> <Catalog>Adventure Works</Catalog> <LocaleIdentifier>1033</LocaleIdentifier> <Format>Tabular</Format> <Content>SchemaData</Content> <Timeout>0</Timeout> <ReturnCellProperties>true</ReturnCellProperties> <DbpropMsmdFlattened2>true</DbpropMsmdFlattened2> <DbpropMsmdActivityID>8ac8460e-281b-4d4e-ba2a-23e3ace266da</DbpropMsmdActivityID> <DbpropMsmdCurrentActivityID>8ac8460e-281b-4d4e-ba2a-23e3ace266da</DbpropMsmdCurrentActivityID> <DbpropMsmdRequestID>1c71dde3-34e5-42f9-b1eb-ed951d6a3041</DbpropMsmdRequestID> </PropertyList>"; QueryBeginEvent beginEvent = new QueryBeginEvent(); beginEvent.RequestProperties = props; var effUser = beginEvent.ParseEffectiveUsername(); Assert.AreEqual("", effUser); }
// This method is called after the WaitForEvent is seen (usually the QueryEnd event) // This is where you can do any processing of the events before displaying them to the UI protected override void ProcessResults() { //if (IsPaused) return; // exit here if we are paused if (Events != null) { foreach (var traceEvent in Events) { var newEvent = new QueryEvent() { QueryType = traceEvent.EventSubclassName.Substring(0, 3).ToUpper(), StartTime = traceEvent.StartTime, Username = traceEvent.NTUserName, Query = traceEvent.TextData, Duration = traceEvent.Duration, DatabaseName = traceEvent.DatabaseFriendlyName, RequestID = traceEvent.RequestID, RequestParameters = traceEvent.RequestParameters, RequestProperties = traceEvent.RequestProperties }; switch (traceEvent.EventClass) { case DaxStudioTraceEventClass.QueryEnd: // if this is the blank query after a "clear cache and run" then skip it if (newEvent.Query == Constants.RefreshSessionQuery) { continue; } // look for any cached rewrite events if (traceEvent.RequestID != null && _rewriteEventCache.ContainsKey(traceEvent.RequestID)) { var summary = _rewriteEventCache[traceEvent.RequestID]; newEvent.AggregationMatchCount = summary.MatchCount; newEvent.AggregationMissCount = summary.MissCount; _rewriteEventCache.Remove(traceEvent.RequestID); } // TODO - update newEvent with queryBegin QueryBeginEvent beginEvent = null; _queryBeginCache.TryGetValue(traceEvent.RequestID ?? "", out beginEvent); if (beginEvent != null) { // Add the parameters XML after the query text if (beginEvent.RequestParameters != null) { newEvent.Query += Environment.NewLine + Environment.NewLine + beginEvent.RequestParameters + Environment.NewLine; } // overwrite the username with the effective user if it's present var effectiveUser = beginEvent.ParseEffectiveUsername(); if (!string.IsNullOrEmpty(effectiveUser)) { newEvent.Username = effectiveUser; } _queryBeginCache.Remove(traceEvent.RequestID); } QueryEvents.Insert(0, newEvent); break; case DaxStudioTraceEventClass.AggregateTableRewriteQuery: // cache rewrite events var rewriteSummary = new AggregateRewriteSummary(traceEvent.RequestID, traceEvent.TextData); if (_rewriteEventCache.ContainsKey(traceEvent.RequestID)) { var summary = _rewriteEventCache[key : traceEvent.RequestID]; summary.MatchCount += rewriteSummary.MatchCount; summary.MissCount += rewriteSummary.MissCount; _rewriteEventCache[key : traceEvent.RequestID] = summary; } else { _rewriteEventCache.Add(traceEvent.RequestID, rewriteSummary); } break; case DaxStudioTraceEventClass.QueryBegin: // if the requestID is null we are running against PowerPivot which does // not seem to expose the RequestID property if (traceEvent.RequestID == null) { break; } // cache rewrite events if (_queryBeginCache.ContainsKey(traceEvent.RequestID)) { // TODO - this should not happen // we should not get 2 begin events for the same request } else { var newBeginEvent = new QueryBeginEvent() { RequestID = traceEvent.RequestID, Query = traceEvent.TextData, RequestProperties = traceEvent.RequestProperties, RequestParameters = traceEvent.RequestParameters }; _queryBeginCache.Add(traceEvent.RequestID, newBeginEvent); } break; } } Events.Clear(); // Clear out any cached rewrite events older than 10 minutes var toRemoveFromCache = _rewriteEventCache.Where((kvp) => kvp.Value.UtcCurrentTime > DateTime.UtcNow.AddMinutes(10)).Select(c => c.Key).ToList(); foreach (var requestId in toRemoveFromCache) { _rewriteEventCache.Remove(requestId); } NotifyOfPropertyChange(() => QueryEvents); NotifyOfPropertyChange(() => CanClearAll); NotifyOfPropertyChange(() => CanCopyAll); NotifyOfPropertyChange(() => CanExport); } }