Skip to content

Commit 785af82

Browse files
author
Gregory LEOCADIE
committed
Add support for events collection through EventPipe
1 parent 7e5e771 commit 785af82

File tree

1 file changed

+166
-2
lines changed

1 file changed

+166
-2
lines changed

src/perfcollect/perfcollect

Lines changed: 166 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -642,6 +642,10 @@ usePerf=1
642642
# Use LTTng
643643
useLTTng=1
644644

645+
# Use EventPipe to collect CLR events
646+
useEventPipe=0
647+
sdkAndToolDir="/tmp/dotnet_sdk_tool"
648+
645649
# LTTng Installed
646650
lttngInstalled=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,6 +1382,18 @@ 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
@@ -1556,6 +1573,13 @@ ProcessCollectedData()
15561573
fi
15571574
fi
15581575

1576+
if [ "$useEventPipe" == "1" ]
1577+
then
1578+
LogAppend "Saving EventPipe trace file."
1579+
cp $eventPipeOutputFile .
1580+
cp $eventPipeLogFile .
1581+
fi
1582+
15591583
if [ "$usePerf" == 1 ]
15601584
then
15611585
# Get any perf-$pid.map files that were used by the
@@ -1829,6 +1853,11 @@ EndCollect()
18291853
StopLTTngCollection
18301854
fi
18311855

1856+
if [ "$useEventPipe" == "1" ]
1857+
then
1858+
StopEventPipeCollection
1859+
fi
1860+
18321861
# Update the user.
18331862
WriteStatus
18341863
WriteStatus "...STOPPED."
@@ -1951,10 +1980,89 @@ BuildPerfRecordArgs()
19511980
durationString="sleep ${duration}"
19521981
fi
19531982

1954-
# Add the events onto the collection command line args.
1983+
# Add the events onto the collection command line args.
19551984
collectionArgs="$collectionArgs -e $eventString $durationString"
19561985
}
19571986

