forked from ServiceStack/ServiceStack.Text
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathCustomTiming.cs
More file actions
127 lines (107 loc) · 4.73 KB
/
Copy pathCustomTiming.cs
File metadata and controls
127 lines (107 loc) · 4.73 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
using System;
using System.Runtime.Serialization;
namespace StackExchange.Profiling
{
/// <summary>
/// A custom timing that usually represents a Remote Procedure Call, allowing better
/// visibility into these longer-running calls.
/// </summary>
[DataContract]
public class CustomTiming : IDisposable
{
private readonly decimal? _minSaveMs;
/// <summary>
/// Don't use this.
/// </summary>
[Obsolete("Used for serialization")]
public CustomTiming() { /* serialization only */ }
/// <summary>
/// Returns a new CustomTiming, also initializing its <see cref="Id"/> and, optionally, its <see cref="StackTraceSnippet"/>.
/// </summary>
/// <param name="profiler">The <see cref="MiniProfiler"/> to attach the timing so.</param>
/// <param name="commandString">The descriptive command string for this timing, e.g. a URL or database command.</param>
/// <param name="minSaveMs">(Optional) The minimum time required to actually save this timing (e.g. do we care?).</param>
public CustomTiming(MiniProfiler profiler, string commandString, decimal? minSaveMs = null)
{
_profiler = profiler;
_startTicks = profiler.ElapsedTicks;
_minSaveMs = minSaveMs;
CommandString = commandString;
Id = Guid.NewGuid();
StartMilliseconds = profiler.GetRoundedMilliseconds(profiler.ElapsedTicks);
if (true/*!MiniProfiler.Settings.ExcludeStackTraceSnippetFromCustomTimings*/)
{
StackTraceSnippet = Helpers.StackTraceSnippet.Get();
}
}
private readonly MiniProfiler _profiler;
private readonly long _startTicks;
/// <summary>
/// Unique identifier for this <see cref="CustomTiming"/>.
/// </summary>
[DataMember(Order = 1)]
public Guid Id { get; set; }
/// <summary>
/// Gets or sets the command that was executed, e.g. "select * from Table" or "INCR my:redis:key"
/// </summary>
[DataMember(Order = 2)]
public string CommandString { get; set; }
// TODO: should this just match the key that the List<CustomTiming> is stored under in Timing.CustomTimings?
/// <summary>
/// Short name describing what kind of custom timing this is, e.g. "Get", "Query", "Fetch".
/// </summary>
[DataMember(Order = 3)]
public string ExecuteType { get; set; }
/// <summary>
/// Gets or sets roughly where in the calling code that this custom timing was executed.
/// </summary>
[DataMember(Order = 4)]
public string StackTraceSnippet { get; set; }
/// <summary>
/// Gets or sets the offset from main <c>MiniProfiler</c> start that this custom command began.
/// </summary>
[DataMember(Order = 5)]
public decimal StartMilliseconds { get; set; }
/// <summary>
/// Gets or sets how long this custom command statement took to execute.
/// </summary>
[DataMember(Order = 6)]
public decimal? DurationMilliseconds { get; set; }
/// <summary>
/// OPTIONAL - how long this tim took to come back initially from the remote server,
/// before all data is fetched and command is completed.
/// </summary>
[DataMember(Order = 7)]
public decimal? FirstFetchDurationMilliseconds { get; set; }
/// <summary>
/// Whether this operation errored.
/// </summary>
[DataMember(Order = 8)]
public bool Errored { get; set; }
internal string Category { get; set; }
/// <summary>
/// OPTIONAL - call after receiving the first response from your Remote Procedure Call to
/// properly set <see cref="FirstFetchDurationMilliseconds"/>.
/// </summary>
public void FirstFetchCompleted()
{
FirstFetchDurationMilliseconds = FirstFetchDurationMilliseconds ?? _profiler.GetDurationMilliseconds(_startTicks);
}
/// <summary>
/// Stops this timing, setting <see cref="DurationMilliseconds"/>.
/// </summary>
public void Stop()
{
DurationMilliseconds = DurationMilliseconds ?? _profiler.GetDurationMilliseconds(_startTicks);
if (_minSaveMs.HasValue && _minSaveMs.Value > 0 && DurationMilliseconds < _minSaveMs.Value)
{
_profiler.Head.RemoveCustomTiming(Category, this);
}
}
void IDisposable.Dispose() => Stop();
/// <summary>
/// Returns <see cref="CommandString"/> for debugging.
/// </summary>
public override string ToString() => CommandString;
}
}