Repository navigation
Add built-in tracing and metrics (ActivitySource/Meter) - #1857
Open
YoussefElshemi wants to merge 4 commits into
Open
YoussefElshemi wants to merge 4 commits into
YoussefElshemi wants to merge 4 commits into
Conversation
Emits spans and an ssh.client.operation.duration histogram from an ActivitySource/Meter named "Renci.SshNet" for Connect, SFTP upload, download and list, and SshCommand execution. Nothing is allocated or read when there are no listeners.
The command span is now ended before the task completes, so it has ended by the time awaiters resume, and a command disposed mid-run also ends its span. Adds integration tests for SFTP, connect and command telemetry.
Adds spans and durations for ChangeDirectory, ChangePermissions, CreateDirectory, DeleteDirectory, DeleteFile, Delete, RenameFile, SymbolicLink, Get, Exists, GetStatus, GetAttributes and SetAttributes, sync and async. Exists reporting a missing path is not an error. Reverts the SCP protocol name, as SCP is a legacy protocol.
YoussefElshemi
requested review from
Rob-Hague,
WojciechNagorski and
drieseng
as code owners
October 27, 2026 21:15
This branch has not been deployed
This file contains hidden or 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
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Closes #1854
Adds built-in tracing and metrics using
System.DiagnosticsActivitySourceandMeter, both namedRenci.SshNet. OpenTelemetry (or any other listener) picks them up with:When nothing is listening,
SshNetTelemetry.IsEnabledis checked first, so no spans, tags or timestamps are created.What is instrumented
Each operation produces a
Clientspan named{protocol} {operation}(e.g.sftp UploadFile) and assh.client.operation.durationhistogram measurement (seconds).SshClient,SftpClientandNetConfClient(ssh/sftp/netconf), sync and asyncUploadFile,DownloadFile,ListDirectory,ChangeDirectory,ChangePermissions,CreateDirectory,DeleteDirectory,DeleteFile,Delete,RenameFile,SymbolicLink,Get,Exists,GetStatus,GetAttributes,SetAttributes— sync, async and Begin/End where they existssh Execute)Not instrumented:
ScpClientis unchanged, as discussed in the issue; its Connect still goes throughBaseClientand shows up asssh Connect)Open*,ReadAll*,WriteAll*,AppendAll*), since a span would only cover opening the handle, not the I/OAttributes
network.protocol.nameserver.address,server.porterror.typefile.pathssh.operation.namesftp.transfer.bytesssh.command.exit_codeThere is no SSH/SFTP semantic convention yet, so the custom names should be treated as experimental. Failed operations set span status to
Errorand recorderror.type(exception type name).Existsreturningfalseis not an error.Notes for review
SshCommand.ExecuteAsyncisn't anasyncmethod, so it restoresActivity.Currentafter starting the span; otherwise the caller would continue inside the command's span.TaskCompletionSourceis completed, so it has ended by the time awaiters resume. It is also ended if the command is disposed mid-run.DeleteandChangePermissionscallGetinternally, so their spans have a childGetspan.System.Diagnostics.DiagnosticSource8.0.1 on net462/netstandard2.0 only (newer TFMs have it in-box).Connect/ConnectAsyncinBaseClientnow wrap privateConnectCore/ConnectCoreAsync; no public API changes.Testing
TelemetryTestsintegration tests (spans, parenting, attributes, durations, errors, command timeout/exit code) pass on net48, net8.0, net9.0 and net10.0This change was developed with AI assistance. I have reviewed and tested all of it.