1987+
BuildEventPipeArgs()
1988+
{
1989+
if [ "$collectionPid" == "" ]
1990+
then
1991+
FatalError "You must specify a .Net process id (-pid) to collect CLR events through EventPipe"
1992+
fi
1993+
eventPipeCollectionArgs="collect -p $collectionPid "
1994+
1995+
activated_providers=()
1996+
if [ "$gcCollectOnly" == "1" ]
1997+
then
1998+
## GC & Exception
1999+
activated_providers+=("Microsoft-Windows-DotNETRuntime:0x0000000000008001:4")
2000+
## Private GC
2001+
activated_providers+=("Microsoft-Windows-DotNETRuntimePrivate:0x0000000000000001:4")
2002+
elif [ "$gcOnly" == "1" ]
2003+
then
2004+
## GC & Jit & Loader & Exception
2005+
activated_providers+=("Microsoft-Windows-DotNETRuntime:0x0000000000080019:5")
2006+
## Private GC
2007+
activated_providers+=("Microsoft-Windows-DotNETRuntimePrivate:0x0000000000000001:5")
2008+
elif [ "$gcWithHeap" == "1" ]
2009+
then
2010+
## GC & GCHeapSurvivalAndMovement
2011+
activated_providers+=("Microsoft-Windows-DotNETRuntime:0x0000000000400001:5")
2012+
else
2013+
if [ "$providers" == "" ]
2014+
then
2015+
# Enable the default set of events.
2016+
2017+
# DotNETRuntime with keywords: Exception, Contention, Jit/NGen, Loader, GC, Compilation
2018+
# Threading, ThreadTransfer & Jit
2019+
activated_providers+=("Microsoft-Windows-DotNETRuntime:0x000000108001C039:5")
2020+
2021+
# DotNETRuntimeRundown with keyword(s): Compilation
2022+
activated_providers+=("Microsoft-Windows-DotNETRuntimeRundown:0x0000001000000000:4")
2023+
2024+
# DotNETRuntimePrivate with keywords: GC, Binding, MulticoreJitPrivate
2025+
activated_providers+=("Microsoft-Windows-DotNETRuntimePrivate:0x0000000000020003:4")
2026+
2027+
elif [ "$providers" == "threading" ]
2028+
then
2029+
activated_providers+=("Microsoft-Windows-DotNETRuntime:0x0000000000010000:5")
2030+
else
2031+
# Enable other keywords
2032+
providers=(${providers//","/" "})
2033+
for provider in ${providers[@]}
2034+
do
2035+
activated_providers+=($provider)
2036+
done
2037+
fi
2038+
fi
2039+
if (( ${#activated_providers[@]} ))
2040+
then
2041+
joined_providers=$( IFS=","; echo "${activated_providers[*]}" )
2042+
eventPipeCollectionArgs="$eventPipeCollectionArgs --providers $joined_providers"
2043+
fi
2044+
eventPipeOutputFile="$sdkAndToolDir/trace.nettrace"
2045+
eventPipeLogFile="$sdkAndToolDir/eventpipe.log"
2046+
eventPipeCollectionArgs="$eventPipeCollectionArgs -o $eventPipeOutputFile"
2047+
}
2048+
2049+
StartEventPipeCollection()
2050+
{
2051+
pushd $sdkAndToolDir > /dev/null
2052+
eval "./dotnet trace $eventPipeCollectionArgs < /dev/null > $eventPipeLogFile 2>&1 &"
2053+
eventPipeCollectionPid=$!
2054+
popd > /dev/null
2055+
}
2056+
2057+
StopEventPipeCollection()
2058+
{
2059+
RunSilent "kill -15 $eventPipeCollectionPid"
2060+
while [ "$eventPipeCollectionPid" != "" ] && [ -e /proc/$eventPipeCollectionPid ]
2061+
do
2062+
sleep .6
2063+
done
2064+
}
2065+
19582066
DoCollect()
19592067
{
19602068
# Ensure the script is run as root.
@@ -1980,6 +2088,12 @@ DoCollect()
19802088
StartLTTngCollection
19812089
fi
19822090

2091+
if [ "$useEventPipe" == "1" ]
2092+
then
2093+
BuildEventPipeArgs
2094+
StartEventPipeCollection
2095+
fi
2096+
19832097
# Tell the user that collection has started and how to exit.
19842098
if [ "$duration" != "" ]
19852099
then
@@ -1998,7 +2112,7 @@ DoCollect()
19982112
# Pass trace directory and session name to the stop process.
19992113
popd > /dev/null
20002114
usePerf=0
2001-
declare -p | grep -e lttngTraceDir -e lttngSessionName -e tempDir -e usePerf -e useLttng -e logFile > $collectInfoFile
2115+
declare -p | grep -e lttngTraceDir -e lttngSessionName -e tempDir -e usePerf -e useLttng -e logFile -e eventPipeCollectionPid -e eventPipeOutputFile -e eventPipeLogFile > $collectInfoFile
20022116
else
20032117
if [ "$usePerf" == "1" ]
20042118
then
@@ -2112,6 +2226,51 @@ DoView()
21122226
rm -rf $tempDir
21132227
}
21142228

2229+
IsTraceToolInstalled()
2230+
{
2231+
# check global
2232+
local installed=0
2233+
2234+
if $($sdkAndToolDir/dotnet tool list -g | grep -q "dotnet-trace")
2235+
then
2236+
installed=1
2237+
elif $($sdkAndToolDir/dotnet tool list --local | grep -q "dotnet-trace")
2238+
then
2239+
installed=1
2240+
fi
2241+
2242+
echo $installed
2243+
}
2244+
2245+
EnsureDotNetTraceToolIsInstalled()
2246+
{
2247+
if [ ! -d "$sdkAndToolDir" ]
2248+
then
2249+
WriteStatus "Installing dotnet sdk in $sdkAndToolDir"
2250+
ResetText
2251+
RunSilent "mkdir $sdkAndToolDir"
2252+
RunSilent "curl -OL https://dot.net/v1/dotnet-install.sh"
2253+
RunSilent "bash ./dotnet-install.sh --install-dir $sdkAndToolDir"
2254+
fi
2255+
2256+
pushd $sdkAndToolDir > /dev/null
2257+
if [ "$(IsTraceToolInstalled)" != "1" ]
2258+
then
2259+
# create a tool-manifest. If there is one, it won't be overwritten.
2260+
WriteStatus "Installing dotnet trace"
2261+
RunSilent "./dotnet new tool-manifest"
2262+
RunSilent "./dotnet tool install dotnet-trace --local"
2263+
fi
2264+
2265+
./dotnet trace --version > /dev/null 2>&1
2266+
if [ "$?" != 0 ]
2267+
then
2268+
FatalError "dotnet-trace tool was installed correctly."
2269+
fi
2270+
LogAppend 'dotnet-trace version:' `$sdkAndToolDir/dotnet trace --version`
2271+
popd > /dev/null
2272+
}
2273+
21152274
#####################################
21162275
## Main Script Start
21172276
#####################################
@@ -2150,6 +2309,11 @@ ProcessArguments $@
21502309
# Ensure prerequisites are installed.
21512310
EnsurePrereqsInstalled
21522311

2312+
if [ "$useEventPipe" == "1" ] && [ "$1" != "stop" ]
2313+
then
2314+
EnsureDotNetTraceToolIsInstalled
2315+
fi
2316+
21532317
# Take the appropriate action.
21542318
if [ "$action" == "collect" ] || [ "$action" == "start" ]
21552319
then

0 commit comments

Comments
 (0)