private IDisposable WriteStartElement(string title, IDictionary <string, string> attribs) { try { var info = new TraceInfo(title, attribs); var ensureMaxXmlFiles = false; if (String.IsNullOrEmpty(_file)) { ensureMaxXmlFiles = true; // generate trace file name base on attribs _file = GenerateFileName(info); } var strb = new StringBuilder(); if (_isStartElement) { strb.AppendLine(">"); } strb.Append(new String(' ', _infos.Count * 2)); strb.AppendFormat("<step title=\"{0}\" ", XmlUtility.EscapeXmlText(title)); strb.AppendFormat("date=\"{0}\" ", info.StartTime.ToString("yyyy-MM-ddTHH:mm:ss.fff")); if (_infos.Count == 0) { strb.AppendFormat("instance=\"{0}\" ", InstanceIdUtility.GetShortInstanceId()); } foreach (var attrib in attribs) { if (TraceExtensions.IsNonDisplayableAttribute(attrib.Key)) { continue; } strb.AppendFormat("{0}=\"{1}\" ", attrib.Key, XmlUtility.EscapeXmlText(attrib.Value)); } FileSystemHelpers.AppendAllTextToFile(_file, strb.ToString()); _infos.Push(info); _isStartElement = true; if (ensureMaxXmlFiles) { EnsureMaxXmlFiles(); } return(new DisposableAction(() => WriteEndTrace())); } catch (Exception ex) { WriteUnexpectedException(ex); } return(DisposableAction.Noop); }
private IDisposable WriteStartElement(string title, IDictionary<string, string> attribs) { try { var info = new TraceInfo(title, attribs); var ensureMaxXmlFiles = false; if (String.IsNullOrEmpty(_file)) { ensureMaxXmlFiles = true; // generate trace file name base on attribs _file = GenerateFileName(info); } var strb = new StringBuilder(); if (_isStartElement) { strb.AppendLine(">"); } strb.Append(new String(' ', _infos.Count * 2)); strb.AppendFormat("<step title=\"{0}\" ", XmlUtility.EscapeXmlText(title)); strb.AppendFormat("date=\"{0}\" ", info.StartTime.ToString("yyyy-MM-ddTHH:mm:ss.fff")); if (_infos.Count == 0) { strb.AppendFormat("instance=\"{0}\" ", InstanceIdUtility.GetShortInstanceId()); } foreach (var attrib in attribs) { if (TraceExtensions.IsNonDisplayableAttribute(attrib.Key)) { continue; } strb.AppendFormat("{0}=\"{1}\" ", attrib.Key, XmlUtility.EscapeXmlText(attrib.Value)); } FileSystemHelpers.AppendAllTextToFile(_file, strb.ToString()); _infos.Push(info); _isStartElement = true; if (ensureMaxXmlFiles) { EnsureMaxXmlFiles(); } return new DisposableAction(() => WriteEndTrace()); } catch (Exception ex) { WriteUnexpectedException(ex); } return DisposableAction.Noop; }
public static bool ShouldTrace(TraceLevel level, TraceInfo info, int statusCode) { // if SCM_TRACE_LEVEL is set to 4 (verbose), always trace. if (level >= TraceLevel.Verbose) { return(true); } // for api taking long time (>10s), always trace. if (DateTime.UtcNow - info.StartTime >= ElapsedThreshold) { return(true); } string type; string method; string path; if (!info.Attributes.TryGetValue("type", out type) || !info.Attributes.TryGetValue("method", out method) || !info.Attributes.TryGetValue("url", out path)) { return(true); } // trace non get request if (!String.Equals("request", type, StringComparison.OrdinalIgnoreCase) || !String.Equals("GET", method, StringComparison.OrdinalIgnoreCase)) { return(true); } // NotModified if (statusCode == 304) { return(false); } // non OK if (statusCode != 200) { return(true); } // filter out those that may be polled by portal. // remove query string path = path.Split('?')[0].TrimEnd('/'); return(!TraceFilters.Any(filter => String.Equals(filter, path, StringComparison.OrdinalIgnoreCase))); }
// such as <datetime>_<instance>_<salt>_get_<url>_<statusCode>.xml // sample: 2014-11-17T04-59-21_d10e51_366_GET_api-deployments_200.xml private string GenerateFileName(TraceInfo info) { var strb = new StringBuilder(); // add salt to avoid collision // mathematically improbable for salt to overflow strb.AppendFormat("{0}_{1}_{2:000}", info.StartTime.ToString("yyyy-MM-ddTHH-mm-ss"), InstanceIdUtility.GetShortInstanceId(), Interlocked.Increment(ref _salt) % 1000); if (info.Title == XmlTracer.IncomingRequestTrace) { var path = info.Attributes["url"].Split('?')[0].Trim('/'); strb.AppendFormat("_{0}_{1}", info.Attributes["method"], path.ToSafeFileName()); } else if (info.Title == XmlTracer.StartupRequestTrace) { var path = info.Attributes["url"].Split('?')[0].Trim('/'); strb.AppendFormat("_Startup_{0}_{1}", info.Attributes["method"], path.ToSafeFileName()); } else if (info.Title == XmlTracer.ProcessShutdownTrace) { strb.Append("_Shutdown"); } else if (info.Title == XmlTracer.ExecutingExternalProcessTrace) { var path = info.Attributes["path"].Split('\\').Last(); strb.AppendFormat("_{0}", path); } else if (string.Equals(XmlTracer.BackgroundTrace, info.Title, StringComparison.Ordinal)) { var path = info.Attributes["url"].Split('?')[0].Trim('/'); strb.AppendFormat("_Background_{0}_{1}", info.Attributes["method"], path.ToSafeFileName()); } else if (!String.IsNullOrEmpty(info.Title)) { strb.AppendFormat("_{0}", info.Title.ToSafeFileName()); } strb.Append(PendingXml); return(Path.Combine(_path, strb.ToString())); }
// such as <datetime>_<instance>_<salt>_get_<url>_<statusCode>.xml // sample: 2014-11-17T04-59-21_d10e51_366_GET_api-deployments_200.xml private string GenerateFileName(TraceInfo info) { var strb = new StringBuilder(); // add salt to avoid collision // mathematically improbable for salt to overflow strb.AppendFormat("{0}_{1}_{2:000}", info.StartTime.ToString("yyyy-MM-ddTHH-mm-ss"), InstanceIdUtility.GetShortInstanceId(), Interlocked.Increment(ref _salt) % 1000); if (info.Title == XmlTracer.IncomingRequestTrace) { var path = info.Attributes["url"].Split('?')[0].Trim('/'); strb.AppendFormat("_{0}_{1}", info.Attributes["method"], path.ToSafeFileName()); } else if (info.Title == XmlTracer.StartupRequestTrace) { var path = info.Attributes["url"].Split('?')[0].Trim('/'); strb.AppendFormat("_Startup_{0}_{1}", info.Attributes["method"], path.ToSafeFileName()); } else if (info.Title == XmlTracer.ProcessShutdownTrace) { strb.Append("_Shutdown"); } else if (info.Title == XmlTracer.ExecutingExternalProcessTrace) { var path = info.Attributes["path"].Split('\\').Last(); strb.AppendFormat("_{0}", path); } else if (string.Equals(XmlTracer.BackgroundTrace, info.Title, StringComparison.Ordinal)) { var path = info.Attributes["url"].Split('?')[0].Trim('/'); strb.AppendFormat("_Background_{0}_{1}", info.Attributes["method"], path.ToSafeFileName()); } else if (!String.IsNullOrEmpty(info.Title)) { strb.AppendFormat("_{0}", info.Title.ToSafeFileName()); } strb.Append(PendingXml); return Path.Combine(_path, strb.ToString()); }
public static bool ShouldTrace(TraceLevel level, TraceInfo info, int statusCode) { // if SCM_TRACE_LEVEL is set to 4 (verbose), always trace. if (level >= TraceLevel.Verbose) { return true; } // for api taking long time (>10s), always trace. if (DateTime.UtcNow - info.StartTime >= ElapsedThreshold) { return true; } string type; string method; string path; if (!info.Attributes.TryGetValue("type", out type) || !info.Attributes.TryGetValue("method", out method) || !info.Attributes.TryGetValue("url", out path)) { return true; } // trace non get request if (!String.Equals("request", type, StringComparison.OrdinalIgnoreCase) || !String.Equals("GET", method, StringComparison.OrdinalIgnoreCase)) { return true; } // NotModified if (statusCode == 304) { return false; } // non OK if (statusCode != 200) { return true; } // filter out those that may be polled by portal. // remove query string path = path.Split('?')[0].TrimEnd('/'); return !TraceFilters.Any(filter => String.Equals(filter, path, StringComparison.OrdinalIgnoreCase)); }