/// <summary> /// Starts a new MiniProfiler and associates it with the current <see cref="HttpContext.Current"/>. /// </summary> public override Profiler Start(ProfileLevel level) { var context = HttpContext.Current; if (context == null) return null; var url = context.Request.Url; var path = context.Request.AppRelativeCurrentExecutionFilePath.Substring(1); // don't profile /content or /scripts, either - happens in web.dev foreach (var ignored in Profiler.Settings.IgnoredPaths ?? new string[0]) { if (path.ToUpperInvariant().Contains((ignored ?? "").ToUpperInvariant())) return null; } var result = new Profiler(url.OriginalString, level); Current = result; SetProfilerActive(result); // don't really want to pass in the context to MiniProfler's constructor or access it statically in there, either result.User = (Settings.UserProvider ?? new IpAddressIdentity()).GetUser(context.Request); return result; }
/// <summary> /// Sets <paramref name="profiler"/> to be active (read to start profiling) /// This should be called once a new MiniProfiler has been created. /// </summary> /// <param name="profiler">The profiler to set to active</param> /// <exception cref="ArgumentNullException">If <paramref name="profiler"/> is null</exception> protected static void SetProfilerActive(Profiler profiler) { if (profiler == null) throw new ArgumentNullException("profiler"); profiler.IsActive = true; }
/// <summary> /// Stops the profiler and marks it as inactive. /// </summary> /// <param name="profiler">The profiler to stop</param> /// <returns>True if successful, false if Stop had previously been called on this profiler</returns> /// <exception cref="ArgumentNullException">If <paramref name="profiler"/> is null</exception> protected static bool StopProfiler(Profiler profiler) { if (profiler == null) throw new ArgumentNullException("profiler"); if (!profiler.StopImpl()) return false; profiler.IsActive = false; return true; }
/// <summary> /// Creates a new Timing named 'name' in the 'profiler's session, with 'parent' as this Timing's immediate ancestor. /// </summary> public Timing(Profiler profiler, Timing parent, string name) { this.Id = Guid.NewGuid(); Profiler = profiler; Profiler.Head = this; if (parent != null) // root will have no parent { parent.AddChild(this); } Name = name; _startTicks = profiler.ElapsedTicks; StartMilliseconds = profiler.GetRoundedMilliseconds(_startTicks); }
/// <summary> /// Creates a new SqlTiming to profile 'command'. /// </summary> public SqlTiming(DbCommand command, ExecuteType type, Profiler profiler) { Id = Guid.NewGuid(); CommandString = AddSpacesToParameters(command.CommandText); Parameters = GetCommandParameters(command); ExecuteType = type; if (!Profiler.Settings.ExcludeStackTraceSnippetFromSqlTimings) StackTraceSnippet = ServiceStack.MiniProfiler.Helpers.StackTraceSnippet.Get(); _profiler = profiler; if (_profiler != null) { _profiler.AddSqlTiming(this); _startTicks = _profiler.ElapsedTicks; StartMilliseconds = _profiler.GetRoundedMilliseconds(_startTicks); } }
/// <summary> /// Calls <see cref="Profiler.Settings.EnsureStorageStrategy"/> to save the current /// profiler using the current storage settings /// </summary> /// <param name="current"></param> protected static void SaveProfiler(Profiler current) { // because we fetch profiler results after the page loads, we have to put them somewhere in the meantime Profiler.Settings.EnsureStorageStrategy(); Profiler.Settings.Storage.Save(current); }
/// <summary> /// Returns a new SqlProfiler to be used in the 'profiler' session. /// </summary> public SqlProfiler(Profiler profiler) { Profiler = profiler; }
/// <summary> /// Build full page result /// </summary> /// <param name="httpRes"></param> /// <param name="profiler"></param> /// <returns></returns> private static string ResultsFullPage(IResponse httpRes, Profiler profiler) { httpRes.ContentType = "text/html"; return new StringBuilder() .AppendLine("<html><head>") .AppendFormat("<title>{0} ({1} ms) - MvcMiniProfiler Results</title>", profiler.Name, profiler.DurationMilliseconds) .AppendLine() .AppendLine("<script type='text/javascript' src='https://ajax.googleapis.com/ajax/libs/jquery/1.6.2/jquery.min.js'></script>") .Append("<script type='text/javascript'> var profiler = ") //.Append(Profiler.ToJson(profiler)) // There is a problem, property ElapsedTicks can't be serialized .Append(SerializeProfiler(profiler)) .AppendLine(";</script>") .Append(RenderIncludes(profiler)) // figure out how to better pass display options .AppendLine("</head><body><div class='profiler-result-full'></div></body></html>") .ToString(); }
/// <summary> /// Profiler JSON serialization. It's better to use exclusion filter than inclusion, this implementation was just for testing purpose. /// </summary> /// <param name="profiler"></param> /// <returns></returns> private static string SerializeProfiler(Profiler profiler) { var jss = new JsonSerializerSettings(); jss.ContractResolver = new DynamicContractResolver(new List<string>() { "Id", "Name", "Started", "MachineName", "Level", "Root", "User", "HasUserViewed", "DurationMilliseconds", "HasTrivialTimings", "HasAllTrivialTimings", "TrivialDurationThresholdMilliseconds", "StartMilliseconds", "Children", "KeyValues", "SqlTimings", "ParentTimingId", "ExecuteType", "CommandString", "FormattedCommandString", "StackTraceSnippet", "FirstFetchDurationMilliseconds", "Parameters", "IsDuplicate", "DurationMillisecondsInSql", "ExecutedNonQueries", "ExecutedReaders", "ExecutedScalars", "HasDuplicateSqlTimings", "HasSqlTimings", "Depth", "DurationMilliseconds", "DurationWithoutChildrenMilliseconds", "HasChildren", "IsRoot", "IsTrivial", "KeyValues", "SqlTimingsDurationMilliseconds", //"ElapsedTicks" }); return JsonConvert.SerializeObject(profiler, jss); }
/// <summary> /// Starts a new MiniProfiler and associates it with the current <see cref="HttpContext.Current"/>. /// </summary> public override Profiler Start(ProfileLevel level) { if (Request == null) return null; var path = Request.RawUrl; // don't profile /content or /scripts, either - happens in web.dev foreach (var ignored in Profiler.Settings.IgnoredPaths ?? new string[0]) { if (path.ToUpperInvariant().Contains((ignored ?? "").ToUpperInvariant())) return null; } var result = new Profiler(Request.Url.ToString(), level); Current = result; SetProfilerActive(result); // I'm not managing user yet result.User = RemoteIp; return result; }
/// <summary> /// Makes sure 'profiler' has a Name, pulling it from route data or url. Add verb for rest api profiling /// </summary> private static void EnsureName(Profiler profiler, HttpListenerRequest request) { // also set the profiler name to Controller/Action or /url if (string.IsNullOrWhiteSpace(profiler.Name)) { profiler.Name = string.Format("{0} {1}", request.HttpMethod, request.RawUrl); if (profiler.Name.Length > 70) profiler.Name = profiler.Name.Remove(70); } }
/// <summary> /// Makes sure 'profiler' has a Name, pulling it from route data or url. /// </summary> private static void EnsureName(Profiler profiler, HttpRequest request) { // also set the profiler name to Controller/Action or /url if (profiler.Name.IsNullOrWhiteSpace()) { //var rc = request.RequestContext; //RouteValueDictionary values; //if (rc != null && rc.RouteData != null && (values = rc.RouteData.Values).Count > 0) //{ // var controller = values["Controller"]; // var action = values["Action"]; // if (controller != null && action != null) // profiler.Name = controller.ToString() + "/" + action.ToString(); //} if (profiler.Name.IsNullOrWhiteSpace()) { profiler.Name = request.Path ?? ""; if (profiler.Name.Length > 70) profiler.Name = profiler.Name.Remove(70); } } }