Created
July 25, 2012 06:23
-
-
Save rebornix/3174719 to your computer and use it in GitHub Desktop.
A Performance Trace Tool
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
using System; | |
using System.Diagnostics; | |
using System.Text; | |
namespace Common | |
{ | |
/// <summary> | |
/// This class will take down the steps in the api flow, and trace it if the latency is larger than config. | |
/// </summary> | |
public static class PerfTracer | |
{ | |
[ThreadStatic] | |
private static StringBuilder _sb; | |
[ThreadStatic] | |
private static Stopwatch _stopwatch; | |
[ThreadStatic] | |
private static bool _inited; | |
[ThreadStatic] | |
private static int _threshold; | |
private static Stopwatch GetStopwatch() | |
{ | |
if (_stopwatch == null) | |
{ | |
_stopwatch = new Stopwatch(); | |
} | |
return _stopwatch; | |
} | |
private static StringBuilder GetStringBuilder() | |
{ | |
if (_sb == null) | |
{ | |
_sb = new StringBuilder(); | |
} | |
return _sb; | |
} | |
public static void Init(int threshold) | |
{ | |
_sb = new StringBuilder(); | |
_stopwatch = Stopwatch.StartNew(); | |
_inited = true; | |
_threshold = threshold; | |
} | |
public static long GetElapsedMillisecond() | |
{ | |
if (_inited) | |
{ | |
return _stopwatch.ElapsedMilliseconds; | |
} | |
return 0; | |
} | |
public static void TraceStep(string stepMessage) | |
{ | |
//TODO: Override this function call by replacing "DateTime.UtcNow()" to whatever u need. | |
TraceStep(stepMessage, DataTime.UtcNow()); | |
} | |
public static void TraceStep(string stepMessage, DateTime dateTime) | |
{ | |
// If not inited, means it comes from the api that is not enabled with perf trace | |
// Then skip to avoid StringBuilder eating memory | |
if (_inited) | |
{ | |
stepMessage = stepMessage.Replace("\r", string.Empty).Replace("\n", string.Empty); | |
// use '|' because the new line cannot go into tako, to get a good view, replace '|' with \r\n manually | |
GetStringBuilder().Append(String.Format("{0} : {1} |", dateTime.ToString("HH:mm:ss.fff"), stepMessage)); | |
} | |
} | |
public static void Flush(string apiName, Guid trackingGuid, string partnerName) | |
{ | |
var stopwatch = GetStopwatch(); | |
stopwatch.Stop(); | |
long latency = stopwatch.ElapsedMilliseconds; | |
// if exceeds the threshold, trace as Warning, otherwise Verbose | |
// only Warning trace would go into Tako | |
TraceLevel level = latency > _threshold ? TraceLevel.Warning : TraceLevel.Verbose; | |
Trace(level, partnerName, apiName, latency, trackingGuid); | |
_inited = false; | |
} | |
private static void Trace(TraceLevel level, string partnerName, string apiName, long latency, Guid trackingGuid) | |
{ | |
var call = Tracer.StartTracing(new TracerTag("CommerceTransactionAPIPerfTracer"), level); | |
if (call != null) | |
{ | |
call.Add(new TracerField("partnername"), partnerName); | |
call.Add(new TracerField("apiname"), apiName); | |
call.Add(new TracerField("latency"), latency); | |
call.Add(new TracerField("trackingguid"), trackingGuid.ToString()); | |
call.Add(new TracerField("perfinfo"), GetStringBuilder().ToString()); | |
call.Trace(String.Format("PerfTrace with threshold = {0}, for apiName = {1}, trackingGuid = {2}.", | |
_threshold, apiName, trackingGuid.ToString())); | |
} | |
} | |
} | |
/// <summary> | |
/// Wrapper of PerfTracer, to provide 'using' pattern | |
/// </summary> | |
public class PerfTraceScope : IDisposable | |
{ | |
private string _step; | |
private long _startPoint; | |
public PerfTraceScope(string step) | |
{ | |
_step = step; | |
_startPoint = PerfTracer.GetElapsedMillisecond(); | |
PerfTracer.TraceStep(String.Format("st {0}", step)); | |
} | |
public void Dispose() | |
{ | |
long latency = PerfTracer.GetElapsedMillisecond() - _startPoint; | |
PerfTracer.TraceStep(String.Format("ed {0} - L:{1}", _step, latency)); | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment