Self-contained EventPipe CPU profiler for ModSharp / CS2 servers — capture a .nettrace from a live server with a single admin command, get a ranked hot-method report posted straight to Discord.
ModSharp Profiler starts an in-process .NET EventPipe trace on a running server, captures managed-thread CPU samples for a chosen duration, then parses the .nettrace in-process (via PerfView's TraceEvent parser) to produce a categorized hot-method report. The report plus the raw trace are uploaded to a Discord webhook — no external tooling required on the server or your machine.
Scope: EventPipe's SampleProfiler samples managed threads only. Native CS2 engine work (engine2.so / server.so) is invisible to it. Sample granularity is ~1 ms, and the profiler itself adds a few % CPU per core while active — keep captures short on populated servers.
Copy the build output into your ModSharp install (<sharp> = your sharp directory):
| From | To |
|---|---|
.build/modules/ModsharpProfiler/ |
<sharp>/modules/ModsharpProfiler/ |
Restart the server (or change map) to load. Requires CommandCenter and AdminManager (ship with ModSharp) — AdminManager gates the commands; without it commands are denied for safety.
All commands work from chat (!profile), client console, server console, and RCON. Console / RCON always counts as the server operator. Chat use requires the configured admin permission (default profiler:admin:use, registered via the AdminManager manifest — root admins pass implicitly).
| Command | Arguments | Description | Permission |
|---|---|---|---|
!profile |
[seconds] |
Start a capture. Duration defaults to msp_default_duration, clamped to msp_max_duration. Auto-uploads when the duration completes. |
msp_admin_permission |
!profile_stop |
— | Stop the running capture early. Does not auto-upload (inspect the file first). | msp_admin_permission |
!profile_status |
— | Show current session state (running / idle, elapsed, last file). | msp_admin_permission |
!profile_upload |
— | Analyze and upload the last finished trace to the Discord webhook. | msp_admin_permission |
All settings are ConVars (set in autoexec / server config / console). Defaults shown:
| ConVar | Default | Meaning |
|---|---|---|
msp_discord_webhook |
(empty) | Discord webhook URL for uploads. Empty disables upload. |
msp_admin_permission |
profiler:admin:use |
Admin permission flag required to use the commands. |
msp_default_duration |
30 |
Capture seconds when !profile is called with no argument. |
msp_max_duration |
300 |
Maximum seconds a single capture may run (range 5–1800). |
msp_buffer_size_mb |
256 |
EventPipe in-process ring-buffer size in MB (range 64–1024). |
msp_output_dir |
(empty) | Output directory for .nettrace files. Empty = <sharp>/profiles. |
msp_tickrate |
64 |
Server tick rate (Hz). Drives the per-tick CPU budget figures in the report (range 16–256). |
msp_report_topn |
30 |
Top-N hot methods listed per report section (range 5–100). |
msp_report_chains |
3 |
Number of dominant call chains rendered in the report. 0 disables (range 0–10). |
msp_report_chain_cutoff |
3 |
Inclusive-% threshold below which a call chain stops descending (range 1–50). |
msp_attach_trace |
1 |
1 = attach the raw .nettrace alongside the text report; 0 = report only (smaller/faster). |
All ConVars are read live — change any of them at runtime (console, RCON, autoexec) and the new value applies immediately, including
msp_discord_webhookfor the next upload. No reload or restart needed.
!profile [seconds] opens an EventPipe session against the running process and records managed CPU samples into an in-process ring buffer, writing a .nettrace to the output directory. On completion (or !profile_upload), the trace is parsed in-process with the TraceEvent parser and rendered into a text report: framework vs. user-plugin vs. runtime sections, top-N hot methods per section, and the dominant call chains. Map name and player counts are snapshotted on the engine thread at capture start so the report reflects real server load. The report (and, by default, the raw trace) is then POSTed to the configured Discord webhook.
See docs/sample-report.txt for an example report.
dotnet build -c ReleaseOutputs .build/modules/ModsharpProfiler/ModsharpProfiler.dll (plus its bundled Microsoft.Diagnostics.* dependencies — the analyzer and EventPipe client are shipped in plugin output, not supplied by ModSharp).
Built by YappersHQ. Uses Microsoft's diagnostics client and PerfView's TraceEvent parser.
Made with ❤️ by yappershq
⭐ Star this repo if you find it useful!