Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Parameter Capturing] Add documentation #5194

Merged
merged 25 commits into from
Aug 25, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions documentation/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ When running a dotnet application, differences in diverse local and production e
- [`/collectionrules`](./api/collectionrules.md)
- [`/stacks`](./api/stacks.md)
- [`/exceptions`](./api/exceptions.md)
- [`/parameters`](./api/parameters.md)
- [Configuration](./configuration/README.md)
- [JSON Schema](./schema.json)
- [Authentication](./authentication.md)
Expand Down
1 change: 1 addition & 0 deletions documentation/api/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -23,5 +23,6 @@ The following are the root routes on the HTTP API surface.
| [`/info`](info.md) | Gets info about `dotnet monitor`. | 6.0 |
| [`/operations`](operations.md) | Gets egress operation status or cancels operations. | 6.0 |
| [`/collectionrules`](collectionrules.md) | Gets the current state of collection rules. | 6.3 |
| [`/parameters`](parameters.md) | Captures parameters for one or more methods each time they are called. | 8.0 RC 1 |

The `dotnet monitor` tool is able to detect .NET Core 3.1 and .NET 5+ applications. When connecting to a .NET Core 3.1 application, some information may not be available and is called out in the documentation.
20 changes: 20 additions & 0 deletions documentation/api/definitions.md
Original file line number Diff line number Diff line change
Expand Up @@ -86,6 +86,16 @@ Enumeration that describes the current state of the collection rule.
| `Throttled` | Indicates that the collection rule is temporarily throttled because the ActionCountLimit has been reached within the ActionCountSlidingWindowDuration. |
| `Finished` | Indicates that the collection rule has completed and will no longer trigger. |

## CaptureParametersConfiguration

First Available: 8.0 RC 1

Object describing the list of methods to capture parameters for.

| Name | Type | Description |
|---|---|---|
| `methods` | [MethodDescription](#methoddescription)[] | Array of methods to capture parameters for. |

## DotnetMonitorInfo

Object describing diagnostic/automation information about the executing instance of `dotnet monitor`.
Expand Down Expand Up @@ -286,6 +296,16 @@ The following configuration will collect logs for the Microsoft.AspNetCore.Hosti
}
```

## MethodDescription

Object describing a method.

| Name | Type | Description |
|---|---|---|
| `moduleName`| string | The name of the module that the method belongs to. |
| `typeName` | string | The name of the type that the method belongs to. |
| `methodName` | string | The name of the method, not including parameters. |

## Metric

Object describing a metric from the application.
Expand Down
176 changes: 176 additions & 0 deletions documentation/api/parameters.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,176 @@

### Was this documentation helpful? [Share feedback](https://www.research.net/r/DGDQWXH?src=documentation%2Fapi%2Fparameters)

# Parameters - Post (experimental feature)

Captures parameters for one or more methods each time they are called. Parameters are logged inside the target application using its [`ILogger`](https://learn.microsoft.com/dotnet/api/microsoft.extensions.logging.ilogger).

>**Note**: Unlike other artifacts, parameters do **not** support being sent to an egress provider.
>**Note**: This feature is not enabled by default and requires configuration to be enabled. See [Enabling](#enabling) for more information.
## Enabling

This feature is currently marked as experimental and so needs to be explicitly enabled. The following configuration must be set for the feature to be used.

```json
"InProcessFeatures": {
"ParameterCapturing": {
"Enabled": true
}
}
```

## HTTP Route

```http
POST /parameters?pid={pid}&uid={uid}&name={name}&durationSeconds={durationSeconds}&tags={tags} HTTP/1.1
```

> **Note**: Process information (IDs, names, environment, etc) may change between invocations of these APIs. Processes may start or stop between API invocations, causing this information to change.
## Host Address

The default host address for these routes is `https://localhost:52323`. This route is only available on the addresses configured via the `--urls` command line parameter and the `DOTNETMONITOR_URLS` environment variable.

## URI Parameters

