@@ -642,6 +642,10 @@ usePerf=1
642642# Use LTTng
643643useLTTng=1
644644
645+ # Use EventPipe to collect CLR events
646+ useEventPipe=0
647+ sdkAndToolDir=" /tmp/dotnet_sdk_tool"
648+
645649# LTTng Installed
646650lttngInstalled=0
647651
@@ -1332,6 +1336,7 @@ ProcessArguments()
13321336 if [ " -events" != " $arg " ]
13331337 then
13341338 # Convert the value to lower case.
1339+ rawvalue=$value
13351340 value=` echo $value | tr ' [:upper:]' ' [:lower:]' `
13361341 fi
13371342 fi
@@ -1377,18 +1382,33 @@ ProcessArguments()
13771382 elif [ " -nolttng" == " $arg " ]
13781383 then
13791384 useLTTng=0
1385+ elif [ " -eventpipe" == " $arg " ]
1386+ then
1387+ useEventPipe=1
1388+ useLTTng=0
1389+ elif [ " -providers" == " $arg " ]
1390+ then
1391+ providers=$rawvalue
1392+ i=$i +1
1393+ elif [ " -sdk-path" == " $arg " ]
1394+ then
1395+ sdkAndToolDir=$value
1396+ i=$i +1
13801397 elif [ " -noperf" == " $arg " ]
13811398 then
13821399 usePerf=0
13831400 elif [ " -gccollectonly" == " $arg " ]
13841401 then
13851402 gcCollectOnly=1
1403+ usePerf=0
13861404 elif [ " -gconly" == " $arg " ]
13871405 then
13881406 gcOnly=1
1407+ usePerf=0
13891408 elif [ " -gcwithheap" == " $arg " ]
13901409 then
13911410 gcWithHeap=1
1411+ usePerf=0
13921412 elif [ " -events" == " $arg " ]
13931413 then
13941414 events=$value
@@ -1438,21 +1458,18 @@ SetupLTTngSession()
14381458 RunSilent " $lttngcmd enable-event --userspace --tracepoint DotNETRuntime:EventSource"
14391459 elif [ " $gcCollectOnly " == " 1" ]
14401460 then
1441- usePerf=0
14421461 EnableLTTngEvents ${DotNETRuntime_GCKeyword_GCCollectOnly[@]}
14431462 EnableLTTngEvents ${DotNETRuntimePrivate_GCPrivateKeyword_GCCollectOnly[@]}
14441463 EnableLTTngEvents ${DotNETRuntime_ExceptionKeyword[@]}
14451464 elif [ " $gcOnly " == " 1" ]
14461465 then
1447- usePerf=0
14481466 EnableLTTngEvents ${DotNETRuntime_GCKeyword[@]}
14491467 EnableLTTngEvents ${DotNETRuntimePrivate_GCPrivateKeyword[@]}
14501468 EnableLTTngEvents ${DotNETRuntime_JitKeyword[@]}
14511469 EnableLTTngEvents ${DotNETRuntime_LoaderKeyword[@]}
14521470 EnableLTTngEvents ${DotNETRuntime_ExceptionKeyword[@]}
14531471 elif [ " $gcWithHeap " == " 1" ]
14541472 then
1455- usePerf=0
14561473 EnableLTTngEvents ${DotNETRuntime_GCKeyword[@]}
14571474 EnableLTTngEvents ${DotNETRuntime_GCHeapSurvivalAndMovementKeyword[@]}
14581475 else
@@ -1559,6 +1576,13 @@ ProcessCollectedData()
15591576 fi
15601577 fi
15611578
1579+ if [ " $useEventPipe " == " 1" ]
1580+ then
1581+ LogAppend " Saving EventPipe trace file."
1582+ cp $eventPipeOutputFile .
1583+ cp $eventPipeLogFile .
1584+ fi
1585+
15621586 if [ " $usePerf " == 1 ]
15631587 then
15641588 # Get any perf-$pid.map files that were used by the
@@ -1832,6 +1856,11 @@ EndCollect()
18321856 StopLTTngCollection
18331857 fi
18341858
1859+ if [ " $useEventPipe " == " 1" ]
1860+ then
1861+ StopEventPipeCollection
1862+ fi
1863+
18351864 # Update the user.
18361865 WriteStatus
18371866 WriteStatus " ...STOPPED."
@@ -1954,10 +1983,89 @@ BuildPerfRecordArgs()
19541983 durationString=" sleep ${duration} "
19551984 fi
19561985
1957- # Add the events onto the collection command line args.
1986+ # Add the events onto the collection command line args.
19581987 collectionArgs=" $collectionArgs -e $eventString $durationString "
19591988}
19601989
1990+ BuildEventPipeArgs ()
1991+ {
1992+ if [ " $collectionPid " == " " ]
1993+ then
1994+ FatalError " You must specify a .Net process id (-pid) to collect CLR events through EventPipe"
1995+ fi
1996+ eventPipeCollectionArgs=" collect -p $collectionPid "
1997+
1998+ activated_providers=()
1999+ if [ " $gcCollectOnly " == " 1" ]
2000+ then
2001+ # # GC & Exception
2002+ activated_providers+=(" Microsoft-Windows-DotNETRuntime:0x0000000000008001:4" )
2003+ # # Private GC
2004+ activated_providers+=(" Microsoft-Windows-DotNETRuntimePrivate:0x0000000000000001:4" )
2005+ elif [ " $gcOnly " == " 1" ]
2006+ then
2007+ # # GC & Jit & Loader & Exception
2008+ activated_providers+=(" Microsoft-Windows-DotNETRuntime:0x0000000000080019:5" )
2009+ # # Private GC
2010+ activated_providers+=(" Microsoft-Windows-DotNETRuntimePrivate:0x0000000000000001:5" )
2011+ elif [ " $gcWithHeap " == " 1" ]
2012+ then
2013+ # # GC & GCHeapSurvivalAndMovement
2014+ activated_providers+=(" Microsoft-Windows-DotNETRuntime:0x0000000000400001:5" )
2015+ else
2016+ if [ " $providers " == " " ]
2017+ then
2018+ # Enable the default set of events.
2019+
2020+ # DotNETRuntime with keywords: Exception, Contention, Jit/NGen, Loader, GC, Compilation
2021+ # Threading, ThreadTransfer & Jit
2022+ activated_providers+=(" Microsoft-Windows-DotNETRuntime:0x000000108001C039:5" )
2023+
2024+ # DotNETRuntimeRundown with keyword(s): Compilation
2025+ activated_providers+=(" Microsoft-Windows-DotNETRuntimeRundown:0x0000001000000000:4" )
2026+
2027+ # DotNETRuntimePrivate with keywords: GC, Binding, MulticoreJitPrivate
2028+ activated_providers+=(" Microsoft-Windows-DotNETRuntimePrivate:0x0000000000020003:4" )
2029+
2030+ elif [ " $providers " == " threading" ]
2031+ then
2032+ activated_providers+=(" Microsoft-Windows-DotNETRuntime:0x0000000000010000:5" )
2033+ else
2034+ # Enable other keywords
2035+ providers=(${providers// " ," / " " } )
2036+ for provider in ${providers[@]}
2037+ do
2038+ activated_providers+=($provider )
2039+ done
2040+ fi
2041+ fi
2042+ if (( ${# activated_providers[@]} ))
2043+ then
2044+ joined_providers=$( IFS=" ," ; echo " ${activated_providers[*]} " )
2045+ eventPipeCollectionArgs=" $eventPipeCollectionArgs --providers $joined_providers "
2046+ fi
2047+ eventPipeOutputFile=" $sdkAndToolDir /trace.nettrace"
2048+ eventPipeLogFile=" $sdkAndToolDir /eventpipe.log"
2049+ eventPipeCollectionArgs=" $eventPipeCollectionArgs -o $eventPipeOutputFile "
2050+ }
2051+
2052+ StartEventPipeCollection ()
2053+ {
2054+ pushd $sdkAndToolDir > /dev/null
2055+ eval " ./dotnet trace $eventPipeCollectionArgs < /dev/null > $eventPipeLogFile 2>&1 &"
2056+ eventPipeCollectionPid=$!
2057+ popd > /dev/null
2058+ }
2059+
2060+ StopEventPipeCollection ()
2061+ {
2062+ RunSilent " kill -15 $eventPipeCollectionPid "
2063+ while [ " $eventPipeCollectionPid " != " " ] && [ -e /proc/$eventPipeCollectionPid ]
2064+ do
2065+ sleep .6
2066+ done
2067+ }
2068+
19612069DoCollect ()
19622070{
19632071 # Ensure the script is run as root.
@@ -1983,6 +2091,12 @@ DoCollect()
19832091 StartLTTngCollection
19842092 fi
19852093
2094+ if [ " $useEventPipe " == " 1" ]
2095+ then
2096+ BuildEventPipeArgs
2097+ StartEventPipeCollection
2098+ fi
2099+
19862100 # Tell the user that collection has started and how to exit.
19872101 if [ " $duration " != " " ]
19882102 then
@@ -2001,7 +2115,7 @@ DoCollect()
20012115 # Pass trace directory and session name to the stop process.
20022116 popd > /dev/null
20032117 usePerf=0
2004- declare -p | grep -e lttngTraceDir -e lttngSessionName -e tempDir -e usePerf -e useLttng -e logFile > $collectInfoFile
2118+ declare -p | grep -e lttngTraceDir -e lttngSessionName -e tempDir -e usePerf -e useLttng -e logFile -e eventPipeCollectionPid -e eventPipeOutputFile -e eventPipeLogFile > $collectInfoFile
20052119 else
20062120 if [ " $usePerf " == " 1" ]
20072121 then
@@ -2115,6 +2229,51 @@ DoView()
21152229 rm -rf $tempDir
21162230}
21172231
2232+ IsTraceToolInstalled ()
2233+ {
2234+ # check global
2235+ local installed=0
2236+
2237+ if $( $sdkAndToolDir /dotnet tool list -g | grep -q " dotnet-trace" )
2238+ then
2239+ installed=1
2240+ elif $( $sdkAndToolDir /dotnet tool list --local | grep -q " dotnet-trace" )
2241+ then
2242+ installed=1
2243+ fi
2244+
2245+ echo $installed
2246+ }
2247+
2248+ EnsureDotNetTraceToolIsInstalled ()
2249+ {
2250+ if [ ! -d " $sdkAndToolDir " ]
2251+ then
2252+ WriteStatus " Installing dotnet sdk in $sdkAndToolDir "
2253+ ResetText
2254+ RunSilent " mkdir $sdkAndToolDir "
2255+ RunSilent " curl -OL https://dot.net/v1/dotnet-install.sh"
2256+ RunSilent " bash ./dotnet-install.sh --install-dir $sdkAndToolDir "
2257+ fi
2258+
2259+ pushd $sdkAndToolDir > /dev/null
2260+ if [ " $( IsTraceToolInstalled) " != " 1" ]
2261+ then
2262+ # create a tool-manifest. If there is one, it won't be overwritten.
2263+ WriteStatus " Installing dotnet trace"
2264+ RunSilent " ./dotnet new tool-manifest"
2265+ RunSilent " ./dotnet tool install dotnet-trace --local"
2266+ fi
2267+
2268+ ./dotnet trace --version > /dev/null 2>&1
2269+ if [ " $? " != 0 ]
2270+ then
2271+ FatalError " dotnet-trace tool was installed correctly."
2272+ fi
2273+ LogAppend ' dotnet-trace version:' ` $sdkAndToolDir /dotnet trace --version`
2274+ popd > /dev/null
2275+ }
2276+
21182277# ####################################
21192278# # Main Script Start
21202279# ####################################
@@ -2153,6 +2312,11 @@ ProcessArguments $@
21532312# Ensure prerequisites are installed.
21542313EnsurePrereqsInstalled
21552314
2315+ if [ " $useEventPipe " == " 1" ] && [ " $1 " != " stop" ]
2316+ then
2317+ EnsureDotNetTraceToolIsInstalled
2318+ fi
2319+
21562320# Take the appropriate action.
21572321if [ " $action " == " collect" ] || [ " $action " == " start" ]
21582322then
0 commit comments