private static IEnumerable<Metric> GetDetailedMerics(XPathNavigator navigator, SiteConfigurationElement site) { var metrics = new List<Metric>(); //Get the test id var node = navigator.SelectSingleNode("response/data/testId"); if (node == null) return metrics; string testId = node.Value; //Get the test url node = navigator.SelectSingleNode("response/data/testUrl"); if (node == null) return metrics; string testUrl = node.Value.Replace("http://", ""); //Get the run date node = navigator.SelectSingleNode("response/data/run//date"); if (node == null) return metrics; string dateTime = node.Value; var timeStamp = EpochToDateTime(dateTime, siteSection.AssumeLocalTimeZone); var request = WebRequest.Create(String.Format(CultureInfo.InvariantCulture, "{0}/result/{1}/{1}_{2}_requests.csv", siteSection.WebPagetestHost, testId, HttpUtility.UrlEncode(testUrl))); request.Timeout = 5000; var response = (HttpWebResponse)request.GetResponse(); var stream = response.GetResponseStream(); try { if (stream == null) { return metrics; } using (var reader = new CsvReader(new StreamReader(stream))) { stream = null; foreach (var row in reader.GetRecords<DetailedWebpagetestRow>()) { if (String.IsNullOrEmpty(row.Host)) { continue; } //Extract the host to group by string host = GetSubDomain("http://" + row.Host); if (host == null) { host = row.Host; } host = host.Replace(".", "_"); //Get the run type string runType = "firstView"; if (row.EventName.StartsWith("Cached")) { runType = "repeatView"; } //TTFB - By Host metrics.Add(new Metric { Key = String.Format(CultureInfo.InvariantCulture, "{0}.{1}.byHost.{2}.ttfb", site.GraphiteKey, runType, host), Timestamp = timeStamp, Value = row.TimeToFirstByte }); //TTFB - By MIME Type if (!String.IsNullOrEmpty(row.ContentType)) { metrics.Add(new Metric { Key = String.Format(CultureInfo.InvariantCulture, "{0}.{1}.byType.{2}.ttfb", site.GraphiteKey, runType, row.ContentType), Timestamp = timeStamp, Value = row.TimeToFirstByte }); } //TTL - By Host metrics.Add(new Metric { Key = String.Format(CultureInfo.InvariantCulture, "{0}.{1}.byHost.{2}.ttl", site.GraphiteKey, runType, host), Timestamp = timeStamp, Value = row.TimeToLoad }); //TTL - By MIME Type if (!String.IsNullOrEmpty(row.ContentType)) { metrics.Add(new Metric { Key = String.Format(CultureInfo.InvariantCulture, "{0}.{1}.byType.{2}.ttl", site.GraphiteKey, runType, row.ContentType), Timestamp = timeStamp, Value = row.TimeToLoad }); } //Total bytes - By Host metrics.Add(new Metric { Key = String.Format(CultureInfo.InvariantCulture, "{0}.{1}.byHost.{2}.bytes.count", site.GraphiteKey, runType, host), Timestamp = timeStamp, Value = row.Bytes }); //Total bytes - By MIME Type if (!String.IsNullOrEmpty(row.ContentType)) { metrics.Add(new Metric { Key = String.Format(CultureInfo.InvariantCulture, "{0}.{1}.byType.{2}.bytes.count", site.GraphiteKey, runType, row.ContentType), Timestamp = timeStamp, Value = row.Bytes }); } //Avg bytes - By Host metrics.Add(new Metric { Key = String.Format(CultureInfo.InvariantCulture, "{0}.{1}.byHost.{2}.bytes.avg", site.GraphiteKey, runType, host), Timestamp = timeStamp, Value = row.Bytes }); //Avg bytes - By MIME Type if (!String.IsNullOrEmpty(row.ContentType)) { metrics.Add(new Metric { Key = String.Format(CultureInfo.InvariantCulture, "{0}.{1}.byType.{2}.bytes.avg", site.GraphiteKey, runType, row.ContentType), Timestamp = timeStamp, Value = row.Bytes }); } } } } finally { if (stream != null) { stream.Dispose(); } } return metrics; }
private IEnumerable<Metric> XmlToMetrics(SiteConfigurationElement site, IXPathNavigable result) { var metrics = new List<Metric>(); if (result == null) throw new ArgumentNullException("result", "WebPagetest result was null"); var navigator = result.CreateNavigator(); //Check test is completed var code = navigator.SelectSingleNode("response/statusCode"); if (code.Value == "200") { foreach (XPathNavigator runNavigator in navigator.Select("response/data/run")) { var idNode = runNavigator.SelectSingleNode("id"); if (idNode == null) continue; var run = site.AllowMultipleRuns ? "." + idNode.Value : String.Empty; //firstView DoView(runNavigator, "firstView", site, run, metrics, keysToKeep); //repeatView DoView(runNavigator, "repeatView", site, run, metrics, keysToKeep); if (!site.AllowMultipleRuns) break; } if (site.DetailedMetrics) { metrics.AddRange(GetDetailedMerics(navigator, site)); } } return metrics; }
private static void DoView(XPathNavigator runNavigator, string view, SiteConfigurationElement site, string run, ICollection<Metric> metrics, ICollection<string> keysToKeep) { var viewNavigator = runNavigator.SelectSingleNode(view + "/results"); if (viewNavigator != null) { var node = viewNavigator.SelectSingleNode("date"); if (node == null) return; string dateTime = node.Value; var timeStamp = EpochToDateTime(dateTime, siteSection.AssumeLocalTimeZone); foreach (XPathNavigator metric in viewNavigator.SelectChildren(XPathNodeType.Element)) { if ((keysToKeep != null) && (!keysToKeep.Contains(metric.Name))) { continue; } int numericValue; if (Int32.TryParse(metric.Value, out numericValue)) { metrics.Add(new Metric { Key = String.Format(CultureInfo.InvariantCulture, "{0}.{1}{2}.{3}", site.GraphiteKey, view, run, metric.Name), Timestamp = timeStamp, Value = numericValue }); } } } }