Skip to content

Commit c753afd

Browse files
Add method for injecting RUM settings into HTML
1 parent 2665bb8 commit c753afd

File tree

4 files changed

+315
-41
lines changed

4 files changed

+315
-41
lines changed

Src/StackifyLib/Extensions.cs

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,13 @@ public static void ConfigureStackifyLogging(this Microsoft.Extensions.Configurat
3838
//tell it to load all the settings since we now have the config
3939
Config.LoadSettings();
4040
}
41+
42+
public static void ConfigureStackifyLib(this Microsoft.Extensions.Configuration.IConfiguration configuration)
43+
{
44+
Config.SetConfiguration(configuration);
45+
//tell it to load all the settings since we now have the config
46+
Config.LoadSettings();
47+
}
4148
#endif
4249
}
4350
}

Src/StackifyLib/Internal/Logs/LogQueue.cs

Lines changed: 4 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,6 @@
1010
using System.Threading.Tasks;
1111

1212
#if NETFULL
13-
using System.Runtime.Remoting.Messaging;
1413
using StackifyLib.Web;
1514
using System.Web;
1615
#endif
@@ -106,27 +105,7 @@ public void QueueLogMessage(Models.LogMsg msg)
106105
#if NETFULL
107106
try
108107
{
109-
if (string.IsNullOrEmpty(msg.TransID))
110-
{
111-
var stackifyRequestID = CallContext.LogicalGetData("Stackify-RequestID");
112-
113-
if (stackifyRequestID != null)
114-
{
115-
msg.TransID = stackifyRequestID.ToString();
116-
}
117-
}
118-
119-
if (string.IsNullOrEmpty(msg.TransID))
120-
{
121-
//gets from Trace.CorrelationManager.ActivityId but doesnt assume it is guid since it technically doesn't have to be
122-
//not calling the CorrelationManager method because it blows up if it isn't a guid
123-
var correltionManagerId = CallContext.LogicalGetData("E2ETrace.ActivityID");
124-
125-
if (correltionManagerId != null && correltionManagerId is Guid && ((Guid)correltionManagerId) != Guid.Empty)
126-
{
127-
msg.TransID = correltionManagerId.ToString();
128-
}
129-
}
108+
msg.TransID = StackifyLib.Utils.HelperFunctions.GetRequestId();
130109

131110
if (string.IsNullOrEmpty(msg.TransID))
132111
{
@@ -186,27 +165,11 @@ public void QueueLogMessage(Models.LogMsg msg)
186165
// get RequestID
187166
if (string.IsNullOrEmpty(msg.TransID))
188167
{
189-
var assemblies = AppDomain.CurrentDomain.GetAssemblies();
168+
string reqId = StackifyLib.Utils.HelperFunctions.GetRequestId();
190169

191-
var agentAssemblyQry = assemblies.Where(assembly => assembly.FullName.Contains("Stackify.Agent"));
192-
if(agentAssemblyQry.Count() > 0)
170+
if (reqId != null)
193171
{
194-
var middleware = agentAssemblyQry.First();
195-
var callContextType = middleware.GetType("Stackify.Agent.Threading.StackifyCallContext");
196-
if (callContextType != null)
197-
{
198-
var traceCtxType = middleware.GetType("Stackify.Agent.Tracing.ITraceContext");
199-
if(traceCtxType != null)
200-
{
201-
var traceContextProp = callContextType.GetProperty("TraceContext")?.GetValue(null);
202-
if (traceContextProp != null)
203-
{
204-
var reqIdProp = traceCtxType.GetProperty("RequestId")?.GetValue(traceContextProp)?.ToString();
205-
if(!string.IsNullOrEmpty(reqIdProp))
206-
msg.TransID = reqIdProp;
207-
}
208-
}
209-
}
172+
msg.TransID = reqId;
210173
}
211174
}
212175
#endif

Src/StackifyLib/Utils/HelperFunctions.cs

Lines changed: 262 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,9 @@
33
using System.Collections.Generic;
44
using System.Linq;
55
using System.Reflection;
6+
#if NETFRAMEWORK
7+
using System.Runtime.Remoting.Messaging;
8+
#endif
69
using System.Text;
710
using Newtonsoft.Json.Linq;
811

@@ -312,6 +315,265 @@ public static string CleanPartialUrl(string url)
312315

313316
return sbNewUrl.ToString();
314317
}
318+
public static string GetRequestId()
319+
{
320+
string reqId = null;
321+
322+
#if NETFULL
323+
try
324+
{
325+
if (string.IsNullOrEmpty(reqId))
326+
{
327+
var stackifyRequestID = CallContext.LogicalGetData("Stackify-RequestID");
328+
329+
if (stackifyRequestID != null)
330+
{
331+
reqId = stackifyRequestID.ToString();
332+
}
333+
}
334+
335+
if (string.IsNullOrEmpty(reqId))
336+
{
337+
//gets from Trace.CorrelationManager.ActivityId but doesnt assume it is guid since it technically doesn't have to be
338+
//not calling the CorrelationManager method because it blows up if it isn't a guid
339+
var correltionManagerId = CallContext.LogicalGetData("E2ETrace.ActivityID");
340+
341+
if (correltionManagerId != null && correltionManagerId is Guid &&
342+
((Guid) correltionManagerId) != Guid.Empty)
343+
{
344+
reqId = correltionManagerId.ToString();
345+
}
346+
}
347+
}
348+
catch (System.Web.HttpException ex)
349+
{
350+
StackifyAPILogger.Log("Request not available \r\n" + ex.ToString());
351+
}
352+
catch (Exception ex)
353+
{
354+
StackifyAPILogger.Log("Error figuring out TransID \r\n" + ex.ToString());
355+
}
356+
#endif
357+
358+
try
359+
{
360+
if (string.IsNullOrEmpty(reqId))
361+
{
362+
reqId = getContextProperty("RequestId") as string;
363+
}
364+
}
365+
catch (Exception ex)
366+
{
367+
StackifyAPILogger.Log("Error figuring out TransID \r\n" + ex.ToString());
368+
}
369+
370+
return reqId;
371+
}
372+
373+
public static string GetReportingUrl()
374+
{
375+
return GetStackifyProperty("REPORTING_URL");
376+
}
377+
378+
public static string GetAppName()
379+
{
380+
if (!IsBeingProfiled)
381+
{
382+
return Config.AppName;
383+
}
384+
385+
// Getting profiler app name and environment are a side effect of checking the profiler wrapper
386+
GetWrapperAssembly();
387+
388+
return _profilerAppName ?? Config.AppName;
389+
}
390+
391+
public static string GetAppEnvironment()
392+
{
393+
if (!IsBeingProfiled)
394+
{
395+
return Config.AppName;
396+
}
397+
398+
// Getting profiler app name and environment are a side effect of checking the profiler wrapper
399+
GetWrapperAssembly();
400+
401+
return _profilerEnvironment ?? Config.Environment;
402+
}
403+
404+
private static Assembly _wrapperAssembly = null;
405+
private static Type _stackifyCallContextType = null;
406+
407+
protected static Assembly GetWrapperAssembly()
408+
{
409+
if (!IsBeingProfiled)
410+
{
411+
return null;
412+
}
413+
414+
if (_wrapperAssembly != null)
415+
{
416+
return _wrapperAssembly;
417+
}
418+
419+
try
420+
{
421+
var assemblies = AppDomain.CurrentDomain.GetAssemblies();
422+
423+
var agentAssemblyQry = assemblies.Where(assembly => assembly.FullName.StartsWith("Stackify.Agent,"));
424+
425+
foreach (var middleware in agentAssemblyQry)
426+
{
427+
var stackifyCallContextType = middleware?.GetType("Stackify.Agent.Threading.StackifyCallContext");
428+
429+
if (stackifyCallContextType != null)
430+
{
431+
GetProfilerAppNameAndEnvironment(middleware);
432+
433+
_stackifyCallContextType = stackifyCallContextType;
434+
_wrapperAssembly = middleware;
435+
}
436+
}
437+
}
438+
catch
439+
{
440+
// Ignore errors
441+
}
442+
443+
return _wrapperAssembly;
444+
}
445+
446+
private static string _profilerAppName = null;
447+
private static string _profilerEnvironment = null;
448+
449+
private static void GetProfilerAppNameAndEnvironment(Assembly middleware)
450+
{
451+
try
452+
{
453+
// Get AppName and Environment and cache them, so we won't query over and over.
454+
var agentConfigType = middleware?.GetType("Stackify.Agent.Configuration.AgentConfig");
455+
456+
if (agentConfigType != null)
457+
{
458+
var profilerSettings = agentConfigType.GetProperty("Settings")?.GetValue(null, null);
459+
460+
if (profilerSettings != null)
461+
{
462+
var settingsType = profilerSettings.GetType();
463+
464+
_profilerAppName = settingsType?.GetProperty("AppName")?.GetValue(profilerSettings, null) as string;
465+
_profilerEnvironment = settingsType?.GetProperty("Environment")?.GetValue(profilerSettings, null) as string;
466+
}
467+
}
468+
}
469+
catch
470+
{
471+
// Ignore errors here
472+
}
473+
}
474+
475+
private static object getContextProperty(string propName)
476+
{
477+
if (!IsBeingProfiled || string.IsNullOrWhiteSpace(propName))
478+
{
479+
return null;
480+
}
481+
482+
if (_wrapperAssembly == null)
483+
{
484+
GetWrapperAssembly();
485+
}
486+
487+
try
488+
{
489+
if (_stackifyCallContextType != null)
490+
{
491+
var traceContextProp = _stackifyCallContextType.GetProperty("TraceContext")?.GetValue(null, null);
492+
if (traceContextProp != null)
493+
{
494+
var traceContextType = traceContextProp.GetType();
495+
var contextProp = traceContextType.GetProperty(propName);
496+
var propValue = contextProp?.GetValue(traceContextProp, null);
497+
return propValue;
498+
}
499+
}
500+
}
501+
catch
502+
{
503+
// Ignore errors
504+
}
505+
506+
return null;
507+
}
508+
509+
private static string GetStackifyProperty(string propName)
510+
{
511+
if (!IsBeingProfiled || string.IsNullOrWhiteSpace(propName))
512+
{
513+
return null;
514+
}
515+
516+
try
517+
{
518+
var stackifyProps = getContextProperty("props");
519+
520+
if (stackifyProps != null)
521+
{
522+
var propsType = stackifyProps.GetType();
523+
524+
var getItemMethod = propsType.GetMethod("get_Item", new[] {typeof(string)});
525+
526+
if (getItemMethod != null)
527+
{
528+
return getItemMethod.Invoke(stackifyProps, new[] {propName}) as string;
529+
}
530+
}
531+
}
532+
catch
533+
{
534+
// Ignore Errors
535+
}
536+
537+
return null;
538+
}
539+
540+
private static Boolean? _isBeingProfiled = null;
541+
542+
protected static bool IsBeingProfiled
543+
{
544+
get
545+
{
546+
if (_isBeingProfiled.HasValue)
547+
{
548+
return _isBeingProfiled.Value;
549+
}
550+
551+
#if NETFRAMEWORK
552+
var profilerEnv = "COR_ENABLE_PROFILING";
553+
var profilerUuidEnv = "COR_PROFILER";
554+
#else
555+
var profilerEnv = "CORECLR_ENABLE_PROFILING";
556+
var profilerUuidEnv = "CORECLR_PROFILER";
557+
#endif
558+
559+
var enableString = Environment.GetEnvironmentVariable(profilerEnv);
560+
var uuidString = Environment.GetEnvironmentVariable(profilerUuidEnv);
561+
562+
if (!string.IsNullOrWhiteSpace(enableString) &&
563+
!string.IsNullOrWhiteSpace(uuidString))
564+
{
565+
_isBeingProfiled = string.Equals("1", enableString?.Trim())
566+
&& string.Equals("{cf0d821e-299b-5307-a3d8-b283c03916da}", uuidString.Trim(), StringComparison.OrdinalIgnoreCase);
567+
}
568+
else
569+
{
570+
_isBeingProfiled = false;
571+
}
572+
573+
return _isBeingProfiled.Value;
574+
}
575+
}
576+
315577
}
316578

317579
public class ToStringConverter : JsonConverter

0 commit comments

Comments
 (0)