| Name | In | Required | Type | Description |
|---|---|---|---|---|
| `pid` | query | false | int | The ID of the process. |
| `uid` | query | false | guid | A value that uniquely identifies a runtime instance within a process. |
| `name` | query | false | string | The name of the process. |
| `durationSeconds` | query | false | int | The duration of the parameters operation in seconds. Default is `30`. Min is `-1` (indefinite duration). Max is `2147483647`. |
| `tags` | query | false | string | A comma-separated list of user-readable identifiers for the operation. |

See [ProcessIdentifier](definitions.md#processidentifier) for more details about the `pid`, `uid`, and `name` parameters.

If none of `pid`, `uid`, or `name` are specified, parameters from the [default process](defaultprocess.md) will be captured. Attempting to capture parameters from the default process when the default process cannot be resolved will fail.

## Authentication

Authentication is enforced for this route. See [Authentication](./../authentication.md) for further information.

Allowed schemes:
- `Bearer`
- `Negotiate` (Windows only, running as unelevated)

## Request Body

A request body of type [CaptureParametersConfiguration](definitions.md#captureparametersconfiguration) is required.

The expected content type is `application/json`.

## Responses

| Name | Type | Description | Content Type |
|---|---|---|---|
| 202 Accepted | | The artifact has begun being collected. | |
| 400 Bad Request | [ValidationProblemDetails](definitions.md#validationproblemdetails) | An error occurred due to invalid input. The response body describes the specific problem(s). | `application/problem+json` |
| 401 Unauthorized | | Authentication is required to complete the request. See [Authentication](./../authentication.md) for further information. | |
| 429 Too Many Requests | | There are too many parameters requests at this time. Try to request parameters at a later time. | `application/problem+json` |

## `UserCode` vs `SystemCode`

Methods that belong to any of the following namespaces are considered `SystemCode`:
- `Microsoft.*`
- `System.*`

All other methods are considered `UserCode`. `UserCode` methods will have their parameters captured inline, meaning that the added log statements are performed synchronously inside your method, preserving the logger's scope.

`SystemCode` methods will have their parameters captured asynchronously and without scope information.

The [examples](#examples) include a mixture of `UserCode` and `SystemCode` to help showcase the difference.

## Logger Categories

The following logger categories are used inside the target application when capturing parameters:
| Category Name | Description |
| -- | -- |
| `DotnetMonitor.ParameterCapture.UserCode` | Parameters captured in methods considered `UserCode`. |
| `DotnetMonitor.ParameterCapture.SystemCode` | Parameters captured in methods considered `SystemCode`. |
| `DotnetMonitor.ParameterCapture.Service` | Diagnostic messages by `dotnet-monitor`, such as when parameter capturing starts, stops, or is unable to find a requested method. |

## Examples

### Sample Request

```http
POST /parameters?pid=21632&durationSeconds=60 HTTP/1.1
Host: localhost:52323
Authorization: Bearer fffffffffffffffffffffffffffffffffffffffffff=
{
"methods": [
{
"moduleName": "SampleWebApp.dll",
"typeName": "SampleWebApp.Controllers.HomeController",
"methodName": "Index"
},
{
"moduleName": "System.Private.CoreLib.dll",
"typeName": "System.String",
"methodName": "Concat"
}
]
}
```

### Sample Response

```http
HTTP/1.1 202 Accepted
Content-Type: application/json
Location: localhost:52323/operations/67f07e40-5cca-4709-9062-26302c484f18
```

### Sample Output (Target Application)

```
info: DotnetMonitor.ParameterCapture.UserCode[0]
=> SpanId:e40e62cffe1cf1cb, TraceId:c76b911969aa8abcf335907e96c62b33, ParentId:0000000000000000 => ConnectionId:0HMT2D6L8GT2Q => RequestPath:/ RequestId:0HMT2D6L8GT2Q:00000003 => SampleWebApp.Controllers.HomeController.Index (SampleWebApp)
SampleWebApp.Controllers.HomeController.Index(
this: 'SampleWebApp.Controllers.HomeController',
number: 10)
info: DotnetMonitor.ParameterCapture.SystemCode[0]
System.String.Concat(
str0: 'firstString',
str1: '.secondString')
```

## Supported Runtimes

| Operating System | Runtime Version |
|---|---|
| Windows | .NET 7+ |
| Linux | .NET 7+ |
| MacOS | .NET 7+ |

## Additional Requirements

- The target application must use ASP.NET Core.
- `dotnet-monitor` must be set to `Listen` mode, and the target application must start suspended. See [diagnostic port configuration](../configuration/diagnostic-port-configuration.md) for information on how to do this.
- The target application must have [`ILogger`](https://learn.microsoft.com/dotnet/api/microsoft.extensions.logging.ilogger) available via [ASP.NET Core's dependency injection](https://learn.microsoft.com/aspnet/core/fundamentals/dependency-injection).
- This feature relies on a hosting startup assembly. If the target application [disabled automatic loading](https://learn.microsoft.com/aspnet/core/fundamentals/host/platform-specific-configuration#disable-automatic-loading-of-hosting-startup-assemblies) of these, this feature will not be available.
jander-msft marked this conversation as resolved.
Show resolved Hide resolved
- This feature relies on a [ICorProfilerCallback](https://docs.microsoft.com/dotnet/framework/unmanaged-api/profiling/icorprofilercallback-interface) implementation. If the target application is already using an `ICorProfiler` that isn't notify-only, this feature will not be available.
- If a target application is using .NET 7 then the `dotnet-monitor` startup hook must be configured. This is automatically done in .NET 8+.
schmittjoseph marked this conversation as resolved.
Show resolved Hide resolved

## Additional Notes

### Unsupported Parameters

Currently some types of parameters are unable to be captured. When a method contains one of these unsupported types, the parameter's value will be represented as `<unsupported>`. Other parameters in the method will still be captured so long as they are supported. The most common unsupported types are listed below.

| Parameter Type | Example |
schmittjoseph marked this conversation as resolved.
Show resolved Hide resolved
| -- | -- |
| [Generic type parameters](https://learn.microsoft.com/dotnet/csharp/programming-guide/generics/generic-type-parameters) | `MyMethod<T>(T t)` |
| [`IntPtr`](https://learn.microsoft.com/dotnet/api/system.intptr) and [`UIntPtr`](https://learn.microsoft.com/dotnet/api/system.uintptr) | `IntPtr i` |
| Parameters with pass-by-reference modifiers ([`in`](https://learn.microsoft.com/dotnet/csharp/language-reference/keywords/in-parameter-modifier), [`out`](https://learn.microsoft.com/dotnet/csharp/language-reference/keywords/out-parameter-modifier), and [`ref`](https://learn.microsoft.com/dotnet/csharp/language-reference/keywords/ref)) | `ref int i` |
| [Nullable value types](https://learn.microsoft.com/dotnet/csharp/language-reference/builtin-types/nullable-value-types) | `int?` |
| [Pointers](https://learn.microsoft.com/dotnet/csharp/language-reference/unsafe-code#pointer-types) | `void*` |
| [Tuples](https://learn.microsoft.com/dotnet/csharp/language-reference/builtin-types/value-tuples) | `(int, int)` |
| [Value types](https://learn.microsoft.com/dotnet/csharp/language-reference/builtin-types/value-types) defined in another assembly | `MyModule.dll!MyClass.MyMethod(HttpStatusCode s)` since [`HttpStatusCode`](https://learn.microsoft.com/dotnet/api/system.net.httpstatuscode) is an [`enum`](https://learn.microsoft.com/dotnet/csharp/language-reference/builtin-types/enum) |

### When to use `pid` vs `uid`

See [Process ID `pid` vs Unique ID `uid`](pidvsuid.md) for clarification on when it is best to use either parameter.
2 changes: 1 addition & 1 deletion documentation/experimental.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,5 +6,5 @@ The following are the current set of experimental features:

| Name | Description | First Available Version | How to Enable |
|---|---|---|---|
| [Parameter Capturing](./api/parameters.md) | Captures parameters for one or more methods each time they are called. | 8.0 RC 1 | [Documentation](./api/parameters.md#enabling)

As of 8.0 Preview 7, there are no experimental features.