diff --git a/.github/learning-path-sha.txt b/.github/learning-path-sha.txt index 73bcecd7c34..9bacc45440c 100644 --- a/.github/learning-path-sha.txt +++ b/.github/learning-path-sha.txt @@ -1 +1 @@ -8e99fe93461686b50ea276b406c5046b252b05e4 \ No newline at end of file +3c31273c42196ec0813b7b5b947ab8e1bd1801ac \ No newline at end of file diff --git a/.github/linters/check-markdown-links-config.json b/.github/linters/check-markdown-links-config.json index 49b07a50043..ef2b131a34c 100644 --- a/.github/linters/check-markdown-links-config.json +++ b/.github/linters/check-markdown-links-config.json @@ -11,6 +11,9 @@ }, { "pattern": "^https://www\\.dotnetfoundation.org/.*" + }, + { + "pattern": "^https://hub\\.docker\\.com/.*" } ], "aliveStatusCodes": [ diff --git a/.github/releases.json b/.github/releases.json index f27bde51f6a..33a60321956 100644 --- a/.github/releases.json +++ b/.github/releases.json @@ -13,8 +13,7 @@ "unsupported": [ "7.3", "7.2", - "7.1", - "7.0" + "7.1" ], "releases": { "6.3": { @@ -26,16 +25,6 @@ "netcoreapp3.1" ] }, - "7.0": { - "tag": "v7.0.2", - "minorReleaseDate": "2022-11-11T00:00:00.000Z", - "patchReleaseDate": "2023-02-14T00:00:00.000Z", - "supportedFrameworks": [ - "net6.0", - "net7.0" - ], - "outOfSupportDate": "2023-06-14T00:00:00.000Z" - }, "7.1": { "tag": "v7.1.3", "minorReleaseDate": "2023-03-14T00:00:00.000Z", @@ -75,9 +64,9 @@ "outOfSupportDate": "2024-05-14T00:00:00.000Z" }, "9.0": { - "tag": "v9.0.0-preview.4.24270.1", - "minorReleaseDate": "2024-05-21T00:00:00.000Z", - "patchReleaseDate": "2024-05-21T00:00:00.000Z", + "tag": "v9.0.0-preview.5.24307.6", + "minorReleaseDate": "2024-06-11T00:00:00.000Z", + "patchReleaseDate": "2024-06-11T00:00:00.000Z", "supportedFrameworks": [ "net9.0" ] diff --git a/.github/workflows/check-markdown-links.yml b/.github/workflows/check-markdown-links.yml index eecf9969116..cd7e01d655b 100644 --- a/.github/workflows/check-markdown-links.yml +++ b/.github/workflows/check-markdown-links.yml @@ -19,7 +19,7 @@ jobs: persist-credentials: false - name: Check markdown links - uses: gaurav-nelson/github-action-markdown-link-check@5c5dfc0ac2e225883c0e5f03a85311ec2830d368 + uses: gaurav-nelson/github-action-markdown-link-check@7d83e59a57f3c201c76eed3d33dff64ec4452d27 with: config-file: .github/linters/check-markdown-links-config.json use-quiet-mode: 'yes' diff --git a/.github/workflows/spellcheck.yml b/.github/workflows/spellcheck.yml index f959d793362..e43eec26e12 100644 --- a/.github/workflows/spellcheck.yml +++ b/.github/workflows/spellcheck.yml @@ -17,7 +17,7 @@ jobs: with: persist-credentials: false - - uses: streetsidesoftware/cspell-action@104110db58e8c9a11c1c6be025e2082f4dded3bb + - uses: streetsidesoftware/cspell-action@542d05c6a8980c81277ec229f9beadf4ab3f5a34 name: Documentation spellcheck if: ${{ !cancelled() }} with: @@ -25,7 +25,7 @@ jobs: inline: error incremental_files_only: true - - uses: streetsidesoftware/cspell-action@104110db58e8c9a11c1c6be025e2082f4dded3bb + - uses: streetsidesoftware/cspell-action@542d05c6a8980c81277ec229f9beadf4ab3f5a34 name: Resx spellcheck if: ${{ !cancelled() }} with: @@ -33,7 +33,7 @@ jobs: inline: error incremental_files_only: true - - uses: streetsidesoftware/cspell-action@104110db58e8c9a11c1c6be025e2082f4dded3bb + - uses: streetsidesoftware/cspell-action@542d05c6a8980c81277ec229f9beadf4ab3f5a34 name: Source code spellcheck if: ${{ !cancelled() }} with: diff --git a/.github/workflows/submit-linter-suggestions.yml b/.github/workflows/submit-linter-suggestions.yml index cc98a9b091b..667e4f3eb77 100644 --- a/.github/workflows/submit-linter-suggestions.yml +++ b/.github/workflows/submit-linter-suggestions.yml @@ -49,7 +49,7 @@ jobs: # The default artifact download action doesn't support cross-workflow # artifacts, so use a 3rd party one. - name: 'Download linting results' - uses: dawidd6/action-download-artifact@09f2f74827fd3a8607589e5ad7f9398816f540fe + uses: dawidd6/action-download-artifact@bf251b5aa9c2f7eeb574a96ee720e24f801b7c11 with: workflow: ${{env.workflow_name}} run_id: ${{github.event.workflow_run.id }} diff --git a/.github/workflows/submit-to-do-issue.yml b/.github/workflows/submit-to-do-issue.yml index 518ac4a701e..cb39366f211 100644 --- a/.github/workflows/submit-to-do-issue.yml +++ b/.github/workflows/submit-to-do-issue.yml @@ -35,7 +35,7 @@ jobs: # The default artifact download action doesn't support cross-workflow # artifacts, so use a 3rd party one. - name: 'Download linting results' - uses: dawidd6/action-download-artifact@09f2f74827fd3a8607589e5ad7f9398816f540fe + uses: dawidd6/action-download-artifact@bf251b5aa9c2f7eeb574a96ee720e24f801b7c11 with: workflow: ${{env.workflow_name}} run_id: ${{github.event.workflow_run.id }} diff --git a/cspell.json b/cspell.json index c2bf4198c58..ebb62e70107 100644 --- a/cspell.json +++ b/cspell.json @@ -66,6 +66,7 @@ "msbuild", "msdata", "MSRC", + "mvid", "ndjson", "netcoreapp", "newtonsoft", diff --git a/documentation/api/definitions.md b/documentation/api/definitions.md index b7b55aa2571..a779a5b2689 100644 --- a/documentation/api/definitions.md +++ b/documentation/api/definitions.md @@ -35,8 +35,11 @@ First Available: 8.0 Preview 7 | Name | Type | Description | |---|---|---| | `methodName` | string | Name of the method for this frame. This includes generic parameters. | +| `methodToken` | int | TypeDef token for the method. | +| `parameterTypes` | string[] | Array of parameter types. Empty array if none. | | `typeName` | string | Name of the class for this frame. This includes generic parameters. | | `moduleName` | string | Name of the module for this frame. | +| `moduleVersionId` | guid | Unique identifier used to distinguish between two versions of the same module. An empty value: `00000000-0000-0000-0000-000000000000`. | ## CallStackResult @@ -54,7 +57,7 @@ Object describing the basic state of a collection rule for the executing instanc | Name | Type | Description | |---|---|---| -| State | [CollectionRuleState](#collectionrulestate-63) | Indicates what state the collection rule is in for the current process. | +| State | [CollectionRuleState](#collectionrulestate) | Indicates what state the collection rule is in for the current process. | | StateReason | string | Human-readable explanation for the current state of the collection rule. | ## CollectionRuleDetailedDescription @@ -65,7 +68,7 @@ Object describing the detailed state of a collection rule for the executing inst | Name | Type | Description | |---|---|---| -| State | [CollectionRuleState](#collectionrulestate-63) | Indicates what state the collection rule is in for the current process. | +| State | [CollectionRuleState](#collectionrulestate) | Indicates what state the collection rule is in for the current process. | | StateReason | string | Human-readable explanation for the current state of the collection rule. | | LifetimeOccurrences | int | The number of times the trigger has executed for a process in its lifetime. | | SlidingWindowOccurrences | int | The number of times the trigger has executed within the current sliding window. | diff --git a/documentation/api/exceptions.md b/documentation/api/exceptions.md index 764000cdb28..904e83f2733 100644 --- a/documentation/api/exceptions.md +++ b/documentation/api/exceptions.md @@ -126,8 +126,54 @@ Accept: application/x-ndjson HTTP/1.1 200 OK Content-Type: application/x-ndjson -{"id":2,"timestamp":"2023-07-13T21:45:11.8056355Z","typeName":"System.InvalidOperationException","moduleName":"System.Private.CoreLib.dll","message":"Operation is not valid due to the current state of the object.","innerExceptions":[],"stack":{"threadId":4768,"threadName":null,"frames":[{"methodName":"MoveNext","parameterTypes":[],"typeName":"WebApplication3.Pages.IndexModel\u002B\u003CGetData\u003Ed__3","moduleName":"WebApplication3.dll"},{"methodName":"RunInternal","parameterTypes":["System.Threading.ExecutionContext","System.Threading.ContextCallback","System.Object"],"typeName":"System.Threading.ExecutionContext","moduleName":"System.Private.CoreLib.dll"},{"methodName":"MoveNext","parameterTypes":["System.Threading.Thread"],"typeName":"System.Runtime.CompilerServices.AsyncTaskMethodBuilder\u00601\u002BAsyncStateMachineBox\u00601[System.Runtime.CompilerServices.AsyncTaskMethodBuilder\u00601\u002BAsyncStateMachineBox\u00601\u002BTResult,System.Runtime.CompilerServices.AsyncTaskMethodBuilder\u00601\u002BAsyncStateMachineBox\u00601\u002BTStateMachine]","moduleName":"System.Private.CoreLib.dll"},{"methodName":"\u003COutputCorrelationEtwEvent\u003Eb__6_0","parameterTypes":["System.Action","System.Threading.Tasks.Task"],"typeName":"System.Runtime.CompilerServices.YieldAwaitable\u002BYieldAwaiter\u002B\u003C\u003Ec","moduleName":"System.Private.CoreLib.dll"},{"methodName":"Dispatch","parameterTypes":[],"typeName":"System.Threading.ThreadPoolWorkQueue","moduleName":"System.Private.CoreLib.dll"},{"methodName":"WorkerThreadStart","parameterTypes":[],"typeName":"System.Threading.PortableThreadPool\u002BWorkerThread","moduleName":"System.Private.CoreLib.dll"}]}} -{"id":3,"timestamp":"2023-07-13T21:46:18.7530773Z","typeName":"System.ObjectDisposedException","moduleName":"System.Private.CoreLib.dll","message":"Cannot access a disposed object.\r\nObject name: \u0027System.Net.Sockets.NetworkStream\u0027.","innerExceptions":[],"stack":{"threadId":15912,"threadName":null,"frames":[{"methodName":"ThrowObjectDisposedException","parameterTypes":["System.Object"],"typeName":"System.ThrowHelper","moduleName":"System.Private.CoreLib.dll"},{"methodName":"ThrowIf","parameterTypes":["System.Boolean","System.Object"],"typeName":"System.ObjectDisposedException","moduleName":"System.Private.CoreLib.dll"},{"methodName":"ReadAsync","parameterTypes":["System.Memory\u00601[[System.Byte, System.Private.CoreLib, Version=8.0.0.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e]][System.Byte]","System.Threading.CancellationToken"],"typeName":"System.Net.Sockets.NetworkStream","moduleName":"System.Net.Sockets.dll"},{"methodName":"MoveNext","parameterTypes":[],"typeName":"System.Net.Http.HttpConnection\u002B\u003C\u003CEnsureReadAheadTaskHasStarted\u003Eg__ReadAheadWithZeroByteReadAsync|43_0\u003Ed","moduleName":"System.Net.Http.dll"},{"methodName":"ExecutionContextCallback","parameterTypes":["System.Object"],"typeName":"System.Runtime.CompilerServices.AsyncTaskMethodBuilder\u00601\u002BAsyncStateMachineBox\u00601[System.Runtime.CompilerServices.AsyncTaskMethodBuilder\u00601\u002BAsyncStateMachineBox\u00601\u002BTResult,System.Runtime.CompilerServices.AsyncTaskMethodBuilder\u00601\u002BAsyncStateMachineBox\u00601\u002BTStateMachine]","moduleName":"System.Private.CoreLib.dll"},{"methodName":"RunInternal","parameterTypes":["System.Threading.ExecutionContext","System.Threading.ContextCallback","System.Object"],"typeName":"System.Threading.ExecutionContext","moduleName":"System.Private.CoreLib.dll"},{"methodName":"MoveNext","parameterTypes":["System.Threading.Thread"],"typeName":"System.Runtime.CompilerServices.AsyncTaskMethodBuilder\u00601\u002BAsyncStateMachineBox\u00601[System.Runtime.CompilerServices.AsyncTaskMethodBuilder\u00601\u002BAsyncStateMachineBox\u00601\u002BTResult,System.Runtime.CompilerServices.AsyncTaskMethodBuilder\u00601\u002BAsyncStateMachineBox\u00601\u002BTStateMachine]","moduleName":"System.Private.CoreLib.dll"},{"methodName":"MoveNext","parameterTypes":[],"typeName":"System.Runtime.CompilerServices.AsyncTaskMethodBuilder\u00601\u002BAsyncStateMachineBox\u00601[System.Runtime.CompilerServices.AsyncTaskMethodBuilder\u00601\u002BAsyncStateMachineBox\u00601\u002BTResult,System.Runtime.CompilerServices.AsyncTaskMethodBuilder\u00601\u002BAsyncStateMachineBox\u00601\u002BTStateMachine]","moduleName":"System.Private.CoreLib.dll"},{"methodName":"\u003C.cctor\u003Eb__176_0","parameterTypes":["System.UInt32","System.UInt32","System.Threading.NativeOverlapped*"],"typeName":"System.Net.Sockets.SocketAsyncEventArgs\u002B\u003C\u003Ec","moduleName":"System.Net.Sockets.dll"},{"methodName":"Invoke","parameterTypes":["System.Threading.PortableThreadPool\u002BIOCompletionPoller\u002BEvent"],"typeName":"System.Threading.PortableThreadPool\u002BIOCompletionPoller\u002BCallback","moduleName":"System.Private.CoreLib.dll"},{"methodName":"System.Threading.IThreadPoolWorkItem.Execute","parameterTypes":[],"typeName":"System.Threading.ThreadPoolTypedWorkItemQueue\u00602[System.Threading.ThreadPoolTypedWorkItemQueue\u00602\u002BT,System.Threading.ThreadPoolTypedWorkItemQueue\u00602\u002BTCallback]","moduleName":"System.Private.CoreLib.dll"},{"methodName":"Dispatch","parameterTypes":[],"typeName":"System.Threading.ThreadPoolWorkQueue","moduleName":"System.Private.CoreLib.dll"},{"methodName":"WorkerThreadStart","parameterTypes":[],"typeName":"System.Threading.PortableThreadPool\u002BWorkerThread","moduleName":"System.Private.CoreLib.dll"}]}} +{ + "id": 2, + "timestamp": "2023-07-13T21:45:11.8056355Z", + "typeName": "System.InvalidOperationException", + "moduleName": "System.Private.CoreLib.dll", + "message": "Operation is not valid due to the current state of the object.", + "innerExceptions": [], + "stack": { + "threadId": 4768, + "threadName": null, + "frames": [ + { + "methodName": "MoveNext", + "methodToken": 100663639, + "parameterTypes": [], + "typeName": "WebApplication3.Pages.IndexModel\u002B\u003CGetData\u003Ed__3", + "moduleName": "WebApplication3.dll", + "moduleVersionId": "bf769014-c2e2-496a-93b7-76fbbcd04be5" + }, + ... // see stacks.md + ] + } +} +{ + "id": 3, + "timestamp": "2023-07-13T21:46:18.7530773Z", + "typeName": "System.ObjectDisposedException", + "moduleName": "System.Private.CoreLib.dll", + "message": "Cannot access a disposed object.\r\nObject name: \u0027System.Net.Sockets.NetworkStream\u0027.", + "innerExceptions": [], + "stack": { + "threadId": 15912, + "threadName": null, + "frames": [ + { + "methodName": "ThrowObjectDisposedException", + "methodToken": 100663639, + "parameterTypes": [ + "System.Object" + ], + "typeName": "System.ThrowHelper", + "moduleName": "System.Private.CoreLib.dll", + "moduleVersionId": "bf769014-c2e2-496a-93b7-76fbbcd04be5" + }, + ... // see stacks.md + ] + } +} ``` ## Supported Runtimes diff --git a/documentation/api/parameters.md b/documentation/api/parameters.md index 2bf5c886da3..93891024716 100644 --- a/documentation/api/parameters.md +++ b/documentation/api/parameters.md @@ -128,13 +128,10 @@ Content-Type: application/x-ndjson ## Additional Requirements -- The target application must use ASP.NET Core. - The target application cannot have [Hot Reload](https://learn.microsoft.com/visualstudio/debugger/hot-reload) enabled. -- `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. +- `dotnet-monitor` must be set to `Listen` mode. See [diagnostic port configuration](../configuration/diagnostic-port-configuration.md) for information on how to do this. +- If the target application is using .NET 7 then the dotnet-monitor startup hook must be manually configured and the target application must start suspended. In .NET 8+ this is not a requirement. - 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+. ## Additional Notes diff --git a/documentation/api/stacks.md b/documentation/api/stacks.md index 7efd903dd52..eeec2510332 100644 --- a/documentation/api/stacks.md +++ b/documentation/api/stacks.md @@ -62,7 +62,7 @@ Allowed schemes: ### Sample Request ```http -GET /stack?pid=21632 HTTP/1.1 +GET /stacks?pid=21632 HTTP/1.1 Host: localhost:52323 Authorization: Bearer fffffffffffffffffffffffffffffffffffffffffff= Accept: application/json @@ -81,26 +81,40 @@ Location: localhost:52323/operations/67f07e40-5cca-4709-9062-26302c484f18 "frames": [ { "methodName": "GetQueuedCompletionStatus", + "methodToken": 100663634, + "parameterTypes": [], "typeName": "Interop\u002BKernel32", "moduleName": "System.Private.CoreLib.dll", + "moduleVersionId": "194ddabd-a802-4520-90ef-854e2f1cd606" }, { "methodName": "WaitForSignal", + "methodToken": 100663639, + "parameterTypes": [ + "System.Threading.ExecutionContext", + "System.Threading.ContextCallback", + "System.Object" + ], "typeName": "System.Threading.LowLevelLifoSemaphore", "moduleName": "System.Private.CoreLib.dll", + "moduleVersionId": "194ddabd-a802-4520-90ef-854e2f1cd606" }, { "methodName": "Wait", + "methodToken": 100663643, + "parameterTypes": [], "typeName": "System.Threading.LowLevelLifoSemaphore", "moduleName": "System.Private.CoreLib.dll", + "moduleVersionId": "194ddabd-a802-4520-90ef-854e2f1cd606" } + ] } ``` ### Sample Request ```http -GET /stack?pid=21632 HTTP/1.1 +GET /stacks?pid=21632 HTTP/1.1 Host: localhost:52323 Authorization: Bearer fffffffffffffffffffffffffffffffffffffffffff= Accept: text/plain diff --git a/documentation/configuration/egress-configuration.md b/documentation/configuration/egress-configuration.md index a457175bfe9..29bda145496 100644 --- a/documentation/configuration/egress-configuration.md +++ b/documentation/configuration/egress-configuration.md @@ -159,6 +159,8 @@ The Queue Message's payload will be the blob name (`/` | preSignedUrlExpiry | TimeStamp? | false | When specified, a pre-signed url is returned after successful upload; this value specifies the amount of time the generated pre-signed url should be accessible. The value has to be between 1 minute and 1 day. | | forcePathStyle | bool | false | The boolean flag set for AWS connection configuration ForcePathStyle option. | | copyBufferSize | int | false | The buffer size to use when copying data from the original artifact to the blob stream. There is a minimum size of 5 MB which is set when the given value is lower.| +| useKmsEncryption | bool | false | A boolean flag which controls whether the Egress should use KMS server side encryption. | +| kmsEncryptionKey | string | false | If UseKmsEncryption is true, this specifies the arn of the "customer managed" KMS encryption key to be used for server side encryption. If no value is set for this field then S3 will use an AWS managed key for KMS encryption. | ### Example S3 storage provider @@ -184,6 +186,25 @@ The Queue Message's payload will be the blob name (`/` ``` +
+ JSON with customer managed KMS encryption + + ```json + { + "Egress": { + "S3Storage": { + "monitorS3Blob": { + "endpoint": "http://localhost:9000", + "bucketName": "myS3Bucket", + "useKmsEncryption": true, + "kmsEncryptionKey": "arn:aws:kms:{region}:{account-id}:key/{resource-id}" + } + } + } + } + ``` +
+
Kubernetes Secret diff --git a/documentation/configuration/in-process-features-configuration.md b/documentation/configuration/in-process-features-configuration.md index 26d7578259d..b8503cc1215 100644 --- a/documentation/configuration/in-process-features-configuration.md +++ b/documentation/configuration/in-process-features-configuration.md @@ -4,6 +4,10 @@ First Available: 8.0 Preview 7 +> [!NOTE] +> In-process features are only supported when running dotnet-monitor in `Listen` mode. +> See [Diagnostic Port](./diagnostic-port-configuration.md) configuration for details. + Some features of `dotnet monitor` require loading libraries into target applications. These libraries ship with `dotnet monitor` and are provisioned to be available to target applications using the `DefaultSharedPath` option in the [storage configuration](./storage-configuration.md) section. The following features require these in-process libraries to be used: - [Call Stacks](#call-stacks) diff --git a/documentation/learningPath/aks.md b/documentation/learningPath/aks.md index aad93a54a57..92ae857e025 100644 --- a/documentation/learningPath/aks.md +++ b/documentation/learningPath/aks.md @@ -9,7 +9,7 @@ In addition to its availability as a .NET CLI tool, the `dotnet monitor` tool is This workflow takes your local development copy of `dotnet-monitor`, patches it with a local development copy of the [.NET Core Diagnostics Repo](https://github.com/dotnet/diagnostics#net-core-diagnostics-repo), and makes it available as an image for you to consume in an ACR (Azure Container Registry). Note that there are many other ways to do this - this is meant to serve as a basic template that can be adapted to match your needs. -1. Open `pwsh` and run the [generate-dev-sln script](https://github.com/dotnet/dotnet-monitor/blob/8e99fe93461686b50ea276b406c5046b252b05e4/generate-dev-sln.ps1), providing a path to your local copy of the diagnostics repo. +1. Open `pwsh` and run the [generate-dev-sln script](https://github.com/dotnet/dotnet-monitor/blob/3c31273c42196ec0813b7b5b947ab8e1bd1801ac/generate-dev-sln.ps1), providing a path to your local copy of the diagnostics repo. > [!NOTE] > If your changes do not involve the [.NET Core Diagnostics Repo](https://github.com/dotnet/diagnostics#net-core-diagnostics-repo), you don't need to complete this step. diff --git a/documentation/learningPath/api.md b/documentation/learningPath/api.md index c12c0b152f6..21048146453 100644 --- a/documentation/learningPath/api.md +++ b/documentation/learningPath/api.md @@ -7,15 +7,15 @@ dotnet-monitor exposes functionality through both [collection rules](./collectio ## Adding New APIs -The web API surface is defined by a series of controllers [here](https://github.com/dotnet/dotnet-monitor/blob/8e99fe93461686b50ea276b406c5046b252b05e4/src/Microsoft.Diagnostics.Monitoring.WebApi/Controllers/). It's common for an API to expose functionality also available via [Actions](./collectionrules.md#actions) and so methods in these controllers are often wrappers around a shared implementation. Each controller may have one or more attributes that configure how and where it is exposed, you can learn more about the notable controller attributes [here](#notable-controller-attributes). +The web API surface is defined by a series of controllers [here](https://github.com/dotnet/dotnet-monitor/blob/3c31273c42196ec0813b7b5b947ab8e1bd1801ac/src/Microsoft.Diagnostics.Monitoring.WebApi/Controllers/). It's common for an API to expose functionality also available via [Actions](./collectionrules.md#actions) and so methods in these controllers are often wrappers around a shared implementation. Each controller may have one or more attributes that configure how and where it is exposed, you can learn more about the notable controller attributes [here](#notable-controller-attributes). -If the new API needs to either accept or return structured data, a dedicated model should be used. Models are defined [here](https://github.com/dotnet/dotnet-monitor/blob/8e99fe93461686b50ea276b406c5046b252b05e4/src/Microsoft.Diagnostics.Monitoring.WebApi/Models/). +If the new API needs to either accept or return structured data, a dedicated model should be used. Models are defined [here](https://github.com/dotnet/dotnet-monitor/blob/3c31273c42196ec0813b7b5b947ab8e1bd1801ac/src/Microsoft.Diagnostics.Monitoring.WebApi/Models/). When adding a new API, it's important to also update the [`openapi.json`](../openapi.json) spec which describes the API surface. There are CI tests that will ensure this file has been updated to reflect any API changes. Learn more about updating `openapi.json` [here](./testing.md#openapi-generation). ### Adding Tests -Web APIs in dotnet-monitor are typically tested using functional tests that leverage the [ApiClient](https://github.com/dotnet/dotnet-monitor/blob/8e99fe93461686b50ea276b406c5046b252b05e4/src/Tests/Microsoft.Diagnostics.Monitoring.Tool.FunctionalTests/HttpApi/ApiClient.cs) to call a specific API. Learn more about how the functional tests are defined and operate [here](./testing.md#functional-tests). +Web APIs in dotnet-monitor are typically tested using functional tests that leverage the [ApiClient](https://github.com/dotnet/dotnet-monitor/blob/3c31273c42196ec0813b7b5b947ab8e1bd1801ac/src/Tests/Microsoft.Diagnostics.Monitoring.Tool.FunctionalTests/HttpApi/ApiClient.cs) to call a specific API. Learn more about how the functional tests are defined and operate [here](./testing.md#functional-tests). ## Notable Controller Attributes @@ -35,6 +35,6 @@ dotnet-monitor supports multiple different [authentication modes](../authenticat ### Determining Authentication Mode -When dotnet-monitor starts, the command line arguments are first inspected to see if a specific authentication mode was set (such as `--no-auth`), referred to as the `StartupAuthenticationMode`, this is calculated [here](https://github.com/dotnet/dotnet-monitor/blob/8e99fe93461686b50ea276b406c5046b252b05e4/src/Tools/dotnet-monitor/Commands/CollectCommandHandler.cs#L28). If no modes were explicitly set via a command line argument, dotnet-monitor will select `Deferred` as the `StartupAuthenticationMode`. This indicates that the user configuration should be looked at to determine the authentication mode later on in the startup process. +When dotnet-monitor starts, the command line arguments are first inspected to see if a specific authentication mode was set (such as `--no-auth`), referred to as the `StartupAuthenticationMode`, this is calculated [here](https://github.com/dotnet/dotnet-monitor/blob/3c31273c42196ec0813b7b5b947ab8e1bd1801ac/src/Tools/dotnet-monitor/Commands/CollectCommandHandler.cs#L28). If no modes were explicitly set via a command line argument, dotnet-monitor will select `Deferred` as the `StartupAuthenticationMode`. This indicates that the user configuration should be looked at to determine the authentication mode later on in the startup process. -After determining the `StartupAuthenticationMode` mode, the relevant [IAuthenticationConfigurator](https://github.com/dotnet/dotnet-monitor/blob/8e99fe93461686b50ea276b406c5046b252b05e4/src/Tools/dotnet-monitor/Auth/IAuthenticationConfigurator.cs) is created by the [AuthConfiguratorFactory](https://github.com/dotnet/dotnet-monitor/blob/8e99fe93461686b50ea276b406c5046b252b05e4/src/Tools/dotnet-monitor/Auth/AuthConfiguratorFactory.cs). This factory also handles deciding what authentication mode to use when `StartupAuthenticationMode` is `Deferred`. The selected configurator is used to configure various parts of dotnet-monitor that are specific to authentication, such as protecting the web APIs and adding authentication-mode specific logging. +After determining the `StartupAuthenticationMode` mode, the relevant [IAuthenticationConfigurator](https://github.com/dotnet/dotnet-monitor/blob/3c31273c42196ec0813b7b5b947ab8e1bd1801ac/src/Tools/dotnet-monitor/Auth/IAuthenticationConfigurator.cs) is created by the [AuthConfiguratorFactory](https://github.com/dotnet/dotnet-monitor/blob/3c31273c42196ec0813b7b5b947ab8e1bd1801ac/src/Tools/dotnet-monitor/Auth/AuthConfiguratorFactory.cs). This factory also handles deciding what authentication mode to use when `StartupAuthenticationMode` is `Deferred`. The selected configurator is used to configure various parts of dotnet-monitor that are specific to authentication, such as protecting the web APIs and adding authentication-mode specific logging. diff --git a/documentation/learningPath/collectionrules.md b/documentation/learningPath/collectionrules.md index acf678a6e99..a95eb10e546 100644 --- a/documentation/learningPath/collectionrules.md +++ b/documentation/learningPath/collectionrules.md @@ -32,49 +32,49 @@ graph LR ### Key Areas Of The Code -* Collection rules are registered [here](https://github.com/dotnet/dotnet-monitor/blob/8e99fe93461686b50ea276b406c5046b252b05e4/src/Tools/dotnet-monitor/ServiceCollectionExtensions.cs#L140). When adding a new trigger or action, these types need to be added here to take effect. This section is also responsible for making sure options get configured and validated. -* Options for collection rules can be found [here](https://github.com/dotnet/dotnet-monitor/blob/8e99fe93461686b50ea276b406c5046b252b05e4/src/Tools/dotnet-monitor/CollectionRules/Options/CollectionRuleOptions.cs). -* Rules are applied, removed, and restarted in response to configuration changes [here](https://github.com/dotnet/dotnet-monitor/blob/8e99fe93461686b50ea276b406c5046b252b05e4/src/Tools/dotnet-monitor/CollectionRules/CollectionRuleService.cs). This is also responsible for generating a description of each collection rule's state for the `/collectionrules` API Endpoint. -* The pipeline responsible for the lifetime of a single executing collection rule can be found [here](https://github.com/dotnet/dotnet-monitor/blob/8e99fe93461686b50ea276b406c5046b252b05e4/src/Tools/dotnet-monitor/CollectionRules/CollectionRulePipeline.cs#L54). -* To run collection rules, `dotnet monitor` must be in `Listen` mode - this is set via [DiagnosticPortOptions](https://github.com/dotnet/dotnet-monitor/blob/8e99fe93461686b50ea276b406c5046b252b05e4/src/Microsoft.Diagnostics.Monitoring.Options/DiagnosticPortOptions.cs). +* Collection rules are registered [here](https://github.com/dotnet/dotnet-monitor/blob/3c31273c42196ec0813b7b5b947ab8e1bd1801ac/src/Tools/dotnet-monitor/ServiceCollectionExtensions.cs#L141). When adding a new trigger or action, these types need to be added here to take effect. This section is also responsible for making sure options get configured and validated. +* Options for collection rules can be found [here](https://github.com/dotnet/dotnet-monitor/blob/3c31273c42196ec0813b7b5b947ab8e1bd1801ac/src/Tools/dotnet-monitor/CollectionRules/Options/CollectionRuleOptions.cs). +* Rules are applied, removed, and restarted in response to configuration changes [here](https://github.com/dotnet/dotnet-monitor/blob/3c31273c42196ec0813b7b5b947ab8e1bd1801ac/src/Tools/dotnet-monitor/CollectionRules/CollectionRuleService.cs). This is also responsible for generating a description of each collection rule's state for the `/collectionrules` API Endpoint. +* The pipeline responsible for the lifetime of a single executing collection rule can be found [here](https://github.com/dotnet/dotnet-monitor/blob/3c31273c42196ec0813b7b5b947ab8e1bd1801ac/src/Tools/dotnet-monitor/CollectionRules/CollectionRulePipeline.cs#L54). +* To run collection rules, `dotnet monitor` must be in `Listen` mode - this is set via [DiagnosticPortOptions](https://github.com/dotnet/dotnet-monitor/blob/3c31273c42196ec0813b7b5b947ab8e1bd1801ac/src/Microsoft.Diagnostics.Monitoring.Options/DiagnosticPortOptions.cs). * For each type of trigger, the [dotnet diagnostics repo](https://github.com/dotnet/diagnostics/blob/v6.0.351802/src/Microsoft.Diagnostics.Monitoring.EventPipe/Triggers/ITraceEventTrigger.cs#L29) is responsible for determining whether the triggering conditions have been satisfied. ### Triggers -A trigger will monitor for a specific condition in the target application and raise a notification when that condition has been observed. Options for triggers can be found [here](https://github.com/dotnet/dotnet-monitor/blob/8e99fe93461686b50ea276b406c5046b252b05e4/src/Tools/dotnet-monitor/CollectionRules/Options/CollectionRuleTriggerOptions.cs); the type of `Settings` is determined by which trigger is being used (possible trigger types can be found [here](https://github.com/dotnet/dotnet-monitor/tree/8e99fe93461686b50ea276b406c5046b252b05e4/src/Tools/dotnet-monitor/CollectionRules/Options/Triggers)). The interface for all triggers can be found [here](https://github.com/dotnet/dotnet-monitor/blob/8e99fe93461686b50ea276b406c5046b252b05e4/src/Tools/dotnet-monitor/CollectionRules/Triggers/ICollectionRuleTrigger.cs) - this allows `dotnet monitor` to start and stop triggers, regardless of the trigger's properties. The collection rule pipeline creates instances of triggers [here](https://github.com/dotnet/dotnet-monitor/blob/8e99fe93461686b50ea276b406c5046b252b05e4/src/Tools/dotnet-monitor/CollectionRules/CollectionRulePipeline.cs#L99) before waiting for the trigger to [satisfy its conditions](https://github.com/dotnet/diagnostics/blob/v6.0.351802/src/Microsoft.Diagnostics.Monitoring.EventPipe/Triggers/Pipelines/TraceEventTriggerPipeline.cs#L107) - each trigger has its own set of criteria that determines when a trigger has been satisfied. +A trigger will monitor for a specific condition in the target application and raise a notification when that condition has been observed. Options for triggers can be found [here](https://github.com/dotnet/dotnet-monitor/blob/3c31273c42196ec0813b7b5b947ab8e1bd1801ac/src/Tools/dotnet-monitor/CollectionRules/Options/CollectionRuleTriggerOptions.cs); the type of `Settings` is determined by which trigger is being used (possible trigger types can be found [here](https://github.com/dotnet/dotnet-monitor/tree/3c31273c42196ec0813b7b5b947ab8e1bd1801ac/src/Tools/dotnet-monitor/CollectionRules/Options/Triggers)). The interface for all triggers can be found [here](https://github.com/dotnet/dotnet-monitor/blob/3c31273c42196ec0813b7b5b947ab8e1bd1801ac/src/Tools/dotnet-monitor/CollectionRules/Triggers/ICollectionRuleTrigger.cs) - this allows `dotnet monitor` to start and stop triggers, regardless of the trigger's properties. The collection rule pipeline creates instances of triggers [here](https://github.com/dotnet/dotnet-monitor/blob/3c31273c42196ec0813b7b5b947ab8e1bd1801ac/src/Tools/dotnet-monitor/CollectionRules/CollectionRulePipeline.cs#L99) before waiting for the trigger to [satisfy its conditions](https://github.com/dotnet/diagnostics/blob/v6.0.351802/src/Microsoft.Diagnostics.Monitoring.EventPipe/Triggers/Pipelines/TraceEventTriggerPipeline.cs#L107) - each trigger has its own set of criteria that determines when a trigger has been satisfied. ### Actions -Actions allow executing an operation or an external executable in response to a trigger condition being satisfied. Options for actions can be found [here](https://github.com/dotnet/dotnet-monitor/blob/8e99fe93461686b50ea276b406c5046b252b05e4/src/Tools/dotnet-monitor/CollectionRules/Options/CollectionRuleActionOptions.cs); the type of `Settings` is determined by which action is being used (possible action types can be found [here](https://github.com/dotnet/dotnet-monitor/tree/8e99fe93461686b50ea276b406c5046b252b05e4/src/Tools/dotnet-monitor/CollectionRules/Options/Actions)). The interface for all actions can be found [here](https://github.com/dotnet/dotnet-monitor/blob/8e99fe93461686b50ea276b406c5046b252b05e4/src/Tools/dotnet-monitor/CollectionRules/Actions/ICollectionRuleAction.cs) - this allows `dotnet monitor` to start an action, wait for it to complete, and get its output values regardless of the action's properties. The action list is [executed](https://github.com/dotnet/dotnet-monitor/blob/8e99fe93461686b50ea276b406c5046b252b05e4/src/Tools/dotnet-monitor/CollectionRules/CollectionRulePipeline.cs#L149) once the triggering condition has been met (assuming the action list isn't throttled), with each action by default starting without waiting for prior actions to complete. +Actions allow executing an operation or an external executable in response to a trigger condition being satisfied. Options for actions can be found [here](https://github.com/dotnet/dotnet-monitor/blob/3c31273c42196ec0813b7b5b947ab8e1bd1801ac/src/Tools/dotnet-monitor/CollectionRules/Options/CollectionRuleActionOptions.cs); the type of `Settings` is determined by which action is being used (possible action types can be found [here](https://github.com/dotnet/dotnet-monitor/tree/3c31273c42196ec0813b7b5b947ab8e1bd1801ac/src/Tools/dotnet-monitor/CollectionRules/Options/Actions)). The interface for all actions can be found [here](https://github.com/dotnet/dotnet-monitor/blob/3c31273c42196ec0813b7b5b947ab8e1bd1801ac/src/Tools/dotnet-monitor/CollectionRules/Actions/ICollectionRuleAction.cs) - this allows `dotnet monitor` to start an action, wait for it to complete, and get its output values regardless of the action's properties. The action list is [executed](https://github.com/dotnet/dotnet-monitor/blob/3c31273c42196ec0813b7b5b947ab8e1bd1801ac/src/Tools/dotnet-monitor/CollectionRules/CollectionRulePipeline.cs#L149) once the triggering condition has been met (assuming the action list isn't throttled), with each action by default starting without waiting for prior actions to complete. ### Filters -Filters can optionally be applied to a collection rule to choose which processes can trigger the rule. This uses the same set of [options](https://github.com/dotnet/dotnet-monitor/blob/8e99fe93461686b50ea276b406c5046b252b05e4/src/Microsoft.Diagnostics.Monitoring.Options/ProcessFilterOptions.cs#L47) as setting the default process for `dotnet-monitor`. When starting a collection rule, [these filters are used to check if the current process should have the collection rule applied to it](https://github.com/dotnet/dotnet-monitor/blob/8e99fe93461686b50ea276b406c5046b252b05e4/src/Tools/dotnet-monitor/CollectionRules/CollectionRuleContainer.cs#L187); if so, the collection rule starts. +Filters can optionally be applied to a collection rule to choose which processes can trigger the rule. This uses the same set of [options](https://github.com/dotnet/dotnet-monitor/blob/3c31273c42196ec0813b7b5b947ab8e1bd1801ac/src/Microsoft.Diagnostics.Monitoring.Options/ProcessFilterOptions.cs#L47) as setting the default process for `dotnet-monitor`. When starting a collection rule, [these filters are used to check if the current process should have the collection rule applied to it](https://github.com/dotnet/dotnet-monitor/blob/3c31273c42196ec0813b7b5b947ab8e1bd1801ac/src/Tools/dotnet-monitor/CollectionRules/CollectionRuleContainer.cs#L187); if so, the collection rule starts. ### Limits -Limits can optionally be applied to a collection rule to constrain the lifetime of the rule and how often its actions can be run before being throttled. Options for limits can be found [here](https://github.com/dotnet/dotnet-monitor/blob/8e99fe93461686b50ea276b406c5046b252b05e4/src/Tools/dotnet-monitor/CollectionRules/Options/CollectionRuleLimitsOptions.cs). When provided (or when using default values), limits are evaluated in the collection rule pipeline while running. `RuleDuration` is used to [create a token](https://github.com/dotnet/dotnet-monitor/blob/8e99fe93461686b50ea276b406c5046b252b05e4/src/Tools/dotnet-monitor/CollectionRules/CollectionRulePipeline.cs#L79) that shuts down the pipeline. `ActionCountSlidingWindowDuration` does not rely on setting cancellation tokens; rather, the number of executions within the sliding window are checked on-demand [here](https://github.com/dotnet/dotnet-monitor/blob/8e99fe93461686b50ea276b406c5046b252b05e4/src/Microsoft.Diagnostics.Monitoring.WebApi/CollectionRulePipelineState.cs#L211), and `ActionCount` is referenced to determine whether the rule needs to [terminate](https://github.com/dotnet/dotnet-monitor/blob/8e99fe93461686b50ea276b406c5046b252b05e4/src/Microsoft.Diagnostics.Monitoring.WebApi/CollectionRulePipelineState.cs#L194) or [throttle](https://github.com/dotnet/dotnet-monitor/blob/8e99fe93461686b50ea276b406c5046b252b05e4/src/Microsoft.Diagnostics.Monitoring.WebApi/CollectionRulePipelineState.cs#L234). +Limits can optionally be applied to a collection rule to constrain the lifetime of the rule and how often its actions can be run before being throttled. Options for limits can be found [here](https://github.com/dotnet/dotnet-monitor/blob/3c31273c42196ec0813b7b5b947ab8e1bd1801ac/src/Tools/dotnet-monitor/CollectionRules/Options/CollectionRuleLimitsOptions.cs). When provided (or when using default values), limits are evaluated in the collection rule pipeline while running. `RuleDuration` is used to [create a token](https://github.com/dotnet/dotnet-monitor/blob/3c31273c42196ec0813b7b5b947ab8e1bd1801ac/src/Tools/dotnet-monitor/CollectionRules/CollectionRulePipeline.cs#L79) that shuts down the pipeline. `ActionCountSlidingWindowDuration` does not rely on setting cancellation tokens; rather, the number of executions within the sliding window are checked on-demand [here](https://github.com/dotnet/dotnet-monitor/blob/3c31273c42196ec0813b7b5b947ab8e1bd1801ac/src/Microsoft.Diagnostics.Monitoring.WebApi/CollectionRulePipelineState.cs#L211), and `ActionCount` is referenced to determine whether the rule needs to [terminate](https://github.com/dotnet/dotnet-monitor/blob/3c31273c42196ec0813b7b5b947ab8e1bd1801ac/src/Microsoft.Diagnostics.Monitoring.WebApi/CollectionRulePipelineState.cs#L194) or [throttle](https://github.com/dotnet/dotnet-monitor/blob/3c31273c42196ec0813b7b5b947ab8e1bd1801ac/src/Microsoft.Diagnostics.Monitoring.WebApi/CollectionRulePipelineState.cs#L234). ## Miscellaneous ### Trigger Shortcuts -Trigger Shortcuts provide improved defaults, range validation, and a simpler syntax for [several commonly used `EventCounter` triggers](https://github.com/dotnet/dotnet-monitor/tree/8e99fe93461686b50ea276b406c5046b252b05e4/src/Tools/dotnet-monitor/CollectionRules/Options/Triggers/EventCounterShortcuts). These shortcuts provide the same functionality as using the standard `EventCounter` syntax, but have fewer available options (since there is no need to specify the `ProviderName` or the `CounterName`) - as a result, shortcuts do not inherit from `EventCounterOptions`, but rather [IEventCounterShortcuts](https://github.com/dotnet/dotnet-monitor/blob/8e99fe93461686b50ea276b406c5046b252b05e4/src/Tools/dotnet-monitor/CollectionRules/Options/Triggers/EventCounterShortcuts/IEventCounterShortcuts.cs). Each type of shortcut is registered independently [here](https://github.com/dotnet/dotnet-monitor/blob/8e99fe93461686b50ea276b406c5046b252b05e4/src/Tools/dotnet-monitor/ServiceCollectionExtensions.cs#L158). After binding with configuration and undergoing validation, shortcuts are then converted to be treated as `EventCounter` triggers [here](https://github.com/dotnet/dotnet-monitor/blob/8e99fe93461686b50ea276b406c5046b252b05e4/src/Tools/dotnet-monitor/CollectionRules/Triggers/EventCounterTriggerFactory.cs), using their respective defaults instead of the generic ones. +Trigger Shortcuts provide improved defaults, range validation, and a simpler syntax for [several commonly used `EventCounter` triggers](https://github.com/dotnet/dotnet-monitor/tree/3c31273c42196ec0813b7b5b947ab8e1bd1801ac/src/Tools/dotnet-monitor/CollectionRules/Options/Triggers/EventCounterShortcuts). These shortcuts provide the same functionality as using the standard `EventCounter` syntax, but have fewer available options (since there is no need to specify the `ProviderName` or the `CounterName`) - as a result, shortcuts do not inherit from `EventCounterOptions`, but rather [IEventCounterShortcuts](https://github.com/dotnet/dotnet-monitor/blob/3c31273c42196ec0813b7b5b947ab8e1bd1801ac/src/Tools/dotnet-monitor/CollectionRules/Options/Triggers/EventCounterShortcuts/IEventCounterShortcuts.cs). Each type of shortcut is registered independently [here](https://github.com/dotnet/dotnet-monitor/blob/3c31273c42196ec0813b7b5b947ab8e1bd1801ac/src/Tools/dotnet-monitor/ServiceCollectionExtensions.cs#L159). After binding with configuration and undergoing validation, shortcuts are then converted to be treated as `EventCounter` triggers [here](https://github.com/dotnet/dotnet-monitor/blob/3c31273c42196ec0813b7b5b947ab8e1bd1801ac/src/Tools/dotnet-monitor/CollectionRules/Triggers/EventCounterTriggerFactory.cs), using their respective defaults instead of the generic ones. ### Templates -Templates allow users to design reusable collection rule components by associating a name with a piece of configuration. Options for templates can be found [here](https://github.com/dotnet/dotnet-monitor/blob/8e99fe93461686b50ea276b406c5046b252b05e4/src/Tools/dotnet-monitor/CollectionRules/Options/TemplateOptions.cs). Before collection rules undergo validation, `dotnet monitor` checks to see if any of the rule's components in configuration [list the name of a template](https://github.com/dotnet/dotnet-monitor/blob/8e99fe93461686b50ea276b406c5046b252b05e4/src/Tools/dotnet-monitor/CollectionRules/Configuration/CollectionRulePostConfigureNamedOptions.cs) - if so, the collection rule's options are populated from the correspondingly named template. Note that templates undergo the same binding process for triggers/actions as collection rules; however, since templates are treated as separate parts of configuration, this binding instead happens [here](https://github.com/dotnet/dotnet-monitor/blob/8e99fe93461686b50ea276b406c5046b252b05e4/src/Tools/dotnet-monitor/CollectionRules/Configuration/TemplatesConfigureNamedOptions.cs). +Templates allow users to design reusable collection rule components by associating a name with a piece of configuration. Options for templates can be found [here](https://github.com/dotnet/dotnet-monitor/blob/3c31273c42196ec0813b7b5b947ab8e1bd1801ac/src/Tools/dotnet-monitor/CollectionRules/Options/TemplateOptions.cs). Before collection rules undergo validation, `dotnet monitor` checks to see if any of the rule's components in configuration [list the name of a template](https://github.com/dotnet/dotnet-monitor/blob/3c31273c42196ec0813b7b5b947ab8e1bd1801ac/src/Tools/dotnet-monitor/CollectionRules/Configuration/CollectionRulePostConfigureNamedOptions.cs) - if so, the collection rule's options are populated from the correspondingly named template. Note that templates undergo the same binding process for triggers/actions as collection rules; however, since templates are treated as separate parts of configuration, this binding instead happens [here](https://github.com/dotnet/dotnet-monitor/blob/3c31273c42196ec0813b7b5b947ab8e1bd1801ac/src/Tools/dotnet-monitor/CollectionRules/Configuration/TemplatesConfigureNamedOptions.cs). ### Collection Rule Defaults -Defaults can be used to limit the verbosity of configuration, allowing frequently used values for collection rules to be assigned as defaults. Options for collection rule defaults can be found [here](https://github.com/dotnet/dotnet-monitor/blob/8e99fe93461686b50ea276b406c5046b252b05e4/src/Tools/dotnet-monitor/CollectionRules/Options/CollectionRuleDefaultsOptions.cs). These defaults are merged with the user's provided configuration [here](https://github.com/dotnet/dotnet-monitor/blob/8e99fe93461686b50ea276b406c5046b252b05e4/src/Tools/dotnet-monitor/CollectionRules/Options/DefaultCollectionRulePostConfigureOptions.cs) - any properties that the user hasn't set (that have corresponding default values) will be updated at this point to use the default values. This step occurs prior to `dotnet monitor` attempting to use its built-in defaults, which allows user defaults to take precedence. +Defaults can be used to limit the verbosity of configuration, allowing frequently used values for collection rules to be assigned as defaults. Options for collection rule defaults can be found [here](https://github.com/dotnet/dotnet-monitor/blob/3c31273c42196ec0813b7b5b947ab8e1bd1801ac/src/Tools/dotnet-monitor/CollectionRules/Options/CollectionRuleDefaultsOptions.cs). These defaults are merged with the user's provided configuration [here](https://github.com/dotnet/dotnet-monitor/blob/3c31273c42196ec0813b7b5b947ab8e1bd1801ac/src/Tools/dotnet-monitor/CollectionRules/Options/DefaultCollectionRulePostConfigureOptions.cs) - any properties that the user hasn't set (that have corresponding default values) will be updated at this point to use the default values. This step occurs prior to `dotnet monitor` attempting to use its built-in defaults, which allows user defaults to take precedence. ### Collection Rule API Endpoint -The Collection Rule API Endpoint allows users to get information about the state of their collection rules, providing general information [here](https://github.com/dotnet/dotnet-monitor/blob/8e99fe93461686b50ea276b406c5046b252b05e4/src/Microsoft.Diagnostics.Monitoring.WebApi/Controllers/DiagController.cs#L525) and more specific information about a particular rule [here](https://github.com/dotnet/dotnet-monitor/blob/8e99fe93461686b50ea276b406c5046b252b05e4/src/Microsoft.Diagnostics.Monitoring.WebApi/Controllers/DiagController.cs#L550). **This API is solely for viewing the current state of rules, not altering state**. +The Collection Rule API Endpoint allows users to get information about the state of their collection rules, providing general information [here](https://github.com/dotnet/dotnet-monitor/blob/3c31273c42196ec0813b7b5b947ab8e1bd1801ac/src/Microsoft.Diagnostics.Monitoring.WebApi/Controllers/DiagController.cs#L525) and more specific information about a particular rule [here](https://github.com/dotnet/dotnet-monitor/blob/3c31273c42196ec0813b7b5b947ab8e1bd1801ac/src/Microsoft.Diagnostics.Monitoring.WebApi/Controllers/DiagController.cs#L550). **This API is solely for viewing the current state of rules, not altering state**. -Each collection rule pipeline has a [state holder](https://github.com/dotnet/dotnet-monitor/blob/8e99fe93461686b50ea276b406c5046b252b05e4/src/Microsoft.Diagnostics.Monitoring.WebApi/CollectionRulePipelineState.cs) that keeps track of the rule's execution. By keeping track of the pipeline's state in real-time, this state doesn't need to be calculated in response to a user hitting the `/collectionrules` endpoint. However, other user-facing information, such as countdowns, are calculated on-demand - these values are solely for display purposes and not used by `dotnet-monitor` when determining when to change state (see [Limits](#limits) for more information). +Each collection rule pipeline has a [state holder](https://github.com/dotnet/dotnet-monitor/blob/3c31273c42196ec0813b7b5b947ab8e1bd1801ac/src/Microsoft.Diagnostics.Monitoring.WebApi/CollectionRulePipelineState.cs) that keeps track of the rule's execution. By keeping track of the pipeline's state in real-time, this state doesn't need to be calculated in response to a user hitting the `/collectionrules` endpoint. However, other user-facing information, such as countdowns, are calculated on-demand - these values are solely for display purposes and not used by `dotnet-monitor` when determining when to change state (see [Limits](#limits) for more information). ## Keeping Documentation Up-To-Date -When making changes to collection rules that require updates to configuration, these changes should be added [here](https://github.com/dotnet/dotnet-monitor/blob/8e99fe93461686b50ea276b406c5046b252b05e4/documentation/configuration/collection-rule-configuration.md). Additional information on collection rules and examples can be provided [here](https://github.com/dotnet/dotnet-monitor/tree/8e99fe93461686b50ea276b406c5046b252b05e4/documentation/collectionrules). +When making changes to collection rules that require updates to configuration, these changes should be added [here](https://github.com/dotnet/dotnet-monitor/blob/3c31273c42196ec0813b7b5b947ab8e1bd1801ac/documentation/configuration/collection-rule-configuration.md). Additional information on collection rules and examples can be provided [here](https://github.com/dotnet/dotnet-monitor/tree/3c31273c42196ec0813b7b5b947ab8e1bd1801ac/documentation/collectionrules). diff --git a/documentation/learningPath/configuration.md b/documentation/learningPath/configuration.md index 2c04f3c9549..7c221c9df2a 100644 --- a/documentation/learningPath/configuration.md +++ b/documentation/learningPath/configuration.md @@ -6,22 +6,22 @@ ## How Configuration Works -`dotnet-monitor` accepts configuration from several different sources, and must [combine these sources for the host builder](https://github.com/dotnet/dotnet-monitor/blob/8e99fe93461686b50ea276b406c5046b252b05e4/src/Tools/dotnet-monitor/HostBuilder/HostBuilderHelper.cs#L47). Configuration sources are added in the order of lowest to highest precedence - meaning that if there is a conflict between a property in two configuration sources, the property found in the latter configuration source will be used. +`dotnet-monitor` accepts configuration from several different sources, and must [combine these sources for the host builder](https://github.com/dotnet/dotnet-monitor/blob/3c31273c42196ec0813b7b5b947ab8e1bd1801ac/src/Tools/dotnet-monitor/HostBuilder/HostBuilderHelper.cs#L47). Configuration sources are added in the order of lowest to highest precedence - meaning that if there is a conflict between a property in two configuration sources, the property found in the latter configuration source will be used. -To see the merged configuration, the user can run the `config show` command (see [here](https://github.com/dotnet/dotnet-monitor/blob/8e99fe93461686b50ea276b406c5046b252b05e4/src/Tools/dotnet-monitor/Program.cs#L71) and [here](https://github.com/dotnet/dotnet-monitor/blob/8e99fe93461686b50ea276b406c5046b252b05e4/src/Tools/dotnet-monitor/Commands/ConfigShowCommandHandler.cs)); the `--show-sources` flag can be used to reveal which configuration source is responsible for each property. The `config show` command's output is [written out as JSON](https://github.com/dotnet/dotnet-monitor/blob/8e99fe93461686b50ea276b406c5046b252b05e4/src/Tools/dotnet-monitor/ConfigurationJsonWriter.cs); this section must be manually updated whenever new options are added (or existing options are changed). +To see the merged configuration, the user can run the `config show` command (see [here](https://github.com/dotnet/dotnet-monitor/blob/3c31273c42196ec0813b7b5b947ab8e1bd1801ac/src/Tools/dotnet-monitor/Program.cs#L71) and [here](https://github.com/dotnet/dotnet-monitor/blob/3c31273c42196ec0813b7b5b947ab8e1bd1801ac/src/Tools/dotnet-monitor/Commands/ConfigShowCommandHandler.cs)); the `--show-sources` flag can be used to reveal which configuration source is responsible for each property. The `config show` command's output is [written out as JSON](https://github.com/dotnet/dotnet-monitor/blob/3c31273c42196ec0813b7b5b947ab8e1bd1801ac/src/Tools/dotnet-monitor/ConfigurationJsonWriter.cs); this section must be manually updated whenever new options are added (or existing options are changed). -Once configuration has been merged, any singletons that have been added to the `IServiceCollection` (see [here](https://github.com/dotnet/dotnet-monitor/blob/8e99fe93461686b50ea276b406c5046b252b05e4/src/Tools/dotnet-monitor/ServiceCollectionExtensions.cs) and [here](https://github.com/dotnet/dotnet-monitor/blob/8e99fe93461686b50ea276b406c5046b252b05e4/src/Tools/dotnet-monitor/Commands/CollectCommandHandler.cs#L84)), such as `IConfigureOptions`, `IPostConfigureOptions`, and `IValidateOptions`, are called when an object of that type is first used, **not on startup**. This step is often used to incorporate defaults for properties that were not explicitly set by configuration, or to validate that options were set correctly. +Once configuration has been merged, any singletons that have been added to the `IServiceCollection` (see [here](https://github.com/dotnet/dotnet-monitor/blob/3c31273c42196ec0813b7b5b947ab8e1bd1801ac/src/Tools/dotnet-monitor/ServiceCollectionExtensions.cs) and [here](https://github.com/dotnet/dotnet-monitor/blob/3c31273c42196ec0813b7b5b947ab8e1bd1801ac/src/Tools/dotnet-monitor/Commands/CollectCommandHandler.cs#L84)), such as `IConfigureOptions`, `IPostConfigureOptions`, and `IValidateOptions`, are called when an object of that type is first used, **not on startup**. This step is often used to incorporate defaults for properties that were not explicitly set by configuration, or to validate that options were set correctly. -Any changes to the configuration need to be propagated to the [schema](https://github.com/dotnet/dotnet-monitor/blob/8e99fe93461686b50ea276b406c5046b252b05e4/documentation/schema.json). **The updated schema should be generated automatically; you should never need to manually edit the JSON.** To update the schema in Visual Studio: -* Set [Microsoft.Diagnostics.Monitoring.ConfigurationSchema](https://github.com/dotnet/dotnet-monitor/tree/8e99fe93461686b50ea276b406c5046b252b05e4/src/Tests/Microsoft.Diagnostics.Monitoring.ConfigurationSchema) as the startup project +Any changes to the configuration need to be propagated to the [schema](https://github.com/dotnet/dotnet-monitor/blob/3c31273c42196ec0813b7b5b947ab8e1bd1801ac/documentation/schema.json). **The updated schema should be generated automatically; you should never need to manually edit the JSON.** To update the schema in Visual Studio: +* Set [Microsoft.Diagnostics.Monitoring.ConfigurationSchema](https://github.com/dotnet/dotnet-monitor/tree/3c31273c42196ec0813b7b5b947ab8e1bd1801ac/src/Tests/Microsoft.Diagnostics.Monitoring.ConfigurationSchema) as the startup project * Build the project, with a single command-line argument for the schema's absolute path -* Validate that the schema was correctly updated using the tests in [Microsoft.Diagnostics.Monitoring.ConfigurationSchema.UnitTests](https://github.com/dotnet/dotnet-monitor/tree/8e99fe93461686b50ea276b406c5046b252b05e4/src/Tests/Microsoft.Diagnostics.Monitoring.ConfigurationSchema.UnitTests) +* Validate that the schema was correctly updated using the tests in [Microsoft.Diagnostics.Monitoring.ConfigurationSchema.UnitTests](https://github.com/dotnet/dotnet-monitor/tree/3c31273c42196ec0813b7b5b947ab8e1bd1801ac/src/Tests/Microsoft.Diagnostics.Monitoring.ConfigurationSchema.UnitTests) ## Keeping Documentation Up-To-Date -Our configuration is primarily documented [here](https://github.com/dotnet/dotnet-monitor/tree/8e99fe93461686b50ea276b406c5046b252b05e4/documentation/configuration). Sections are typically comprised of: +Our configuration is primarily documented [here](https://github.com/dotnet/dotnet-monitor/tree/3c31273c42196ec0813b7b5b947ab8e1bd1801ac/documentation/configuration). Sections are typically comprised of: * A brief overview of the feature that is being configured * Configuration samples in all supported formats * A list of properties with descriptions, types, and whether a property is required -Types are defined in [definitions.md](https://github.com/dotnet/dotnet-monitor/blob/8e99fe93461686b50ea276b406c5046b252b05e4/documentation/api/definitions.md), and additional information about configuring collection rules can be found in the [collection rules](https://github.com/dotnet/dotnet-monitor/blob/8e99fe93461686b50ea276b406c5046b252b05e4/documentation/collectionrules) directory. Where appropriate, indicate if configuration only pertains to a specific version of `dotnet-monitor` (e.g. `7.0+`). +Types are defined in [definitions.md](https://github.com/dotnet/dotnet-monitor/blob/3c31273c42196ec0813b7b5b947ab8e1bd1801ac/documentation/api/definitions.md), and additional information about configuring collection rules can be found in the [collection rules](https://github.com/dotnet/dotnet-monitor/blob/3c31273c42196ec0813b7b5b947ab8e1bd1801ac/documentation/collectionrules) directory. Where appropriate, indicate if configuration only pertains to a specific version of `dotnet-monitor` (e.g. `7.0+`). diff --git a/documentation/learningPath/egress.md b/documentation/learningPath/egress.md index 0f745a51e6b..1fe84a64f10 100644 --- a/documentation/learningPath/egress.md +++ b/documentation/learningPath/egress.md @@ -26,11 +26,11 @@ graph LR class ide2 altColor ``` -1. [User initiates collection of artifact with a designated egress provider](https://github.com/dotnet/dotnet-monitor/blob/8e99fe93461686b50ea276b406c5046b252b05e4/src/Microsoft.Diagnostics.Monitoring.WebApi/Operation/EgressOperation.cs#L45) -1. [Locate extension's executable and manifest](https://github.com/dotnet/dotnet-monitor/blob/8e99fe93461686b50ea276b406c5046b252b05e4/src/Tools/dotnet-monitor/Extensibility/ExtensionDiscoverer.cs#L28) -1. [Start extension and pass configuration/artifact via StdIn to the other process](https://github.com/dotnet/dotnet-monitor/blob/8e99fe93461686b50ea276b406c5046b252b05e4/src/Tools/dotnet-monitor/Egress/Extension/EgressExtension.cs#L102) -1. [Connect to egress provider using configuration and send artifact](https://github.com/dotnet/dotnet-monitor/blob/8e99fe93461686b50ea276b406c5046b252b05e4/src/Extensions/AzureBlobStorage/AzureBlobEgressProvider.cs#L36) -1. [Provide success/failure information via StdOut to dotnet-monitor](https://github.com/dotnet/dotnet-monitor/blob/8e99fe93461686b50ea276b406c5046b252b05e4/src/Microsoft.Diagnostics.Monitoring.Extension.Common/EgressHelper.cs#L77) +1. [User initiates collection of artifact with a designated egress provider](https://github.com/dotnet/dotnet-monitor/blob/3c31273c42196ec0813b7b5b947ab8e1bd1801ac/src/Microsoft.Diagnostics.Monitoring.WebApi/Operation/EgressOperation.cs#L45) +1. [Locate extension's executable and manifest](https://github.com/dotnet/dotnet-monitor/blob/3c31273c42196ec0813b7b5b947ab8e1bd1801ac/src/Tools/dotnet-monitor/Extensibility/ExtensionDiscoverer.cs#L28) +1. [Start extension and pass configuration/artifact via StdIn to the other process](https://github.com/dotnet/dotnet-monitor/blob/3c31273c42196ec0813b7b5b947ab8e1bd1801ac/src/Tools/dotnet-monitor/Egress/Extension/EgressExtension.cs#L102) +1. [Connect to egress provider using configuration and send artifact](https://github.com/dotnet/dotnet-monitor/blob/3c31273c42196ec0813b7b5b947ab8e1bd1801ac/src/Extensions/AzureBlobStorage/AzureBlobEgressProvider.cs#L36) +1. [Provide success/failure information via StdOut to dotnet-monitor](https://github.com/dotnet/dotnet-monitor/blob/3c31273c42196ec0813b7b5b947ab8e1bd1801ac/src/Microsoft.Diagnostics.Monitoring.Extension.Common/EgressHelper.cs#L77) ## Distribution and Acquisition Model @@ -41,7 +41,7 @@ There are two versions of the `dotnet-monitor` image being offered: `monitor` an ### Well Known Egress Provider Locations -There are 3 [locations](https://github.com/dotnet/dotnet-monitor/blob/8e99fe93461686b50ea276b406c5046b252b05e4/src/Tools/dotnet-monitor/ServiceCollectionExtensions.cs#L279) that `dotnet-monitor` scans when looking for the extensions directory (the highest priority location is listed first): +There are 3 [locations](https://github.com/dotnet/dotnet-monitor/blob/3c31273c42196ec0813b7b5b947ab8e1bd1801ac/src/Tools/dotnet-monitor/ServiceCollectionExtensions.cs#L280) that `dotnet-monitor` scans when looking for the extensions directory (the highest priority location is listed first): - Next to the executing `dotnet-monitor` assembly - SharedConfigDirectory - On Windows, `%ProgramData%\dotnet-monitor` @@ -59,23 +59,23 @@ The distribution/acquisition model for third-party egress providers is determine ### Extension Manifest -All extensions must include a manifest titled [`extension.json`](https://github.com/dotnet/dotnet-monitor/blob/8e99fe93461686b50ea276b406c5046b252b05e4/src/Extensions/AzureBlobStorage/extension.json) that provides `dotnet-monitor` with some basic information about the extension. +All extensions must include a manifest titled [`extension.json`](https://github.com/dotnet/dotnet-monitor/blob/3c31273c42196ec0813b7b5b947ab8e1bd1801ac/src/Extensions/AzureBlobStorage/extension.json) that provides `dotnet-monitor` with some basic information about the extension. | Name | Required | Type | Description | |---|---|---|---| | `Name` | true | string | The name of the extension (e.g. AzureBlobStorage) that users will use when writing configuration for the egress provider. | | `ExecutableFileName` | false | string | If specified, the executable file (without extension) to be launched when executing the extension; either `AssemblyFileName` or `ExecutableFileName` must be specified. | | `AssemblyFileName` | false | string | If specified, executes the extension using the shared .NET host (e.g. dotnet.exe) with the specified entry point assembly (without extension); either `AssemblyFileName` or `ExecutableFileName` must be specified. | -| `Modes` | false | [[ExtensionMode](../api/definitions.md#extensionmode)] | Additional modes the extension can be configured to run in (see an example of Validation [here](https://github.com/dotnet/dotnet-monitor/blob/8e99fe93461686b50ea276b406c5046b252b05e4/src/Microsoft.Diagnostics.Monitoring.Extension.Common/EgressHelper.cs#L80)). | +| `Modes` | false | [[ExtensionMode](../api/definitions.md#extensionmode)] | Additional modes the extension can be configured to run in (see an example of Validation [here](https://github.com/dotnet/dotnet-monitor/blob/3c31273c42196ec0813b7b5b947ab8e1bd1801ac/src/Microsoft.Diagnostics.Monitoring.Extension.Common/EgressHelper.cs#L80)). | ### Configuration Extensions are designed to receive all user configuration through `dotnet monitor` - the extension itself should not rely on any additional configuration sources. -In addition to the configuration provided specifically for your egress provider, `dotnet-monitor` also includes the values stored in [`Properties`](https://github.com/dotnet/dotnet-monitor/blob/8e99fe93461686b50ea276b406c5046b252b05e4/src/Microsoft.Diagnostics.Monitoring.Options/EgressOptions.cs#L21). Note that `Properties` may include information that is not relevant to the current egress provider, since it is a shared bucket between all configured egress providers. +In addition to the configuration provided specifically for your egress provider, `dotnet-monitor` also includes the values stored in [`Properties`](https://github.com/dotnet/dotnet-monitor/blob/3c31273c42196ec0813b7b5b947ab8e1bd1801ac/src/Microsoft.Diagnostics.Monitoring.Options/EgressOptions.cs#L21). Note that `Properties` may include information that is not relevant to the current egress provider, since it is a shared bucket between all configured egress providers. ### Communicating With Dotnet-Monitor -[`dotnet monitor` will pass serialized configuration via `StdIn` to the extension](https://github.com/dotnet/dotnet-monitor/blob/8e99fe93461686b50ea276b406c5046b252b05e4/src/Tools/dotnet-monitor/Egress/Extension/EgressExtension.cs#L182); an example of how the `AzureBlobStorage` egress provider interprets the egress payload can be found [here](https://github.com/dotnet/dotnet-monitor/blob/8e99fe93461686b50ea276b406c5046b252b05e4/src/Microsoft.Diagnostics.Monitoring.Extension.Common/EgressHelper.cs#L141). **It's important to validate the version number at the beginning of the stream; if an extension does not have the same version as `dotnet-monitor`, it should not attempt to continue reading from the stream, and users may need to update to a newer version of the extension.** +[`dotnet monitor` will pass serialized configuration via `StdIn` to the extension](https://github.com/dotnet/dotnet-monitor/blob/3c31273c42196ec0813b7b5b947ab8e1bd1801ac/src/Tools/dotnet-monitor/Egress/Extension/EgressExtension.cs#L182); an example of how the `AzureBlobStorage` egress provider interprets the egress payload can be found [here](https://github.com/dotnet/dotnet-monitor/blob/3c31273c42196ec0813b7b5b947ab8e1bd1801ac/src/Microsoft.Diagnostics.Monitoring.Extension.Common/EgressHelper.cs#L141). **It's important to validate the version number at the beginning of the stream; if an extension does not have the same version as `dotnet-monitor`, it should not attempt to continue reading from the stream, and users may need to update to a newer version of the extension.** -All output from the extension will be passed back to `dotnet-monitor`; this is logged [here](https://github.com/dotnet/dotnet-monitor/blob/8e99fe93461686b50ea276b406c5046b252b05e4/src/Tools/dotnet-monitor/Egress/Extension/EgressExtension.OutputParser.cs#L62). The contents of the `StandardOutput` and `StandardError` streams are handled and logged as seen [here](https://github.com/dotnet/dotnet-monitor/blob/8e99fe93461686b50ea276b406c5046b252b05e4/src/Tools/dotnet-monitor/Egress/Extension/EgressExtension.OutputParser.cs#L32), with the `StandardOutput` stream being logged at the `Info` level and the `StandardError` stream being logged at the `Warning` level. `Dotnet-Monitor` will continue reading output until it receives a [result](https://github.com/dotnet/dotnet-monitor/blob/8e99fe93461686b50ea276b406c5046b252b05e4/src/Tools/dotnet-monitor/Egress/Extension/EgressArtifactResult.cs) from the extension via the `StandardOutput` stream, at which point the extension's process will be terminated and `dotnet-monitor` will display the appropriate log message depending on the success/failure of the operation. Exceptions thrown during the egress operation are caught [here](https://github.com/dotnet/dotnet-monitor/blob/8e99fe93461686b50ea276b406c5046b252b05e4/src/Microsoft.Diagnostics.Monitoring.Extension.Common/EgressHelper.cs#L71); this allows the extension to report a failure message back to `dotnet-monitor` that will be displayed to the user. +All output from the extension will be passed back to `dotnet-monitor`; this is logged [here](https://github.com/dotnet/dotnet-monitor/blob/3c31273c42196ec0813b7b5b947ab8e1bd1801ac/src/Tools/dotnet-monitor/Egress/Extension/EgressExtension.OutputParser.cs#L62). The contents of the `StandardOutput` and `StandardError` streams are handled and logged as seen [here](https://github.com/dotnet/dotnet-monitor/blob/3c31273c42196ec0813b7b5b947ab8e1bd1801ac/src/Tools/dotnet-monitor/Egress/Extension/EgressExtension.OutputParser.cs#L32), with the `StandardOutput` stream being logged at the `Info` level and the `StandardError` stream being logged at the `Warning` level. `Dotnet-Monitor` will continue reading output until it receives a [result](https://github.com/dotnet/dotnet-monitor/blob/3c31273c42196ec0813b7b5b947ab8e1bd1801ac/src/Tools/dotnet-monitor/Egress/Extension/EgressArtifactResult.cs) from the extension via the `StandardOutput` stream, at which point the extension's process will be terminated and `dotnet-monitor` will display the appropriate log message depending on the success/failure of the operation. Exceptions thrown during the egress operation are caught [here](https://github.com/dotnet/dotnet-monitor/blob/3c31273c42196ec0813b7b5b947ab8e1bd1801ac/src/Microsoft.Diagnostics.Monitoring.Extension.Common/EgressHelper.cs#L71); this allows the extension to report a failure message back to `dotnet-monitor` that will be displayed to the user. diff --git a/documentation/learningPath/testing.md b/documentation/learningPath/testing.md index 6eb88df2381..a16d4fdf213 100644 --- a/documentation/learningPath/testing.md +++ b/documentation/learningPath/testing.md @@ -7,81 +7,81 @@ Tests can be executed with the command line (via [build.cmd](../../Build.cmd) -test), as part of the PR build, or in Visual Studio. Note that because of limited resources in the build pool, tests ran from the command line or in the build pool are serialized. This avoids test failures associated with parallel testing. Visual Studio does not have such restrictions and is best used for individual tests and test investigations. When running from the command line, using the `-testgroup` parameter can be used to limit the amount of tests executed. For example `build.cmd -test -testgroup PR` will run the same tests as the PR build. -The framework of the test assemblies is controlled by [TestTargetFrameworks](https://github.com/dotnet/dotnet-monitor/blob/8e99fe93461686b50ea276b406c5046b252b05e4/eng/Versions.props). The test itself is attributed with a particular framework based on the [TargetFrameworkMonikerTraitAttribute](https://github.com/dotnet/dotnet-monitor/blob/8e99fe93461686b50ea276b406c5046b252b05e4/src/Tests/Microsoft.Diagnostics.Monitoring.TestCommon/TargetFrameworkMonikerTraitAttribute.cs). +The framework of the test assemblies is controlled by [TestTargetFrameworks](https://github.com/dotnet/dotnet-monitor/blob/3c31273c42196ec0813b7b5b947ab8e1bd1801ac/eng/Versions.props). The test itself is attributed with a particular framework based on the [TargetFrameworkMonikerTraitAttribute](https://github.com/dotnet/dotnet-monitor/blob/3c31273c42196ec0813b7b5b947ab8e1bd1801ac/src/Tests/Microsoft.Diagnostics.Monitoring.TestCommon/TargetFrameworkMonikerTraitAttribute.cs). ## Unit Tests -- [Microsoft.Diagnostics.Monitoring.Tool.UnitTests](https://github.com/dotnet/dotnet-monitor/blob/8e99fe93461686b50ea276b406c5046b252b05e4/src/Tests/Microsoft.Diagnostics.Monitoring.Tool.UnitTests) -- [Microsoft.Diagnostics.Monitoring.WebApi.UnitTests](https://github.com/dotnet/dotnet-monitor/blob/8e99fe93461686b50ea276b406c5046b252b05e4/src/Tests/Microsoft.Diagnostics.Monitoring.WebApi.UnitTests/) -- [CollectionRuleActions.UnitTests](https://github.com/dotnet/dotnet-monitor/blob/8e99fe93461686b50ea276b406c5046b252b05e4/src/Tests/CollectionRuleActions.UnitTests/) +- [Microsoft.Diagnostics.Monitoring.Tool.UnitTests](https://github.com/dotnet/dotnet-monitor/blob/3c31273c42196ec0813b7b5b947ab8e1bd1801ac/src/Tests/Microsoft.Diagnostics.Monitoring.Tool.UnitTests) +- [Microsoft.Diagnostics.Monitoring.WebApi.UnitTests](https://github.com/dotnet/dotnet-monitor/blob/3c31273c42196ec0813b7b5b947ab8e1bd1801ac/src/Tests/Microsoft.Diagnostics.Monitoring.WebApi.UnitTests/) +- [CollectionRuleActions.UnitTests](https://github.com/dotnet/dotnet-monitor/blob/3c31273c42196ec0813b7b5b947ab8e1bd1801ac/src/Tests/CollectionRuleActions.UnitTests/) Unit test assemblies directly reference types from various dotnet-monitor assemblies. However, since most of dotnet-monitor heavily relies on code injection, there are utility classes to simplify unit test creation. -- [TestHostHelper](https://github.com/dotnet/dotnet-monitor/blob/8e99fe93461686b50ea276b406c5046b252b05e4/src/Tests/Microsoft.Diagnostics.Monitoring.Tool.UnitTestCommon/TestHostHelper.cs) can be used to setup a basic unit test scenario using dependency injection. -- [CollectionRuleOptionsExtensions](https://github.com/dotnet/dotnet-monitor/blob/8e99fe93461686b50ea276b406c5046b252b05e4/src/Tests/Microsoft.Diagnostics.Monitoring.Tool.UnitTestCommon/Options/CollectionRuleOptionsExtensions.cs) can be used to easily create collection rules from configuration. +- [TestHostHelper](https://github.com/dotnet/dotnet-monitor/blob/3c31273c42196ec0813b7b5b947ab8e1bd1801ac/src/Tests/Microsoft.Diagnostics.Monitoring.Tool.UnitTestCommon/TestHostHelper.cs) can be used to setup a basic unit test scenario using dependency injection. +- [CollectionRuleOptionsExtensions](https://github.com/dotnet/dotnet-monitor/blob/3c31273c42196ec0813b7b5b947ab8e1bd1801ac/src/Tests/Microsoft.Diagnostics.Monitoring.Tool.UnitTestCommon/Options/CollectionRuleOptionsExtensions.cs) can be used to easily create collection rules from configuration. ## Functional Tests -- [Microsoft.Diagnostics.Monitoring.Tool.FunctionalTests](https://github.com/dotnet/dotnet-monitor/blob/8e99fe93461686b50ea276b406c5046b252b05e4/src/Tests/Microsoft.Diagnostics.Monitoring.Tool.FunctionalTests) -- [Microsoft.Diagnostics.Monitoring.UnitTestApp](https://github.com/dotnet/dotnet-monitor/blob/8e99fe93461686b50ea276b406c5046b252b05e4/src/Tests/Microsoft.Diagnostics.Monitoring.UnitTestApp/) +- [Microsoft.Diagnostics.Monitoring.Tool.FunctionalTests](https://github.com/dotnet/dotnet-monitor/blob/3c31273c42196ec0813b7b5b947ab8e1bd1801ac/src/Tests/Microsoft.Diagnostics.Monitoring.Tool.FunctionalTests) +- [Microsoft.Diagnostics.Monitoring.UnitTestApp](https://github.com/dotnet/dotnet-monitor/blob/3c31273c42196ec0813b7b5b947ab8e1bd1801ac/src/Tests/Microsoft.Diagnostics.Monitoring.UnitTestApp/) Functional tests are composed of 3 main parts: 1. The test itself, which sets up and validates the results. 1. An instance of dotnet-monitor 1. An instance of an application that is being monitored (from the UnitTestApp assembly) -* [ScenarioRunner](https://github.com/dotnet/dotnet-monitor/blob/8e99fe93461686b50ea276b406c5046b252b05e4/src/Tests/Microsoft.Diagnostics.Monitoring.Tool.FunctionalTests/Runners/ScenarioRunner.cs) is typically used to orchestrate test runs. The class will spawn both an instance of dotnet-monitor and an instance of test application. The app and the test communicate via stdio. The test communicates with dotnet-monitor via its Api surface. -* The dotnet-monitor Api surface can be accessed through the [ApiClient](https://github.com/dotnet/dotnet-monitor/blob/8e99fe93461686b50ea276b406c5046b252b05e4/src/Tests/Microsoft.Diagnostics.Monitoring.Tool.FunctionalTests/HttpApi/ApiClient.cs). -* New scenarios can be added [here](https://github.com/dotnet/dotnet-monitor/blob/8e99fe93461686b50ea276b406c5046b252b05e4/src/Tests/Microsoft.Diagnostics.Monitoring.UnitTestApp/Scenarios/). -* The [AsyncWaitScenario](https://github.com/dotnet/dotnet-monitor/blob/8e99fe93461686b50ea276b406c5046b252b05e4/src/Tests/Microsoft.Diagnostics.Monitoring.UnitTestApp/Scenarios/AsyncWaitScenario.cs) is sufficient for most tests. -* Coordination of the scenario and the test is done via message passing (json over stdio) between the test and the app. To send messages to the app from the test, [AppRunner](https://github.com/dotnet/dotnet-monitor/blob/8e99fe93461686b50ea276b406c5046b252b05e4/src/Tests/Microsoft.Diagnostics.Monitoring.TestCommon/Runners/AppRunner.cs)'s `SendCommandAsync` is used. In the scenario definition, [ScenarioHelpers](https://github.com/dotnet/dotnet-monitor/blob/8e99fe93461686b50ea276b406c5046b252b05e4/src/Tests/Microsoft.Diagnostics.Monitoring.UnitTestApp/ScenarioHelpers.cs)'s `WaitForCommandAsync` is used. This can be used to synchronize various points of the test application with the execution of the dotnet-monitor Api from the test itself. +* [ScenarioRunner](https://github.com/dotnet/dotnet-monitor/blob/3c31273c42196ec0813b7b5b947ab8e1bd1801ac/src/Tests/Microsoft.Diagnostics.Monitoring.Tool.FunctionalTests/Runners/ScenarioRunner.cs) is typically used to orchestrate test runs. The class will spawn both an instance of dotnet-monitor and an instance of test application. The app and the test communicate via stdio. The test communicates with dotnet-monitor via its Api surface. +* The dotnet-monitor Api surface can be accessed through the [ApiClient](https://github.com/dotnet/dotnet-monitor/blob/3c31273c42196ec0813b7b5b947ab8e1bd1801ac/src/Tests/Microsoft.Diagnostics.Monitoring.Tool.FunctionalTests/HttpApi/ApiClient.cs). +* New scenarios can be added [here](https://github.com/dotnet/dotnet-monitor/blob/3c31273c42196ec0813b7b5b947ab8e1bd1801ac/src/Tests/Microsoft.Diagnostics.Monitoring.UnitTestApp/Scenarios/). +* The [AsyncWaitScenario](https://github.com/dotnet/dotnet-monitor/blob/3c31273c42196ec0813b7b5b947ab8e1bd1801ac/src/Tests/Microsoft.Diagnostics.Monitoring.UnitTestApp/Scenarios/AsyncWaitScenario.cs) is sufficient for most tests. +* Coordination of the scenario and the test is done via message passing (json over stdio) between the test and the app. To send messages to the app from the test, [AppRunner](https://github.com/dotnet/dotnet-monitor/blob/3c31273c42196ec0813b7b5b947ab8e1bd1801ac/src/Tests/Microsoft.Diagnostics.Monitoring.TestCommon/Runners/AppRunner.cs)'s `SendCommandAsync` is used. In the scenario definition, [ScenarioHelpers](https://github.com/dotnet/dotnet-monitor/blob/3c31273c42196ec0813b7b5b947ab8e1bd1801ac/src/Tests/Microsoft.Diagnostics.Monitoring.UnitTestApp/ScenarioHelpers.cs)'s `WaitForCommandAsync` is used. This can be used to synchronize various points of the test application with the execution of the dotnet-monitor Api from the test itself. ## Native/Profiler Tests -- [Microsoft.Diagnostics.Monitoring.Profiler.UnitTests](https://github.com/dotnet/dotnet-monitor/blob/8e99fe93461686b50ea276b406c5046b252b05e4/src/Tests/Microsoft.Diagnostics.Monitoring.Profiler.UnitTests/) -- [Microsoft.Diagnostics.Monitoring.Profiler.UnitTestApp](https://github.com/dotnet/dotnet-monitor/blob/8e99fe93461686b50ea276b406c5046b252b05e4/src/Tests/Microsoft.Diagnostics.Monitoring.Profiler.UnitTestApp/) +- [Microsoft.Diagnostics.Monitoring.Profiler.UnitTests](https://github.com/dotnet/dotnet-monitor/blob/3c31273c42196ec0813b7b5b947ab8e1bd1801ac/src/Tests/Microsoft.Diagnostics.Monitoring.Profiler.UnitTests/) +- [Microsoft.Diagnostics.Monitoring.Profiler.UnitTestApp](https://github.com/dotnet/dotnet-monitor/blob/3c31273c42196ec0813b7b5b947ab8e1bd1801ac/src/Tests/Microsoft.Diagnostics.Monitoring.Profiler.UnitTestApp/) This test assembly provides a test to make sure the dotnet-monitor profiler can load into a target app. ## Schema Generation -- [Microsoft.Diagnostics.Monitoring.ConfigurationSchema.UnitTests](https://github.com/dotnet/dotnet-monitor/blob/8e99fe93461686b50ea276b406c5046b252b05e4/src/Tests/Microsoft.Diagnostics.Monitoring.ConfigurationSchema.UnitTests/) -- [Microsoft.Diagnostics.Monitoring.ConfigurationSchema](https://github.com/dotnet/dotnet-monitor/blob/8e99fe93461686b50ea276b406c5046b252b05e4/src/Tests/Microsoft.Diagnostics.Monitoring.ConfigurationSchema/) -- [Microsoft.Diagnostics.Monitoring.Options](https://github.com/dotnet/dotnet-monitor/blob/8e99fe93461686b50ea276b406c5046b252b05e4/src/Microsoft.Diagnostics.Monitoring.Options) +- [Microsoft.Diagnostics.Monitoring.ConfigurationSchema.UnitTests](https://github.com/dotnet/dotnet-monitor/blob/3c31273c42196ec0813b7b5b947ab8e1bd1801ac/src/Tests/Microsoft.Diagnostics.Monitoring.ConfigurationSchema.UnitTests/) +- [Microsoft.Diagnostics.Monitoring.ConfigurationSchema](https://github.com/dotnet/dotnet-monitor/blob/3c31273c42196ec0813b7b5b947ab8e1bd1801ac/src/Tests/Microsoft.Diagnostics.Monitoring.ConfigurationSchema/) +- [Microsoft.Diagnostics.Monitoring.Options](https://github.com/dotnet/dotnet-monitor/blob/3c31273c42196ec0813b7b5b947ab8e1bd1801ac/src/Microsoft.Diagnostics.Monitoring.Options) -Dotnet-monitor generates [schema.json](https://github.com/dotnet/dotnet-monitor/blob/8e99fe93461686b50ea276b406c5046b252b05e4/documentation/schema.json) using unit tests. If dotnet-monitor's configuration changes, the schema.json file needs to be updated. -Note that it is possible to compile option classes directly into the `ConfigurationSchema` project. This may be necessary in order to attribute properties appropriately for schema generation. See [Microsoft.Diagnostics.Monitoring.ConfigurationSchema.csproj](https://github.com/dotnet/dotnet-monitor/blob/8e99fe93461686b50ea276b406c5046b252b05e4/src/Tests/Microsoft.Diagnostics.Monitoring.ConfigurationSchema/Microsoft.Diagnostics.Monitoring.ConfigurationSchema.csproj). See the [Configuration](./configuration.md#how-configuration-works) learning path for more details. +Dotnet-monitor generates [schema.json](https://github.com/dotnet/dotnet-monitor/blob/3c31273c42196ec0813b7b5b947ab8e1bd1801ac/documentation/schema.json) using unit tests. If dotnet-monitor's configuration changes, the schema.json file needs to be updated. +Note that it is possible to compile option classes directly into the `ConfigurationSchema` project. This may be necessary in order to attribute properties appropriately for schema generation. See [Microsoft.Diagnostics.Monitoring.ConfigurationSchema.csproj](https://github.com/dotnet/dotnet-monitor/blob/3c31273c42196ec0813b7b5b947ab8e1bd1801ac/src/Tests/Microsoft.Diagnostics.Monitoring.ConfigurationSchema/Microsoft.Diagnostics.Monitoring.ConfigurationSchema.csproj). See the [Configuration](./configuration.md#how-configuration-works) learning path for more details. ## OpenAPI generation -- [Microsoft.Diagnostics.Monitoring.OpenApiGen.UnitTests](https://github.com/dotnet/dotnet-monitor/blob/8e99fe93461686b50ea276b406c5046b252b05e4/src/Tests/Microsoft.Diagnostics.Monitoring.OpenApiGen.UnitTests/) -- [Microsoft.Diagnostics.Monitoring.OpenApiGen](https://github.com/dotnet/dotnet-monitor/blob/8e99fe93461686b50ea276b406c5046b252b05e4/src/Tests/Microsoft.Diagnostics.Monitoring.OpenApiGen/) +- [Microsoft.Diagnostics.Monitoring.OpenApiGen.UnitTests](https://github.com/dotnet/dotnet-monitor/blob/3c31273c42196ec0813b7b5b947ab8e1bd1801ac/src/Tests/Microsoft.Diagnostics.Monitoring.OpenApiGen.UnitTests/) +- [Microsoft.Diagnostics.Monitoring.OpenApiGen](https://github.com/dotnet/dotnet-monitor/blob/3c31273c42196ec0813b7b5b947ab8e1bd1801ac/src/Tests/Microsoft.Diagnostics.Monitoring.OpenApiGen/) -These assemblies and tests are used to generate the [OpenAPI spec](https://github.com/dotnet/dotnet-monitor/blob/8e99fe93461686b50ea276b406c5046b252b05e4/documentation/openapi.json) for the dotnet-monitor API. Changes to the dotnet-monitor api surface require updating `openapi.json`. +These assemblies and tests are used to generate the [OpenAPI spec](https://github.com/dotnet/dotnet-monitor/blob/3c31273c42196ec0813b7b5b947ab8e1bd1801ac/documentation/openapi.json) for the dotnet-monitor API. Changes to the dotnet-monitor api surface require updating `openapi.json`. If using VSCode or Codespaces, you can also use the `Regenerate openapi.json` task. ## Startup hooks / hosting startup -- [Microsoft.Diagnostics.Monitoring.Tool.TestStartupHook](https://github.com/dotnet/dotnet-monitor/blob/8e99fe93461686b50ea276b406c5046b252b05e4/src/Tests/Microsoft.Diagnostics.Monitoring.Tool.TestStartupHook/) +- [Microsoft.Diagnostics.Monitoring.Tool.TestStartupHook](https://github.com/dotnet/dotnet-monitor/blob/3c31273c42196ec0813b7b5b947ab8e1bd1801ac/src/Tests/Microsoft.Diagnostics.Monitoring.Tool.TestStartupHook/) This assembly is injected into a dotnet-monitor runner (using `DOTNET_STARTUP_HOOKS`) to facilitate Assembly resolution during test runs. -- [Microsoft.Diagnostics.Monitoring.Tool.TestHostingStartup](https://github.com/dotnet/dotnet-monitor/blob/8e99fe93461686b50ea276b406c5046b252b05e4/src/Tests/Microsoft.Diagnostics.Monitoring.Tool.TestHostingStartup/) +- [Microsoft.Diagnostics.Monitoring.Tool.TestHostingStartup](https://github.com/dotnet/dotnet-monitor/blob/3c31273c42196ec0813b7b5b947ab8e1bd1801ac/src/Tests/Microsoft.Diagnostics.Monitoring.Tool.TestHostingStartup/) Uses `ASPNETCORE_HOSTINGSTARTUPASSEMBLIES` to inject a service into dotnet-monitor during test time. This allows tests to locate files that are not normally part of the test deployment, such as the native profiler. -- [Microsoft.Diagnostics.Monitoring.StartupHook.UnitTests](https://github.com/dotnet/dotnet-monitor/blob/8e99fe93461686b50ea276b406c5046b252b05e4/src/Tests/Microsoft.Diagnostics.Monitoring.StartupHook.UnitTests/) +- [Microsoft.Diagnostics.Monitoring.StartupHook.UnitTests](https://github.com/dotnet/dotnet-monitor/blob/3c31273c42196ec0813b7b5b947ab8e1bd1801ac/src/Tests/Microsoft.Diagnostics.Monitoring.StartupHook.UnitTests/) Unit tests around features that are injected via `DOTNET_STARTUP_HOOKS` into the target application. This currently includes the Exceptions History feature. ## Misc test assemblies -- [Microsoft.Diagnostics.Monitoring.TestCommon](https://github.com/dotnet/dotnet-monitor/blob/8e99fe93461686b50ea276b406c5046b252b05e4/src/Tests/Microsoft.Diagnostics.Monitoring.TestCommon/) +- [Microsoft.Diagnostics.Monitoring.TestCommon](https://github.com/dotnet/dotnet-monitor/blob/3c31273c42196ec0813b7b5b947ab8e1bd1801ac/src/Tests/Microsoft.Diagnostics.Monitoring.TestCommon/) Utility classes that are shared between Unit Tests and Functional Tests. -- [Microsoft.Diagnostics.Monitoring.Tool.UnitTestCommon](https://github.com/dotnet/dotnet-monitor/blob/8e99fe93461686b50ea276b406c5046b252b05e4/src/Tests/Microsoft.Diagnostics.Monitoring.Tool.UnitTestCommon/) +- [Microsoft.Diagnostics.Monitoring.Tool.UnitTestCommon](https://github.com/dotnet/dotnet-monitor/blob/3c31273c42196ec0813b7b5b947ab8e1bd1801ac/src/Tests/Microsoft.Diagnostics.Monitoring.Tool.UnitTestCommon/) Utility classes shared between unit test assemblies. diff --git a/documentation/releaseNotes/releaseNotes.v9.0.0-preview.5.md b/documentation/releaseNotes/releaseNotes.v9.0.0-preview.5.md new file mode 100644 index 00000000000..91d55275b55 --- /dev/null +++ b/documentation/releaseNotes/releaseNotes.v9.0.0-preview.5.md @@ -0,0 +1,8 @@ +Today we are releasing the next official preview version of the `dotnet monitor` tool. This release includes: + +- Fix an issue where operations could finish, or fail, but their state would be still be reported as `Starting` ([issue #6683](https://github.com/dotnet/dotnet-monitor/issues/6683)). ([#6686](https://github.com/dotnet/dotnet-monitor/pull/6686)) +- Fix the error log message shown when an action could not be registered. ([#6665](https://github.com/dotnet/dotnet-monitor/pull/6665)) + + + +If you would like to provide additional feedback to the team [please fill out this survey](https://aka.ms/dotnet-monitor-survey?src=rn). \ No newline at end of file diff --git a/documentation/releases.md b/documentation/releases.md index 80b33cd4b19..ec5a43ad572 100644 --- a/documentation/releases.md +++ b/documentation/releases.md @@ -18,13 +18,12 @@ | 7.3 | August 8, 2023 | [7.3.4](https://github.com/dotnet/dotnet-monitor/releases/tag/v7.3.4) | May 14, 2024 | May 14, 2024 | net6.0
net7.0 | | 7.2 | June 13, 2023 | [7.2.3](https://github.com/dotnet/dotnet-monitor/releases/tag/v7.2.3) | October 10, 2023 | November 8, 2023 | net6.0
net7.0 | | 7.1 | March 14, 2023 | [7.1.3](https://github.com/dotnet/dotnet-monitor/releases/tag/v7.1.3) | August 8, 2023 | September 13, 2023 | net6.0
net7.0 | -| 7.0 | November 11, 2022 | [7.0.2](https://github.com/dotnet/dotnet-monitor/releases/tag/v7.0.2) | February 14, 2023 | June 14, 2023 | net6.0
net7.0 | ## Preview versions | Version | Release Date | Latest Version | Runtime Frameworks | | --- | --- | --- | --- | -| 9.0 | May 21, 2024 | [9.0.0 preview 4](https://github.com/dotnet/dotnet-monitor/releases/tag/v9.0.0-preview.4.24270.1) | net9.0 | +| 9.0 | June 11, 2024 | [9.0.0 preview 5](https://github.com/dotnet/dotnet-monitor/releases/tag/v9.0.0-preview.5.24307.6) | net9.0 | diff --git a/documentation/schema.json b/documentation/schema.json index a2bf76bcaf4..7bf746094a7 100644 --- a/documentation/schema.json +++ b/documentation/schema.json @@ -2998,6 +2998,17 @@ "format": "int32", "maximum": 2147483647.0, "minimum": 1.0 + }, + "UseKmsEncryption": { + "type": "boolean", + "description": "A boolean flag which controls whether the Egress should use KMS server side encryption." + }, + "KmsEncryptionKey": { + "type": [ + "null", + "string" + ], + "description": "If UseKmsEncryption is true, this specifies the arn of the \"customer managed\" KMS encryption key to be used for server side encryption. If no value is set for this field then S3 will use an AWS managed key for KMS encryption." } } } diff --git a/dotnet-monitor.sln b/dotnet-monitor.sln index a44a392a57e..338f5bdc028 100644 --- a/dotnet-monitor.sln +++ b/dotnet-monitor.sln @@ -70,10 +70,6 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Microsoft.Diagnostics.Monit EndProject Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Extensions", "Extensions", "{D3FEE1C0-E1E7-4796-A217-B46E3B6CCCCD}" EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Microsoft.Diagnostics.Monitoring.HostingStartup", "src\Microsoft.Diagnostics.Monitoring.HostingStartup\Microsoft.Diagnostics.Monitoring.HostingStartup.csproj", "{86BDA5CD-6A18-4EC2-9F13-F1A2723DD864}" -EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Microsoft.Diagnostics.Monitoring.HostingStartup.UnitTests", "src\Tests\Microsoft.Diagnostics.Monitoring.HostingStartup.UnitTests\Microsoft.Diagnostics.Monitoring.HostingStartup.UnitTests.csproj", "{B9216DD7-F216-490A-A388-BBE0EC946EF2}" -EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU @@ -188,14 +184,6 @@ Global {E7EA323B-0CFE-4D42-9844-4C322A3BC54A}.Debug|Any CPU.Build.0 = Debug|Any CPU {E7EA323B-0CFE-4D42-9844-4C322A3BC54A}.Release|Any CPU.ActiveCfg = Release|Any CPU {E7EA323B-0CFE-4D42-9844-4C322A3BC54A}.Release|Any CPU.Build.0 = Release|Any CPU - {86BDA5CD-6A18-4EC2-9F13-F1A2723DD864}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {86BDA5CD-6A18-4EC2-9F13-F1A2723DD864}.Debug|Any CPU.Build.0 = Debug|Any CPU - {86BDA5CD-6A18-4EC2-9F13-F1A2723DD864}.Release|Any CPU.ActiveCfg = Release|Any CPU - {86BDA5CD-6A18-4EC2-9F13-F1A2723DD864}.Release|Any CPU.Build.0 = Release|Any CPU - {B9216DD7-F216-490A-A388-BBE0EC946EF2}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {B9216DD7-F216-490A-A388-BBE0EC946EF2}.Debug|Any CPU.Build.0 = Debug|Any CPU - {B9216DD7-F216-490A-A388-BBE0EC946EF2}.Release|Any CPU.ActiveCfg = Release|Any CPU - {B9216DD7-F216-490A-A388-BBE0EC946EF2}.Release|Any CPU.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE @@ -231,8 +219,6 @@ Global {72EC615C-E1BE-4D27-A0FC-C0FEE483D3D2} = {19FAB78C-3351-4911-8F0C-8C6056401740} {E7EA323B-0CFE-4D42-9844-4C322A3BC54A} = {C7568468-1C79-4944-8136-18812A7F9EA7} {D3FEE1C0-E1E7-4796-A217-B46E3B6CCCCD} = {19FAB78C-3351-4911-8F0C-8C6056401740} - {86BDA5CD-6A18-4EC2-9F13-F1A2723DD864} = {19FAB78C-3351-4911-8F0C-8C6056401740} - {B9216DD7-F216-490A-A388-BBE0EC946EF2} = {C7568468-1C79-4944-8136-18812A7F9EA7} EndGlobalSection GlobalSection(ExtensibilityGlobals) = postSolution SolutionGuid = {46465737-C938-44FC-BE1A-4CE139EBB5E0} diff --git a/eng/AfterSolutionBuild.targets b/eng/AfterSolutionBuild.targets index af7ca5f7f55..809cbd183bc 100644 --- a/eng/AfterSolutionBuild.targets +++ b/eng/AfterSolutionBuild.targets @@ -3,7 +3,6 @@ - diff --git a/eng/Version.Details.xml b/eng/Version.Details.xml index fb9956beb08..bc22aa8a2ab 100644 --- a/eng/Version.Details.xml +++ b/eng/Version.Details.xml @@ -1,66 +1,66 @@ - + https://github.com/dotnet/aspnetcore - 8af96e042134fb3b2f21df26dd0f32ea1c00dd37 + 77994c64cee73e0093fe25cd434bee8bd2580b4e - + https://github.com/dotnet/diagnostics - 05f88f687a02aa865384beda97a8910d4d57b17b + 36353b20e53e0c4af482e4fbe1d0a572515f14a2 - + https://github.com/dotnet/diagnostics - 05f88f687a02aa865384beda97a8910d4d57b17b + 36353b20e53e0c4af482e4fbe1d0a572515f14a2 - + https://github.com/dotnet/command-line-api - 963d34b1fb712c673bfb198133d7e988182c9ef4 + 803d8598f98fb4efd94604b32627ee9407f246db - + https://github.com/dotnet/roslyn-analyzers - 1d1b6bc0be25482a9105912d71649c03866733b0 + 43709af7570da7140fb3e9a5237f55ffb24677e7 - + https://github.com/dotnet/arcade - 2c08708d18855f2e2779ac5d0623a5978751c4f3 + ede13bd35571c0c8b0c01edcb057031904c5c955 - + https://github.com/dotnet/arcade - 2c08708d18855f2e2779ac5d0623a5978751c4f3 + ede13bd35571c0c8b0c01edcb057031904c5c955 - + https://github.com/dotnet/arcade - 2c08708d18855f2e2779ac5d0623a5978751c4f3 + ede13bd35571c0c8b0c01edcb057031904c5c955 - + https://github.com/dotnet/arcade - 2c08708d18855f2e2779ac5d0623a5978751c4f3 + ede13bd35571c0c8b0c01edcb057031904c5c955 - + https://github.com/dotnet/arcade - 2c08708d18855f2e2779ac5d0623a5978751c4f3 + ede13bd35571c0c8b0c01edcb057031904c5c955 - + https://github.com/dotnet/diagnostics - 05f88f687a02aa865384beda97a8910d4d57b17b + 36353b20e53e0c4af482e4fbe1d0a572515f14a2 - + https://github.com/dotnet/runtime - a5cc707d976a14495462c9c492a921ff0927b8f5 + d88e6680e1f9e2cb4f5ee428aa169ab715158eab - + https://github.com/dotnet/aspnetcore - 8af96e042134fb3b2f21df26dd0f32ea1c00dd37 + 77994c64cee73e0093fe25cd434bee8bd2580b4e - + https://github.com/dotnet/sdk - 35b2c21ea64c7b401b77076516d9319879d8314b + a081e8d8cdcce5cb0b0329cf68cf190060e870a6 - + https://github.com/dotnet/runtime - a5cc707d976a14495462c9c492a921ff0927b8f5 + d88e6680e1f9e2cb4f5ee428aa169ab715158eab diff --git a/eng/Versions.props b/eng/Versions.props index 102b87663dc..3cce96a6727 100644 --- a/eng/Versions.props +++ b/eng/Versions.props @@ -5,7 +5,7 @@ https://github.com/dotnet/dotnet-monitor 9.0.0 preview - 5 + 6 true - 9.0.0-beta.24303.1 - 9.0.0-beta.24303.1 - 9.0.0-beta.24303.1 + 9.0.0-beta.24327.1 + 9.0.0-beta.24327.1 + 9.0.0-beta.24327.1 - 9.0.0-preview.5.24306.11 - 9.0.0-preview.5.24306.11 + 9.0.0-preview.7.24328.7 + 9.0.0-preview.7.24328.7 - 2.0.0-beta4.24209.3 + 2.0.0-beta4.24324.3 - 8.0.0-preview.24263.1 - 8.0.0-preview.24263.1 - - 9.0.100-preview.4.24267.66 + 8.0.0-preview.24328.1 + 8.0.0-preview.24328.1 - 9.0.0-preview.24303.1 + 9.0.0-preview.24324.1 - 9.0.0-preview.5.24306.7 - 9.0.0-preview.5.24306.7 + 9.0.0-preview.7.24327.11 + 9.0.0-preview.7.24327.11 - 9.0.100-preview.5.24307.3 + 9.0.100-preview.7.24329.1 - 1.0.530301 + 1.0.532801 $(MicrosoftNETCoreApp31Version) diff --git a/eng/common/SetupNugetSources.ps1 b/eng/common/SetupNugetSources.ps1 index c07f6a52601..2b0a5c9e665 100644 --- a/eng/common/SetupNugetSources.ps1 +++ b/eng/common/SetupNugetSources.ps1 @@ -1,32 +1,31 @@ # This script adds internal feeds required to build commits that depend on internal package sources. For instance, # dotnet6-internal would be added automatically if dotnet6 was found in the nuget.config file. In addition also enables # disabled internal Maestro (darc-int*) feeds. -# -# Optionally, this script also adds a credential entry for each of the internal feeds if supplied. This credential -# is added via the standard environment variable VSS_NUGET_EXTERNAL_FEED_ENDPOINTS. See -# https://github.com/microsoft/artifacts-credprovider/tree/v1.1.1?tab=readme-ov-file#environment-variables for more details +# +# Optionally, this script also adds a credential entry for each of the internal feeds if supplied. # # See example call for this script below. # # - task: PowerShell@2 -# displayName: Setup Internal Feeds +# displayName: Setup Private Feeds Credentials # condition: eq(variables['Agent.OS'], 'Windows_NT') # inputs: # filePath: $(Build.SourcesDirectory)/eng/common/SetupNugetSources.ps1 -# arguments: -ConfigFile $(Build.SourcesDirectory)/NuGet.config -# - task: NuGetAuthenticate@1 -# +# arguments: -ConfigFile $(Build.SourcesDirectory)/NuGet.config -Password $Env:Token +# env: +# Token: $(dn-bot-dnceng-artifact-feeds-rw) +# # Note that the NuGetAuthenticate task should be called after SetupNugetSources. # This ensures that: # - Appropriate creds are set for the added internal feeds (if not supplied to the scrupt) -# - The credential provider is installed +# - The credential provider is installed. # # This logic is also abstracted into enable-internal-sources.yml. [CmdletBinding()] param ( [Parameter(Mandatory = $true)][string]$ConfigFile, - [string]$Password + $Password ) $ErrorActionPreference = "Stop" @@ -35,23 +34,12 @@ Set-StrictMode -Version 2.0 . $PSScriptRoot\tools.ps1 -$feedEndpoints = $null - -# If a credential is provided, ensure that we don't overwrite the current set of -# credentials that may have been provided by a previous call to the credential provider. -if ($Password -and $null -ne $env:VSS_NUGET_EXTERNAL_FEED_ENDPOINTS) { - $feedEndpoints = $env:VSS_NUGET_EXTERNAL_FEED_ENDPOINTS | ConvertFrom-Json -} elseif ($Password) { - $feedEndpoints = @{ endpointCredentials = @() } -} - # Add source entry to PackageSources -function AddPackageSource($sources, $SourceName, $SourceEndPoint, $pwd) { +function AddPackageSource($sources, $SourceName, $SourceEndPoint, $creds, $Username, $pwd) { $packageSource = $sources.SelectSingleNode("add[@key='$SourceName']") - if ($null -eq $packageSource) + if ($packageSource -eq $null) { - Write-Host "`tAdding package source" $SourceName $packageSource = $doc.CreateElement("add") $packageSource.SetAttribute("key", $SourceName) $packageSource.SetAttribute("value", $SourceEndPoint) @@ -61,33 +49,63 @@ function AddPackageSource($sources, $SourceName, $SourceEndPoint, $pwd) { Write-Host "Package source $SourceName already present." } - if ($pwd) { - $feedEndpoints.endpointCredentials = AddCredential -endpointCredentials $feedEndpoints.endpointCredentials -source $SourceEndPoint -pwd $pwd - } + AddCredential -Creds $creds -Source $SourceName -Username $Username -pwd $pwd } -# Add a new feed endpoint credential -function AddCredential([array]$endpointCredentials, $source, $pwd) { - $endpointCredentials += @{ - endpoint = $source; - password = $pwd +# Add a credential node for the specified source +function AddCredential($creds, $source, $username, $pwd) { + # If no cred supplied, don't do anything. + if (!$pwd) { + return; } - return $endpointCredentials + + # Looks for credential configuration for the given SourceName. Create it if none is found. + $sourceElement = $creds.SelectSingleNode($Source) + if ($sourceElement -eq $null) + { + $sourceElement = $doc.CreateElement($Source) + $creds.AppendChild($sourceElement) | Out-Null + } + + # Add the node to the credential if none is found. + $usernameElement = $sourceElement.SelectSingleNode("add[@key='Username']") + if ($usernameElement -eq $null) + { + $usernameElement = $doc.CreateElement("add") + $usernameElement.SetAttribute("key", "Username") + $sourceElement.AppendChild($usernameElement) | Out-Null + } + $usernameElement.SetAttribute("value", $Username) + + # Add the to the credential if none is found. + # Add it as a clear text because there is no support for encrypted ones in non-windows .Net SDKs. + # -> https://github.com/NuGet/Home/issues/5526 + $passwordElement = $sourceElement.SelectSingleNode("add[@key='ClearTextPassword']") + if ($passwordElement -eq $null) + { + $passwordElement = $doc.CreateElement("add") + $passwordElement.SetAttribute("key", "ClearTextPassword") + $sourceElement.AppendChild($passwordElement) | Out-Null + } + + $passwordElement.SetAttribute("value", $pwd) } -function InsertMaestroInternalFeedCredentials($Sources, $pwd) { - $maestroInternalSources = $Sources.SelectNodes("add[contains(@key,'darc-int')]") +function InsertMaestroPrivateFeedCredentials($Sources, $Creds, $Username, $pwd) { + $maestroPrivateSources = $Sources.SelectNodes("add[contains(@key,'darc-int')]") - ForEach ($PackageSource in $maestroInternalSources) { - Write-Host "`tAdding credential for Maestro's feed:" $PackageSource.Key - $feedEndpoints.endpointCredentials = AddCredential -endpointCredentials $feedEndpoints.endpointCredentials -source $PackageSource.value -pwd $pwd + Write-Host "Inserting credentials for $($maestroPrivateSources.Count) Maestro's private feeds." + + ForEach ($PackageSource in $maestroPrivateSources) { + Write-Host "`tInserting credential for Maestro's feed:" $PackageSource.Key + AddCredential -Creds $creds -Source $PackageSource.Key -Username $Username -pwd $pwd } } -function EnableInternalPackageSources($DisabledPackageSources) { - $maestroInternalSources = $DisabledPackageSources.SelectNodes("add[contains(@key,'darc-int')]") - ForEach ($DisabledPackageSource in $maestroInternalSources) { - Write-Host "`tEnsuring internal source '$($DisabledPackageSource.key)' is enabled by deleting it from disabledPackageSource" +function EnablePrivatePackageSources($DisabledPackageSources) { + $maestroPrivateSources = $DisabledPackageSources.SelectNodes("add[contains(@key,'darc-int')]") + ForEach ($DisabledPackageSource in $maestroPrivateSources) { + Write-Host "`tEnsuring private source '$($DisabledPackageSource.key)' is enabled by deleting it from disabledPackageSource" # Due to https://github.com/NuGet/Home/issues/10291, we must actually remove the disabled entries $DisabledPackageSources.RemoveChild($DisabledPackageSource) } @@ -105,27 +123,38 @@ $doc.Load($filename) # Get reference to or create one if none exist already $sources = $doc.DocumentElement.SelectSingleNode("packageSources") -if ($null -eq $sources) { +if ($sources -eq $null) { $sources = $doc.CreateElement("packageSources") $doc.DocumentElement.AppendChild($sources) | Out-Null } +$creds = $null +if ($Password) { + # Looks for a node. Create it if none is found. + $creds = $doc.DocumentElement.SelectSingleNode("packageSourceCredentials") + if ($creds -eq $null) { + $creds = $doc.CreateElement("packageSourceCredentials") + $doc.DocumentElement.AppendChild($creds) | Out-Null + } +} + # Check for disabledPackageSources; we'll enable any darc-int ones we find there $disabledSources = $doc.DocumentElement.SelectSingleNode("disabledPackageSources") -if ($null -ne $disabledSources) { +if ($disabledSources -ne $null) { Write-Host "Checking for any darc-int disabled package sources in the disabledPackageSources node" - EnableInternalPackageSources -DisabledPackageSources $disabledSources + EnablePrivatePackageSources -DisabledPackageSources $disabledSources } -if ($Password) { - InsertMaestroInternalFeedCredentials -Sources $sources -pwd $Password -} +$userName = "dn-bot" + +# Insert credential nodes for Maestro's private feeds +InsertMaestroPrivateFeedCredentials -Sources $sources -Creds $creds -Username $userName -pwd $Password # 3.1 uses a different feed url format so it's handled differently here $dotnet31Source = $sources.SelectSingleNode("add[@key='dotnet3.1']") -if ($null -ne $dotnet31Source) { - AddPackageSource -Sources $sources -SourceName "dotnet3.1-internal" -SourceEndPoint "https://pkgs.dev.azure.com/dnceng/_packaging/dotnet3.1-internal/nuget/v3/index.json" -pwd $Password - AddPackageSource -Sources $sources -SourceName "dotnet3.1-internal-transport" -SourceEndPoint "https://pkgs.dev.azure.com/dnceng/_packaging/dotnet3.1-internal-transport/nuget/v3/index.json" -pwd $Password +if ($dotnet31Source -ne $null) { + AddPackageSource -Sources $sources -SourceName "dotnet3.1-internal" -SourceEndPoint "https://pkgs.dev.azure.com/dnceng/_packaging/dotnet3.1-internal/nuget/v2" -Creds $creds -Username $userName -pwd $Password + AddPackageSource -Sources $sources -SourceName "dotnet3.1-internal-transport" -SourceEndPoint "https://pkgs.dev.azure.com/dnceng/_packaging/dotnet3.1-internal-transport/nuget/v2" -Creds $creds -Username $userName -pwd $Password } $dotnetVersions = @('5','6','7','8') @@ -133,18 +162,10 @@ $dotnetVersions = @('5','6','7','8') foreach ($dotnetVersion in $dotnetVersions) { $feedPrefix = "dotnet" + $dotnetVersion; $dotnetSource = $sources.SelectSingleNode("add[@key='$feedPrefix']") - if ($dotnetSource) { - AddPackageSource -Sources $sources -SourceName "$feedPrefix-internal" -SourceEndPoint "https://pkgs.dev.azure.com/dnceng/internal/_packaging/$feedprefix-internal/nuget/v3/index.json" -pwd $Password - AddPackageSource -Sources $sources -SourceName "$feedPrefix-internal-transport" -SourceEndPoint "https://pkgs.dev.azure.com/dnceng/internal/_packaging/$feedPrefix-internal-transport/nuget/v3/index.json" -pwd $Password + if ($dotnetSource -ne $null) { + AddPackageSource -Sources $sources -SourceName "$feedPrefix-internal" -SourceEndPoint "https://pkgs.dev.azure.com/dnceng/internal/_packaging/$feedPrefix-internal/nuget/v2" -Creds $creds -Username $userName -pwd $Password + AddPackageSource -Sources $sources -SourceName "$feedPrefix-internal-transport" -SourceEndPoint "https://pkgs.dev.azure.com/dnceng/internal/_packaging/$feedPrefix-internal-transport/nuget/v2" -Creds $creds -Username $userName -pwd $Password } } $doc.Save($filename) - -# If any credentials were added or altered, update the VSS_NUGET_EXTERNAL_FEED_ENDPOINTS environment variable -if ($null -ne $feedEndpoints) { - # ci is set to true so vso logging commands will be used. - $ci = $true - Write-PipelineSetVariable -Name 'VSS_NUGET_EXTERNAL_FEED_ENDPOINTS' -Value $($feedEndpoints | ConvertTo-Json) -IsMultiJobVariable $false - Write-PipelineSetVariable -Name 'NUGET_CREDENTIALPROVIDER_SESSIONTOKENCACHE_ENABLED' -Value "False" -IsMultiJobVariable $false -} \ No newline at end of file diff --git a/eng/common/SetupNugetSources.sh b/eng/common/SetupNugetSources.sh index 16c1e29ea3b..b493479a1da 100644 --- a/eng/common/SetupNugetSources.sh +++ b/eng/common/SetupNugetSources.sh @@ -1,6 +1,6 @@ #!/usr/bin/env bash -# This script adds internal feeds required to build commits that depend on intenral package sources. For instance, +# This script adds internal feeds required to build commits that depend on internal package sources. For instance, # dotnet6-internal would be added automatically if dotnet6 was found in the nuget.config file. In addition also enables # disabled internal Maestro (darc-int*) feeds. # diff --git a/eng/common/core-templates/job/publish-build-assets.yml b/eng/common/core-templates/job/publish-build-assets.yml index 8fe9299542c..d99a1a3b284 100644 --- a/eng/common/core-templates/job/publish-build-assets.yml +++ b/eng/common/core-templates/job/publish-build-assets.yml @@ -87,13 +87,15 @@ jobs: - task: NuGetAuthenticate@1 - - task: PowerShell@2 + - task: AzureCLI@2 displayName: Publish Build Assets inputs: - filePath: eng\common\sdk-task.ps1 + azureSubscription: "Darc: Maestro Production" + scriptType: ps + scriptLocation: scriptPath + scriptPath: $(Build.SourcesDirectory)/eng/common/sdk-task.ps1 arguments: -task PublishBuildAssets -restore -msbuildEngine dotnet /p:ManifestsPath='$(Build.StagingDirectory)/Download/AssetManifests' - /p:BuildAssetRegistryToken=$(MaestroAccessToken) /p:MaestroApiEndpoint=https://maestro.dot.net /p:PublishUsingPipelines=${{ parameters.publishUsingPipelines }} /p:OfficialBuildId=$(Build.BuildNumber) @@ -153,14 +155,16 @@ jobs: PromoteToChannelIds: ${{ parameters.PromoteToChannelIds }} is1ESPipeline: ${{ parameters.is1ESPipeline }} - - task: PowerShell@2 + - task: AzureCLI@2 displayName: Publish Using Darc inputs: - filePath: $(Build.SourcesDirectory)/eng/common/post-build/publish-using-darc.ps1 + azureSubscription: "Darc: Maestro Production" + scriptType: ps + scriptLocation: scriptPath + scriptPath: $(Build.SourcesDirectory)/eng/common/post-build/publish-using-darc.ps1 arguments: -BuildId $(BARBuildId) -PublishingInfraVersion 3 -AzdoToken '$(publishing-dnceng-devdiv-code-r-build-re)' - -MaestroToken '$(MaestroApiAccessToken)' -WaitPublishingFinish true -ArtifactsPublishingAdditionalParameters '${{ parameters.artifactsPublishingAdditionalParameters }}' -SymbolPublishingAdditionalParameters '${{ parameters.symbolPublishingAdditionalParameters }}' diff --git a/eng/common/core-templates/post-build/common-variables.yml b/eng/common/core-templates/post-build/common-variables.yml index b9ede10bf09..d5627a994ae 100644 --- a/eng/common/core-templates/post-build/common-variables.yml +++ b/eng/common/core-templates/post-build/common-variables.yml @@ -8,8 +8,6 @@ variables: # Default Maestro++ API Endpoint and API Version - name: MaestroApiEndPoint value: "https://maestro.dot.net" - - name: MaestroApiAccessToken - value: $(MaestroAccessToken) - name: MaestroApiVersion value: "2020-02-20" diff --git a/eng/common/core-templates/post-build/post-build.yml b/eng/common/core-templates/post-build/post-build.yml index 865bc1ecb4f..20924366b8a 100644 --- a/eng/common/core-templates/post-build/post-build.yml +++ b/eng/common/core-templates/post-build/post-build.yml @@ -145,8 +145,7 @@ stages: displayName: Validate inputs: filePath: $(Build.SourcesDirectory)/eng/common/post-build/nuget-validation.ps1 - arguments: -PackagesPath $(Build.ArtifactStagingDirectory)/PackageArtifacts/ - -ToolDestinationPath $(Agent.BuildDirectory)/Extract/ + arguments: -PackagesPath $(Build.ArtifactStagingDirectory)/PackageArtifacts/ - job: displayName: Signing Validation @@ -301,14 +300,16 @@ stages: - task: NuGetAuthenticate@1 - - task: PowerShell@2 + - task: AzureCLI@2 displayName: Publish Using Darc inputs: - filePath: $(Build.SourcesDirectory)/eng/common/post-build/publish-using-darc.ps1 + azureSubscription: "Darc: Maestro Production" + scriptType: ps + scriptLocation: scriptPath + scriptPath: $(Build.SourcesDirectory)/eng/common/post-build/publish-using-darc.ps1 arguments: -BuildId $(BARBuildId) -PublishingInfraVersion ${{ parameters.publishingInfraVersion }} -AzdoToken '$(publishing-dnceng-devdiv-code-r-build-re)' - -MaestroToken '$(MaestroApiAccessToken)' -WaitPublishingFinish true -ArtifactsPublishingAdditionalParameters '${{ parameters.artifactsPublishingAdditionalParameters }}' -SymbolPublishingAdditionalParameters '${{ parameters.symbolPublishingAdditionalParameters }}' diff --git a/eng/common/core-templates/post-build/setup-maestro-vars.yml b/eng/common/core-templates/post-build/setup-maestro-vars.yml index 8d56b572679..f7602980dbe 100644 --- a/eng/common/core-templates/post-build/setup-maestro-vars.yml +++ b/eng/common/core-templates/post-build/setup-maestro-vars.yml @@ -15,19 +15,20 @@ steps: artifactName: ReleaseConfigs checkDownloadedFiles: true - - task: PowerShell@2 + - task: AzureCLI@2 name: setReleaseVars displayName: Set Release Configs Vars inputs: - targetType: inline - pwsh: true - script: | + azureSubscription: "Darc: Maestro Production" + scriptType: pscore + scriptLocation: inlineScript + inlineScript: | try { if (!$Env:PromoteToMaestroChannels -or $Env:PromoteToMaestroChannels.Trim() -eq '') { $Content = Get-Content $(Build.StagingDirectory)/ReleaseConfigs/ReleaseConfigs.txt $BarId = $Content | Select -Index 0 - $Channels = $Content | Select -Index 1 + $Channels = $Content | Select -Index 1 $IsStableBuild = $Content | Select -Index 2 $AzureDevOpsProject = $Env:System_TeamProject @@ -35,15 +36,16 @@ steps: $AzureDevOpsBuildId = $Env:Build_BuildId } else { - $buildApiEndpoint = "${Env:MaestroApiEndPoint}/api/builds/${Env:BARBuildId}?api-version=${Env:MaestroApiVersion}" + . $(Build.SourcesDirectory)\eng\common\tools.ps1 + $darc = Get-Darc + $buildInfo = & $darc get-build ` + --id ${{ parameters.BARBuildId }} ` + --extended ` + --output-format json ` + --ci ` + | convertFrom-Json - $apiHeaders = New-Object 'System.Collections.Generic.Dictionary[[String],[String]]' - $apiHeaders.Add('Accept', 'application/json') - $apiHeaders.Add('Authorization',"Bearer ${Env:MAESTRO_API_TOKEN}") - - $buildInfo = try { Invoke-WebRequest -Method Get -Uri $buildApiEndpoint -Headers $apiHeaders | ConvertFrom-Json } catch { Write-Host "Error: $_" } - - $BarId = $Env:BARBuildId + $BarId = ${{ parameters.BARBuildId }} $Channels = $Env:PromoteToMaestroChannels -split "," $Channels = $Channels -join "][" $Channels = "[$Channels]" @@ -69,6 +71,4 @@ steps: exit 1 } env: - MAESTRO_API_TOKEN: $(MaestroApiAccessToken) - BARBuildId: ${{ parameters.BARBuildId }} PromoteToMaestroChannels: ${{ parameters.PromoteToChannelIds }} diff --git a/eng/common/core-templates/post-build/trigger-subscription.yml b/eng/common/core-templates/post-build/trigger-subscription.yml deleted file mode 100644 index da669030daf..00000000000 --- a/eng/common/core-templates/post-build/trigger-subscription.yml +++ /dev/null @@ -1,13 +0,0 @@ -parameters: - ChannelId: 0 - -steps: -- task: PowerShell@2 - displayName: Triggering subscriptions - inputs: - filePath: $(Build.SourcesDirectory)/eng/common/post-build/trigger-subscriptions.ps1 - arguments: -SourceRepo $(Build.Repository.Uri) - -ChannelId ${{ parameters.ChannelId }} - -MaestroApiAccessToken $(MaestroAccessToken) - -MaestroApiEndPoint $(MaestroApiEndPoint) - -MaestroApiVersion $(MaestroApiVersion) diff --git a/eng/common/core-templates/steps/add-build-to-channel.yml b/eng/common/core-templates/steps/add-build-to-channel.yml deleted file mode 100644 index f67a210d62f..00000000000 --- a/eng/common/core-templates/steps/add-build-to-channel.yml +++ /dev/null @@ -1,13 +0,0 @@ -parameters: - ChannelId: 0 - -steps: -- task: PowerShell@2 - displayName: Add Build to Channel - inputs: - filePath: $(Build.SourcesDirectory)/eng/common/post-build/add-build-to-channel.ps1 - arguments: -BuildId $(BARBuildId) - -ChannelId ${{ parameters.ChannelId }} - -MaestroApiAccessToken $(MaestroApiAccessToken) - -MaestroApiEndPoint $(MaestroApiEndPoint) - -MaestroApiVersion $(MaestroApiVersion) diff --git a/eng/common/core-templates/steps/component-governance.yml b/eng/common/core-templates/steps/component-governance.yml index df449a34c11..b8815892a5e 100644 --- a/eng/common/core-templates/steps/component-governance.yml +++ b/eng/common/core-templates/steps/component-governance.yml @@ -2,7 +2,8 @@ parameters: disableComponentGovernance: false componentGovernanceIgnoreDirectories: '' is1ESPipeline: false - + displayName: 'Component Detection' + steps: - ${{ if eq(parameters.disableComponentGovernance, 'true') }}: - script: echo "##vso[task.setvariable variable=skipComponentGovernanceDetection]true" @@ -10,5 +11,6 @@ steps: - ${{ if ne(parameters.disableComponentGovernance, 'true') }}: - task: ComponentGovernanceComponentDetection@0 continueOnError: true + displayName: ${{ parameters.displayName }} inputs: ignoreDirectories: ${{ parameters.componentGovernanceIgnoreDirectories }} \ No newline at end of file diff --git a/eng/common/core-templates/steps/enable-internal-sources.yml b/eng/common/core-templates/steps/enable-internal-sources.yml index 80deddafb1b..64f881bffc3 100644 --- a/eng/common/core-templates/steps/enable-internal-sources.yml +++ b/eng/common/core-templates/steps/enable-internal-sources.yml @@ -6,30 +6,42 @@ parameters: - name: is1ESPipeline type: boolean default: false +# Legacy parameters to allow for PAT usage +- name: legacyCredential + type: string + default: '' steps: - ${{ if ne(variables['System.TeamProject'], 'public') }}: - # If running on dnceng (internal project), just use the default behavior for NuGetAuthenticate. - # If running on DevDiv, NuGetAuthenticate is not really an option. It's scoped to a single feed, and we have many feeds that - # may be added. Instead, we'll use the traditional approach (add cred to nuget.config), but use an account token. - - ${{ if eq(variables['System.TeamProject'], 'internal') }}: + - ${{ if ne(parameters.legacyCredential, '') }}: - task: PowerShell@2 displayName: Setup Internal Feeds inputs: filePath: $(Build.SourcesDirectory)/eng/common/SetupNugetSources.ps1 - arguments: -ConfigFile $(Build.SourcesDirectory)/NuGet.config - - task: NuGetAuthenticate@1 + arguments: -ConfigFile $(Build.SourcesDirectory)/NuGet.config -Password $Env:Token + env: + Token: ${{ parameters.legacyCredential }} + # If running on dnceng (internal project), just use the default behavior for NuGetAuthenticate. + # If running on DevDiv, NuGetAuthenticate is not really an option. It's scoped to a single feed, and we have many feeds that + # may be added. Instead, we'll use the traditional approach (add cred to nuget.config), but use an account token. - ${{ else }}: - - template: /eng/common/templates/steps/get-federated-access-token.yml - parameters: - federatedServiceConnection: ${{ parameters.nugetFederatedServiceConnection }} - outputVariableName: 'dnceng-artifacts-feeds-read-access-token' - - task: PowerShell@2 - displayName: Setup Internal Feeds - inputs: - filePath: $(Build.SourcesDirectory)/eng/common/SetupNugetSources.ps1 - arguments: -ConfigFile $(Build.SourcesDirectory)/NuGet.config -Password $(dnceng-artifacts-feeds-read-access-token) - # This is required in certain scenarios to install the ADO credential provider. - # It installed by default in some msbuild invocations (e.g. VS msbuild), but needs to be installed for others - # (e.g. dotnet msbuild). - - task: NuGetAuthenticate@1 + - ${{ if eq(variables['System.TeamProject'], 'internal') }}: + - task: PowerShell@2 + displayName: Setup Internal Feeds + inputs: + filePath: $(Build.SourcesDirectory)/eng/common/SetupNugetSources.ps1 + arguments: -ConfigFile $(Build.SourcesDirectory)/NuGet.config + - ${{ else }}: + - template: /eng/common/templates/steps/get-federated-access-token.yml + parameters: + federatedServiceConnection: ${{ parameters.nugetFederatedServiceConnection }} + outputVariableName: 'dnceng-artifacts-feeds-read-access-token' + - task: PowerShell@2 + displayName: Setup Internal Feeds + inputs: + filePath: $(Build.SourcesDirectory)/eng/common/SetupNugetSources.ps1 + arguments: -ConfigFile $(Build.SourcesDirectory)/NuGet.config -Password $(dnceng-artifacts-feeds-read-access-token) + # This is required in certain scenarios to install the ADO credential provider. + # It installed by default in some msbuild invocations (e.g. VS msbuild), but needs to be installed for others + # (e.g. dotnet msbuild). + - task: NuGetAuthenticate@1 diff --git a/eng/common/core-templates/steps/source-build.yml b/eng/common/core-templates/steps/source-build.yml index 16c778d92cb..2915d29bb7f 100644 --- a/eng/common/core-templates/steps/source-build.yml +++ b/eng/common/core-templates/steps/source-build.yml @@ -121,7 +121,9 @@ steps: # a nupkg cache of input packages (a local feed). # This path must match the upstream cache path in property 'CurrentRepoSourceBuiltNupkgCacheDir' # in src\Microsoft.DotNet.Arcade.Sdk\tools\SourceBuild\SourceBuildArcade.targets -- task: ComponentGovernanceComponentDetection@0 - displayName: Component Detection (Exclude upstream cache) - inputs: - ignoreDirectories: '$(Build.SourcesDirectory)/artifacts/sb/src/artifacts/obj/source-built-upstream-cache' +- template: /eng/common/core-templates/steps/component-governance.yml + parameters: + displayName: Component Detection (Exclude upstream cache) + is1ESPipeline: ${{ parameters.is1ESPipeline }} + componentGovernanceIgnoreDirectories: '$(Build.SourcesDirectory)/artifacts/sb/src/artifacts/obj/source-built-upstream-cache' + disableComponentGovernance: ${{ eq(variables['System.TeamProject'], 'public') }} diff --git a/eng/common/cross/arm/sources.list.bionic b/eng/common/cross/arm/sources.list.bionic deleted file mode 100644 index 21095574095..00000000000 --- a/eng/common/cross/arm/sources.list.bionic +++ /dev/null @@ -1,11 +0,0 @@ -deb http://ports.ubuntu.com/ubuntu-ports/ bionic main restricted universe -deb-src http://ports.ubuntu.com/ubuntu-ports/ bionic main restricted universe - -deb http://ports.ubuntu.com/ubuntu-ports/ bionic-updates main restricted universe -deb-src http://ports.ubuntu.com/ubuntu-ports/ bionic-updates main restricted universe - -deb http://ports.ubuntu.com/ubuntu-ports/ bionic-backports main restricted -deb-src http://ports.ubuntu.com/ubuntu-ports/ bionic-backports main restricted - -deb http://ports.ubuntu.com/ubuntu-ports/ bionic-security main restricted universe multiverse -deb-src http://ports.ubuntu.com/ubuntu-ports/ bionic-security main restricted universe multiverse diff --git a/eng/common/cross/arm/sources.list.focal b/eng/common/cross/arm/sources.list.focal deleted file mode 100644 index 4de2600c174..00000000000 --- a/eng/common/cross/arm/sources.list.focal +++ /dev/null @@ -1,11 +0,0 @@ -deb http://ports.ubuntu.com/ubuntu-ports/ focal main restricted universe -deb-src http://ports.ubuntu.com/ubuntu-ports/ focal main restricted universe - -deb http://ports.ubuntu.com/ubuntu-ports/ focal-updates main restricted universe -deb-src http://ports.ubuntu.com/ubuntu-ports/ focal-updates main restricted universe - -deb http://ports.ubuntu.com/ubuntu-ports/ focal-backports main restricted -deb-src http://ports.ubuntu.com/ubuntu-ports/ focal-backports main restricted - -deb http://ports.ubuntu.com/ubuntu-ports/ focal-security main restricted universe multiverse -deb-src http://ports.ubuntu.com/ubuntu-ports/ focal-security main restricted universe multiverse diff --git a/eng/common/cross/arm/sources.list.jammy b/eng/common/cross/arm/sources.list.jammy deleted file mode 100644 index 6bb0453029c..00000000000 --- a/eng/common/cross/arm/sources.list.jammy +++ /dev/null @@ -1,11 +0,0 @@ -deb http://ports.ubuntu.com/ubuntu-ports/ jammy main restricted universe -deb-src http://ports.ubuntu.com/ubuntu-ports/ jammy main restricted universe - -deb http://ports.ubuntu.com/ubuntu-ports/ jammy-updates main restricted universe -deb-src http://ports.ubuntu.com/ubuntu-ports/ jammy-updates main restricted universe - -deb http://ports.ubuntu.com/ubuntu-ports/ jammy-backports main restricted -deb-src http://ports.ubuntu.com/ubuntu-ports/ jammy-backports main restricted - -deb http://ports.ubuntu.com/ubuntu-ports/ jammy-security main restricted universe multiverse -deb-src http://ports.ubuntu.com/ubuntu-ports/ jammy-security main restricted universe multiverse diff --git a/eng/common/cross/arm/sources.list.jessie b/eng/common/cross/arm/sources.list.jessie deleted file mode 100644 index 4d142ac9b10..00000000000 --- a/eng/common/cross/arm/sources.list.jessie +++ /dev/null @@ -1,3 +0,0 @@ -# Debian (sid) # UNSTABLE -deb http://ftp.debian.org/debian/ sid main contrib non-free -deb-src http://ftp.debian.org/debian/ sid main contrib non-free diff --git a/eng/common/cross/arm/sources.list.xenial b/eng/common/cross/arm/sources.list.xenial deleted file mode 100644 index 56fbb36a59f..00000000000 --- a/eng/common/cross/arm/sources.list.xenial +++ /dev/null @@ -1,11 +0,0 @@ -deb http://ports.ubuntu.com/ubuntu-ports/ xenial main restricted universe -deb-src http://ports.ubuntu.com/ubuntu-ports/ xenial main restricted universe - -deb http://ports.ubuntu.com/ubuntu-ports/ xenial-updates main restricted universe -deb-src http://ports.ubuntu.com/ubuntu-ports/ xenial-updates main restricted universe - -deb http://ports.ubuntu.com/ubuntu-ports/ xenial-backports main restricted -deb-src http://ports.ubuntu.com/ubuntu-ports/ xenial-backports main restricted - -deb http://ports.ubuntu.com/ubuntu-ports/ xenial-security main restricted universe multiverse -deb-src http://ports.ubuntu.com/ubuntu-ports/ xenial-security main restricted universe multiverse diff --git a/eng/common/cross/arm/sources.list.zesty b/eng/common/cross/arm/sources.list.zesty deleted file mode 100644 index ea2c14a7874..00000000000 --- a/eng/common/cross/arm/sources.list.zesty +++ /dev/null @@ -1,11 +0,0 @@ -deb http://ports.ubuntu.com/ubuntu-ports/ zesty main restricted universe -deb-src http://ports.ubuntu.com/ubuntu-ports/ zesty main restricted universe - -deb http://ports.ubuntu.com/ubuntu-ports/ zesty-updates main restricted universe -deb-src http://ports.ubuntu.com/ubuntu-ports/ zesty-updates main restricted universe - -deb http://ports.ubuntu.com/ubuntu-ports/ zesty-backports main restricted -deb-src http://ports.ubuntu.com/ubuntu-ports/ zesty-backports main restricted - -deb http://ports.ubuntu.com/ubuntu-ports/ zesty-security main restricted universe multiverse -deb-src http://ports.ubuntu.com/ubuntu-ports/ zesty-security main restricted universe multiverse diff --git a/eng/common/cross/arm64/sources.list.bionic b/eng/common/cross/arm64/sources.list.bionic deleted file mode 100644 index 21095574095..00000000000 --- a/eng/common/cross/arm64/sources.list.bionic +++ /dev/null @@ -1,11 +0,0 @@ -deb http://ports.ubuntu.com/ubuntu-ports/ bionic main restricted universe -deb-src http://ports.ubuntu.com/ubuntu-ports/ bionic main restricted universe - -deb http://ports.ubuntu.com/ubuntu-ports/ bionic-updates main restricted universe -deb-src http://ports.ubuntu.com/ubuntu-ports/ bionic-updates main restricted universe - -deb http://ports.ubuntu.com/ubuntu-ports/ bionic-backports main restricted -deb-src http://ports.ubuntu.com/ubuntu-ports/ bionic-backports main restricted - -deb http://ports.ubuntu.com/ubuntu-ports/ bionic-security main restricted universe multiverse -deb-src http://ports.ubuntu.com/ubuntu-ports/ bionic-security main restricted universe multiverse diff --git a/eng/common/cross/arm64/sources.list.buster b/eng/common/cross/arm64/sources.list.buster deleted file mode 100644 index 7194ac64a96..00000000000 --- a/eng/common/cross/arm64/sources.list.buster +++ /dev/null @@ -1,11 +0,0 @@ -deb http://deb.debian.org/debian buster main -deb-src http://deb.debian.org/debian buster main - -deb http://deb.debian.org/debian-security/ buster/updates main -deb-src http://deb.debian.org/debian-security/ buster/updates main - -deb http://deb.debian.org/debian buster-updates main -deb-src http://deb.debian.org/debian buster-updates main - -deb http://deb.debian.org/debian buster-backports main contrib non-free -deb-src http://deb.debian.org/debian buster-backports main contrib non-free diff --git a/eng/common/cross/arm64/sources.list.focal b/eng/common/cross/arm64/sources.list.focal deleted file mode 100644 index 4de2600c174..00000000000 --- a/eng/common/cross/arm64/sources.list.focal +++ /dev/null @@ -1,11 +0,0 @@ -deb http://ports.ubuntu.com/ubuntu-ports/ focal main restricted universe -deb-src http://ports.ubuntu.com/ubuntu-ports/ focal main restricted universe - -deb http://ports.ubuntu.com/ubuntu-ports/ focal-updates main restricted universe -deb-src http://ports.ubuntu.com/ubuntu-ports/ focal-updates main restricted universe - -deb http://ports.ubuntu.com/ubuntu-ports/ focal-backports main restricted -deb-src http://ports.ubuntu.com/ubuntu-ports/ focal-backports main restricted - -deb http://ports.ubuntu.com/ubuntu-ports/ focal-security main restricted universe multiverse -deb-src http://ports.ubuntu.com/ubuntu-ports/ focal-security main restricted universe multiverse diff --git a/eng/common/cross/arm64/sources.list.jammy b/eng/common/cross/arm64/sources.list.jammy deleted file mode 100644 index 6bb0453029c..00000000000 --- a/eng/common/cross/arm64/sources.list.jammy +++ /dev/null @@ -1,11 +0,0 @@ -deb http://ports.ubuntu.com/ubuntu-ports/ jammy main restricted universe -deb-src http://ports.ubuntu.com/ubuntu-ports/ jammy main restricted universe - -deb http://ports.ubuntu.com/ubuntu-ports/ jammy-updates main restricted universe -deb-src http://ports.ubuntu.com/ubuntu-ports/ jammy-updates main restricted universe - -deb http://ports.ubuntu.com/ubuntu-ports/ jammy-backports main restricted -deb-src http://ports.ubuntu.com/ubuntu-ports/ jammy-backports main restricted - -deb http://ports.ubuntu.com/ubuntu-ports/ jammy-security main restricted universe multiverse -deb-src http://ports.ubuntu.com/ubuntu-ports/ jammy-security main restricted universe multiverse diff --git a/eng/common/cross/arm64/sources.list.stretch b/eng/common/cross/arm64/sources.list.stretch deleted file mode 100644 index 0e121577436..00000000000 --- a/eng/common/cross/arm64/sources.list.stretch +++ /dev/null @@ -1,12 +0,0 @@ -deb http://deb.debian.org/debian stretch main -deb-src http://deb.debian.org/debian stretch main - -deb http://deb.debian.org/debian-security/ stretch/updates main -deb-src http://deb.debian.org/debian-security/ stretch/updates main - -deb http://deb.debian.org/debian stretch-updates main -deb-src http://deb.debian.org/debian stretch-updates main - -deb http://deb.debian.org/debian stretch-backports main contrib non-free -deb-src http://deb.debian.org/debian stretch-backports main contrib non-free - diff --git a/eng/common/cross/arm64/sources.list.xenial b/eng/common/cross/arm64/sources.list.xenial deleted file mode 100644 index 56fbb36a59f..00000000000 --- a/eng/common/cross/arm64/sources.list.xenial +++ /dev/null @@ -1,11 +0,0 @@ -deb http://ports.ubuntu.com/ubuntu-ports/ xenial main restricted universe -deb-src http://ports.ubuntu.com/ubuntu-ports/ xenial main restricted universe - -deb http://ports.ubuntu.com/ubuntu-ports/ xenial-updates main restricted universe -deb-src http://ports.ubuntu.com/ubuntu-ports/ xenial-updates main restricted universe - -deb http://ports.ubuntu.com/ubuntu-ports/ xenial-backports main restricted -deb-src http://ports.ubuntu.com/ubuntu-ports/ xenial-backports main restricted - -deb http://ports.ubuntu.com/ubuntu-ports/ xenial-security main restricted universe multiverse -deb-src http://ports.ubuntu.com/ubuntu-ports/ xenial-security main restricted universe multiverse diff --git a/eng/common/cross/arm64/sources.list.zesty b/eng/common/cross/arm64/sources.list.zesty deleted file mode 100644 index ea2c14a7874..00000000000 --- a/eng/common/cross/arm64/sources.list.zesty +++ /dev/null @@ -1,11 +0,0 @@ -deb http://ports.ubuntu.com/ubuntu-ports/ zesty main restricted universe -deb-src http://ports.ubuntu.com/ubuntu-ports/ zesty main restricted universe - -deb http://ports.ubuntu.com/ubuntu-ports/ zesty-updates main restricted universe -deb-src http://ports.ubuntu.com/ubuntu-ports/ zesty-updates main restricted universe - -deb http://ports.ubuntu.com/ubuntu-ports/ zesty-backports main restricted -deb-src http://ports.ubuntu.com/ubuntu-ports/ zesty-backports main restricted - -deb http://ports.ubuntu.com/ubuntu-ports/ zesty-security main restricted universe multiverse -deb-src http://ports.ubuntu.com/ubuntu-ports/ zesty-security main restricted universe multiverse diff --git a/eng/common/cross/armel/sources.list.jessie b/eng/common/cross/armel/sources.list.jessie deleted file mode 100644 index 3d9c3059d89..00000000000 --- a/eng/common/cross/armel/sources.list.jessie +++ /dev/null @@ -1,3 +0,0 @@ -# Debian (jessie) # Stable -deb http://ftp.debian.org/debian/ jessie main contrib non-free -deb-src http://ftp.debian.org/debian/ jessie main contrib non-free diff --git a/eng/common/cross/armv6/sources.list.bookworm b/eng/common/cross/armv6/sources.list.bookworm deleted file mode 100644 index 10161135265..00000000000 --- a/eng/common/cross/armv6/sources.list.bookworm +++ /dev/null @@ -1,2 +0,0 @@ -deb http://raspbian.raspberrypi.org/raspbian/ bookworm main contrib non-free rpi -deb-src http://raspbian.raspberrypi.org/raspbian/ bookworm main contrib non-free rpi diff --git a/eng/common/cross/armv6/sources.list.buster b/eng/common/cross/armv6/sources.list.buster deleted file mode 100644 index f27fc4fb346..00000000000 --- a/eng/common/cross/armv6/sources.list.buster +++ /dev/null @@ -1,2 +0,0 @@ -deb http://raspbian.raspberrypi.org/raspbian/ buster main contrib non-free rpi -deb-src http://raspbian.raspberrypi.org/raspbian/ buster main contrib non-free rpi diff --git a/eng/common/cross/build-android-rootfs.sh b/eng/common/cross/build-android-rootfs.sh index f163fb9dae9..7e9ba2b75ed 100644 --- a/eng/common/cross/build-android-rootfs.sh +++ b/eng/common/cross/build-android-rootfs.sh @@ -5,15 +5,15 @@ __NDK_Version=r21 usage() { echo "Creates a toolchain and sysroot used for cross-compiling for Android." - echo. + echo echo "Usage: $0 [BuildArch] [ApiLevel]" - echo. + echo echo "BuildArch is the target architecture of Android. Currently only arm64 is supported." echo "ApiLevel is the target Android API level. API levels usually match to Android releases. See https://source.android.com/source/build-numbers.html" - echo. + echo echo "By default, the toolchain and sysroot will be generated in cross/android-rootfs/toolchain/[BuildArch]. You can change this behavior" echo "by setting the TOOLCHAIN_DIR environment variable" - echo. + echo echo "By default, the NDK will be downloaded into the cross/android-rootfs/android-ndk-$__NDK_Version directory. If you already have an NDK installation," echo "you can set the NDK_DIR environment variable to have this script use that installation of the NDK." echo "By default, this script will generate a file, android_platform, in the root of the ROOTFS_DIR directory that contains the RID for the supported and tested Android build: android.28-arm64. This file is to replace '/etc/os-release', which is not available for Android." diff --git a/eng/common/cross/build-rootfs.sh b/eng/common/cross/build-rootfs.sh index 7455dcb6af4..eb1a9080464 100644 --- a/eng/common/cross/build-rootfs.sh +++ b/eng/common/cross/build-rootfs.sh @@ -30,7 +30,8 @@ __IllumosArch=arm7 __HaikuArch=arm __QEMUArch=arm __UbuntuArch=armhf -__UbuntuRepo="http://ports.ubuntu.com/" +__UbuntuRepo= +__UbuntuSuites="updates security backports" __LLDB_Package="liblldb-3.9-dev" __SkipUnmount=0 @@ -129,6 +130,7 @@ __AlpineKeys=' 616db30d:MIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEAnpUpyWDWjlUk3smlWeA0\nlIMW+oJ38t92CRLHH3IqRhyECBRW0d0aRGtq7TY8PmxjjvBZrxTNDpJT6KUk4LRm\na6A6IuAI7QnNK8SJqM0DLzlpygd7GJf8ZL9SoHSH+gFsYF67Cpooz/YDqWrlN7Vw\ntO00s0B+eXy+PCXYU7VSfuWFGK8TGEv6HfGMALLjhqMManyvfp8hz3ubN1rK3c8C\nUS/ilRh1qckdbtPvoDPhSbTDmfU1g/EfRSIEXBrIMLg9ka/XB9PvWRrekrppnQzP\nhP9YE3x/wbFc5QqQWiRCYyQl/rgIMOXvIxhkfe8H5n1Et4VAorkpEAXdsfN8KSVv\nLSMazVlLp9GYq5SUpqYX3KnxdWBgN7BJoZ4sltsTpHQ/34SXWfu3UmyUveWj7wp0\nx9hwsPirVI00EEea9AbP7NM2rAyu6ukcm4m6ATd2DZJIViq2es6m60AE6SMCmrQF\nwmk4H/kdQgeAELVfGOm2VyJ3z69fQuywz7xu27S6zTKi05Qlnohxol4wVb6OB7qG\nLPRtK9ObgzRo/OPumyXqlzAi/Yvyd1ZQk8labZps3e16bQp8+pVPiumWioMFJDWV\nGZjCmyMSU8V6MB6njbgLHoyg2LCukCAeSjbPGGGYhnKLm1AKSoJh3IpZuqcKCk5C\n8CM1S15HxV78s9dFntEqIokCAwEAAQ== ' __Keyring= +__KeyringFile="/usr/share/keyrings/ubuntu-archive-keyring.gpg" __SkipSigCheck=0 __UseMirror=0 @@ -162,6 +164,7 @@ while :; do __UbuntuArch=armel __UbuntuRepo="http://ftp.debian.org/debian/" __CodeName=jessie + __KeyringFile="/usr/share/keyrings/debian-archive-keyring.gpg" ;; armv6) __BuildArch=armv6 @@ -169,10 +172,12 @@ while :; do __QEMUArch=arm __UbuntuRepo="http://raspbian.raspberrypi.org/raspbian/" __CodeName=buster + __KeyringFile="/usr/share/keyrings/raspbian-archive-keyring.gpg" __LLDB_Package="liblldb-6.0-dev" + __UbuntuSuites= - if [[ -e "/usr/share/keyrings/raspbian-archive-keyring.gpg" ]]; then - __Keyring="--keyring /usr/share/keyrings/raspbian-archive-keyring.gpg" + if [[ -e "$__KeyringFile" ]]; then + __Keyring="--keyring $__KeyringFile" fi ;; riscv64) @@ -181,13 +186,8 @@ while :; do __AlpinePackages="${__AlpinePackages// lldb-dev/}" __QEMUArch=riscv64 __UbuntuArch=riscv64 - __UbuntuRepo="http://deb.debian.org/debian" __UbuntuPackages="${__UbuntuPackages// libunwind8-dev/}" unset __LLDB_Package - - if [[ -e "/usr/share/keyrings/debian-archive-keyring.gpg" ]]; then - __Keyring="--keyring /usr/share/keyrings/debian-archive-keyring.gpg --include=debian-archive-keyring" - fi ;; ppc64le) __BuildArch=ppc64le @@ -288,8 +288,17 @@ while :; do __CodeName=jammy fi ;; + noble) # Ubuntu 24.04 + if [[ "$__CodeName" != "jessie" ]]; then + __CodeName=noble + fi + if [[ -n "$__LLDB_Package" ]]; then + __LLDB_Package="liblldb-18-dev" + fi + ;; jessie) # Debian 8 __CodeName=jessie + __KeyringFile="/usr/share/keyrings/debian-archive-keyring.gpg" if [[ -z "$__UbuntuRepo" ]]; then __UbuntuRepo="http://ftp.debian.org/debian/" @@ -298,6 +307,7 @@ while :; do stretch) # Debian 9 __CodeName=stretch __LLDB_Package="liblldb-6.0-dev" + __KeyringFile="/usr/share/keyrings/debian-archive-keyring.gpg" if [[ -z "$__UbuntuRepo" ]]; then __UbuntuRepo="http://ftp.debian.org/debian/" @@ -306,6 +316,7 @@ while :; do buster) # Debian 10 __CodeName=buster __LLDB_Package="liblldb-6.0-dev" + __KeyringFile="/usr/share/keyrings/debian-archive-keyring.gpg" if [[ -z "$__UbuntuRepo" ]]; then __UbuntuRepo="http://ftp.debian.org/debian/" @@ -313,6 +324,7 @@ while :; do ;; bullseye) # Debian 11 __CodeName=bullseye + __KeyringFile="/usr/share/keyrings/debian-archive-keyring.gpg" if [[ -z "$__UbuntuRepo" ]]; then __UbuntuRepo="http://ftp.debian.org/debian/" @@ -320,6 +332,7 @@ while :; do ;; bookworm) # Debian 12 __CodeName=bookworm + __KeyringFile="/usr/share/keyrings/debian-archive-keyring.gpg" if [[ -z "$__UbuntuRepo" ]]; then __UbuntuRepo="http://ftp.debian.org/debian/" @@ -327,6 +340,7 @@ while :; do ;; sid) # Debian sid __CodeName=sid + __KeyringFile="/usr/share/keyrings/debian-archive-keyring.gpg" if [[ -z "$__UbuntuRepo" ]]; then __UbuntuRepo="http://ftp.debian.org/debian/" @@ -436,6 +450,10 @@ fi __UbuntuPackages+=" ${__LLDB_Package:-}" +if [[ -z "$__UbuntuRepo" ]]; then + __UbuntuRepo="http://ports.ubuntu.com/" +fi + if [[ -n "$__LLVM_MajorVersion" ]]; then __UbuntuPackages+=" libclang-common-${__LLVM_MajorVersion}${__LLVM_MinorVersion:+.$__LLVM_MinorVersion}-dev" fi @@ -732,8 +750,18 @@ elif [[ -n "$__CodeName" ]]; then fi # shellcheck disable=SC2086 + echo running debootstrap "--variant=minbase" $__Keyring --arch "$__UbuntuArch" "$__CodeName" "$__RootfsDir" "$__UbuntuRepo" debootstrap "--variant=minbase" $__Keyring --arch "$__UbuntuArch" "$__CodeName" "$__RootfsDir" "$__UbuntuRepo" - cp "$__CrossDir/$__BuildArch/sources.list.$__CodeName" "$__RootfsDir/etc/apt/sources.list" + + mkdir -p "$__RootfsDir/etc/apt/sources.list.d/" + cat > "$__RootfsDir/etc/apt/sources.list.d/$__CodeName.sources" < .\verify.ps1 *.nupkg + Verifies the metadata of all .nupkg files in the currect working directory. +.EXAMPLE + PS> .\verify.ps1 --help + Displays the help text of the downloaded verifiction tool. +.LINK + https://github.com/NuGet/NuGetGallery/blob/master/src/VerifyMicrosoftPackage/README.md +#> + +# This script was copied from https://github.com/NuGet/NuGetGallery/blob/3e25ad135146676bcab0050a516939d9958bfa5d/src/VerifyMicrosoftPackage/verify.ps1 + +[CmdletBinding(PositionalBinding = $false)] +param( + [string]$NuGetExePath, + [string]$PackageSource = "https://api.nuget.org/v3/index.json", + [string]$DownloadPath, + [Parameter(ValueFromRemainingArguments = $true)] + [string[]]$args +) + +# The URL to download nuget.exe. +$nugetExeUrl = "https://dist.nuget.org/win-x86-commandline/v4.9.4/nuget.exe" + +# The package ID of the verification tool. +$packageId = "NuGet.VerifyMicrosoftPackage" + +# The location that nuget.exe and the verification tool will be downloaded to. +if (!$DownloadPath) { + $DownloadPath = (Join-Path $env:TEMP "NuGet.VerifyMicrosoftPackage") +} + +$fence = New-Object -TypeName string -ArgumentList '=', 80 + +# Create the download directory, if it doesn't already exist. +if (!(Test-Path $DownloadPath)) { + New-Item -ItemType Directory $DownloadPath | Out-Null +} +Write-Host "Using download path: $DownloadPath" + +if ($NuGetExePath) { + $nuget = $NuGetExePath +} else { + $downloadedNuGetExe = Join-Path $DownloadPath "nuget.exe" + + # Download nuget.exe, if it doesn't already exist. + if (!(Test-Path $downloadedNuGetExe)) { + Write-Host "Downloading nuget.exe from $nugetExeUrl..." + $ProgressPreference = 'SilentlyContinue' + try { + Invoke-WebRequest $nugetExeUrl -OutFile $downloadedNuGetExe + $ProgressPreference = 'Continue' + } catch { + $ProgressPreference = 'Continue' + Write-Error $_ + Write-Error "nuget.exe failed to download." + exit + } + } + + $nuget = $downloadedNuGetExe +} + +Write-Host "Using nuget.exe path: $nuget" +Write-Host " " + +# Download the latest version of the verification tool. +Write-Host "Downloading the latest version of $packageId from $packageSource..." +Write-Host $fence +& $nuget install $packageId ` + -Prerelease ` + -OutputDirectory $DownloadPath ` + -Source $PackageSource +Write-Host $fence +Write-Host " " + +if ($LASTEXITCODE -ne 0) { + Write-Error "nuget.exe failed to fetch the verify tool." + exit +} + +# Find the most recently downloaded tool +Write-Host "Finding the most recently downloaded verification tool." +$verifyProbePath = Join-Path $DownloadPath "$packageId.*" +$verifyPath = Get-ChildItem -Path $verifyProbePath -Directory ` + | Sort-Object -Property LastWriteTime -Descending ` + | Select-Object -First 1 +$verify = Join-Path $verifyPath "tools\NuGet.VerifyMicrosoftPackage.exe" +Write-Host "Using verification tool: $verify" +Write-Host " " + +# Execute the verification tool. +Write-Host "Executing the verify tool..." +Write-Host $fence +& $verify $args +Write-Host $fence +Write-Host " " + +# Respond to the exit code. +if ($LASTEXITCODE -ne 0) { + Write-Error "The verify tool found some problems." +} else { + Write-Output "The verify tool succeeded." +} diff --git a/eng/common/post-build/post-build-utils.ps1 b/eng/common/post-build/post-build-utils.ps1 deleted file mode 100644 index 534f6988d5b..00000000000 --- a/eng/common/post-build/post-build-utils.ps1 +++ /dev/null @@ -1,91 +0,0 @@ -# Most of the functions in this file require the variables `MaestroApiEndPoint`, -# `MaestroApiVersion` and `MaestroApiAccessToken` to be globally available. - -$ErrorActionPreference = 'Stop' -Set-StrictMode -Version 2.0 - -# `tools.ps1` checks $ci to perform some actions. Since the post-build -# scripts don't necessarily execute in the same agent that run the -# build.ps1/sh script this variable isn't automatically set. -$ci = $true -$disableConfigureToolsetImport = $true -. $PSScriptRoot\..\tools.ps1 - -function Create-MaestroApiRequestHeaders([string]$ContentType = 'application/json') { - Validate-MaestroVars - - $headers = New-Object 'System.Collections.Generic.Dictionary[[String],[String]]' - $headers.Add('Accept', $ContentType) - $headers.Add('Authorization',"Bearer $MaestroApiAccessToken") - return $headers -} - -function Get-MaestroChannel([int]$ChannelId) { - Validate-MaestroVars - - $apiHeaders = Create-MaestroApiRequestHeaders - $apiEndpoint = "$MaestroApiEndPoint/api/channels/${ChannelId}?api-version=$MaestroApiVersion" - - $result = try { Invoke-WebRequest -Method Get -Uri $apiEndpoint -Headers $apiHeaders | ConvertFrom-Json } catch { Write-Host "Error: $_" } - return $result -} - -function Get-MaestroBuild([int]$BuildId) { - Validate-MaestroVars - - $apiHeaders = Create-MaestroApiRequestHeaders -AuthToken $MaestroApiAccessToken - $apiEndpoint = "$MaestroApiEndPoint/api/builds/${BuildId}?api-version=$MaestroApiVersion" - - $result = try { return Invoke-WebRequest -Method Get -Uri $apiEndpoint -Headers $apiHeaders | ConvertFrom-Json } catch { Write-Host "Error: $_" } - return $result -} - -function Get-MaestroSubscriptions([string]$SourceRepository, [int]$ChannelId) { - Validate-MaestroVars - - $SourceRepository = [System.Web.HttpUtility]::UrlEncode($SourceRepository) - $apiHeaders = Create-MaestroApiRequestHeaders -AuthToken $MaestroApiAccessToken - $apiEndpoint = "$MaestroApiEndPoint/api/subscriptions?sourceRepository=$SourceRepository&channelId=$ChannelId&api-version=$MaestroApiVersion" - - $result = try { Invoke-WebRequest -Method Get -Uri $apiEndpoint -Headers $apiHeaders | ConvertFrom-Json } catch { Write-Host "Error: $_" } - return $result -} - -function Assign-BuildToChannel([int]$BuildId, [int]$ChannelId) { - Validate-MaestroVars - - $apiHeaders = Create-MaestroApiRequestHeaders -AuthToken $MaestroApiAccessToken - $apiEndpoint = "$MaestroApiEndPoint/api/channels/${ChannelId}/builds/${BuildId}?api-version=$MaestroApiVersion" - Invoke-WebRequest -Method Post -Uri $apiEndpoint -Headers $apiHeaders | Out-Null -} - -function Trigger-Subscription([string]$SubscriptionId) { - Validate-MaestroVars - - $apiHeaders = Create-MaestroApiRequestHeaders -AuthToken $MaestroApiAccessToken - $apiEndpoint = "$MaestroApiEndPoint/api/subscriptions/$SubscriptionId/trigger?api-version=$MaestroApiVersion" - Invoke-WebRequest -Uri $apiEndpoint -Headers $apiHeaders -Method Post | Out-Null -} - -function Validate-MaestroVars { - try { - Get-Variable MaestroApiEndPoint | Out-Null - Get-Variable MaestroApiVersion | Out-Null - Get-Variable MaestroApiAccessToken | Out-Null - - if (!($MaestroApiEndPoint -Match '^http[s]?://maestro-(int|prod).westus2.cloudapp.azure.com$')) { - Write-PipelineTelemetryError -Category 'MaestroVars' -Message "MaestroApiEndPoint is not a valid Maestro URL. '$MaestroApiEndPoint'" - ExitWithExitCode 1 - } - - if (!($MaestroApiVersion -Match '^[0-9]{4}-[0-9]{2}-[0-9]{2}$')) { - Write-PipelineTelemetryError -Category 'MaestroVars' -Message "MaestroApiVersion does not match a version string in the format yyyy-MM-DD. '$MaestroApiVersion'" - ExitWithExitCode 1 - } - } - catch { - Write-PipelineTelemetryError -Category 'MaestroVars' -Message 'Error: Variables `MaestroApiEndPoint`, `MaestroApiVersion` and `MaestroApiAccessToken` are required while using this script.' - Write-Host $_ - ExitWithExitCode 1 - } -} diff --git a/eng/common/post-build/publish-using-darc.ps1 b/eng/common/post-build/publish-using-darc.ps1 index 5a3a32ea8d7..4ff587ca46a 100644 --- a/eng/common/post-build/publish-using-darc.ps1 +++ b/eng/common/post-build/publish-using-darc.ps1 @@ -2,7 +2,6 @@ param( [Parameter(Mandatory=$true)][int] $BuildId, [Parameter(Mandatory=$true)][int] $PublishingInfraVersion, [Parameter(Mandatory=$true)][string] $AzdoToken, - [Parameter(Mandatory=$true)][string] $MaestroToken, [Parameter(Mandatory=$false)][string] $MaestroApiEndPoint = 'https://maestro.dot.net', [Parameter(Mandatory=$true)][string] $WaitPublishingFinish, [Parameter(Mandatory=$false)][string] $ArtifactsPublishingAdditionalParameters, @@ -10,7 +9,12 @@ param( ) try { - . $PSScriptRoot\post-build-utils.ps1 + # `tools.ps1` checks $ci to perform some actions. Since the post-build + # scripts don't necessarily execute in the same agent that run the + # build.ps1/sh script this variable isn't automatically set. + $ci = $true + $disableConfigureToolsetImport = $true + . $PSScriptRoot\..\tools.ps1 $darc = Get-Darc @@ -31,13 +35,13 @@ try { } & $darc add-build-to-channel ` - --id $buildId ` - --publishing-infra-version $PublishingInfraVersion ` - --default-channels ` - --source-branch main ` - --azdev-pat $AzdoToken ` - --bar-uri $MaestroApiEndPoint ` - --password $MaestroToken ` + --id $buildId ` + --publishing-infra-version $PublishingInfraVersion ` + --default-channels ` + --source-branch main ` + --azdev-pat "$AzdoToken" ` + --bar-uri "$MaestroApiEndPoint" ` + --ci ` @optionalParams if ($LastExitCode -ne 0) { diff --git a/eng/common/post-build/redact-logs.ps1 b/eng/common/post-build/redact-logs.ps1 index 82d91f6fd02..b7fc1959150 100644 --- a/eng/common/post-build/redact-logs.ps1 +++ b/eng/common/post-build/redact-logs.ps1 @@ -11,7 +11,15 @@ param( ) try { - . $PSScriptRoot\post-build-utils.ps1 + $ErrorActionPreference = 'Stop' + Set-StrictMode -Version 2.0 + + # `tools.ps1` checks $ci to perform some actions. Since the post-build + # scripts don't necessarily execute in the same agent that run the + # build.ps1/sh script this variable isn't automatically set. + $ci = $true + $disableConfigureToolsetImport = $true + . $PSScriptRoot\..\tools.ps1 $packageName = 'binlogtool' diff --git a/eng/common/post-build/sourcelink-validation.ps1 b/eng/common/post-build/sourcelink-validation.ps1 index 4011d324e73..1976ef70fb8 100644 --- a/eng/common/post-build/sourcelink-validation.ps1 +++ b/eng/common/post-build/sourcelink-validation.ps1 @@ -6,7 +6,15 @@ param( [Parameter(Mandatory=$true)][string] $SourcelinkCliVersion # Version of SourceLink CLI to use ) -. $PSScriptRoot\post-build-utils.ps1 +$ErrorActionPreference = 'Stop' +Set-StrictMode -Version 2.0 + +# `tools.ps1` checks $ci to perform some actions. Since the post-build +# scripts don't necessarily execute in the same agent that run the +# build.ps1/sh script this variable isn't automatically set. +$ci = $true +$disableConfigureToolsetImport = $true +. $PSScriptRoot\..\tools.ps1 # Cache/HashMap (File -> Exist flag) used to consult whether a file exist # in the repository at a specific commit point. This is populated by inserting diff --git a/eng/common/post-build/symbols-validation.ps1 b/eng/common/post-build/symbols-validation.ps1 index cd2181bafa0..7146e593ffa 100644 --- a/eng/common/post-build/symbols-validation.ps1 +++ b/eng/common/post-build/symbols-validation.ps1 @@ -322,8 +322,6 @@ function InstallDotnetSymbol { } try { - . $PSScriptRoot\post-build-utils.ps1 - InstallDotnetSymbol foreach ($Job in @(Get-Job)) { diff --git a/eng/common/post-build/trigger-subscriptions.ps1 b/eng/common/post-build/trigger-subscriptions.ps1 deleted file mode 100644 index ac9a95778fc..00000000000 --- a/eng/common/post-build/trigger-subscriptions.ps1 +++ /dev/null @@ -1,64 +0,0 @@ -param( - [Parameter(Mandatory=$true)][string] $SourceRepo, - [Parameter(Mandatory=$true)][int] $ChannelId, - [Parameter(Mandatory=$true)][string] $MaestroApiAccessToken, - [Parameter(Mandatory=$false)][string] $MaestroApiEndPoint = 'https://maestro.dot.net', - [Parameter(Mandatory=$false)][string] $MaestroApiVersion = '2019-01-16' -) - -try { - . $PSScriptRoot\post-build-utils.ps1 - - # Get all the $SourceRepo subscriptions - $normalizedSourceRepo = $SourceRepo.Replace('dnceng@', '') - $subscriptions = Get-MaestroSubscriptions -SourceRepository $normalizedSourceRepo -ChannelId $ChannelId - - if (!$subscriptions) { - Write-PipelineTelemetryError -Category 'TriggerSubscriptions' -Message "No subscriptions found for source repo '$normalizedSourceRepo' in channel '$ChannelId'" - ExitWithExitCode 0 - } - - $subscriptionsToTrigger = New-Object System.Collections.Generic.List[string] - $failedTriggeredSubscription = $false - - # Get all enabled subscriptions that need dependency flow on 'everyBuild' - foreach ($subscription in $subscriptions) { - if ($subscription.enabled -and $subscription.policy.updateFrequency -like 'everyBuild' -and $subscription.channel.id -eq $ChannelId) { - Write-Host "Should trigger this subscription: ${$subscription.id}" - [void]$subscriptionsToTrigger.Add($subscription.id) - } - } - - foreach ($subscriptionToTrigger in $subscriptionsToTrigger) { - try { - Write-Host "Triggering subscription '$subscriptionToTrigger'." - - Trigger-Subscription -SubscriptionId $subscriptionToTrigger - - Write-Host 'done.' - } - catch - { - Write-Host "There was an error while triggering subscription '$subscriptionToTrigger'" - Write-Host $_ - Write-Host $_.ScriptStackTrace - $failedTriggeredSubscription = $true - } - } - - if ($subscriptionsToTrigger.Count -eq 0) { - Write-Host "No subscription matched source repo '$normalizedSourceRepo' and channel ID '$ChannelId'." - } - elseif ($failedTriggeredSubscription) { - Write-PipelineTelemetryError -Category 'TriggerSubscriptions' -Message 'At least one subscription failed to be triggered...' - ExitWithExitCode 1 - } - else { - Write-Host 'All subscriptions were triggered successfully!' - } -} -catch { - Write-Host $_.ScriptStackTrace - Write-PipelineTelemetryError -Category 'TriggerSubscriptions' -Message $_ - ExitWithExitCode 1 -} diff --git a/eng/common/template-guidance.md b/eng/common/template-guidance.md index c114bc28dcb..5ef6c30ba92 100644 --- a/eng/common/template-guidance.md +++ b/eng/common/template-guidance.md @@ -76,13 +76,11 @@ eng\common\ source-build.yml (shim) post-build\ post-build.yml (shim) - trigger-subscription.yml (shim) common-variabls.yml (shim) setup-maestro-vars.yml (shim) steps\ publish-build-artifacts.yml (logic) publish-pipeline-artifacts.yml (logic) - add-build-channel.yml (shim) component-governance.yml (shim) generate-sbom.yml (shim) publish-logs.yml (shim) @@ -107,9 +105,7 @@ eng\common\ common-variabls.yml (logic) post-build.yml (logic) setup-maestro-vars.yml (logic) - trigger-subscription.yml (logic) steps\ - add-build-to-channel.yml (logic) component-governance.yml (logic) generate-sbom.yml (logic) publish-build-artifacts.yml (redirect) diff --git a/eng/common/templates-official/post-build/trigger-subscription.yml b/eng/common/templates-official/post-build/trigger-subscription.yml deleted file mode 100644 index da669030daf..00000000000 --- a/eng/common/templates-official/post-build/trigger-subscription.yml +++ /dev/null @@ -1,13 +0,0 @@ -parameters: - ChannelId: 0 - -steps: -- task: PowerShell@2 - displayName: Triggering subscriptions - inputs: - filePath: $(Build.SourcesDirectory)/eng/common/post-build/trigger-subscriptions.ps1 - arguments: -SourceRepo $(Build.Repository.Uri) - -ChannelId ${{ parameters.ChannelId }} - -MaestroApiAccessToken $(MaestroAccessToken) - -MaestroApiEndPoint $(MaestroApiEndPoint) - -MaestroApiVersion $(MaestroApiVersion) diff --git a/eng/common/templates-official/steps/add-build-to-channel.yml b/eng/common/templates-official/steps/add-build-to-channel.yml deleted file mode 100644 index 543dea8c696..00000000000 --- a/eng/common/templates-official/steps/add-build-to-channel.yml +++ /dev/null @@ -1,7 +0,0 @@ -steps: -- template: /eng/common/core-templates/steps/add-build-to-channel.yml - parameters: - is1ESPipeline: true - - ${{ each parameter in parameters }}: - ${{ parameter.key }}: ${{ parameter.value }} diff --git a/eng/common/templates/post-build/trigger-subscription.yml b/eng/common/templates/post-build/trigger-subscription.yml deleted file mode 100644 index da669030daf..00000000000 --- a/eng/common/templates/post-build/trigger-subscription.yml +++ /dev/null @@ -1,13 +0,0 @@ -parameters: - ChannelId: 0 - -steps: -- task: PowerShell@2 - displayName: Triggering subscriptions - inputs: - filePath: $(Build.SourcesDirectory)/eng/common/post-build/trigger-subscriptions.ps1 - arguments: -SourceRepo $(Build.Repository.Uri) - -ChannelId ${{ parameters.ChannelId }} - -MaestroApiAccessToken $(MaestroAccessToken) - -MaestroApiEndPoint $(MaestroApiEndPoint) - -MaestroApiVersion $(MaestroApiVersion) diff --git a/eng/common/templates/steps/add-build-to-channel.yml b/eng/common/templates/steps/add-build-to-channel.yml deleted file mode 100644 index 42bbba161b9..00000000000 --- a/eng/common/templates/steps/add-build-to-channel.yml +++ /dev/null @@ -1,7 +0,0 @@ -steps: -- template: /eng/common/core-templates/steps/add-build-to-channel.yml - parameters: - is1ESPipeline: false - - ${{ each parameter in parameters }}: - ${{ parameter.key }}: ${{ parameter.value }} diff --git a/eng/common/tools.ps1 b/eng/common/tools.ps1 index 0febe696dbd..9574f4eb9df 100644 --- a/eng/common/tools.ps1 +++ b/eng/common/tools.ps1 @@ -653,7 +653,7 @@ function GetNuGetPackageCachePath() { $env:NUGET_PACKAGES = Join-Path $env:UserProfile '.nuget\packages\' } else { $env:NUGET_PACKAGES = Join-Path $RepoRoot '.packages\' - $env:RESTORENOCACHE = $true + $env:RESTORENOHTTPCACHE = $true } } diff --git a/eng/common/tools.sh b/eng/common/tools.sh index a4f5d1b7761..00473c9f918 100644 --- a/eng/common/tools.sh +++ b/eng/common/tools.sh @@ -347,14 +347,14 @@ function InitializeBuildTool { fi } -# Set RestoreNoCache as a workaround for https://github.com/NuGet/Home/issues/3116 +# Set RestoreNoHttpCache as a workaround for https://github.com/NuGet/Home/issues/3116 function GetNuGetPackageCachePath { if [[ -z ${NUGET_PACKAGES:-} ]]; then if [[ "$use_global_nuget_cache" == true ]]; then - export NUGET_PACKAGES="$HOME/.nuget/packages" + export NUGET_PACKAGES="$HOME/.nuget/packages/" else - export NUGET_PACKAGES="$repo_root/.packages" - export RESTORENOCACHE=true + export NUGET_PACKAGES="$repo_root/.packages/" + export RESTORENOHTTPCACHE=true fi fi diff --git a/eng/dependabot/independent/Versions.props b/eng/dependabot/independent/Versions.props index c40341aaac7..a9d931e2b94 100644 --- a/eng/dependabot/independent/Versions.props +++ b/eng/dependabot/independent/Versions.props @@ -2,18 +2,18 @@ - 1.11.3 + 1.12.0 12.20.0 12.18.0 - 2.19.0 - 1.6.14 + 2.19.1 + 1.6.15 4.3.2 5.0.0 13.0.3 11.0.0 - 6.6.1 + 6.6.2 3.7.305.7 3.7.300.33 diff --git a/eng/dependabot/net8.0/Versions.props b/eng/dependabot/net8.0/Versions.props index 0dd5910c8a9..81bacd28d4c 100644 --- a/eng/dependabot/net8.0/Versions.props +++ b/eng/dependabot/net8.0/Versions.props @@ -10,6 +10,6 @@ 8.0.0 - 8.0.5 + 8.0.6 diff --git a/eng/dependabot/nuget.org/Versions.props b/eng/dependabot/nuget.org/Versions.props index 285eba92209..44806cae084 100644 --- a/eng/dependabot/nuget.org/Versions.props +++ b/eng/dependabot/nuget.org/Versions.props @@ -2,6 +2,6 @@ - 8.0.510501 + 8.0.532401 diff --git a/eng/pipelines/dotnet-monitor-compliance.yml b/eng/pipelines/dotnet-monitor-compliance.yml index e443bd43067..86caff41e50 100644 --- a/eng/pipelines/dotnet-monitor-compliance.yml +++ b/eng/pipelines/dotnet-monitor-compliance.yml @@ -71,8 +71,6 @@ extends: arguments: >- -BarBuildId "$(BuildBarId)" -AzdoToken "$(dn-bot-all-drop-rw-code-rw-release-all)" - -MaestroToken "$(MaestroAccessToken)" - -GitHubToken "$(BotAccount-dotnet-bot-repo-PAT)" -DownloadTargetPath "$(System.ArtifactsDirectory)\BuildAssets" -SasSuffixes "$(dotnetbuilds-internal-checksums-container-read-token),$(dotnetbuilds-internal-container-read-token)" -ReleaseVersion "$(BuildVersion)" diff --git a/eng/pipelines/dotnet-monitor-release.yml b/eng/pipelines/dotnet-monitor-release.yml index 4e31668eb9d..2dec67a9cc8 100644 --- a/eng/pipelines/dotnet-monitor-release.yml +++ b/eng/pipelines/dotnet-monitor-release.yml @@ -70,7 +70,7 @@ extends: -BarId $(BarId) -MaestroToken $(MaestroAccessToken) -TaskVariableName 'ReleaseVersion' - + - task: PowerShell@2 displayName: Get Build Version inputs: @@ -107,10 +107,15 @@ extends: variables: - ${{ if eq(parameters.IsTestRun, 'true') }}: - - group: DotNet-Diagnostics-Storage-Test + - name: DestinationAccountName + value: monitortestcli + - name: ChecksumsAccountName + value: monitortestchecksums - ${{ else }}: - - group: DotNetCli storage account tokens - - group: DotNet-DotNetStage-Storage + - name: DestinationAccountName + value: dotnetcli + - name: ChecksumsAccountName + value: dotnetclichecksums workspace: clean: all @@ -164,42 +169,28 @@ extends: - powershell: Install-Module Az.Storage -Force -Scope CurrentUser -AllowClobber -Verbose -RequiredVersion 5.10.1 displayName: Install Az.Storage Module 5.10.1 - - powershell: | - Write-Host "##vso[task.setvariable variable=DestinationAccountName]$env:DESTINATION_ACCOUNT_NAME" - Write-Host "##vso[task.setvariable variable=DestinationSasTokenBase64;issecret=true]$env:DESTINATION_SAS_TOKEN_BASE64" - Write-Host "##vso[task.setvariable variable=ChecksumsAccountName]$env:CHECKSUMS_ACCOUNT_NAME" - Write-Host "##vso[task.setvariable variable=ChecksumsSasTokenBase64;issecret=true]$env:CHECKSUMS_SAS_TOKEN_BASE64" - displayName: Set Storage Accounts - ${{ if eq(parameters.IsTestRun, 'true') }}: - env: - # Variables provided by DotNet-Diagnostics-Storage-Test group - DESTINATION_ACCOUNT_NAME: $(dotnet-monitor-test-storage-accountname) - DESTINATION_SAS_TOKEN_BASE64: $(dotnet-monitor-test-blob-write-token-base64) - CHECKSUMS_ACCOUNT_NAME: $(dotnet-monitor-checksums-test-storage-accountname) - CHECKSUMS_SAS_TOKEN_BASE64: $(dotnet-monitor-checksums-test-blob-write-token-base64) - ${{ else }}: - env: - # Variables provided by "DotNetCli storage account tokens" group - DESTINATION_ACCOUNT_NAME: dotnetcli - DESTINATION_SAS_TOKEN_BASE64: $(dotnetcli-account-blob-write-token-base64) - CHECKSUMS_ACCOUNT_NAME: dotnetclichecksums - CHECKSUMS_SAS_TOKEN_BASE64: $(dotnetclichecksums-account-blob-write-token-base64) - - - task: PowerShell@2 + - task: AzureCLI@2 displayName: Publish Assets inputs: - filePath: $(Build.SourcesDirectory)/eng/release/Scripts/PublishToBlobAccounts.ps1 + # It seems that azureSubscription can't use runtime expressions, so we need to use a compile time expression + # to set it. + ${{ if eq(parameters.IsTestRun, 'true') }}: + azureSubscription: dotnet-monitor-test-publish + ${{ else }}: + azureSubscription: dotnet-monitor-cli-storage-accounts-publish + # Save the service principal details to the environment so that azcopy can use them + addSpnToEnvironment: true + scriptType: ps + scriptLocation: scriptPath + scriptPath: $(Build.SourcesDirectory)/eng/release/Scripts/PublishToBlobAccounts.ps1 arguments: >- -AzCopyPath $(AzCopyPath) -BuildVersion $(BuildVersion) -ReleaseVersion $(ReleaseVersion) - -DotnetStageAccountKey $(dotnetstage-storage-key) -DestinationAccountName $(DestinationAccountName) - -DestinationSasTokenBase64 $(DestinationSasTokenBase64) -ChecksumsAccountName $(ChecksumsAccountName) - -ChecksumsSasTokenBase64 $(ChecksumsSasTokenBase64) -WhatIf:${{ format('${0}', parameters.IsDryRun) }} - + - task: 1ES.PublishBuildArtifacts@1 displayName: Publish Logs inputs: diff --git a/eng/pipelines/stages/preparerelease.yml b/eng/pipelines/stages/preparerelease.yml index 6a728d15ebf..743f9aaf2d4 100644 --- a/eng/pipelines/stages/preparerelease.yml +++ b/eng/pipelines/stages/preparerelease.yml @@ -28,14 +28,18 @@ stages: packageType: runtime version: 6.x installationPath: '$(Build.Repository.LocalPath)\.dotnet' + - script: mkdir $(System.ArtifactsDirectory)\StagingToolLogs displayName: Create Staging Tool Logs Directory + - script: '$(Build.SourcesDirectory)\dotnet.cmd build $(Build.Repository.LocalPath)\eng\release\DiagnosticsReleaseTool\DiagnosticsReleaseTool.csproj -c Release /bl' workingDirectory: '$(System.ArtifactsDirectory)\StagingToolLogs' displayName: 'Build Staging Tool' + # Run tool for release and test release branches - ${{ if and(ne(variables['System.TeamProject'], 'public'), notin(variables['Build.Reason'], 'PullRequest'), or(startsWith(variables['Build.SourceBranch'], 'refs/heads/release/'), startsWith(variables['Build.SourceBranch'], 'refs/heads/internal/release/'), startsWith(variables['Build.SourceBranch'], 'refs/heads/test/release/'))) }}: - template: /eng/common/templates-official/post-build/setup-maestro-vars.yml@self + - task: PowerShell@2 displayName: Get Build Version inputs: @@ -44,42 +48,53 @@ stages: -BarId $(BARBuildId) -MaestroToken $(MaestroAccessToken) -TaskVariableName 'BuildVersion' - - task: PowerShell@2 + + - task: AzureCLI@2 displayName: 'Download Build Assets' inputs: - targetType: filePath - filePath: '$(Build.Repository.LocalPath)/eng/release/Scripts/AcquireBuild.ps1' + azureSubscription: 'Darc: Maestro Production' + scriptType: ps + scriptPath: '$(Build.Repository.LocalPath)/eng/release/Scripts/AcquireBuild.ps1' arguments: >- -BarBuildId "$(BARBuildId)" -AzdoToken "$(dn-bot-all-drop-rw-code-rw-release-all)" - -MaestroToken "$(MaestroAccessToken)" - -GitHubToken "$(BotAccount-dotnet-bot-repo-PAT)" -DownloadTargetPath "$(System.ArtifactsDirectory)\BuildAssets" -SasSuffixes "$(dotnetbuilds-internal-checksums-container-read-token),$(dotnetbuilds-internal-container-read-token)" -ReleaseVersion "$(Build.BuildNumber)" workingDirectory: '$(Build.Repository.LocalPath)' continueOnError: true - - script: >- - $(Build.SourcesDirectory)\dotnet.cmd run --project $(Build.Repository.LocalPath)\eng\release\DiagnosticsReleaseTool\DiagnosticsReleaseTool.csproj -c Release - -- - prepare-release - --input-drop-path "$(System.ArtifactsDirectory)\BuildAssets" - --tool-manifest "$(Build.Repository.LocalPath)\eng\release\tool-list.json" - --staging-directory "$(System.ArtifactsDirectory)\AssetsLayout" - --release-name "$(Build.BuildNumber)" - --build-version "$(BuildVersion)" - --account-name "$(dotnet-diagnostics-storage-accountname)" - --account-key "$(dotnetstage-storage-key)" - --sas-valid-days "$(dotnet-diagnostics-storage-retentiondays)" - -v True - workingDirectory: '$(System.ArtifactsDirectory)\StagingToolLogs' - displayName: 'Stage Build Assets and Manifest' + + - task: AzureCLI@2 + displayName: 'Manifest Generation and Asset Publishing' + inputs: + workingDirectory: '$(System.ArtifactsDirectory)\StagingToolLogs' + azureSubscription: 'dotnetstage-dotnet-monitor-rw' + scriptType: pscore + scriptLocation: inlineScript + addSpnToEnvironment: true + inlineScript: >- + $(Build.SourcesDirectory)\dotnet.cmd run + --project $(Build.Repository.LocalPath)\eng\release\DiagnosticsReleaseTool\DiagnosticsReleaseTool.csproj + -c Release + -- + prepare-release + --input-drop-path "$(System.ArtifactsDirectory)\BuildAssets" + --tool-manifest "$(Build.Repository.LocalPath)\eng\release\tool-list.json" + --staging-directory "$(System.ArtifactsDirectory)\AssetsLayout" + --release-name "$(Build.BuildNumber)" + --build-version "$(BuildVersion)" + --account-name "$(dotnet-diagnostics-storage-accountname)" + --container-name $(dotnet-monitor-container-name) + --client-id "$env:servicePrincipalId" + -v True + - template: /eng/pipelines/steps/publish-pipeline-artifact.yml@self parameters: displayName: 'Upload Assets Layout' targetPath: '$(System.ArtifactsDirectory)\AssetsLayout' artifact: 'StagingToolAssetsLayout' is1ESPipeline: ${{ parameters.is1ESPipeline }} + # Only tag build from real release branches - ${{ if not(startsWith(variables['Build.SourceBranch'], 'refs/heads/test/release/')) }}: - task: Powershell@2 @@ -87,12 +102,14 @@ stages: inputs: targetType: inline script: Write-Host "##vso[build.addbuildtag]MonitorRelease" + - template: /eng/pipelines/steps/publish-pipeline-artifact.yml@self parameters: displayName: 'Upload Staging Tool Logs' targetPath: '$(System.ArtifactsDirectory)\StagingToolLogs' artifact: 'StagingToolLogs' is1ESPipeline: ${{ parameters.is1ESPipeline }} + - ${{ if and(ne(variables['System.TeamProject'], 'public'), notin(variables['Build.Reason'], 'PullRequest')) }}: - task: Powershell@2 displayName: 'Tag Build with update-docker' diff --git a/eng/release/DiagnosticsReleaseTool/Common/AzureBlobPublisher.cs b/eng/release/DiagnosticsReleaseTool/Common/AzureBlobPublisher.cs index 04becfb2293..945ac240ed8 100644 --- a/eng/release/DiagnosticsReleaseTool/Common/AzureBlobPublisher.cs +++ b/eng/release/DiagnosticsReleaseTool/Common/AzureBlobPublisher.cs @@ -1,10 +1,10 @@ // Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. -using Azure.Storage; +using Azure.Core; +using Azure.Identity; using Azure.Storage.Blobs; using Azure.Storage.Blobs.Models; -using Azure.Storage.Sas; using Microsoft.Extensions.Logging; using System; using System.Buffers; @@ -17,17 +17,14 @@ namespace ReleaseTool.Core { public class AzureBlobBublisher : IPublisher { - private const int ClockSkewSec = 15 * 60; private const int MaxRetries = 15; private const int MaxFullLoopRetries = 5; private readonly TimeSpan FullLoopRetryDelay = TimeSpan.FromSeconds(1); - private const string AccessPolicyDownloadId = "DownloadDrop"; private readonly string _accountName; - private readonly string _accountKey; + private readonly string _clientId; private readonly string _containerName; private readonly string _buildVersion; - private readonly int _sasValidDays; private readonly ILogger _logger; private BlobContainerClient _client; @@ -40,12 +37,17 @@ private Uri AccountBlobUri } } - private StorageSharedKeyCredential AccountCredential + private TokenCredential Credentials { get { - StorageSharedKeyCredential credential = new StorageSharedKeyCredential(_accountName, _accountKey); - return credential; + if (_clientId == null) + { + // Local development scenario. Use the default credential. + return new DefaultAzureCredential(); + } + + return new DefaultAzureCredential(new DefaultAzureCredentialOptions { ManagedIdentityClientId = _clientId }); } } @@ -68,13 +70,12 @@ private BlobClientOptions BlobOptions } } - public AzureBlobBublisher(string accountName, string accountKey, string containerName, string buildVersion, int sasValidDays, ILogger logger) + public AzureBlobBublisher(string accountName, string clientId, string containerName, string buildVersion, ILogger logger) { _accountName = accountName; - _accountKey = accountKey; + _clientId = clientId; _containerName = containerName; _buildVersion = buildVersion; - _sasValidDays = sasValidDays; _logger = logger; } @@ -107,20 +108,11 @@ public async Task PublishFileAsync(FileMapping fileMap, CancellationToke await blobClient.UploadAsync(srcStream, overwrite: true, ct); - BlobSasBuilder sasBuilder = new BlobSasBuilder() - { - BlobContainerName = client.Name, - BlobName = blobClient.Name, - Identifier = AccessPolicyDownloadId, - Protocol = SasProtocol.Https - }; - Uri accessUri = blobClient.GenerateSasUri(sasBuilder); - using BlobDownloadStreamingResult blobStream = (await blobClient.DownloadStreamingAsync(cancellationToken: ct)).Value; srcStream.Position = 0; completed = await VerifyFileStreamsMatchAsync(srcStream, blobStream, ct); - result = accessUri; + result = blobClient.Uri; } catch (IOException ioEx) when (!(ioEx is PathTooLongException)) { @@ -155,7 +147,7 @@ private async Task GetClient(CancellationToken ct) { if (_client == null) { - BlobServiceClient serviceClient = new BlobServiceClient(AccountBlobUri, AccountCredential, BlobOptions); + BlobServiceClient serviceClient = new BlobServiceClient(AccountBlobUri, Credentials, BlobOptions); _logger.LogInformation($"Attempting to connect to {serviceClient.Uri} to store blobs."); BlobContainerClient newClient; @@ -176,31 +168,6 @@ private async Task GetClient(CancellationToken ct) continue; } - try - { - DateTime baseTime = DateTime.UtcNow; - // Add the new (or update existing) "download" policy to the container - // This is used to mint the SAS tokens without an expiration policy - // Expiration can be added later by modifying this policy - BlobSignedIdentifier downloadPolicyIdentifier = new BlobSignedIdentifier() - { - Id = AccessPolicyDownloadId, - AccessPolicy = new BlobAccessPolicy() - { - Permissions = "r", - PolicyStartsOn = new DateTimeOffset(baseTime.AddSeconds(-ClockSkewSec)), - PolicyExpiresOn = new DateTimeOffset(DateTime.UtcNow.AddDays(_sasValidDays).AddSeconds(ClockSkewSec)), - } - }; - _logger.LogInformation($"Writing download access policy: {AccessPolicyDownloadId} to {_containerName}."); - await newClient.SetAccessPolicyAsync(PublicAccessType.None, new BlobSignedIdentifier[] { downloadPolicyIdentifier }, cancellationToken: ct); - } - catch (Exception ex) - { - _logger.LogWarning(ex, $"Failed to write access policy for {_containerName}, retrying."); - continue; - } - _logger.LogInformation($"Container {_containerName} is ready."); _client = newClient; break; diff --git a/eng/release/DiagnosticsReleaseTool/Config.cs b/eng/release/DiagnosticsReleaseTool/Config.cs index 637fda3a393..475b84c8188 100644 --- a/eng/release/DiagnosticsReleaseTool/Config.cs +++ b/eng/release/DiagnosticsReleaseTool/Config.cs @@ -14,9 +14,8 @@ internal class Config public string ReleaseName { get; } public string BuildVersion { get; } public string AccountName { get; } - public string AccountKey { get; } + public string ClientId { get; } public string ContainerName { get; } - public int SasValidDays { get; } public Config( FileInfo toolManifest, @@ -26,9 +25,8 @@ public Config( string releaseName, string buildVersion, string accountName, - string accountKey, - string containerName, - int sasValidDays) + string clientId, + string containerName) { ToolManifest = toolManifest; ShouldVerifyManifest = verifyToolManifest; @@ -37,9 +35,8 @@ public Config( ReleaseName = releaseName; BuildVersion = buildVersion; AccountName = accountName; - AccountKey = accountKey; + ClientId = clientId; ContainerName = containerName; - SasValidDays = sasValidDays; } } } diff --git a/eng/release/DiagnosticsReleaseTool/DiagnosticsReleaseCommandLine.cs b/eng/release/DiagnosticsReleaseTool/DiagnosticsReleaseCommandLine.cs index 06072d77a3e..5884f3a3cb6 100644 --- a/eng/release/DiagnosticsReleaseTool/DiagnosticsReleaseCommandLine.cs +++ b/eng/release/DiagnosticsReleaseTool/DiagnosticsReleaseCommandLine.cs @@ -107,8 +107,9 @@ private static Option AzureStorageAccountNameOption() => private static Option AzureStorageAccountKeyOption() => new Option( - aliases: new[] { "-k", "--account-key" }, - description: "Storage account key, in base 64 format.") + aliases: new[] { "-k", "--client-id" }, + description: "Identity Client ID. If left blank, ambient identity will be used.", + getDefaultValue: () => null) { IsRequired = true, }; diff --git a/eng/release/DiagnosticsReleaseTool/DiagnosticsReleaseRunner.cs b/eng/release/DiagnosticsReleaseTool/DiagnosticsReleaseRunner.cs index 3ecfa62f936..e9024d55d48 100644 --- a/eng/release/DiagnosticsReleaseTool/DiagnosticsReleaseRunner.cs +++ b/eng/release/DiagnosticsReleaseTool/DiagnosticsReleaseRunner.cs @@ -49,7 +49,7 @@ internal async static Task PrepareRelease(Config releaseConfig, bool verbos IPublisher releasePublisher = dryRun ? new SkipPublisher() : - new AzureBlobBublisher(releaseConfig.AccountName, releaseConfig.AccountKey, releaseConfig.ContainerName, releaseConfig.BuildVersion, releaseConfig.SasValidDays, logger); + new AzureBlobBublisher(releaseConfig.AccountName, releaseConfig.ClientId, releaseConfig.ContainerName, releaseConfig.BuildVersion, logger); IManifestGenerator manifestGenerator = new DiagnosticsManifestGenerator(releaseMetadata, releaseConfig.ToolManifest, logger); using var diagnosticsRelease = new Release( diff --git a/eng/release/DiagnosticsReleaseTool/DiagnosticsReleaseTool.csproj b/eng/release/DiagnosticsReleaseTool/DiagnosticsReleaseTool.csproj index fc0720a3fb5..336e0567bce 100644 --- a/eng/release/DiagnosticsReleaseTool/DiagnosticsReleaseTool.csproj +++ b/eng/release/DiagnosticsReleaseTool/DiagnosticsReleaseTool.csproj @@ -13,15 +13,16 @@ - - - - - - + + + + + + - - + + + diff --git a/eng/release/Directory.Build.props b/eng/release/Directory.Build.props index a8133bfcf5e..100d8a4ebf8 100644 --- a/eng/release/Directory.Build.props +++ b/eng/release/Directory.Build.props @@ -1,4 +1,3 @@ - - + \ No newline at end of file diff --git a/eng/release/Scripts/AcquireBuild.ps1 b/eng/release/Scripts/AcquireBuild.ps1 index b76c6279a09..220c6ff13fd 100644 --- a/eng/release/Scripts/AcquireBuild.ps1 +++ b/eng/release/Scripts/AcquireBuild.ps1 @@ -4,9 +4,6 @@ param( [Parameter(Mandatory=$true)][string] $DownloadTargetPath, [Parameter(Mandatory=$true)][string] $SasSuffixes, [Parameter(Mandatory=$true)][string] $AzdoToken, - [Parameter(Mandatory=$true)][string] $MaestroToken, - [Parameter(Mandatory=$true)][string] $GitHubToken, - [Parameter(Mandatory=$false)][string] $MaestroApiEndPoint = 'https://maestro-prod.westus2.cloudapp.azure.com', [Parameter(Mandatory=$false)][string] $DarcVersion = $null, [Parameter(Mandatory=$false)][bool] $Separated = $true, [switch] $help, @@ -19,9 +16,6 @@ function Write-Help() { Write-Host " -DownloadTargetPath Path to download the build to." Write-Host " -SasSuffixes Comma separated list of potential uri suffixes that can be used if anonymous access to a blob uri fails. Appended directly to the end of the URI. Use full SAS syntax with ?." Write-Host " -AzdoToken Azure DevOps token to use for builds queries" - Write-Host " -MaestroToken Maestro token to use for querying BAR" - Write-Host " -GitHubToken GitHub token to use for querying repository information" - Write-Host " -MaestroApiEndPoint BAR endpoint to use for build queries." Write-Host " -Separated <`$true|`$false> Download files to their repo separated locations." Write-Host "" } @@ -62,12 +56,10 @@ try { --output-dir $DownloadTargetPath ` --overwrite ` --sas-suffixes $SasSuffixes ` - --github-pat $GitHubToken ` --azdev-pat $AzdoToken ` - --bar-uri $MaestroApiEndPoint ` - --password $MaestroToken ` --verbose ` --continue-on-error ` + --ci ` $separatedArgs if ($LastExitCode -ne 0) { diff --git a/eng/release/Scripts/PublishToBlobAccounts.ps1 b/eng/release/Scripts/PublishToBlobAccounts.ps1 index 4e0313a464b..19e418a677f 100644 --- a/eng/release/Scripts/PublishToBlobAccounts.ps1 +++ b/eng/release/Scripts/PublishToBlobAccounts.ps1 @@ -3,23 +3,20 @@ Param( [Parameter(Mandatory=$true)][string]$AzCopyPath, [Parameter(Mandatory=$true)][string]$BuildVersion, [Parameter(Mandatory=$true)][string]$ReleaseVersion, - [Parameter(Mandatory=$true)][string]$DotnetStageAccountKey, [Parameter(Mandatory=$true)][string]$DestinationAccountName, - [Parameter(Mandatory=$true)][string]$DestinationSasTokenBase64, - [Parameter(Mandatory=$true)][string]$ChecksumsAccountName, - [Parameter(Mandatory=$true)][string]$ChecksumsSasTokenBase64 + [Parameter(Mandatory=$true)][string]$ChecksumsAccountName ) $ErrorActionPreference = 'Stop' Set-StrictMode -Version 2.0 +# Use the OAuth token that was obtained by the az cli when it logged in. +$Env:AZCOPY_AUTO_LOGIN_TYPE="AZCLI" + $sourceAccountName = 'dotnetstage' $sourceContainerName = 'dotnet-monitor' $destinationContainerName = 'dotnet' -$destinationSasToken = [Text.Encoding]::UTF8.GetString([Convert]::FromBase64String($DestinationSasTokenBase64)) -$checksumsSasToken = [Text.Encoding]::UTF8.GetString([Convert]::FromBase64String($ChecksumsSasTokenBase64)) - function Generate-Source-Uri{ [CmdletBinding()] Param( @@ -38,34 +35,11 @@ function Generate-Destination-Uri{ return "https://$AccountName.blob.core.windows.net/$destinationContainerName/diagnostics/monitor/$ReleaseVersion" } -function Generate-Sas-Token{ - [CmdletBinding()] - Param( - [Parameter(Mandatory=$true)][string]$StorageAccountName, - [Parameter(Mandatory=$true)][string]$ContainerName, - [Parameter(Mandatory=$true)][string]$AccountKey, - [Parameter(Mandatory=$true)][string]$Permissions - ) - - $context = New-AzStorageContext ` - -StorageAccountName $StorageAccountName ` - -StorageAccountKey $AccountKey - - return New-AzStorageContainerSASToken ` - -Container $ContainerName ` - -Context $context ` - -Permission $Permissions ` - -StartTime (Get-Date).AddMinutes(-15.0) ` - -ExpiryTime (Get-Date).AddHours(1.0) -} - function Transfer-File{ [CmdletBinding(SupportsShouldProcess)] Param( [Parameter(Mandatory=$true)][string]$From, - [Parameter(Mandatory=$true)][string]$To, - [Parameter(Mandatory=$true)][string]$FromToken, - [Parameter(Mandatory=$true)][string]$ToToken + [Parameter(Mandatory=$true)][string]$To ) Write-Host "Copy $From -> $To" @@ -73,8 +47,8 @@ function Transfer-File{ if ($From -eq $to) { Write-Host 'Skipping copy because source and destination are the same.' } else { - [array]$azCopyArgs = "$From$FromToken" - $azCopyArgs += "$To$ToToken" + [array]$azCopyArgs = "$From" + $azCopyArgs += "$To" $azCopyArgs += "--s2s-preserve-properties" $azCopyArgs += "--s2s-preserve-access-tier=false" if ($WhatIfPreference) { @@ -84,14 +58,9 @@ function Transfer-File{ } } -# Create source URI and SAS token +# Create source URI $sourceUri = Generate-Source-Uri ` -AssetType 'Blob' -$soureSasToken = Generate-Sas-Token ` - -StorageAccountName $sourceAccountName ` - -ContainerName $sourceContainerName ` - -AccountKey $DotnetStageAccountKey ` - -Permissions 'rl' # Create destination URI $destinationUri = Generate-Destination-Uri ` @@ -100,9 +69,7 @@ $destinationUri = Generate-Destination-Uri ` # Copy files to destination account Transfer-File ` -From $sourceUri ` - -FromToken $soureSasToken ` -To $destinationUri ` - -ToToken $destinationSasToken ` -WhatIf:$WhatIfPreference # Create source checksums URI @@ -116,7 +83,5 @@ $checksumsDestinationUri = Generate-Destination-Uri ` # Copy checksums to checksum account Transfer-File ` -From $checksumsSourceUri ` - -FromToken $soureSasToken ` -To $checksumsDestinationUri ` - -ToToken $checksumsSasToken ` - -WhatIf:$WhatIfPreference \ No newline at end of file + -WhatIf:$WhatIfPreference diff --git a/global.json b/global.json index 860f58ac87b..5f91d176963 100644 --- a/global.json +++ b/global.json @@ -1,6 +1,6 @@ { "tools": { - "dotnet": "9.0.100-preview.4.24267.66", + "dotnet": "9.0.100-preview.5.24307.3", "runtimes": { "aspnetcore": [ "$(MicrosoftAspNetCoreApp60Version)", @@ -31,7 +31,7 @@ }, "msbuild-sdks": { "Microsoft.Build.NoTargets": "3.7.0", - "Microsoft.DotNet.Arcade.Sdk": "9.0.0-beta.24303.1", - "Microsoft.DotNet.Helix.Sdk": "9.0.0-beta.24303.1" + "Microsoft.DotNet.Arcade.Sdk": "9.0.0-beta.24327.1", + "Microsoft.DotNet.Helix.Sdk": "9.0.0-beta.24327.1" } } diff --git a/src/Extensions/S3Storage/OptionsDisplayStrings.Designer.cs b/src/Extensions/S3Storage/OptionsDisplayStrings.Designer.cs index 0d45d0dab2e..dfa1b337afc 100644 --- a/src/Extensions/S3Storage/OptionsDisplayStrings.Designer.cs +++ b/src/Extensions/S3Storage/OptionsDisplayStrings.Designer.cs @@ -1,7 +1,6 @@ //------------------------------------------------------------------------------ // // This code was generated by a tool. -// Runtime Version:4.0.30319.42000 // // Changes to this file may cause incorrect behavior and will be lost if // the code is regenerated. @@ -132,6 +131,15 @@ public static string DisplayAttributeDescription_S3StorageEgressProviderOptions_ } } + /// + /// Looks up a localized string similar to If UseKmsEncryption is true, this specifies the arn of the "customer managed" KMS encryption key to be used for server side encryption. If no value is set for this field then S3 will use an AWS managed key for KMS encryption. + /// + public static string DisplayAttributeDescription_S3StorageEgressProviderOptions_KmsEncryptionKey { + get { + return ResourceManager.GetString("DisplayAttributeDescription_S3StorageEgressProviderOptions_KmsEncryptionKey", resourceCulture); + } + } + /// /// Looks up a localized string similar to The amount of time the generated pre-signed url will be accessible.. /// @@ -158,5 +166,14 @@ public static string DisplayAttributeDescription_S3StorageEgressProviderOptions_ return ResourceManager.GetString("DisplayAttributeDescription_S3StorageEgressProviderOptions_SecretAccessKey", resourceCulture); } } + + /// + /// Looks up a localized string similar to A boolean flag which controls whether the Egress should use KMS server side encryption.. + /// + public static string DisplayAttributeDescription_S3StorageEgressProviderOptions_UseKmsEncryption { + get { + return ResourceManager.GetString("DisplayAttributeDescription_S3StorageEgressProviderOptions_UseKmsEncryption", resourceCulture); + } + } } } diff --git a/src/Extensions/S3Storage/OptionsDisplayStrings.resx b/src/Extensions/S3Storage/OptionsDisplayStrings.resx index fbf39e2a960..b8d17917bb2 100644 --- a/src/Extensions/S3Storage/OptionsDisplayStrings.resx +++ b/src/Extensions/S3Storage/OptionsDisplayStrings.resx @@ -157,6 +157,14 @@ The boolean flag set for AWS connection configuration ForcePathStyle option. The description provided for the ForcePathStyle parameter on S3StorageEgressProviderOptions. + + A boolean flag which controls whether the Egress should use KMS server side encryption. + The description provided for the UseKmsEncryption parameter on S3StorageEgressProviderOptions. + + + If UseKmsEncryption is true, this specifies the arn of the "customer managed" KMS encryption key to be used for server side encryption. If no value is set for this field then S3 will use an AWS managed key for KMS encryption. + The description provided for the KmsEncryptionKey parameter on S3StorageEgressProviderOptions. + Buffer size used when copying data from an egress callback returning a stream to the egress callback that is provided a stream to which data is written. The description provided for the CopyBufferSize parameter on all egress provider options. diff --git a/src/Extensions/S3Storage/S3Storage.cs b/src/Extensions/S3Storage/S3Storage.cs index a743c87407b..04829e8e53a 100644 --- a/src/Extensions/S3Storage/S3Storage.cs +++ b/src/Extensions/S3Storage/S3Storage.cs @@ -23,13 +23,17 @@ internal sealed class S3Storage : IS3Storage private readonly string _bucketName; private readonly string _objectId; private readonly string _contentType; + private readonly bool _useKmsEncryption; + private readonly string _kmsEncryptionKey; - public S3Storage(IAmazonS3 client, string bucketName, string objectId, string contentType) + public S3Storage(IAmazonS3 client, string bucketName, string objectId, string contentType, bool useKmsEncryption, string kmsEncryptionKey) { _s3Client = client; _bucketName = bucketName; _objectId = objectId; _contentType = contentType; + _useKmsEncryption = useKmsEncryption; + _kmsEncryptionKey = kmsEncryptionKey; } public static async Task CreateAsync(S3StorageEgressProviderOptions options, EgressArtifactSettings settings, CancellationToken cancellationToken) @@ -73,11 +77,17 @@ public static async Task CreateAsync(S3StorageEgressProviderOptions if (awsCredentials == null) throw new AmazonClientException("Failed to find AWS Credentials for constructing AWS service client"); + if (options.UseKmsEncryption) + { + // Required for generating pre-signed URLs with KMS encryption + AWSConfigsS3.UseSignatureVersion4 = true; + } + IAmazonS3 s3Client = new AmazonS3Client(awsCredentials, configuration); bool exists = await AmazonS3Util.DoesS3BucketExistV2Async(s3Client, options.BucketName); if (!exists) await s3Client.PutBucketAsync(options.BucketName, cancellationToken); - return new S3Storage(s3Client, options.BucketName, settings.Name, settings.ContentType); + return new S3Storage(s3Client, options.BucketName, settings.Name, settings.ContentType, options.UseKmsEncryption, options.KmsEncryptionKey); } public async Task PutAsync(Stream inputStream, CancellationToken token) @@ -90,6 +100,16 @@ public async Task PutAsync(Stream inputStream, CancellationToken token) InputStream = inputStream, AutoCloseStream = false, }; + + if (_useKmsEncryption) + { + request.ServerSideEncryptionMethod = ServerSideEncryptionMethod.AWSKMS; + if (!string.IsNullOrEmpty(_kmsEncryptionKey)) + { + request.ServerSideEncryptionKeyManagementServiceKeyId = _kmsEncryptionKey; + } + } + await _s3Client.PutObjectAsync(request, token); } @@ -102,6 +122,16 @@ public async Task UploadAsync(Stream inputStream, CancellationToken token) public async Task InitMultiPartUploadAsync(IDictionary metadata, CancellationToken cancellationToken) { var request = new InitiateMultipartUploadRequest { BucketName = _bucketName, Key = _objectId, ContentType = _contentType }; + + if (_useKmsEncryption) + { + request.ServerSideEncryptionMethod = ServerSideEncryptionMethod.AWSKMS; + if (!string.IsNullOrEmpty(_kmsEncryptionKey)) + { + request.ServerSideEncryptionKeyManagementServiceKeyId = _kmsEncryptionKey; + } + } + foreach (var metaData in metadata) request.Metadata[metaData.Key] = metaData.Value; var response = await _s3Client.InitiateMultipartUploadAsync(request, cancellationToken); diff --git a/src/Extensions/S3Storage/S3StorageEgressProviderOptions.cs b/src/Extensions/S3Storage/S3StorageEgressProviderOptions.cs index 08ac17a9f0a..d85c576fee8 100644 --- a/src/Extensions/S3Storage/S3StorageEgressProviderOptions.cs +++ b/src/Extensions/S3Storage/S3StorageEgressProviderOptions.cs @@ -63,5 +63,15 @@ internal sealed partial class S3StorageEgressProviderOptions Description = nameof(OptionsDisplayStrings.DisplayAttributeDescription_CommonEgressProviderOptions_CopyBufferSize))] [Range(1, int.MaxValue)] public int? CopyBufferSize { get; set; } + + [Display( + ResourceType = typeof(OptionsDisplayStrings), + Description = nameof(OptionsDisplayStrings.DisplayAttributeDescription_S3StorageEgressProviderOptions_UseKmsEncryption))] + public bool UseKmsEncryption { get; set; } + + [Display( + ResourceType = typeof(OptionsDisplayStrings), + Description = nameof(OptionsDisplayStrings.DisplayAttributeDescription_S3StorageEgressProviderOptions_KmsEncryptionKey))] + public string KmsEncryptionKey { get; set; } } } diff --git a/src/Microsoft.Diagnostics.Monitoring.HostingStartup/FunctionProbeCategories.cs b/src/Microsoft.Diagnostics.Monitoring.HostingStartup/FunctionProbeCategories.cs deleted file mode 100644 index c742134347d..00000000000 --- a/src/Microsoft.Diagnostics.Monitoring.HostingStartup/FunctionProbeCategories.cs +++ /dev/null @@ -1,25 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -namespace DotnetMonitor.ParameterCapture -{ - /// - /// Special namespace and class used for Parameter Capture logging. - /// This is to prevent log filtering that normally occurs for Microsoft categories. - /// We can also use this to classify different types of logs, such as user vs. library code. - /// - internal sealed class UserCode - { - } - - internal sealed class SystemCode - { - } - - internal sealed class Service - { - } -} - - - diff --git a/src/Microsoft.Diagnostics.Monitoring.HostingStartup/HostingStartup.cs b/src/Microsoft.Diagnostics.Monitoring.HostingStartup/HostingStartup.cs deleted file mode 100644 index 613cff749d3..00000000000 --- a/src/Microsoft.Diagnostics.Monitoring.HostingStartup/HostingStartup.cs +++ /dev/null @@ -1,37 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -using Microsoft.AspNetCore.Hosting; -using Microsoft.Diagnostics.Monitoring.HostingStartup; -using Microsoft.Diagnostics.Monitoring.HostingStartup.ParameterCapturing; -using Microsoft.Diagnostics.Tools.Monitor; -using Microsoft.Diagnostics.Tools.Monitor.HostingStartup; -using Microsoft.Extensions.DependencyInjection; -using System.Threading; - -[assembly: HostingStartup(typeof(HostingStartup))] -namespace Microsoft.Diagnostics.Monitoring.HostingStartup -{ - internal sealed class HostingStartup : IHostingStartup - { - public static int InvocationCount; - - public void Configure(IWebHostBuilder builder) - { - builder.ConfigureServices(services => - { - // Keep track of how many times this hosting startup has been invoked for easy - // validation in tests. - Interlocked.Increment(ref InvocationCount); - - if (ToolIdentifiers.IsEnvVarEnabled(InProcessFeaturesIdentifiers.EnvironmentVariables.ParameterCapturing.Enable)) - { - services.AddSingleton(); - services.AddHostedService(); - } - }); - - ToolIdentifiers.EnableEnvVar(InProcessFeaturesIdentifiers.EnvironmentVariables.AvailableInfrastructure.HostingStartup); - } - } -} diff --git a/src/Microsoft.Diagnostics.Monitoring.HostingStartup/Microsoft.Diagnostics.Monitoring.HostingStartup.csproj b/src/Microsoft.Diagnostics.Monitoring.HostingStartup/Microsoft.Diagnostics.Monitoring.HostingStartup.csproj deleted file mode 100644 index 9c34122f9e8..00000000000 --- a/src/Microsoft.Diagnostics.Monitoring.HostingStartup/Microsoft.Diagnostics.Monitoring.HostingStartup.csproj +++ /dev/null @@ -1,47 +0,0 @@ - - - - - net6.0 - true - Library - $(DefineConstants);HOSTINGSTARTUP - enable - True - - - - - - - - - - - - - - - - - - - - - - - - True - True - ParameterCapturingStrings.resx - - - - - - ResXFileCodeGenerator - ParameterCapturingStrings.Designer.cs - - - - diff --git a/src/Microsoft.Diagnostics.Monitoring.HostingStartup/ParameterCapturing/MethodTemplateString.cs b/src/Microsoft.Diagnostics.Monitoring.HostingStartup/ParameterCapturing/MethodTemplateString.cs deleted file mode 100644 index 76e5a0134c3..00000000000 --- a/src/Microsoft.Diagnostics.Monitoring.HostingStartup/ParameterCapturing/MethodTemplateString.cs +++ /dev/null @@ -1,198 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -using System; -using System.Reflection; -using System.Text; - -namespace Microsoft.Diagnostics.Monitoring.HostingStartup.ParameterCapturing -{ - internal sealed class MethodTemplateString - { - private static class Tokens - { - private static class Internal - { - public const string Prefix = "<"; - public const string Postfix = ">"; - } - - public static class Types - { - public const char ArityDelimiter = '`'; - public const char Separator = '.'; - public const string Unknown = Internal.Prefix + "unknown" + Internal.Postfix; - } - - public static class Parameters - { - public const char Start = '('; - public const string Separator = ", "; - public const string NameValueSeparator = ": "; - public const char End = ')'; - - public static class Modifiers - { - public const char Separator = ' '; - public const string RefOrRefLike = "ref"; - public const string In = "in"; - public const string Out = "out"; - } - - public static class Names - { - public const string ImplicitThis = "this"; - public const string Unknown = Internal.Prefix + "unknown" + Internal.Postfix; - } - } - - public static class Generics - { - public const char Start = '<'; - public const string Separator = ", "; - public const char End = '>'; - } - } - - - public string ModuleName { get; } - public string TypeName { get; } - public string MethodName { get; } - - public string Template { get; } - - public MethodTemplateString(MethodInfo method) - { - ModuleName = GetModuleName(method); - TypeName = GetDeclaringTypeName(method); - MethodName = GetMethodName(method); - - Template = string.Concat( - TypeName, - Tokens.Types.Separator, - MethodName, - Tokens.Parameters.Start, - GetTemplatedParameters(method), - Tokens.Parameters.End); - } - - private static string GetModuleName(MethodInfo method) => method.Module.Name; - - private static string GetDeclaringTypeName(MethodInfo method) - { - StringBuilder builder = new(); - - // For a generic declaring type, trim the arity information and replace it with the known generic argument names. - string declaringTypeName = method.DeclaringType?.FullName?.Split(Tokens.Types.ArityDelimiter)?[0] ?? Tokens.Types.Unknown; - builder.Append(declaringTypeName); - EmitGenericArguments(builder, method.DeclaringType?.GetGenericArguments()); - - return builder.ToString(); - } - - private static string GetMethodName(MethodInfo method) - { - StringBuilder builder = new(); - - builder.Append(method.Name); - EmitGenericArguments(builder, method.GetGenericArguments()); - - return builder.ToString(); - } - - private static string GetTemplatedParameters(MethodInfo method) - { - StringBuilder builder = new(); - - int parameterIndex = 0; - ParameterInfo[] explicitParameters = method.GetParameters(); - - // Implicit this - if (method.HasImplicitThis()) - { - EmitParameter( - builder, - method.DeclaringType, - Tokens.Parameters.Names.ImplicitThis); - parameterIndex++; - } - - foreach (ParameterInfo paramInfo in explicitParameters) - { - if (parameterIndex != 0) - { - builder.Append(Tokens.Parameters.Separator); - } - - string name = paramInfo.Name ?? Tokens.Parameters.Names.Unknown; - EmitParameter( - builder, - paramInfo.ParameterType, - name, - paramInfo); - - parameterIndex++; - } - - return builder.ToString(); - } - - private static void EmitParameter(StringBuilder stringBuilder, Type? type, string name, ParameterInfo? paramInfo = null) - { - stringBuilder.AppendLine(); - stringBuilder.Append('\t'); - - // Modifiers - if (paramInfo?.IsIn == true) - { - stringBuilder.Append(Tokens.Parameters.Modifiers.In); - stringBuilder.Append(Tokens.Parameters.Modifiers.Separator); - } - else if (paramInfo?.IsOut == true) - { - stringBuilder.Append(Tokens.Parameters.Modifiers.Out); - stringBuilder.Append(Tokens.Parameters.Modifiers.Separator); - } - else if (type?.IsByRef == true || - type?.IsByRefLike == true) - { - stringBuilder.Append(Tokens.Parameters.Modifiers.RefOrRefLike); - stringBuilder.Append(Tokens.Parameters.Modifiers.Separator); - } - - // Name - stringBuilder.Append(name); - stringBuilder.Append(Tokens.Parameters.NameValueSeparator); - - // Value - EmitFormatItem(stringBuilder, name); - } - - private static void EmitGenericArguments(StringBuilder stringBuilder, Type[]? genericArgs) - { - if (genericArgs == null || genericArgs.Length == 0) - { - return; - } - - stringBuilder.Append(Tokens.Generics.Start); - for (int i = 0; i < genericArgs.Length; i++) - { - if (i != 0) - { - stringBuilder.Append(Tokens.Generics.Separator); - } - - stringBuilder.Append(genericArgs[i].Name); - } - stringBuilder.Append(Tokens.Generics.End); - } - - private static void EmitFormatItem(StringBuilder stringBuilder, string name) - { - stringBuilder.Append('{'); - stringBuilder.Append(name); - stringBuilder.Append('}'); - } - } -} diff --git a/src/Microsoft.Diagnostics.Monitoring.HostingStartup/ParameterCapturing/ParameterCapturingLogger.cs b/src/Microsoft.Diagnostics.Monitoring.HostingStartup/ParameterCapturing/ParameterCapturingLogger.cs deleted file mode 100644 index fa47674e379..00000000000 --- a/src/Microsoft.Diagnostics.Monitoring.HostingStartup/ParameterCapturing/ParameterCapturingLogger.cs +++ /dev/null @@ -1,168 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -using Microsoft.Diagnostics.Monitoring.HostingStartup.ParameterCapturing.FunctionProbes; -using Microsoft.Diagnostics.Monitoring.StartupHook; -using Microsoft.Extensions.Logging; -using System; -using System.Collections.Concurrent; -using System.Diagnostics; -using System.Globalization; -using System.Linq; -using System.Threading; - -namespace Microsoft.Diagnostics.Monitoring.HostingStartup.ParameterCapturing -{ - internal sealed class ParameterCapturingLogger : IDisposable - { - private record QueuedLogStatement(string Format, string[] Args, KeyValueLogScope Scope); - - internal static class Scopes - { - private const string Prefix = "DotnetMonitor_"; - - public const string TimeStamp = Prefix + "Timestamp"; - - public const string ThreadId = Prefix + "ThreadId"; - - public const string ActivityId = Prefix + "ActivityId"; - public const string ActivityIdFormat = Prefix + "ActivityIdFormat"; - - public static class CaptureSite - { - private const string Prefix = Scopes.Prefix + "CaptureSite_"; - - public const string MethodName = Prefix + "MethodName"; - public const string ModuleName = Prefix + "ModuleName"; - public const string TypeName = Prefix + "TypeName"; - } - } - - private readonly ILogger _userLogger; - private readonly ILogger _systemLogger; - private readonly Thread _thread; - private BlockingCollection _messages; - private uint _droppedMessageCounter; - private const int BackgroundLoggingCapacity = 1024; - private const string BackgroundLoggingThreadName = "[dotnet-monitor] Probe Logging Thread"; - private long _disposedState; - - private static readonly string[] ExcludedThreads = new[] - { - "Console logger queue processing thread", - }; - - public ParameterCapturingLogger(ILogger userLogger, ILogger systemLogger) - { - _userLogger = userLogger; - _systemLogger = systemLogger; - _thread = new Thread(ThreadProc); - - _thread.Priority = ThreadPriority.BelowNormal; - _thread.IsBackground = true; - _thread.Name = BackgroundLoggingThreadName; - _messages = new BlockingCollection(BackgroundLoggingCapacity); - _thread.Start(); - } - - public bool ShouldLog() - { - // Probes should not attempt to log on the console logging thread - // or on the background thread that is used to log system messages. - - if (Environment.CurrentManagedThreadId == _thread.ManagedThreadId) - { - return false; - } - if (ExcludedThreads.Contains(Thread.CurrentThread.Name)) - { - return false; - } - - return true; - } - - public void Log(ParameterCaptureMode mode, MethodTemplateString methodTemplateString, string[] args) - { - DisposableHelper.ThrowIfDisposed(ref _disposedState); - - KeyValueLogScope scope = GenerateScope(methodTemplateString); - - if (mode == ParameterCaptureMode.Inline) - { - Log(_userLogger, methodTemplateString.Template, args, scope); - } - else if (mode == ParameterCaptureMode.Background) - { - if (!_messages.TryAdd(new QueuedLogStatement(methodTemplateString.Template, args, scope))) - { - Interlocked.Increment(ref _droppedMessageCounter); - } - } - } - - private static KeyValueLogScope GenerateScope(MethodTemplateString methodTemplateString) - { - KeyValueLogScope scope = new(); - - // Store timestamp as ISO 8601 compliant - scope.Values.Add(Scopes.TimeStamp, DateTime.UtcNow.ToString("o", CultureInfo.InvariantCulture)); - scope.Values.Add(Scopes.ThreadId, Environment.CurrentManagedThreadId); - - scope.Values.Add(Scopes.CaptureSite.MethodName, methodTemplateString.MethodName); - scope.Values.Add(Scopes.CaptureSite.ModuleName, methodTemplateString.ModuleName); - scope.Values.Add(Scopes.CaptureSite.TypeName, methodTemplateString.TypeName); - - Activity? currentActivity = Activity.Current; - if (currentActivity?.Id != null) - { - scope.Values.Add(Scopes.ActivityId, currentActivity.Id); - scope.Values.Add(Scopes.ActivityIdFormat, currentActivity.IdFormat); - } - - return scope; - } - - private void ThreadProc() - { - using IDisposable _ = MonitorExecutionContextTracker.MonitorScope(); - - try - { - while (_messages.TryTake(out QueuedLogStatement? entry, Timeout.InfiniteTimeSpan)) - { - Log(_systemLogger, entry.Format, entry.Args, entry.Scope); - } - } - catch (ObjectDisposedException) - { - } - catch - { - } - } - - public void Complete() - { - // NOTE We currently do not wait for the background thread in production code - _messages.CompleteAdding(); - _thread.Join(); - } - - private static void Log(ILogger logger, string format, string[] args, KeyValueLogScope scope) - { - using var _ = logger.BeginScope(scope); - logger.Log(LogLevel.Information, format, args); - } - - public void Dispose() - { - if (!DisposableHelper.CanDispose(ref _disposedState)) - { - return; - } - _messages.CompleteAdding(); - _messages.Dispose(); - } - } -} diff --git a/src/Microsoft.Diagnostics.Monitoring.HostingStartup/ProjectsToPublish.props b/src/Microsoft.Diagnostics.Monitoring.HostingStartup/ProjectsToPublish.props deleted file mode 100644 index 958e293fe26..00000000000 --- a/src/Microsoft.Diagnostics.Monitoring.HostingStartup/ProjectsToPublish.props +++ /dev/null @@ -1,15 +0,0 @@ - - - net6.0 - Microsoft.Diagnostics.Monitoring.HostingStartup - $(ArtifactsDir)pub\$(HostingStartupLibraryName)\$(Configuration)\$(HostingStartupTargetFramework)\ - $(HostingStartupPublishPath)$(HostingStartupLibraryName).dll - $(HostingStartupPublishPath)$(HostingStartupLibraryName).pdb - - - - - TargetFramework=$(HostingStartupTargetFramework);RuntimeIdentifier=;PublishDir=$(HostingStartupPublishPath) - - - diff --git a/src/Microsoft.Diagnostics.Monitoring.Options/IMethodDescription.cs b/src/Microsoft.Diagnostics.Monitoring.Options/IMethodDescription.cs index a2c5c1b1173..7191e1f9931 100644 --- a/src/Microsoft.Diagnostics.Monitoring.Options/IMethodDescription.cs +++ b/src/Microsoft.Diagnostics.Monitoring.Options/IMethodDescription.cs @@ -3,7 +3,7 @@ using System.Text.Json.Serialization; -#if STARTUPHOOK || HOSTINGSTARTUP +#if STARTUPHOOK namespace Microsoft.Diagnostics.Monitoring.StartupHook.MonitorMessageDispatcher.Models #else namespace Microsoft.Diagnostics.Monitoring.Options diff --git a/src/Microsoft.Diagnostics.Monitoring.StartupHook/AspNetHostingStartupLoader.cs b/src/Microsoft.Diagnostics.Monitoring.StartupHook/AspNetHostingStartupLoader.cs deleted file mode 100644 index 158a17fe3ee..00000000000 --- a/src/Microsoft.Diagnostics.Monitoring.StartupHook/AspNetHostingStartupLoader.cs +++ /dev/null @@ -1,69 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -using System; -using System.IO; -using System.Reflection; -using System.Runtime.Loader; - -namespace Microsoft.Diagnostics.Monitoring.StartupHook -{ - internal sealed class AspNetHostingStartupLoader : IDisposable - { - private readonly string _filePath; - private readonly string _simpleAssemblyName; - - private long _disposedState; - - public AspNetHostingStartupLoader(string filePath) - { - _filePath = filePath; - _simpleAssemblyName = CalculateSimpleAssemblyName(filePath); - - RegisterHostingStartupAssembly(_simpleAssemblyName); - AssemblyLoadContext.Default.Resolving += AssemblyResolver; - } - - private Assembly? AssemblyResolver(AssemblyLoadContext context, AssemblyName assemblyName) - { - if (_simpleAssemblyName.Equals(assemblyName.Name, StringComparison.OrdinalIgnoreCase)) - { - return AssemblyLoadContext.Default.LoadFromAssemblyPath(_filePath); - } - - return null; - } - - private static string CalculateSimpleAssemblyName(string filePath) - { - string fileName = Path.GetFileName(filePath); - const string dllExtension = ".dll"; - if (dllExtension.Equals(Path.GetExtension(fileName), StringComparison.OrdinalIgnoreCase)) - { - return fileName[..^dllExtension.Length]; - } - - return fileName; - } - - private static void RegisterHostingStartupAssembly(string simpleAssemblyName) - { - const string HostingStartupEnvVariable = "ASPNETCORE_HOSTINGSTARTUPASSEMBLIES"; - // aspnetcore explicitly uses ; as the delimiter for the above environment variable. - // ref: https://github.com/dotnet/aspnetcore/blob/898c164a1f537a8210a26eaf388bdc92531f6b09/src/Hosting/Hosting/src/Internal/WebHostOptions.cs#L79 - const char Delimiter = ';'; - - string? curValue = Environment.GetEnvironmentVariable(HostingStartupEnvVariable); - string newValue = string.IsNullOrWhiteSpace(curValue) ? simpleAssemblyName : string.Concat(curValue, Delimiter, simpleAssemblyName); - Environment.SetEnvironmentVariable(HostingStartupEnvVariable, newValue); - } - - public void Dispose() - { - if (!DisposableHelper.CanDispose(ref _disposedState)) - return; - - AssemblyLoadContext.Default.Resolving -= AssemblyResolver; - } - } -} diff --git a/src/Microsoft.Diagnostics.Monitoring.StartupHook/BackgroundService.cs b/src/Microsoft.Diagnostics.Monitoring.StartupHook/BackgroundService.cs new file mode 100644 index 00000000000..9a2d43b8210 --- /dev/null +++ b/src/Microsoft.Diagnostics.Monitoring.StartupHook/BackgroundService.cs @@ -0,0 +1,62 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +using System; +using System.Threading; +using System.Threading.Tasks; + +namespace Microsoft.Diagnostics.Monitoring.StartupHook +{ + internal abstract class BackgroundService : IDisposable + { + private readonly CancellationTokenSource _cts = new(); + private long _disposedState; + + public Task? ExecutingTask { get; private set; } + + public void Start() + { + ExecutingTask = Task.Run(async () => + { + await ExecuteAsync(_cts.Token).ConfigureAwait(false); + }, _cts.Token); + } + + public void Stop() + { + SafeCancel(); + + try + { + ExecutingTask?.Wait(TimeSpan.FromSeconds(1)); + } + catch + { + // ignore + } + } + + public virtual void Dispose() + { + if (!DisposableHelper.CanDispose(ref _disposedState)) + return; + + SafeCancel(); + _cts.Dispose(); + } + + private void SafeCancel() + { + try + { + _cts.Cancel(); + } + catch (AggregateException) + { + // Ignore all exceptions thrown by registered callbacks on the associated CancellationToken. + } + } + + protected abstract Task ExecuteAsync(CancellationToken stoppingToken); + } +} diff --git a/src/Microsoft.Diagnostics.Monitoring.StartupHook/DiagnosticsBootstrapper.cs b/src/Microsoft.Diagnostics.Monitoring.StartupHook/DiagnosticsBootstrapper.cs index 414c677e5b3..080201c31e5 100644 --- a/src/Microsoft.Diagnostics.Monitoring.StartupHook/DiagnosticsBootstrapper.cs +++ b/src/Microsoft.Diagnostics.Monitoring.StartupHook/DiagnosticsBootstrapper.cs @@ -3,12 +3,11 @@ using Microsoft.Diagnostics.Monitoring.StartupHook.Exceptions; using Microsoft.Diagnostics.Monitoring.StartupHook.Monitoring; +using Microsoft.Diagnostics.Monitoring.StartupHook.ParameterCapturing; using Microsoft.Diagnostics.Tools.Monitor; -using Microsoft.Diagnostics.Tools.Monitor.HostingStartup; using Microsoft.Diagnostics.Tools.Monitor.Profiler; using Microsoft.Diagnostics.Tools.Monitor.StartupHook; using System; -using System.IO; using MessageDispatcher = Microsoft.Diagnostics.Monitoring.StartupHook.MonitorMessageDispatcher; namespace Microsoft.Diagnostics.Monitoring.StartupHook @@ -17,7 +16,7 @@ internal sealed class DiagnosticsBootstrapper : IDisposable { private readonly CurrentAppDomainExceptionProcessor _exceptionProcessor; - private readonly AspNetHostingStartupLoader? _hostingStartupLoader; + private readonly ParameterCapturingService? _parameterCapturingService; private long _disposedState; @@ -28,13 +27,6 @@ public DiagnosticsBootstrapper() using IDisposable _ = MonitorExecutionContextTracker.MonitorScope(); - string? hostingStartupPath = Environment.GetEnvironmentVariable(StartupHookIdentifiers.EnvironmentVariables.HostingStartupPath); - // TODO: Log if specified hosting startup assembly doesn't exist - if (File.Exists(hostingStartupPath)) - { - _hostingStartupLoader = new AspNetHostingStartupLoader(hostingStartupPath); - } - try { // Check that the profiler is loaded before establishing the dispatcher, which has a dependency on the existence of the profiler @@ -44,6 +36,12 @@ public DiagnosticsBootstrapper() new MessageDispatcher.ProfilerMessageSource(CommandSet.StartupHook)); ToolIdentifiers.EnableEnvVar(InProcessFeaturesIdentifiers.EnvironmentVariables.AvailableInfrastructure.ManagedMessaging); } + + if (ToolIdentifiers.IsEnvVarEnabled(InProcessFeaturesIdentifiers.EnvironmentVariables.ParameterCapturing.Enable)) + { + _parameterCapturingService = new(); + _parameterCapturingService.Start(); + } } catch { @@ -58,7 +56,8 @@ public void Dispose() return; _exceptionProcessor.Dispose(); - _hostingStartupLoader?.Dispose(); + _parameterCapturingService?.Stop(); + _parameterCapturingService?.Dispose(); SharedInternals.MessageDispatcher?.Dispose(); } } diff --git a/src/Microsoft.Diagnostics.Monitoring.StartupHook/Exceptions/Eventing/ExceptionsEventSource.cs b/src/Microsoft.Diagnostics.Monitoring.StartupHook/Exceptions/Eventing/ExceptionsEventSource.cs index 3bcb89b13da..efa325bb9a9 100644 --- a/src/Microsoft.Diagnostics.Monitoring.StartupHook/Exceptions/Eventing/ExceptionsEventSource.cs +++ b/src/Microsoft.Diagnostics.Monitoring.StartupHook/Exceptions/Eventing/ExceptionsEventSource.cs @@ -97,6 +97,7 @@ public void ClassDescription( [Event(ExceptionEvents.EventIds.FunctionDescription)] public void FunctionDescription( ulong FunctionId, + uint MethodToken, ulong ClassId, uint ClassToken, ulong ModuleId, @@ -104,7 +105,7 @@ public void FunctionDescription( ulong[] TypeArgs, ulong[] ParameterTypes) { - Span data = stackalloc EventData[7]; + Span data = stackalloc EventData[8]; using PinnedData namePinned = PinnedData.Create(Name); Span typeArgsSpan = stackalloc byte[GetArrayDataSize(TypeArgs)]; FillArrayData(typeArgsSpan, TypeArgs); @@ -112,6 +113,7 @@ public void FunctionDescription( FillArrayData(parameterTypesSpan, ParameterTypes); SetValue(ref data[NameIdentificationEvents.FunctionDescPayloads.FunctionId], FunctionId); + SetValue(ref data[NameIdentificationEvents.FunctionDescPayloads.MethodToken], MethodToken); SetValue(ref data[NameIdentificationEvents.FunctionDescPayloads.ClassId], ClassId); SetValue(ref data[NameIdentificationEvents.FunctionDescPayloads.ClassToken], ClassToken); SetValue(ref data[NameIdentificationEvents.FunctionDescPayloads.ModuleId], ModuleId); @@ -125,12 +127,14 @@ public void FunctionDescription( [Event(ExceptionEvents.EventIds.ModuleDescription)] public void ModuleDescription( ulong ModuleId, + Guid ModuleVersionId, string Name) { - Span data = stackalloc EventData[2]; + Span data = stackalloc EventData[3]; using PinnedData namePinned = PinnedData.Create(Name); SetValue(ref data[NameIdentificationEvents.ModuleDescPayloads.ModuleId], ModuleId); + SetValue(ref data[NameIdentificationEvents.ModuleDescPayloads.ModuleVersionId], ModuleVersionId); SetValue(ref data[NameIdentificationEvents.ModuleDescPayloads.Name], namePinned); WriteEventWithFlushing(ExceptionEvents.EventIds.ModuleDescription, data); diff --git a/src/Microsoft.Diagnostics.Monitoring.StartupHook/Exceptions/Eventing/ExceptionsEventSourceIdentifierCacheCallback.cs b/src/Microsoft.Diagnostics.Monitoring.StartupHook/Exceptions/Eventing/ExceptionsEventSourceIdentifierCacheCallback.cs index f59bd20b5b2..5a76d8ea968 100644 --- a/src/Microsoft.Diagnostics.Monitoring.StartupHook/Exceptions/Eventing/ExceptionsEventSourceIdentifierCacheCallback.cs +++ b/src/Microsoft.Diagnostics.Monitoring.StartupHook/Exceptions/Eventing/ExceptionsEventSourceIdentifierCacheCallback.cs @@ -38,8 +38,9 @@ public override void OnFunctionData(ulong functionId, FunctionData data) { _source.FunctionDescription( functionId, + data.MethodToken, data.ParentClass, - data.ParentToken, + data.ParentClassToken, data.ModuleId, data.Name, data.TypeArgs, @@ -50,6 +51,7 @@ public override void OnModuleData(ulong moduleId, ModuleData data) { _source.ModuleDescription( moduleId, + data.ModuleVersionId, data.Name); } diff --git a/src/Microsoft.Diagnostics.Monitoring.StartupHook/Exceptions/Identification/ExceptionGroupIdentifierCache.cs b/src/Microsoft.Diagnostics.Monitoring.StartupHook/Exceptions/Identification/ExceptionGroupIdentifierCache.cs index 9b93c7e6f22..99ef3d1f5e6 100644 --- a/src/Microsoft.Diagnostics.Monitoring.StartupHook/Exceptions/Identification/ExceptionGroupIdentifierCache.cs +++ b/src/Microsoft.Diagnostics.Monitoring.StartupHook/Exceptions/Identification/ExceptionGroupIdentifierCache.cs @@ -83,13 +83,19 @@ public ulong GetOrAdd(MethodBase method) return methodId; // Dynamic methods do not have metadata tokens - uint metadataToken = 0; + uint methodToken = 0; try { - metadataToken = Convert.ToUInt32(method.MetadataToken); + methodToken = Convert.ToUInt32(method.MetadataToken); } catch (Exception) { } + uint parentClassToken = 0; + if (null != method.DeclaringType) + { + parentClassToken = Convert.ToUInt32(method.DeclaringType.MetadataToken); + } + // RTDynamicMethod does not implement GetGenericArguments. Type[] genericArguments = Array.Empty(); try @@ -100,8 +106,9 @@ public ulong GetOrAdd(MethodBase method) FunctionData data = new( method.Name, + methodToken, AddOrDefault(method.DeclaringType), - metadataToken, + parentClassToken, GetOrAdd(method.Module), GetOrAdd(genericArguments), GetOrAdd(method.GetParameters()) @@ -128,7 +135,7 @@ public ulong GetOrAdd(Module module) if (!GetOrCreateIdentifier(_moduleIds, module, ref _nextModuleId, out ulong moduleId)) return moduleId; - ModuleData data = new(module.Name); + ModuleData data = new(module.Name, module.ModuleVersionId); if (_nameCache.ModuleData.TryAdd(moduleId, data)) { @@ -212,16 +219,16 @@ public ulong GetOrAdd(Type type) ModuleScopedToken key = new(moduleId, typeToken); if (!_nameCache.TokenData.ContainsKey(key)) { - uint parentToken = 0; + uint parentClassToken = 0; if (null != type.DeclaringType) { - parentToken = Convert.ToUInt32(type.DeclaringType.MetadataToken); + parentClassToken = Convert.ToUInt32(type.DeclaringType.MetadataToken); } TokenData tokenData = new( type.Name, null == type.DeclaringType ? type.Namespace ?? string.Empty : string.Empty, - parentToken); + parentClassToken); if (!_nameCache.TokenData.TryAdd(key, tokenData)) break; diff --git a/src/Microsoft.Diagnostics.Monitoring.StartupHook/Microsoft.Diagnostics.Monitoring.StartupHook.csproj b/src/Microsoft.Diagnostics.Monitoring.StartupHook/Microsoft.Diagnostics.Monitoring.StartupHook.csproj index 0311295165c..353f6c571e0 100644 --- a/src/Microsoft.Diagnostics.Monitoring.StartupHook/Microsoft.Diagnostics.Monitoring.StartupHook.csproj +++ b/src/Microsoft.Diagnostics.Monitoring.StartupHook/Microsoft.Diagnostics.Monitoring.StartupHook.csproj @@ -14,9 +14,9 @@ - + @@ -26,10 +26,23 @@ - - + + + True + True + ParameterCapturingStrings.resx + + + + + + ResXFileCodeGenerator + ParameterCapturingStrings.Designer.cs + + + diff --git a/src/Microsoft.Diagnostics.Monitoring.HostingStartup/ParameterCapturing/Boxing/BoxingInstructions.cs b/src/Microsoft.Diagnostics.Monitoring.StartupHook/ParameterCapturing/Boxing/BoxingInstructions.cs similarity index 98% rename from src/Microsoft.Diagnostics.Monitoring.HostingStartup/ParameterCapturing/Boxing/BoxingInstructions.cs rename to src/Microsoft.Diagnostics.Monitoring.StartupHook/ParameterCapturing/Boxing/BoxingInstructions.cs index 6f4dfa23120..10c049d724b 100644 --- a/src/Microsoft.Diagnostics.Monitoring.HostingStartup/ParameterCapturing/Boxing/BoxingInstructions.cs +++ b/src/Microsoft.Diagnostics.Monitoring.StartupHook/ParameterCapturing/Boxing/BoxingInstructions.cs @@ -1,14 +1,14 @@ // Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. -using Microsoft.Diagnostics.Monitoring.HostingStartup.ParameterCapturing.FunctionProbes; +using Microsoft.Diagnostics.Monitoring.StartupHook.ParameterCapturing.FunctionProbes; using System; using System.Diagnostics; using System.Reflection; using System.Reflection.Metadata; using System.Reflection.Metadata.Ecma335; -namespace Microsoft.Diagnostics.Monitoring.HostingStartup.ParameterCapturing.Boxing +namespace Microsoft.Diagnostics.Monitoring.StartupHook.ParameterCapturing.Boxing { internal static class BoxingInstructions { diff --git a/src/Microsoft.Diagnostics.Monitoring.HostingStartup/ParameterCapturing/Boxing/BoxingTokensSignatureProvider.cs b/src/Microsoft.Diagnostics.Monitoring.StartupHook/ParameterCapturing/Boxing/BoxingTokensSignatureProvider.cs similarity index 94% rename from src/Microsoft.Diagnostics.Monitoring.HostingStartup/ParameterCapturing/Boxing/BoxingTokensSignatureProvider.cs rename to src/Microsoft.Diagnostics.Monitoring.StartupHook/ParameterCapturing/Boxing/BoxingTokensSignatureProvider.cs index 010129a8756..11b8d0c4366 100644 --- a/src/Microsoft.Diagnostics.Monitoring.HostingStartup/ParameterCapturing/Boxing/BoxingTokensSignatureProvider.cs +++ b/src/Microsoft.Diagnostics.Monitoring.StartupHook/ParameterCapturing/Boxing/BoxingTokensSignatureProvider.cs @@ -1,12 +1,12 @@ // Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. -using Microsoft.Diagnostics.Monitoring.HostingStartup.ParameterCapturing.FunctionProbes; +using Microsoft.Diagnostics.Monitoring.StartupHook.ParameterCapturing.FunctionProbes; using System.Collections.Immutable; using System.Reflection.Metadata; using System.Reflection.Metadata.Ecma335; -namespace Microsoft.Diagnostics.Monitoring.HostingStartup.ParameterCapturing.Boxing +namespace Microsoft.Diagnostics.Monitoring.StartupHook.ParameterCapturing.Boxing { /// /// This decoder is made specifically for parameters of the following types: diff --git a/src/Microsoft.Diagnostics.Monitoring.HostingStartup/ParameterCapturing/Boxing/MethodDefinitionExtensions.cs b/src/Microsoft.Diagnostics.Monitoring.StartupHook/ParameterCapturing/Boxing/MethodDefinitionExtensions.cs similarity index 97% rename from src/Microsoft.Diagnostics.Monitoring.HostingStartup/ParameterCapturing/Boxing/MethodDefinitionExtensions.cs rename to src/Microsoft.Diagnostics.Monitoring.StartupHook/ParameterCapturing/Boxing/MethodDefinitionExtensions.cs index 307bdac6629..9758230fdfd 100644 --- a/src/Microsoft.Diagnostics.Monitoring.HostingStartup/ParameterCapturing/Boxing/MethodDefinitionExtensions.cs +++ b/src/Microsoft.Diagnostics.Monitoring.StartupHook/ParameterCapturing/Boxing/MethodDefinitionExtensions.cs @@ -1,14 +1,14 @@ // Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. -using Microsoft.Diagnostics.Monitoring.HostingStartup.ParameterCapturing.FunctionProbes; +using Microsoft.Diagnostics.Monitoring.StartupHook.ParameterCapturing.FunctionProbes; using System; using System.Collections.Immutable; using System.Diagnostics; using System.Reflection.Metadata; using System.Reflection.Metadata.Ecma335; -namespace Microsoft.Diagnostics.Monitoring.HostingStartup.ParameterCapturing.Boxing +namespace Microsoft.Diagnostics.Monitoring.StartupHook.ParameterCapturing.Boxing { internal static class MethodDefinitionExtensions { diff --git a/src/Microsoft.Diagnostics.Monitoring.HostingStartup/ParameterCapturing/DeniedMethodsException.cs b/src/Microsoft.Diagnostics.Monitoring.StartupHook/ParameterCapturing/DeniedMethodsException.cs similarity index 93% rename from src/Microsoft.Diagnostics.Monitoring.HostingStartup/ParameterCapturing/DeniedMethodsException.cs rename to src/Microsoft.Diagnostics.Monitoring.StartupHook/ParameterCapturing/DeniedMethodsException.cs index b8b3675945a..bb433ca9f7b 100644 --- a/src/Microsoft.Diagnostics.Monitoring.HostingStartup/ParameterCapturing/DeniedMethodsException.cs +++ b/src/Microsoft.Diagnostics.Monitoring.StartupHook/ParameterCapturing/DeniedMethodsException.cs @@ -7,7 +7,7 @@ using System.Globalization; using System.Text; -namespace Microsoft.Diagnostics.Monitoring.HostingStartup.ParameterCapturing +namespace Microsoft.Diagnostics.Monitoring.StartupHook.ParameterCapturing { internal sealed class DeniedMethodsException : ArgumentException { diff --git a/src/Microsoft.Diagnostics.Monitoring.HostingStartup/ParameterCapturing/Eventing/AsyncParameterCapturingEventSource.cs b/src/Microsoft.Diagnostics.Monitoring.StartupHook/ParameterCapturing/Eventing/AsyncParameterCapturingEventSource.cs similarity index 96% rename from src/Microsoft.Diagnostics.Monitoring.HostingStartup/ParameterCapturing/Eventing/AsyncParameterCapturingEventSource.cs rename to src/Microsoft.Diagnostics.Monitoring.StartupHook/ParameterCapturing/Eventing/AsyncParameterCapturingEventSource.cs index c034a77fa48..4dbcfdf9e86 100644 --- a/src/Microsoft.Diagnostics.Monitoring.HostingStartup/ParameterCapturing/Eventing/AsyncParameterCapturingEventSource.cs +++ b/src/Microsoft.Diagnostics.Monitoring.StartupHook/ParameterCapturing/Eventing/AsyncParameterCapturingEventSource.cs @@ -1,13 +1,12 @@ // Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. -using Microsoft.Diagnostics.Monitoring.StartupHook; using System; using System.Collections.Concurrent; using System.Diagnostics; using System.Threading; -namespace Microsoft.Diagnostics.Monitoring.HostingStartup.ParameterCapturing.Eventing +namespace Microsoft.Diagnostics.Monitoring.StartupHook.ParameterCapturing.Eventing { internal sealed class AsyncParameterCapturingEventSource : IDisposable { diff --git a/src/Microsoft.Diagnostics.Monitoring.HostingStartup/ParameterCapturing/Eventing/ParameterCapturingEventSource.cs b/src/Microsoft.Diagnostics.Monitoring.StartupHook/ParameterCapturing/Eventing/ParameterCapturingEventSource.cs similarity index 98% rename from src/Microsoft.Diagnostics.Monitoring.HostingStartup/ParameterCapturing/Eventing/ParameterCapturingEventSource.cs rename to src/Microsoft.Diagnostics.Monitoring.StartupHook/ParameterCapturing/Eventing/ParameterCapturingEventSource.cs index 49460e11446..c1e81fbccd8 100644 --- a/src/Microsoft.Diagnostics.Monitoring.HostingStartup/ParameterCapturing/Eventing/ParameterCapturingEventSource.cs +++ b/src/Microsoft.Diagnostics.Monitoring.StartupHook/ParameterCapturing/Eventing/ParameterCapturingEventSource.cs @@ -9,7 +9,7 @@ using System.Reflection; using static Microsoft.Diagnostics.Tools.Monitor.ParameterCapturing.ParameterCapturingEvents; -namespace Microsoft.Diagnostics.Monitoring.HostingStartup.ParameterCapturing.Eventing +namespace Microsoft.Diagnostics.Monitoring.StartupHook.ParameterCapturing.Eventing { [EventSource(Name = ParameterCapturingEvents.SourceName)] internal sealed class ParameterCapturingEventSource : AbstractMonitorEventSource diff --git a/src/Microsoft.Diagnostics.Monitoring.HostingStartup/ParameterCapturing/FunctionProbes/EventSourceEmittingProbes.cs b/src/Microsoft.Diagnostics.Monitoring.StartupHook/ParameterCapturing/FunctionProbes/EventSourceEmittingProbes.cs similarity index 93% rename from src/Microsoft.Diagnostics.Monitoring.HostingStartup/ParameterCapturing/FunctionProbes/EventSourceEmittingProbes.cs rename to src/Microsoft.Diagnostics.Monitoring.StartupHook/ParameterCapturing/FunctionProbes/EventSourceEmittingProbes.cs index 08cbf44b053..b44a572d380 100644 --- a/src/Microsoft.Diagnostics.Monitoring.HostingStartup/ParameterCapturing/FunctionProbes/EventSourceEmittingProbes.cs +++ b/src/Microsoft.Diagnostics.Monitoring.StartupHook/ParameterCapturing/FunctionProbes/EventSourceEmittingProbes.cs @@ -1,13 +1,13 @@ // Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. -using Microsoft.Diagnostics.Monitoring.HostingStartup.ParameterCapturing.Eventing; -using Microsoft.Diagnostics.Monitoring.HostingStartup.ParameterCapturing.ObjectFormatting; +using Microsoft.Diagnostics.Monitoring.StartupHook.ParameterCapturing.Eventing; +using Microsoft.Diagnostics.Monitoring.StartupHook.ParameterCapturing.ObjectFormatting; using System; using System.Collections.Generic; using System.Reflection; -namespace Microsoft.Diagnostics.Monitoring.HostingStartup.ParameterCapturing.FunctionProbes +namespace Microsoft.Diagnostics.Monitoring.StartupHook.ParameterCapturing.FunctionProbes { internal sealed class EventSourceEmittingProbes : IFunctionProbes { diff --git a/src/Microsoft.Diagnostics.Monitoring.HostingStartup/ParameterCapturing/FunctionProbes/FunctionProbesManager.cs b/src/Microsoft.Diagnostics.Monitoring.StartupHook/ParameterCapturing/FunctionProbes/FunctionProbesManager.cs similarity index 93% rename from src/Microsoft.Diagnostics.Monitoring.HostingStartup/ParameterCapturing/FunctionProbes/FunctionProbesManager.cs rename to src/Microsoft.Diagnostics.Monitoring.StartupHook/ParameterCapturing/FunctionProbes/FunctionProbesManager.cs index a30600f7d90..ce1416e360f 100644 --- a/src/Microsoft.Diagnostics.Monitoring.HostingStartup/ParameterCapturing/FunctionProbes/FunctionProbesManager.cs +++ b/src/Microsoft.Diagnostics.Monitoring.StartupHook/ParameterCapturing/FunctionProbes/FunctionProbesManager.cs @@ -1,11 +1,9 @@ // Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. -using Microsoft.Diagnostics.Monitoring.HostingStartup.ParameterCapturing.Boxing; -using Microsoft.Diagnostics.Monitoring.HostingStartup.ParameterCapturing.ObjectFormatting; -using Microsoft.Diagnostics.Monitoring.StartupHook; +using Microsoft.Diagnostics.Monitoring.StartupHook.ParameterCapturing.Boxing; +using Microsoft.Diagnostics.Monitoring.StartupHook.ParameterCapturing.ObjectFormatting; using Microsoft.Diagnostics.Tools.Monitor.Profiler; -using Microsoft.Extensions.Logging; using System; using System.Collections.Generic; using System.Collections.ObjectModel; @@ -15,7 +13,7 @@ using System.Threading; using System.Threading.Tasks; -namespace Microsoft.Diagnostics.Monitoring.HostingStartup.ParameterCapturing.FunctionProbes +namespace Microsoft.Diagnostics.Monitoring.StartupHook.ParameterCapturing.FunctionProbes { internal sealed class FunctionProbesManager : IFunctionProbesManager { @@ -71,14 +69,11 @@ private static extern void RegisterFunctionProbeCallbacks( public event EventHandler? OnProbeFault; - private readonly ILogger _logger; - - public FunctionProbesManager(ILogger logger) + public FunctionProbesManager() { ProfilerResolver.InitializeResolver(); _disposalToken = _disposalTokenSource.Token; - _logger = logger; // // CONSIDER: @@ -103,8 +98,6 @@ public FunctionProbesManager(ILogger logger) private void OnRegistration(int hresult) { - _logger.LogDebug(ParameterCapturingStrings.ProbeManagementCallback, nameof(OnRegistration), hresult); - TransitionStateFromHr(_probeRegistrationTaskSource, hresult, expectedState: ProbeStateUninitialized, succeededState: ProbeStateUninstalled, @@ -113,8 +106,6 @@ private void OnRegistration(int hresult) private void OnInstallation(int hresult) { - _logger.LogDebug(ParameterCapturingStrings.ProbeManagementCallback, nameof(OnInstallation), hresult); - TransitionStateFromHr(_installationTaskSource, hresult, expectedState: ProbeStateInstalling, succeededState: ProbeStateInstalled, @@ -123,8 +114,6 @@ private void OnInstallation(int hresult) private void OnUninstallation(int hresult) { - _logger.LogDebug(ParameterCapturingStrings.ProbeManagementCallback, nameof(OnUninstallation), hresult); - TransitionStateFromHr(_uninstallationTaskSource, hresult, expectedState: ProbeStateUninstalling, succeededState: ProbeStateUninstalled, @@ -147,7 +136,7 @@ private void OnFault(ulong uniquifier) OnProbeFault?.Invoke(this, instrumentedMethod); } - + private void TransitionStateFromHr(TaskCompletionSource? taskCompletionSource, int hresult, long expectedState, long succeededState, long failedState) { Exception? ex = Marshal.GetExceptionForHR(hresult); @@ -304,7 +293,6 @@ public async Task StartCapturingAsync(IList methods, IFunctionProbes { using IDisposable _ = linkedCancellationToken.Register(() => { - _logger.LogDebug(ParameterCapturingStrings.CancellationRequestedDuringProbeInstallation, token.IsCancellationRequested, _disposalToken.IsCancellationRequested); _installationTaskSource?.TrySetCanceled(linkedCancellationToken); // diff --git a/src/Microsoft.Diagnostics.Monitoring.HostingStartup/ParameterCapturing/FunctionProbes/FunctionProbesState.cs b/src/Microsoft.Diagnostics.Monitoring.StartupHook/ParameterCapturing/FunctionProbes/FunctionProbesState.cs similarity index 86% rename from src/Microsoft.Diagnostics.Monitoring.HostingStartup/ParameterCapturing/FunctionProbes/FunctionProbesState.cs rename to src/Microsoft.Diagnostics.Monitoring.StartupHook/ParameterCapturing/FunctionProbes/FunctionProbesState.cs index 21bc960f331..6b05187affd 100644 --- a/src/Microsoft.Diagnostics.Monitoring.HostingStartup/ParameterCapturing/FunctionProbes/FunctionProbesState.cs +++ b/src/Microsoft.Diagnostics.Monitoring.StartupHook/ParameterCapturing/FunctionProbes/FunctionProbesState.cs @@ -3,7 +3,7 @@ using System.Collections.ObjectModel; -namespace Microsoft.Diagnostics.Monitoring.HostingStartup.ParameterCapturing.FunctionProbes +namespace Microsoft.Diagnostics.Monitoring.StartupHook.ParameterCapturing.FunctionProbes { internal sealed class FunctionProbesState { diff --git a/src/Microsoft.Diagnostics.Monitoring.HostingStartup/ParameterCapturing/FunctionProbes/FunctionProbesStub.cs b/src/Microsoft.Diagnostics.Monitoring.StartupHook/ParameterCapturing/FunctionProbes/FunctionProbesStub.cs similarity index 89% rename from src/Microsoft.Diagnostics.Monitoring.HostingStartup/ParameterCapturing/FunctionProbes/FunctionProbesStub.cs rename to src/Microsoft.Diagnostics.Monitoring.StartupHook/ParameterCapturing/FunctionProbes/FunctionProbesStub.cs index bd84b097f67..f0b4cdc51db 100644 --- a/src/Microsoft.Diagnostics.Monitoring.HostingStartup/ParameterCapturing/FunctionProbes/FunctionProbesStub.cs +++ b/src/Microsoft.Diagnostics.Monitoring.StartupHook/ParameterCapturing/FunctionProbes/FunctionProbesStub.cs @@ -1,10 +1,9 @@ // Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. -using Microsoft.Diagnostics.Monitoring.StartupHook; using System; -namespace Microsoft.Diagnostics.Monitoring.HostingStartup.ParameterCapturing.FunctionProbes +namespace Microsoft.Diagnostics.Monitoring.StartupHook.ParameterCapturing.FunctionProbes { public static class FunctionProbesStub { diff --git a/src/Microsoft.Diagnostics.Monitoring.HostingStartup/ParameterCapturing/FunctionProbes/IFunctionProbes.cs b/src/Microsoft.Diagnostics.Monitoring.StartupHook/ParameterCapturing/FunctionProbes/IFunctionProbes.cs similarity index 88% rename from src/Microsoft.Diagnostics.Monitoring.HostingStartup/ParameterCapturing/FunctionProbes/IFunctionProbes.cs rename to src/Microsoft.Diagnostics.Monitoring.StartupHook/ParameterCapturing/FunctionProbes/IFunctionProbes.cs index b33985f23e9..87b78bd2e44 100644 --- a/src/Microsoft.Diagnostics.Monitoring.HostingStartup/ParameterCapturing/FunctionProbes/IFunctionProbes.cs +++ b/src/Microsoft.Diagnostics.Monitoring.StartupHook/ParameterCapturing/FunctionProbes/IFunctionProbes.cs @@ -5,7 +5,7 @@ using System.Collections.Generic; using System.Reflection; -namespace Microsoft.Diagnostics.Monitoring.HostingStartup.ParameterCapturing.FunctionProbes +namespace Microsoft.Diagnostics.Monitoring.StartupHook.ParameterCapturing.FunctionProbes { internal interface IFunctionProbes { diff --git a/src/Microsoft.Diagnostics.Monitoring.HostingStartup/ParameterCapturing/FunctionProbes/IFunctionProbesManager.cs b/src/Microsoft.Diagnostics.Monitoring.StartupHook/ParameterCapturing/FunctionProbes/IFunctionProbesManager.cs similarity index 86% rename from src/Microsoft.Diagnostics.Monitoring.HostingStartup/ParameterCapturing/FunctionProbes/IFunctionProbesManager.cs rename to src/Microsoft.Diagnostics.Monitoring.StartupHook/ParameterCapturing/FunctionProbes/IFunctionProbesManager.cs index 59edc813f34..e6918c7e0c6 100644 --- a/src/Microsoft.Diagnostics.Monitoring.HostingStartup/ParameterCapturing/FunctionProbes/IFunctionProbesManager.cs +++ b/src/Microsoft.Diagnostics.Monitoring.StartupHook/ParameterCapturing/FunctionProbes/IFunctionProbesManager.cs @@ -7,7 +7,7 @@ using System.Threading; using System.Threading.Tasks; -namespace Microsoft.Diagnostics.Monitoring.HostingStartup.ParameterCapturing.FunctionProbes +namespace Microsoft.Diagnostics.Monitoring.StartupHook.ParameterCapturing.FunctionProbes { internal interface IFunctionProbesManager : IDisposable { diff --git a/src/Microsoft.Diagnostics.Monitoring.HostingStartup/ParameterCapturing/FunctionProbes/InstrumentedMethod.cs b/src/Microsoft.Diagnostics.Monitoring.StartupHook/ParameterCapturing/FunctionProbes/InstrumentedMethod.cs similarity index 81% rename from src/Microsoft.Diagnostics.Monitoring.HostingStartup/ParameterCapturing/FunctionProbes/InstrumentedMethod.cs rename to src/Microsoft.Diagnostics.Monitoring.StartupHook/ParameterCapturing/FunctionProbes/InstrumentedMethod.cs index 52843a8bf03..38c0fd63a3d 100644 --- a/src/Microsoft.Diagnostics.Monitoring.HostingStartup/ParameterCapturing/FunctionProbes/InstrumentedMethod.cs +++ b/src/Microsoft.Diagnostics.Monitoring.StartupHook/ParameterCapturing/FunctionProbes/InstrumentedMethod.cs @@ -1,10 +1,10 @@ // Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. -using Microsoft.Diagnostics.Monitoring.HostingStartup.ParameterCapturing.Boxing; +using Microsoft.Diagnostics.Monitoring.StartupHook.ParameterCapturing.Boxing; using System.Reflection; -namespace Microsoft.Diagnostics.Monitoring.HostingStartup.ParameterCapturing.FunctionProbes +namespace Microsoft.Diagnostics.Monitoring.StartupHook.ParameterCapturing.FunctionProbes { internal enum ParameterCaptureMode { @@ -21,7 +21,6 @@ public InstrumentedMethod(MethodInfo method, ParameterBoxingInstructions[] boxin { FunctionId = method.GetFunctionId(); SupportedParameters = BoxingInstructions.AreParametersSupported(boxingInstructions); - MethodTemplateString = new MethodTemplateString(method); //TODO: remove! MethodSignature = new MethodSignature(method); foreach (bool isParameterSupported in SupportedParameters) { @@ -68,13 +67,6 @@ private static ParameterCaptureMode ComputeCaptureMode(MethodInfo method) /// public bool[] SupportedParameters { get; } - /// - /// A template string that contains the full method name with parameter names and - /// format items for each supported parameter. - /// - /// TODO: remove! - public MethodTemplateString MethodTemplateString { get; } - /// /// Information about the method (name, parameter types, parameter names). /// diff --git a/src/Microsoft.Diagnostics.Monitoring.HostingStartup/ParameterCapturing/FunctionProbes/ProfilerAbi.cs b/src/Microsoft.Diagnostics.Monitoring.StartupHook/ParameterCapturing/FunctionProbes/ProfilerAbi.cs similarity index 95% rename from src/Microsoft.Diagnostics.Monitoring.HostingStartup/ParameterCapturing/FunctionProbes/ProfilerAbi.cs rename to src/Microsoft.Diagnostics.Monitoring.StartupHook/ParameterCapturing/FunctionProbes/ProfilerAbi.cs index fdc1a491d59..dd85a7690dc 100644 --- a/src/Microsoft.Diagnostics.Monitoring.HostingStartup/ParameterCapturing/FunctionProbes/ProfilerAbi.cs +++ b/src/Microsoft.Diagnostics.Monitoring.StartupHook/ParameterCapturing/FunctionProbes/ProfilerAbi.cs @@ -9,7 +9,7 @@ using System.Runtime.InteropServices; -namespace Microsoft.Diagnostics.Monitoring.HostingStartup.ParameterCapturing.FunctionProbes +namespace Microsoft.Diagnostics.Monitoring.StartupHook.ParameterCapturing.FunctionProbes { internal enum SpecialCaseBoxingTypes : uint { diff --git a/src/Microsoft.Diagnostics.Monitoring.HostingStartup/ParameterCapturing/IMethodDescriptionValidator.cs b/src/Microsoft.Diagnostics.Monitoring.StartupHook/ParameterCapturing/IMethodDescriptionValidator.cs similarity index 83% rename from src/Microsoft.Diagnostics.Monitoring.HostingStartup/ParameterCapturing/IMethodDescriptionValidator.cs rename to src/Microsoft.Diagnostics.Monitoring.StartupHook/ParameterCapturing/IMethodDescriptionValidator.cs index 5c2f367ff75..41668d3ddd0 100644 --- a/src/Microsoft.Diagnostics.Monitoring.HostingStartup/ParameterCapturing/IMethodDescriptionValidator.cs +++ b/src/Microsoft.Diagnostics.Monitoring.StartupHook/ParameterCapturing/IMethodDescriptionValidator.cs @@ -3,7 +3,7 @@ using Microsoft.Diagnostics.Monitoring.StartupHook.MonitorMessageDispatcher.Models; -namespace Microsoft.Diagnostics.Monitoring.HostingStartup.ParameterCapturing +namespace Microsoft.Diagnostics.Monitoring.StartupHook.ParameterCapturing { internal interface IMethodDescriptionValidator { diff --git a/src/Microsoft.Diagnostics.Monitoring.HostingStartup/ParameterCapturing/MethodDescriptionValidator.cs b/src/Microsoft.Diagnostics.Monitoring.StartupHook/ParameterCapturing/MethodDescriptionValidator.cs similarity index 93% rename from src/Microsoft.Diagnostics.Monitoring.HostingStartup/ParameterCapturing/MethodDescriptionValidator.cs rename to src/Microsoft.Diagnostics.Monitoring.StartupHook/ParameterCapturing/MethodDescriptionValidator.cs index bb624a4cdc2..7d09f5e072f 100644 --- a/src/Microsoft.Diagnostics.Monitoring.HostingStartup/ParameterCapturing/MethodDescriptionValidator.cs +++ b/src/Microsoft.Diagnostics.Monitoring.StartupHook/ParameterCapturing/MethodDescriptionValidator.cs @@ -3,7 +3,7 @@ using Microsoft.Diagnostics.Monitoring.StartupHook.MonitorMessageDispatcher.Models; -namespace Microsoft.Diagnostics.Monitoring.HostingStartup.ParameterCapturing +namespace Microsoft.Diagnostics.Monitoring.StartupHook.ParameterCapturing { internal class MethodDescriptionValidator : IMethodDescriptionValidator { diff --git a/src/Microsoft.Diagnostics.Monitoring.HostingStartup/ParameterCapturing/MethodInfoExtensions.cs b/src/Microsoft.Diagnostics.Monitoring.StartupHook/ParameterCapturing/MethodInfoExtensions.cs similarity index 91% rename from src/Microsoft.Diagnostics.Monitoring.HostingStartup/ParameterCapturing/MethodInfoExtensions.cs rename to src/Microsoft.Diagnostics.Monitoring.StartupHook/ParameterCapturing/MethodInfoExtensions.cs index 8f94594ca69..b580295aa72 100644 --- a/src/Microsoft.Diagnostics.Monitoring.HostingStartup/ParameterCapturing/MethodInfoExtensions.cs +++ b/src/Microsoft.Diagnostics.Monitoring.StartupHook/ParameterCapturing/MethodInfoExtensions.cs @@ -3,7 +3,7 @@ using System.Reflection; -namespace Microsoft.Diagnostics.Monitoring.HostingStartup.ParameterCapturing +namespace Microsoft.Diagnostics.Monitoring.StartupHook.ParameterCapturing { internal static class MethodInfoExtensions { diff --git a/src/Microsoft.Diagnostics.Monitoring.HostingStartup/ParameterCapturing/MethodResolver.cs b/src/Microsoft.Diagnostics.Monitoring.StartupHook/ParameterCapturing/MethodResolver.cs similarity index 98% rename from src/Microsoft.Diagnostics.Monitoring.HostingStartup/ParameterCapturing/MethodResolver.cs rename to src/Microsoft.Diagnostics.Monitoring.StartupHook/ParameterCapturing/MethodResolver.cs index 3399fab720f..4d0016e3dea 100644 --- a/src/Microsoft.Diagnostics.Monitoring.HostingStartup/ParameterCapturing/MethodResolver.cs +++ b/src/Microsoft.Diagnostics.Monitoring.StartupHook/ParameterCapturing/MethodResolver.cs @@ -7,7 +7,7 @@ using System.Linq; using System.Reflection; -namespace Microsoft.Diagnostics.Monitoring.HostingStartup.ParameterCapturing +namespace Microsoft.Diagnostics.Monitoring.StartupHook.ParameterCapturing { internal sealed class MethodResolver { diff --git a/src/Microsoft.Diagnostics.Monitoring.HostingStartup/ParameterCapturing/MethodSignature.cs b/src/Microsoft.Diagnostics.Monitoring.StartupHook/ParameterCapturing/MethodSignature.cs similarity index 98% rename from src/Microsoft.Diagnostics.Monitoring.HostingStartup/ParameterCapturing/MethodSignature.cs rename to src/Microsoft.Diagnostics.Monitoring.StartupHook/ParameterCapturing/MethodSignature.cs index 2cfc29b3de5..3bebdb796fe 100644 --- a/src/Microsoft.Diagnostics.Monitoring.HostingStartup/ParameterCapturing/MethodSignature.cs +++ b/src/Microsoft.Diagnostics.Monitoring.StartupHook/ParameterCapturing/MethodSignature.cs @@ -6,7 +6,7 @@ using System.Reflection; using System.Text; -namespace Microsoft.Diagnostics.Monitoring.HostingStartup.ParameterCapturing +namespace Microsoft.Diagnostics.Monitoring.StartupHook.ParameterCapturing { internal sealed class MethodSignature(MethodInfo method) { diff --git a/src/Microsoft.Diagnostics.Monitoring.HostingStartup/ParameterCapturing/ObjectFormatting/Formatters/DebuggerDisplay/DebuggerDisplayFormatter.cs b/src/Microsoft.Diagnostics.Monitoring.StartupHook/ParameterCapturing/ObjectFormatting/Formatters/DebuggerDisplay/DebuggerDisplayFormatter.cs similarity index 92% rename from src/Microsoft.Diagnostics.Monitoring.HostingStartup/ParameterCapturing/ObjectFormatting/Formatters/DebuggerDisplay/DebuggerDisplayFormatter.cs rename to src/Microsoft.Diagnostics.Monitoring.StartupHook/ParameterCapturing/ObjectFormatting/Formatters/DebuggerDisplay/DebuggerDisplayFormatter.cs index 3b7b4078814..ca7a4cc105a 100644 --- a/src/Microsoft.Diagnostics.Monitoring.HostingStartup/ParameterCapturing/ObjectFormatting/Formatters/DebuggerDisplay/DebuggerDisplayFormatter.cs +++ b/src/Microsoft.Diagnostics.Monitoring.StartupHook/ParameterCapturing/ObjectFormatting/Formatters/DebuggerDisplay/DebuggerDisplayFormatter.cs @@ -6,9 +6,9 @@ using System.Diagnostics; using System.Linq; using System.Reflection; -using static Microsoft.Diagnostics.Monitoring.HostingStartup.ParameterCapturing.ObjectFormatting.Formatters.DebuggerDisplay.DebuggerDisplayParser; +using static Microsoft.Diagnostics.Monitoring.StartupHook.ParameterCapturing.ObjectFormatting.Formatters.DebuggerDisplay.DebuggerDisplayParser; -namespace Microsoft.Diagnostics.Monitoring.HostingStartup.ParameterCapturing.ObjectFormatting.Formatters.DebuggerDisplay +namespace Microsoft.Diagnostics.Monitoring.StartupHook.ParameterCapturing.ObjectFormatting.Formatters.DebuggerDisplay { internal static class DebuggerDisplayFormatter { diff --git a/src/Microsoft.Diagnostics.Monitoring.HostingStartup/ParameterCapturing/ObjectFormatting/Formatters/DebuggerDisplay/DebuggerDisplayParser.cs b/src/Microsoft.Diagnostics.Monitoring.StartupHook/ParameterCapturing/ObjectFormatting/Formatters/DebuggerDisplay/DebuggerDisplayParser.cs similarity index 98% rename from src/Microsoft.Diagnostics.Monitoring.HostingStartup/ParameterCapturing/ObjectFormatting/Formatters/DebuggerDisplay/DebuggerDisplayParser.cs rename to src/Microsoft.Diagnostics.Monitoring.StartupHook/ParameterCapturing/ObjectFormatting/Formatters/DebuggerDisplay/DebuggerDisplayParser.cs index fd693269093..3ea670813d9 100644 --- a/src/Microsoft.Diagnostics.Monitoring.HostingStartup/ParameterCapturing/ObjectFormatting/Formatters/DebuggerDisplay/DebuggerDisplayParser.cs +++ b/src/Microsoft.Diagnostics.Monitoring.StartupHook/ParameterCapturing/ObjectFormatting/Formatters/DebuggerDisplay/DebuggerDisplayParser.cs @@ -5,7 +5,7 @@ using System.Collections.Generic; using System.Text; -namespace Microsoft.Diagnostics.Monitoring.HostingStartup.ParameterCapturing.ObjectFormatting.Formatters.DebuggerDisplay +namespace Microsoft.Diagnostics.Monitoring.StartupHook.ParameterCapturing.ObjectFormatting.Formatters.DebuggerDisplay { internal static class DebuggerDisplayParser { diff --git a/src/Microsoft.Diagnostics.Monitoring.HostingStartup/ParameterCapturing/ObjectFormatting/Formatters/DebuggerDisplay/ExpressionBinder.cs b/src/Microsoft.Diagnostics.Monitoring.StartupHook/ParameterCapturing/ObjectFormatting/Formatters/DebuggerDisplay/ExpressionBinder.cs similarity index 97% rename from src/Microsoft.Diagnostics.Monitoring.HostingStartup/ParameterCapturing/ObjectFormatting/Formatters/DebuggerDisplay/ExpressionBinder.cs rename to src/Microsoft.Diagnostics.Monitoring.StartupHook/ParameterCapturing/ObjectFormatting/Formatters/DebuggerDisplay/ExpressionBinder.cs index 478c74fd68b..ca51028df86 100644 --- a/src/Microsoft.Diagnostics.Monitoring.HostingStartup/ParameterCapturing/ObjectFormatting/Formatters/DebuggerDisplay/ExpressionBinder.cs +++ b/src/Microsoft.Diagnostics.Monitoring.StartupHook/ParameterCapturing/ObjectFormatting/Formatters/DebuggerDisplay/ExpressionBinder.cs @@ -4,9 +4,9 @@ using System; using System.Collections.Generic; using System.Reflection; -using static Microsoft.Diagnostics.Monitoring.HostingStartup.ParameterCapturing.ObjectFormatting.Formatters.DebuggerDisplay.DebuggerDisplayParser; +using static Microsoft.Diagnostics.Monitoring.StartupHook.ParameterCapturing.ObjectFormatting.Formatters.DebuggerDisplay.DebuggerDisplayParser; -namespace Microsoft.Diagnostics.Monitoring.HostingStartup.ParameterCapturing.ObjectFormatting.Formatters.DebuggerDisplay +namespace Microsoft.Diagnostics.Monitoring.StartupHook.ParameterCapturing.ObjectFormatting.Formatters.DebuggerDisplay { internal static class ExpressionBinder { diff --git a/src/Microsoft.Diagnostics.Monitoring.HostingStartup/ParameterCapturing/ObjectFormatting/Formatters/RuntimeFormatters.cs b/src/Microsoft.Diagnostics.Monitoring.StartupHook/ParameterCapturing/ObjectFormatting/Formatters/RuntimeFormatters.cs similarity index 93% rename from src/Microsoft.Diagnostics.Monitoring.HostingStartup/ParameterCapturing/ObjectFormatting/Formatters/RuntimeFormatters.cs rename to src/Microsoft.Diagnostics.Monitoring.StartupHook/ParameterCapturing/ObjectFormatting/Formatters/RuntimeFormatters.cs index 41cead7910f..645654e3ea8 100644 --- a/src/Microsoft.Diagnostics.Monitoring.HostingStartup/ParameterCapturing/ObjectFormatting/Formatters/RuntimeFormatters.cs +++ b/src/Microsoft.Diagnostics.Monitoring.StartupHook/ParameterCapturing/ObjectFormatting/Formatters/RuntimeFormatters.cs @@ -4,7 +4,7 @@ using System; using System.Globalization; -namespace Microsoft.Diagnostics.Monitoring.HostingStartup.ParameterCapturing.ObjectFormatting +namespace Microsoft.Diagnostics.Monitoring.StartupHook.ParameterCapturing.ObjectFormatting { internal static class RuntimeFormatters { diff --git a/src/Microsoft.Diagnostics.Monitoring.HostingStartup/ParameterCapturing/ObjectFormatting/ObjectFormatter.cs b/src/Microsoft.Diagnostics.Monitoring.StartupHook/ParameterCapturing/ObjectFormatting/ObjectFormatter.cs similarity index 97% rename from src/Microsoft.Diagnostics.Monitoring.HostingStartup/ParameterCapturing/ObjectFormatting/ObjectFormatter.cs rename to src/Microsoft.Diagnostics.Monitoring.StartupHook/ParameterCapturing/ObjectFormatting/ObjectFormatter.cs index d556b7a6822..0c8970d00c5 100644 --- a/src/Microsoft.Diagnostics.Monitoring.HostingStartup/ParameterCapturing/ObjectFormatting/ObjectFormatter.cs +++ b/src/Microsoft.Diagnostics.Monitoring.StartupHook/ParameterCapturing/ObjectFormatting/ObjectFormatter.cs @@ -4,7 +4,7 @@ using System; using static Microsoft.Diagnostics.Tools.Monitor.ParameterCapturing.ParameterCapturingEvents; -namespace Microsoft.Diagnostics.Monitoring.HostingStartup.ParameterCapturing.ObjectFormatting +namespace Microsoft.Diagnostics.Monitoring.StartupHook.ParameterCapturing.ObjectFormatting { internal delegate ObjectFormatterResult ObjectFormatterFunc(object obj, FormatSpecifier formatSpecifier = FormatSpecifier.None); diff --git a/src/Microsoft.Diagnostics.Monitoring.HostingStartup/ParameterCapturing/ObjectFormatting/ObjectFormatterCache.cs b/src/Microsoft.Diagnostics.Monitoring.StartupHook/ParameterCapturing/ObjectFormatting/ObjectFormatterCache.cs similarity index 95% rename from src/Microsoft.Diagnostics.Monitoring.HostingStartup/ParameterCapturing/ObjectFormatting/ObjectFormatterCache.cs rename to src/Microsoft.Diagnostics.Monitoring.StartupHook/ParameterCapturing/ObjectFormatting/ObjectFormatterCache.cs index f68cb2fbb3b..546b5d1a39b 100644 --- a/src/Microsoft.Diagnostics.Monitoring.HostingStartup/ParameterCapturing/ObjectFormatting/ObjectFormatterCache.cs +++ b/src/Microsoft.Diagnostics.Monitoring.StartupHook/ParameterCapturing/ObjectFormatting/ObjectFormatterCache.cs @@ -6,7 +6,7 @@ using System.Diagnostics; using System.Reflection; -namespace Microsoft.Diagnostics.Monitoring.HostingStartup.ParameterCapturing.ObjectFormatting +namespace Microsoft.Diagnostics.Monitoring.StartupHook.ParameterCapturing.ObjectFormatting { [DebuggerDisplay("Count = {_cache.Count}, UseDebuggerDisplayAttribute={_useDebuggerDisplayAttribute}")] internal sealed class ObjectFormatterCache diff --git a/src/Microsoft.Diagnostics.Monitoring.HostingStartup/ParameterCapturing/ObjectFormatting/ObjectFormatterFactory.cs b/src/Microsoft.Diagnostics.Monitoring.StartupHook/ParameterCapturing/ObjectFormatting/ObjectFormatterFactory.cs similarity index 88% rename from src/Microsoft.Diagnostics.Monitoring.HostingStartup/ParameterCapturing/ObjectFormatting/ObjectFormatterFactory.cs rename to src/Microsoft.Diagnostics.Monitoring.StartupHook/ParameterCapturing/ObjectFormatting/ObjectFormatterFactory.cs index 57cdb3a8c28..11cce22223a 100644 --- a/src/Microsoft.Diagnostics.Monitoring.HostingStartup/ParameterCapturing/ObjectFormatting/ObjectFormatterFactory.cs +++ b/src/Microsoft.Diagnostics.Monitoring.StartupHook/ParameterCapturing/ObjectFormatting/ObjectFormatterFactory.cs @@ -1,11 +1,11 @@ // Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. -using Microsoft.Diagnostics.Monitoring.HostingStartup.ParameterCapturing.ObjectFormatting.Formatters.DebuggerDisplay; +using Microsoft.Diagnostics.Monitoring.StartupHook.ParameterCapturing.ObjectFormatting.Formatters.DebuggerDisplay; using System; using System.Collections.Generic; -namespace Microsoft.Diagnostics.Monitoring.HostingStartup.ParameterCapturing.ObjectFormatting +namespace Microsoft.Diagnostics.Monitoring.StartupHook.ParameterCapturing.ObjectFormatting { /// /// The results from GetFormatter. diff --git a/src/Microsoft.Diagnostics.Monitoring.HostingStartup/ParameterCapturing/ParameterCapturingService.cs b/src/Microsoft.Diagnostics.Monitoring.StartupHook/ParameterCapturing/ParameterCapturingService.cs similarity index 74% rename from src/Microsoft.Diagnostics.Monitoring.HostingStartup/ParameterCapturing/ParameterCapturingService.cs rename to src/Microsoft.Diagnostics.Monitoring.StartupHook/ParameterCapturing/ParameterCapturingService.cs index 0599943c75c..74371cc2603 100644 --- a/src/Microsoft.Diagnostics.Monitoring.HostingStartup/ParameterCapturing/ParameterCapturingService.cs +++ b/src/Microsoft.Diagnostics.Monitoring.StartupHook/ParameterCapturing/ParameterCapturingService.cs @@ -1,24 +1,21 @@ // Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. -using Microsoft.Diagnostics.Monitoring.HostingStartup.ParameterCapturing.Eventing; -using Microsoft.Diagnostics.Monitoring.HostingStartup.ParameterCapturing.FunctionProbes; -using Microsoft.Diagnostics.Monitoring.HostingStartup.ParameterCapturing.Pipeline; -using Microsoft.Diagnostics.Monitoring.StartupHook; using Microsoft.Diagnostics.Monitoring.StartupHook.Monitoring; +using Microsoft.Diagnostics.Monitoring.StartupHook.ParameterCapturing.Eventing; +using Microsoft.Diagnostics.Monitoring.StartupHook.ParameterCapturing.FunctionProbes; +using Microsoft.Diagnostics.Monitoring.StartupHook.ParameterCapturing.Pipeline; using Microsoft.Diagnostics.Tools.Monitor.ParameterCapturing; using Microsoft.Diagnostics.Tools.Monitor.Profiler; using Microsoft.Diagnostics.Tools.Monitor.StartupHook; -using Microsoft.Extensions.DependencyInjection; -using Microsoft.Extensions.Hosting; -using Microsoft.Extensions.Logging; using System; using System.Collections.Generic; +using System.Globalization; using System.Reflection; using System.Threading; using System.Threading.Tasks; -namespace Microsoft.Diagnostics.Monitoring.HostingStartup.ParameterCapturing +namespace Microsoft.Diagnostics.Monitoring.StartupHook.ParameterCapturing { internal sealed class ParameterCapturingService : BackgroundService, IParameterCapturingPipelineCallbacks, IDisposable { @@ -30,11 +27,8 @@ internal sealed class ParameterCapturingService : BackgroundService, IParameterC private readonly ParameterCapturingEventSource _eventSource = new(); private readonly AsyncParameterCapturingEventSource? _asyncEventSource; private readonly ParameterCapturingPipeline? _pipeline; - private readonly ParameterCapturingLogger? _parameterCapturingLogger; - private readonly ILogger? _logger; - - public ParameterCapturingService(IServiceProvider services) + public ParameterCapturingService() { using IDisposable _ = MonitorExecutionContextTracker.MonitorScope(); @@ -52,19 +46,9 @@ public ParameterCapturingService(IServiceProvider services) StartupHookCommand.StopCapturingParameters, OnStopMessage); - IMethodDescriptionValidator _methodDescriptionValidator = services.GetRequiredService(); - - _logger = services.GetService>() - ?? throw new NotSupportedException(ParameterCapturingStrings.FeatureUnsupported_NoLogger); - - ILogger userLogger = services.GetService>() - ?? throw new NotSupportedException(ParameterCapturingStrings.FeatureUnsupported_NoLogger); - - ILogger systemLogger = services.GetService>() - ?? throw new NotSupportedException(ParameterCapturingStrings.FeatureUnsupported_NoLogger); + IMethodDescriptionValidator _methodDescriptionValidator = new MethodDescriptionValidator(); - _parameterCapturingLogger = new(userLogger, systemLogger); - FunctionProbesManager probeManager = new(_logger); + FunctionProbesManager probeManager = new(); _pipeline = new ParameterCapturingPipeline(probeManager, this, _methodDescriptionValidator); @@ -84,32 +68,30 @@ public ParameterCapturingService(IServiceProvider services) public void CapturingStart(StartCapturingParametersPayload request, IList methods) { _eventSource.CapturingStart(request.RequestId); - _logger?.LogInformation( - ParameterCapturingStrings.StartParameterCapturingFormatString, - request.Duration, - methods.Count); } public void CapturingStop(Guid requestId) { _eventSource.CapturingStop(requestId); - _logger?.LogInformation(ParameterCapturingStrings.StopParameterCapturing); } public void FailedToCapture(Guid requestId, ParameterCapturingEvents.CapturingFailedReason reason, string details) { _eventSource.FailedToCapture(requestId, reason, details); - if (reason == ParameterCapturingEvents.CapturingFailedReason.UnresolvedMethods) - { - _logger?.LogWarning(details); - } } public void ProbeFault(Guid requestId, InstrumentedMethod faultingMethod) { - // TODO: Report back this fault on ParameterCapturingEventSource. - _logger?.LogWarning(ParameterCapturingStrings.StoppingParameterCapturingDueToProbeFault, faultingMethod.MethodTemplateString.Template); - + _eventSource.FailedToCapture( + requestId, + ParameterCapturingEvents.CapturingFailedReason.ProbeFaulted, + string.Format( + CultureInfo.InvariantCulture, + ParameterCapturingStrings.StoppingParameterCapturingDueToProbeFault, + faultingMethod.MethodSignature.ModuleName, + faultingMethod.MethodSignature.TypeName, + faultingMethod.MethodSignature.MethodName + )); try { _pipeline?.RequestStop(requestId); @@ -128,7 +110,7 @@ private bool IsAvailable() private void OnStartMessage(StartCapturingParametersPayload payload) { - if (!IsAvailable() || _pipeline == null || _parameterCapturingLogger == null || _asyncEventSource == null) + if (!IsAvailable() || _pipeline == null || _asyncEventSource == null) { BroadcastServiceState(); return; @@ -233,7 +215,6 @@ public override void Dispose() SharedInternals.MessageDispatcher?.UnregisterCallback(StartupHookCommand.StopCapturingParameters); _pipeline?.Dispose(); - _parameterCapturingLogger?.Dispose(); _asyncEventSource?.Dispose(); diff --git a/src/Microsoft.Diagnostics.Monitoring.HostingStartup/ParameterCapturing/ParameterCapturingStrings.Designer.cs b/src/Microsoft.Diagnostics.Monitoring.StartupHook/ParameterCapturing/ParameterCapturingStrings.Designer.cs similarity index 70% rename from src/Microsoft.Diagnostics.Monitoring.HostingStartup/ParameterCapturing/ParameterCapturingStrings.Designer.cs rename to src/Microsoft.Diagnostics.Monitoring.StartupHook/ParameterCapturing/ParameterCapturingStrings.Designer.cs index b92a947219a..49469887ad2 100644 --- a/src/Microsoft.Diagnostics.Monitoring.HostingStartup/ParameterCapturing/ParameterCapturingStrings.Designer.cs +++ b/src/Microsoft.Diagnostics.Monitoring.StartupHook/ParameterCapturing/ParameterCapturingStrings.Designer.cs @@ -8,7 +8,7 @@ // //------------------------------------------------------------------------------ -namespace Microsoft.Diagnostics.Monitoring.HostingStartup.ParameterCapturing { +namespace Microsoft.Diagnostics.Monitoring.StartupHook.ParameterCapturing { using System; @@ -39,8 +39,8 @@ internal ParameterCapturingStrings() { internal static global::System.Resources.ResourceManager ResourceManager { get { if (object.ReferenceEquals(resourceMan, null)) { - global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("Microsoft.Diagnostics.Monitoring.HostingStartup.ParameterCapturing.ParameterCaptu" + - "ringStrings", typeof(ParameterCapturingStrings).Assembly); + global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("Microsoft.Diagnostics.Monitoring.StartupHook.ParameterCapturing.ParameterCapturin" + + "gStrings", typeof(ParameterCapturingStrings).Assembly); resourceMan = temp; } return resourceMan; @@ -61,15 +61,6 @@ internal ParameterCapturingStrings() { } } - /// - /// Looks up a localized string similar to Cancellation has been requested during probe installation. Cancellation tokens request state (Provided:{isProvidedTokenCancelled}, Disposal:{isDisposalTokenCancelled}).. - /// - internal static string CancellationRequestedDuringProbeInstallation { - get { - return ResourceManager.GetString("CancellationRequestedDuringProbeInstallation", resourceCulture); - } - } - /// /// Looks up a localized string similar to The following method descriptions are not allowed: {0}. /// @@ -107,43 +98,7 @@ internal static string ErrorMessage_SignatureIsNotForAMethod { } /// - /// Looks up a localized string similar to Unable to create an ILogger instance in the target process.. - /// - internal static string FeatureUnsupported_NoLogger { - get { - return ResourceManager.GetString("FeatureUnsupported_NoLogger", resourceCulture); - } - } - - /// - /// Looks up a localized string similar to {callbackName}, hr={hr}. - /// - internal static string ProbeManagementCallback { - get { - return ResourceManager.GetString("ProbeManagementCallback", resourceCulture); - } - } - - /// - /// Looks up a localized string similar to Started parameter capturing for {duration} on {numberOfMethods} method(s).. - /// - internal static string StartParameterCapturingFormatString { - get { - return ResourceManager.GetString("StartParameterCapturingFormatString", resourceCulture); - } - } - - /// - /// Looks up a localized string similar to Stopped parameter capturing.. - /// - internal static string StopParameterCapturing { - get { - return ResourceManager.GetString("StopParameterCapturing", resourceCulture); - } - } - - /// - /// Looks up a localized string similar to Parameter capturing encountered an internal error when processing '{method}', stopping.. + /// Looks up a localized string similar to Parameter capturing encountered an internal error when processing '{0}!{1}.{2}', stopping.. /// internal static string StoppingParameterCapturingDueToProbeFault { get { diff --git a/src/Microsoft.Diagnostics.Monitoring.HostingStartup/ParameterCapturing/ParameterCapturingStrings.resx b/src/Microsoft.Diagnostics.Monitoring.StartupHook/ParameterCapturing/ParameterCapturingStrings.resx similarity index 88% rename from src/Microsoft.Diagnostics.Monitoring.HostingStartup/ParameterCapturing/ParameterCapturingStrings.resx rename to src/Microsoft.Diagnostics.Monitoring.StartupHook/ParameterCapturing/ParameterCapturingStrings.resx index a40f1ee7666..be3c284e2a3 100644 --- a/src/Microsoft.Diagnostics.Monitoring.HostingStartup/ParameterCapturing/ParameterCapturingStrings.resx +++ b/src/Microsoft.Diagnostics.Monitoring.StartupHook/ParameterCapturing/ParameterCapturingStrings.resx @@ -117,9 +117,6 @@ System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - Cancellation has been requested during probe installation. Cancellation tokens request state (Provided:{isProvidedTokenCancelled}, Disposal:{isDisposalTokenCancelled}). - The following method descriptions are not allowed: {0} @@ -132,20 +129,9 @@ The provided signature blob must be for a method. - - Unable to create an ILogger instance in the target process. - - - {callbackName}, hr={hr} - - - Started parameter capturing for {duration} on {numberOfMethods} method(s). - - - Stopped parameter capturing. - - Parameter capturing encountered an internal error when processing '{method}', stopping. + Parameter capturing encountered an internal error when processing '{0}!{1}.{2}', stopping. + 0 is the module name, 1 is the method type and 2 is the method name. Too many requests @@ -153,4 +139,4 @@ Unable to resolve one or more method descriptions: {0} - \ No newline at end of file + diff --git a/src/Microsoft.Diagnostics.Monitoring.HostingStartup/ParameterCapturing/ParameterSignature.cs b/src/Microsoft.Diagnostics.Monitoring.StartupHook/ParameterCapturing/ParameterSignature.cs similarity index 80% rename from src/Microsoft.Diagnostics.Monitoring.HostingStartup/ParameterCapturing/ParameterSignature.cs rename to src/Microsoft.Diagnostics.Monitoring.StartupHook/ParameterCapturing/ParameterSignature.cs index abe151ac1ef..ffdc64d4d1e 100644 --- a/src/Microsoft.Diagnostics.Monitoring.HostingStartup/ParameterCapturing/ParameterSignature.cs +++ b/src/Microsoft.Diagnostics.Monitoring.StartupHook/ParameterCapturing/ParameterSignature.cs @@ -3,7 +3,7 @@ using System.Reflection; -namespace Microsoft.Diagnostics.Monitoring.HostingStartup.ParameterCapturing +namespace Microsoft.Diagnostics.Monitoring.StartupHook.ParameterCapturing { internal sealed record ParameterSignature(string? Name, string? Type, string? TypeModuleName, ParameterAttributes Attributes, bool IsByRef) { diff --git a/src/Microsoft.Diagnostics.Monitoring.HostingStartup/ParameterCapturing/Pipeline/CaptureLimitPolicyProbes.cs b/src/Microsoft.Diagnostics.Monitoring.StartupHook/ParameterCapturing/Pipeline/CaptureLimitPolicyProbes.cs similarity index 90% rename from src/Microsoft.Diagnostics.Monitoring.HostingStartup/ParameterCapturing/Pipeline/CaptureLimitPolicyProbes.cs rename to src/Microsoft.Diagnostics.Monitoring.StartupHook/ParameterCapturing/Pipeline/CaptureLimitPolicyProbes.cs index ea9815e121f..5b1f3b63461 100644 --- a/src/Microsoft.Diagnostics.Monitoring.HostingStartup/ParameterCapturing/Pipeline/CaptureLimitPolicyProbes.cs +++ b/src/Microsoft.Diagnostics.Monitoring.StartupHook/ParameterCapturing/Pipeline/CaptureLimitPolicyProbes.cs @@ -1,13 +1,13 @@ // Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. -using Microsoft.Diagnostics.Monitoring.HostingStartup.ParameterCapturing.FunctionProbes; +using Microsoft.Diagnostics.Monitoring.StartupHook.ParameterCapturing.FunctionProbes; using System.Collections.Generic; using System.Reflection; using System.Threading; using System.Threading.Tasks; -namespace Microsoft.Diagnostics.Monitoring.HostingStartup.ParameterCapturing.Pipeline +namespace Microsoft.Diagnostics.Monitoring.StartupHook.ParameterCapturing.Pipeline { internal sealed class CaptureLimitPolicyProbes : IFunctionProbes { diff --git a/src/Microsoft.Diagnostics.Monitoring.HostingStartup/ParameterCapturing/Pipeline/IParameterCapturingPipelineCallbacks.cs b/src/Microsoft.Diagnostics.Monitoring.StartupHook/ParameterCapturing/Pipeline/IParameterCapturingPipelineCallbacks.cs similarity index 89% rename from src/Microsoft.Diagnostics.Monitoring.HostingStartup/ParameterCapturing/Pipeline/IParameterCapturingPipelineCallbacks.cs rename to src/Microsoft.Diagnostics.Monitoring.StartupHook/ParameterCapturing/Pipeline/IParameterCapturingPipelineCallbacks.cs index 5c90d6bd3a6..f2d47c4a813 100644 --- a/src/Microsoft.Diagnostics.Monitoring.HostingStartup/ParameterCapturing/Pipeline/IParameterCapturingPipelineCallbacks.cs +++ b/src/Microsoft.Diagnostics.Monitoring.StartupHook/ParameterCapturing/Pipeline/IParameterCapturingPipelineCallbacks.cs @@ -7,7 +7,7 @@ using System.Collections.Generic; using System.Reflection; -namespace Microsoft.Diagnostics.Monitoring.HostingStartup.ParameterCapturing.FunctionProbes +namespace Microsoft.Diagnostics.Monitoring.StartupHook.ParameterCapturing.FunctionProbes { internal interface IParameterCapturingPipelineCallbacks { diff --git a/src/Microsoft.Diagnostics.Monitoring.HostingStartup/ParameterCapturing/Pipeline/ParameterCapturingPipeline.cs b/src/Microsoft.Diagnostics.Monitoring.StartupHook/ParameterCapturing/Pipeline/ParameterCapturingPipeline.cs similarity index 98% rename from src/Microsoft.Diagnostics.Monitoring.HostingStartup/ParameterCapturing/Pipeline/ParameterCapturingPipeline.cs rename to src/Microsoft.Diagnostics.Monitoring.StartupHook/ParameterCapturing/Pipeline/ParameterCapturingPipeline.cs index d2df9465d73..1cd6eb69067 100644 --- a/src/Microsoft.Diagnostics.Monitoring.HostingStartup/ParameterCapturing/Pipeline/ParameterCapturingPipeline.cs +++ b/src/Microsoft.Diagnostics.Monitoring.StartupHook/ParameterCapturing/Pipeline/ParameterCapturingPipeline.cs @@ -1,7 +1,7 @@ // Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. -using Microsoft.Diagnostics.Monitoring.HostingStartup.ParameterCapturing.FunctionProbes; +using Microsoft.Diagnostics.Monitoring.StartupHook.ParameterCapturing.FunctionProbes; using Microsoft.Diagnostics.Monitoring.StartupHook.MonitorMessageDispatcher.Models; using Microsoft.Diagnostics.Tools.Monitor.ParameterCapturing; using Microsoft.Diagnostics.Tools.Monitor.Profiler; @@ -13,7 +13,7 @@ using System.Threading.Channels; using System.Threading.Tasks; -namespace Microsoft.Diagnostics.Monitoring.HostingStartup.ParameterCapturing.Pipeline +namespace Microsoft.Diagnostics.Monitoring.StartupHook.ParameterCapturing.Pipeline { internal sealed class ParameterCapturingPipeline : IDisposable { diff --git a/src/Microsoft.Diagnostics.Monitoring.HostingStartup/ParameterCapturing/Pipeline/TooManyRequestsException.cs b/src/Microsoft.Diagnostics.Monitoring.StartupHook/ParameterCapturing/Pipeline/TooManyRequestsException.cs similarity index 78% rename from src/Microsoft.Diagnostics.Monitoring.HostingStartup/ParameterCapturing/Pipeline/TooManyRequestsException.cs rename to src/Microsoft.Diagnostics.Monitoring.StartupHook/ParameterCapturing/Pipeline/TooManyRequestsException.cs index 68c861ad746..ef629e047dd 100644 --- a/src/Microsoft.Diagnostics.Monitoring.HostingStartup/ParameterCapturing/Pipeline/TooManyRequestsException.cs +++ b/src/Microsoft.Diagnostics.Monitoring.StartupHook/ParameterCapturing/Pipeline/TooManyRequestsException.cs @@ -3,7 +3,7 @@ using System; -namespace Microsoft.Diagnostics.Monitoring.HostingStartup.ParameterCapturing.Pipeline +namespace Microsoft.Diagnostics.Monitoring.StartupHook.ParameterCapturing.Pipeline { internal sealed class TooManyRequestsException : Exception { diff --git a/src/Microsoft.Diagnostics.Monitoring.HostingStartup/ParameterCapturing/ResolvedParameterInfo.cs b/src/Microsoft.Diagnostics.Monitoring.StartupHook/ParameterCapturing/ResolvedParameterInfo.cs similarity index 68% rename from src/Microsoft.Diagnostics.Monitoring.HostingStartup/ParameterCapturing/ResolvedParameterInfo.cs rename to src/Microsoft.Diagnostics.Monitoring.StartupHook/ParameterCapturing/ResolvedParameterInfo.cs index 7ac627f9ab1..d59a46400aa 100644 --- a/src/Microsoft.Diagnostics.Monitoring.HostingStartup/ParameterCapturing/ResolvedParameterInfo.cs +++ b/src/Microsoft.Diagnostics.Monitoring.StartupHook/ParameterCapturing/ResolvedParameterInfo.cs @@ -1,10 +1,10 @@ // Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. -using Microsoft.Diagnostics.Monitoring.HostingStartup.ParameterCapturing.ObjectFormatting; +using Microsoft.Diagnostics.Monitoring.StartupHook.ParameterCapturing.ObjectFormatting; using System.Reflection; -namespace Microsoft.Diagnostics.Monitoring.HostingStartup.ParameterCapturing +namespace Microsoft.Diagnostics.Monitoring.StartupHook.ParameterCapturing { internal sealed record ResolvedParameterInfo(string? Name, string? Type, string? TypeModuleName, ObjectFormatterResult Value, ParameterAttributes Attributes, bool IsByRef) { diff --git a/src/Microsoft.Diagnostics.Monitoring.HostingStartup/ParameterCapturing/TypeUtils.cs b/src/Microsoft.Diagnostics.Monitoring.StartupHook/ParameterCapturing/TypeUtils.cs similarity index 93% rename from src/Microsoft.Diagnostics.Monitoring.HostingStartup/ParameterCapturing/TypeUtils.cs rename to src/Microsoft.Diagnostics.Monitoring.StartupHook/ParameterCapturing/TypeUtils.cs index 547cd7a4ac4..d119bfa7b39 100644 --- a/src/Microsoft.Diagnostics.Monitoring.HostingStartup/ParameterCapturing/TypeUtils.cs +++ b/src/Microsoft.Diagnostics.Monitoring.StartupHook/ParameterCapturing/TypeUtils.cs @@ -3,7 +3,7 @@ using System; -namespace Microsoft.Diagnostics.Monitoring.HostingStartup.ParameterCapturing +namespace Microsoft.Diagnostics.Monitoring.StartupHook.ParameterCapturing { internal static class TypeUtils { diff --git a/src/Microsoft.Diagnostics.Monitoring.HostingStartup/ParameterCapturing/UnresolvedMethodsException.cs b/src/Microsoft.Diagnostics.Monitoring.StartupHook/ParameterCapturing/UnresolvedMethodsException.cs similarity index 93% rename from src/Microsoft.Diagnostics.Monitoring.HostingStartup/ParameterCapturing/UnresolvedMethodsException.cs rename to src/Microsoft.Diagnostics.Monitoring.StartupHook/ParameterCapturing/UnresolvedMethodsException.cs index ce23592b18e..31054a38e3a 100644 --- a/src/Microsoft.Diagnostics.Monitoring.HostingStartup/ParameterCapturing/UnresolvedMethodsException.cs +++ b/src/Microsoft.Diagnostics.Monitoring.StartupHook/ParameterCapturing/UnresolvedMethodsException.cs @@ -7,7 +7,7 @@ using System.Globalization; using System.Text; -namespace Microsoft.Diagnostics.Monitoring.HostingStartup.ParameterCapturing +namespace Microsoft.Diagnostics.Monitoring.StartupHook.ParameterCapturing { internal sealed class UnresolvedMethodsExceptions : Exception { diff --git a/src/Microsoft.Diagnostics.Monitoring.WebApi/IInProcessFeatures.cs b/src/Microsoft.Diagnostics.Monitoring.WebApi/IInProcessFeatures.cs index e0c7b2123d5..3ce243d9c73 100644 --- a/src/Microsoft.Diagnostics.Monitoring.WebApi/IInProcessFeatures.cs +++ b/src/Microsoft.Diagnostics.Monitoring.WebApi/IInProcessFeatures.cs @@ -10,8 +10,6 @@ public interface IInProcessFeatures bool IsStartupHookRequired { get; } - bool IsHostingStartupRequired { get; } - bool IsLibrarySharingRequired { get; } } } diff --git a/src/Microsoft.Diagnostics.Monitoring.WebApi/KeyValueLogScope.cs b/src/Microsoft.Diagnostics.Monitoring.WebApi/KeyValueLogScope.cs index 76f62de6635..8039539695f 100644 --- a/src/Microsoft.Diagnostics.Monitoring.WebApi/KeyValueLogScope.cs +++ b/src/Microsoft.Diagnostics.Monitoring.WebApi/KeyValueLogScope.cs @@ -5,11 +5,7 @@ using System.Collections.Generic; using System.Text; -#if HOSTINGSTARTUP -namespace Microsoft.Diagnostics.Monitoring.HostingStartup -#else namespace Microsoft.Diagnostics.Monitoring.WebApi -#endif { // Logger implementations have different ways of serializing log scopes. This class helps those loggers // serialize the scope information in the best way possible for each of the implementations. diff --git a/src/Microsoft.Diagnostics.Monitoring.WebApi/KeyValueLogScopeExtensions.cs b/src/Microsoft.Diagnostics.Monitoring.WebApi/KeyValueLogScopeExtensions.cs index b94b3e0972a..43f0f238c17 100644 --- a/src/Microsoft.Diagnostics.Monitoring.WebApi/KeyValueLogScopeExtensions.cs +++ b/src/Microsoft.Diagnostics.Monitoring.WebApi/KeyValueLogScopeExtensions.cs @@ -2,14 +2,9 @@ // The .NET Foundation licenses this file to you under the MIT license. using System.Collections.Generic; - -#if HOSTINGSTARTUP -namespace Microsoft.Diagnostics.Monitoring.HostingStartup -#else using System.Globalization; namespace Microsoft.Diagnostics.Monitoring.WebApi -#endif { internal static class KeyValueLogScopeExtensions { @@ -17,7 +12,7 @@ public static void Add(this List> values, string ke { values.Add(new KeyValuePair(key, value)); } -#if !HOSTINGSTARTUP + public static void AddArtifactType(this KeyValueLogScope scope, string artifactType) { scope.Values.Add("ArtifactType", artifactType); @@ -32,6 +27,5 @@ public static void AddArtifactEndpointInfo(this KeyValueLogScope scope, IEndpoin ArtifactMetadataNames.ArtifactSource.RuntimeInstanceCookie, endpointInfo.RuntimeInstanceCookie.ToString("N")); } -#endif } } diff --git a/src/Microsoft.Diagnostics.Monitoring.WebApi/Models/CallStackResults.cs b/src/Microsoft.Diagnostics.Monitoring.WebApi/Models/CallStackResults.cs index a93e0f2ecb9..3d410000a49 100644 --- a/src/Microsoft.Diagnostics.Monitoring.WebApi/Models/CallStackResults.cs +++ b/src/Microsoft.Diagnostics.Monitoring.WebApi/Models/CallStackResults.cs @@ -1,6 +1,7 @@ // Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. +using System; using System.Collections.Generic; using System.Text.Json.Serialization; @@ -11,12 +12,18 @@ public class CallStackFrame [JsonPropertyName("methodName")] public string MethodName { get; set; } + [JsonPropertyName("methodToken")] + public uint MethodToken { get; set; } + [JsonPropertyName("typeName")] public string TypeName { get; set; } [JsonPropertyName("moduleName")] public string ModuleName { get; set; } + [JsonPropertyName("moduleVersionId")] + public Guid ModuleVersionId { get; set; } + [JsonIgnore] internal IList SimpleGenericArgTypes { get; set; } = new List(); diff --git a/src/Microsoft.Diagnostics.Monitoring.WebApi/Models/CaptureParametersConfiguration.cs b/src/Microsoft.Diagnostics.Monitoring.WebApi/Models/CaptureParametersConfiguration.cs index e967a080b30..e0c4a7181b2 100644 --- a/src/Microsoft.Diagnostics.Monitoring.WebApi/Models/CaptureParametersConfiguration.cs +++ b/src/Microsoft.Diagnostics.Monitoring.WebApi/Models/CaptureParametersConfiguration.cs @@ -5,7 +5,7 @@ using System.ComponentModel.DataAnnotations; using System.Text.Json.Serialization; -#if STARTUPHOOK || HOSTINGSTARTUP +#if STARTUPHOOK namespace Microsoft.Diagnostics.Monitoring.StartupHook.MonitorMessageDispatcher.Models #else namespace Microsoft.Diagnostics.Monitoring.WebApi.Models diff --git a/src/Microsoft.Diagnostics.Monitoring.WebApi/Models/MethodDescription.cs b/src/Microsoft.Diagnostics.Monitoring.WebApi/Models/MethodDescription.cs index 62aea680ec6..8a7b18afca0 100644 --- a/src/Microsoft.Diagnostics.Monitoring.WebApi/Models/MethodDescription.cs +++ b/src/Microsoft.Diagnostics.Monitoring.WebApi/Models/MethodDescription.cs @@ -4,7 +4,7 @@ using System; using System.ComponentModel.DataAnnotations; -#if STARTUPHOOK || HOSTINGSTARTUP +#if STARTUPHOOK namespace Microsoft.Diagnostics.Monitoring.StartupHook.MonitorMessageDispatcher.Models #else using Microsoft.Diagnostics.Monitoring.Options; diff --git a/src/Microsoft.Diagnostics.Monitoring.WebApi/ProfilerMessage.cs b/src/Microsoft.Diagnostics.Monitoring.WebApi/ProfilerMessage.cs index 6255ace92af..f40475a9489 100644 --- a/src/Microsoft.Diagnostics.Monitoring.WebApi/ProfilerMessage.cs +++ b/src/Microsoft.Diagnostics.Monitoring.WebApi/ProfilerMessage.cs @@ -6,7 +6,7 @@ using System.Text.Json; -#if STARTUPHOOK || HOSTINGSTARTUP +#if STARTUPHOOK namespace Microsoft.Diagnostics.Monitoring.StartupHook.Monitoring #else namespace Microsoft.Diagnostics.Monitoring @@ -29,9 +29,6 @@ public enum ProfilerCommand : ushort Callstack }; - /// - /// Shared between the StartupHook and HostingStartup assembly. - /// public enum StartupHookCommand : ushort { StartCapturingParameters, diff --git a/src/Microsoft.Diagnostics.Monitoring.WebApi/Stacks/CallStackData.cs b/src/Microsoft.Diagnostics.Monitoring.WebApi/Stacks/CallStackData.cs index 5e8acce7503..47e4f73b5ae 100644 --- a/src/Microsoft.Diagnostics.Monitoring.WebApi/Stacks/CallStackData.cs +++ b/src/Microsoft.Diagnostics.Monitoring.WebApi/Stacks/CallStackData.cs @@ -1,6 +1,7 @@ // Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. +using System; using System.Collections.Generic; namespace Microsoft.Diagnostics.Monitoring.WebApi.Stacks @@ -20,6 +21,10 @@ internal sealed class CallStackFrame { public ulong FunctionId { get; set; } + public uint MethodToken { get; set; } + + public Guid ModuleVersionId { get; set; } + public ulong Offset { get; set; } } diff --git a/src/Microsoft.Diagnostics.Monitoring.WebApi/Stacks/EventStacksPipeline.cs b/src/Microsoft.Diagnostics.Monitoring.WebApi/Stacks/EventStacksPipeline.cs index ec280574838..50508001b1e 100644 --- a/src/Microsoft.Diagnostics.Monitoring.WebApi/Stacks/EventStacksPipeline.cs +++ b/src/Microsoft.Diagnostics.Monitoring.WebApi/Stacks/EventStacksPipeline.cs @@ -85,7 +85,22 @@ private void Callback(TraceEvent action) { for (int i = 0; i < functionIds.Length; i++) { - stack.Frames.Add(new CallStackFrame { FunctionId = functionIds[i], Offset = offsets[i] }); + CallStackFrame stackFrame = new CallStackFrame + { + FunctionId = functionIds[i], + Offset = offsets[i] + }; + + if (_result.NameCache.FunctionData.TryGetValue(stackFrame.FunctionId, out FunctionData functionData)) + { + stackFrame.MethodToken = functionData.MethodToken; + if (_result.NameCache.ModuleData.TryGetValue(functionData.ModuleId, out ModuleData moduleData)) + { + stackFrame.ModuleVersionId = moduleData.ModuleVersionId; + } + } + + stack.Frames.Add(stackFrame); } } } @@ -94,6 +109,7 @@ private void Callback(TraceEvent action) ulong id = action.GetPayload(NameIdentificationEvents.FunctionDescPayloads.FunctionId); var functionData = new FunctionData( action.GetPayload(NameIdentificationEvents.FunctionDescPayloads.Name), + action.GetPayload(NameIdentificationEvents.FunctionDescPayloads.MethodToken), action.GetPayload(NameIdentificationEvents.FunctionDescPayloads.ClassId), action.GetPayload(NameIdentificationEvents.FunctionDescPayloads.ClassToken), action.GetPayload(NameIdentificationEvents.FunctionDescPayloads.ModuleId), @@ -119,7 +135,8 @@ private void Callback(TraceEvent action) { ulong id = action.GetPayload(NameIdentificationEvents.ModuleDescPayloads.ModuleId); var moduleData = new ModuleData( - action.GetPayload(NameIdentificationEvents.ModuleDescPayloads.Name) + action.GetPayload(NameIdentificationEvents.ModuleDescPayloads.Name), + action.GetPayload(NameIdentificationEvents.ModuleDescPayloads.ModuleVersionId) ); _result.NameCache.ModuleData.TryAdd(id, moduleData); diff --git a/src/Microsoft.Diagnostics.Monitoring.WebApi/Stacks/NameCache.cs b/src/Microsoft.Diagnostics.Monitoring.WebApi/Stacks/NameCache.cs index 9fb10cfe8e2..6207e0837a5 100644 --- a/src/Microsoft.Diagnostics.Monitoring.WebApi/Stacks/NameCache.cs +++ b/src/Microsoft.Diagnostics.Monitoring.WebApi/Stacks/NameCache.cs @@ -1,6 +1,7 @@ // Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. +using System; using System.Collections.Concurrent; using System.Diagnostics; @@ -43,20 +44,22 @@ internal sealed record class ClassData(uint Token, ulong ModuleId, ClassFlags Fl internal sealed record class TokenData(string Name, string Namespace, uint OuterToken); /// The name of the function. + /// The method token of the function (methodDef token). /// The parent class identifier of the function. - /// The parent metadata token of the function. + /// The parent metadata token of the function (typeDef token). /// The identifier of the module that contains the function. /// The class identifiers of the generic type arguments of the function. /// The class identifiers of the parameter types of the function. /// - /// If is 0, then use . + /// If is 0, then use . /// [DebuggerDisplay("{Name}")] - internal sealed record class FunctionData(string Name, ulong ParentClass, uint ParentToken, ulong ModuleId, ulong[] TypeArgs, ulong[] ParameterTypes); + internal sealed record class FunctionData(string Name, uint MethodToken, ulong ParentClass, uint ParentClassToken, ulong ModuleId, ulong[] TypeArgs, ulong[] ParameterTypes); /// The name of the module. + /// The version identifier of the module. [DebuggerDisplay("{Name}")] - internal sealed record class ModuleData(string Name); + internal sealed record class ModuleData(string Name, Guid ModuleVersionId); internal sealed record class ModuleScopedToken(ulong ModuleId, uint Token); } diff --git a/src/Microsoft.Diagnostics.Monitoring.WebApi/Stacks/NameFormatter.cs b/src/Microsoft.Diagnostics.Monitoring.WebApi/Stacks/NameFormatter.cs index 3d5d9031076..050ab763dc8 100644 --- a/src/Microsoft.Diagnostics.Monitoring.WebApi/Stacks/NameFormatter.cs +++ b/src/Microsoft.Diagnostics.Monitoring.WebApi/Stacks/NameFormatter.cs @@ -42,7 +42,7 @@ public static void BuildTypeName(StringBuilder builder, NameCache cache, Functio } else { - BuildTypeName(builder, cache, functionData.ModuleId, functionData.ParentToken, TypeFormat.Full); + BuildTypeName(builder, cache, functionData.ModuleId, functionData.ParentClassToken, TypeFormat.Full); } } @@ -80,11 +80,11 @@ public static void BuildTypeName(StringBuilder builder, NameCache cache, ulong c } } - private static void BuildTypeName(StringBuilder builder, NameCache cache, ulong moduleId, uint token, TypeFormat typeFormat) + private static void BuildTypeName(StringBuilder builder, NameCache cache, ulong moduleId, uint classToken, TypeFormat typeFormat) { var typeNames = new Stack(); - uint currentToken = token; + uint currentToken = classToken; while (currentToken != 0 && cache.TokenData.TryGetValue(new ModuleScopedToken(moduleId, currentToken), out TokenData? tokenData)) { string typeName = tokenData.Name; diff --git a/src/Microsoft.Diagnostics.Monitoring.WebApi/Stacks/NameIdentificationEvents.cs b/src/Microsoft.Diagnostics.Monitoring.WebApi/Stacks/NameIdentificationEvents.cs index 5991b064d66..91394002118 100644 --- a/src/Microsoft.Diagnostics.Monitoring.WebApi/Stacks/NameIdentificationEvents.cs +++ b/src/Microsoft.Diagnostics.Monitoring.WebApi/Stacks/NameIdentificationEvents.cs @@ -12,12 +12,13 @@ internal static class NameIdentificationEvents public static class FunctionDescPayloads { public const int FunctionId = 0; - public const int ClassId = 1; - public const int ClassToken = 2; - public const int ModuleId = 3; - public const int Name = 4; - public const int TypeArgs = 5; - public const int ParameterTypes = 6; + public const int MethodToken = 1; + public const int ClassId = 2; + public const int ClassToken = 3; + public const int ModuleId = 4; + public const int Name = 5; + public const int TypeArgs = 6; + public const int ParameterTypes = 7; } public static class ClassDescPayloads @@ -32,7 +33,8 @@ public static class ClassDescPayloads public static class ModuleDescPayloads { public const int ModuleId = 0; - public const int Name = 1; + public const int ModuleVersionId = 1; + public const int Name = 2; } public static class TokenDescPayloads diff --git a/src/Microsoft.Diagnostics.Monitoring.WebApi/Utilities/StackUtilities.cs b/src/Microsoft.Diagnostics.Monitoring.WebApi/Utilities/StackUtilities.cs index 269b2a55dad..c20962c5fad 100644 --- a/src/Microsoft.Diagnostics.Monitoring.WebApi/Utilities/StackUtilities.cs +++ b/src/Microsoft.Diagnostics.Monitoring.WebApi/Utilities/StackUtilities.cs @@ -48,9 +48,11 @@ internal static Models.CallStackFrame CreateFrameModel(CallStackFrame frame, Nam { TypeName = NameFormatter.UnknownClass, MethodName = StacksFormatter.UnknownFunction, + MethodToken = 0, //TODO Bring this back once we have a useful offset value //Offset = frame.Offset, - ModuleName = NameFormatter.UnknownModule + ModuleName = NameFormatter.UnknownModule, + ModuleVersionId = Guid.Empty }; if (frame.FunctionId == 0) { @@ -60,8 +62,14 @@ internal static Models.CallStackFrame CreateFrameModel(CallStackFrame frame, Nam } else if (cache.FunctionData.TryGetValue(frame.FunctionId, out FunctionData functionData)) { + frameModel.MethodToken = functionData.MethodToken; frameModel.ModuleName = NameFormatter.GetModuleName(cache, functionData.ModuleId); + if (cache.ModuleData.TryGetValue(functionData.ModuleId, out ModuleData moduleData)) + { + frameModel.ModuleVersionId = moduleData.ModuleVersionId; + } + builder.Clear(); builder.Append(functionData.Name); diff --git a/src/Profilers/CommonMonitorProfiler/CommonUtilities/ClrData.h b/src/Profilers/CommonMonitorProfiler/CommonUtilities/ClrData.h index 2945daa412d..c243c31a63c 100644 --- a/src/Profilers/CommonMonitorProfiler/CommonUtilities/ClrData.h +++ b/src/Profilers/CommonMonitorProfiler/CommonUtilities/ClrData.h @@ -11,15 +11,17 @@ class ModuleData { public: - ModuleData(tstring&& name) : - _moduleName(name) + ModuleData(tstring&& name, GUID mvid) : + _moduleName(name), _mvid(mvid) { } const tstring& GetName() const { return _moduleName; } + const GUID GetMvid() const { return _mvid; } private: tstring _moduleName; + GUID _mvid; }; enum class ClassFlags : UINT32 diff --git a/src/Profilers/CommonMonitorProfiler/CommonUtilities/NameCache.cpp b/src/Profilers/CommonMonitorProfiler/CommonUtilities/NameCache.cpp index ee793687b8f..dd0f99ab3e1 100644 --- a/src/Profilers/CommonMonitorProfiler/CommonUtilities/NameCache.cpp +++ b/src/Profilers/CommonMonitorProfiler/CommonUtilities/NameCache.cpp @@ -40,9 +40,9 @@ bool NameCache::TryGetTokenData(ModuleID modId, mdTypeDef token, std::shared_ptr return false; } -void NameCache::AddModuleData(ModuleID moduleId, tstring&& name) +void NameCache::AddModuleData(ModuleID moduleId, tstring&& name, GUID mvid) { - _moduleNames.emplace(moduleId, std::make_shared(std::move(name))); + _moduleNames.emplace(moduleId, std::make_shared(std::move(name), mvid)); } HRESULT NameCache::GetFullyQualifiedName(FunctionID id, tstring& name) diff --git a/src/Profilers/CommonMonitorProfiler/CommonUtilities/NameCache.h b/src/Profilers/CommonMonitorProfiler/CommonUtilities/NameCache.h index a895ed3f6a7..d1549d071bc 100644 --- a/src/Profilers/CommonMonitorProfiler/CommonUtilities/NameCache.h +++ b/src/Profilers/CommonMonitorProfiler/CommonUtilities/NameCache.h @@ -24,7 +24,7 @@ class NameCache bool TryGetModuleData(ModuleID id, std::shared_ptr& data); bool TryGetTokenData(ModuleID modId, mdTypeDef token, std::shared_ptr& data); - void AddModuleData(ModuleID moduleId, tstring&& name); + void AddModuleData(ModuleID moduleId, tstring&& name, GUID mvid); void AddFunctionData(ModuleID moduleId, FunctionID id, tstring&& name, ClassID parent, mdToken methodToken, mdTypeDef parentToken, ClassID* typeArgs, int typeArgsCount); void AddClassData(ModuleID moduleId, ClassID id, mdTypeDef typeDef, ClassFlags flags, ClassID* typeArgs, int typeArgsCount); void AddTokenData(ModuleID moduleId, mdTypeDef typeDef, mdTypeDef outerToken, tstring&& name, tstring&& Namespace); diff --git a/src/Profilers/CommonMonitorProfiler/CommonUtilities/TypeNameUtilities.cpp b/src/Profilers/CommonMonitorProfiler/CommonUtilities/TypeNameUtilities.cpp index 66afb44f502..647cdc10f99 100644 --- a/src/Profilers/CommonMonitorProfiler/CommonUtilities/TypeNameUtilities.cpp +++ b/src/Profilers/CommonMonitorProfiler/CommonUtilities/TypeNameUtilities.cpp @@ -244,18 +244,20 @@ HRESULT TypeNameUtilities::GetModuleInfo(NameCache& nameCache, ModuleID moduleId return S_OK; } + ComPtr pIMDImport; + IfFailRet(_profilerInfo->GetModuleMetaData(moduleId, + ofRead, + IID_IMetaDataImport, + (IUnknown**)&pIMDImport)); + WCHAR moduleFullName[256]; ULONG nameLength = 0; - AssemblyID assemblyID; - - IfFailRet(_profilerInfo->GetModuleInfo(moduleId, - nullptr, + GUID mvid = {0}; + IfFailRet(pIMDImport->GetScopeProps( + moduleFullName, 256, &nameLength, - moduleFullName, - &assemblyID)); - - WCHAR* ptr = nullptr; + &mvid)); int pathSeparatorIndex = nameLength - 1; while (pathSeparatorIndex >= 0) @@ -277,7 +279,7 @@ HRESULT TypeNameUtilities::GetModuleInfo(NameCache& nameCache, ModuleID moduleId moduleName = tstring(moduleFullName, pathSeparatorIndex + 1, nameLength - pathSeparatorIndex - 1); } - nameCache.AddModuleData(moduleId, std::move(moduleName)); + nameCache.AddModuleData(moduleId, std::move(moduleName), mvid); return S_OK; } diff --git a/src/Profilers/CommonMonitorProfiler/EventProvider/EventTypeMapping.h b/src/Profilers/CommonMonitorProfiler/EventProvider/EventTypeMapping.h index 567cdb84cab..922bea98dbe 100644 --- a/src/Profilers/CommonMonitorProfiler/EventProvider/EventTypeMapping.h +++ b/src/Profilers/CommonMonitorProfiler/EventProvider/EventTypeMapping.h @@ -59,6 +59,17 @@ class EventTypeMapping } }; +template<> +class EventTypeMapping +{ +public: + void GetType(COR_PRF_EVENTPIPE_PARAM_DESC& descriptor) + { + descriptor.type = COR_PRF_EVENTPIPE_GUID; + descriptor.elementType = 0; + } +}; + template<> class EventTypeMapping> { diff --git a/src/Profilers/CommonMonitorProfiler/EventProvider/ProfilerEvent.h b/src/Profilers/CommonMonitorProfiler/EventProvider/ProfilerEvent.h index d07f9110e49..037b98a2284 100644 --- a/src/Profilers/CommonMonitorProfiler/EventProvider/ProfilerEvent.h +++ b/src/Profilers/CommonMonitorProfiler/EventProvider/ProfilerEvent.h @@ -43,6 +43,9 @@ class ProfilerEvent template HRESULT WritePayload(COR_PRF_EVENT_DATA* data, const tstring& first, TArgs... rest); + template + HRESULT WritePayload(COR_PRF_EVENT_DATA* data, const GUID& first, TArgs... rest); + template HRESULT WritePayload(COR_PRF_EVENT_DATA* data, const std::vector& first, TArgs... rest); @@ -140,6 +143,33 @@ HRESULT ProfilerEvent::WritePayload(COR_PRF_EVENT_DATA* data, const tst return WritePayload(data, rest...); } +template +template +HRESULT ProfilerEvent::WritePayload(COR_PRF_EVENT_DATA* data, const GUID& first, TArgs... rest) +{ + // Manually copy the GUID into a buffer and pass the buffer address. + // We can't pass the GUID address directly (or use sizeof(GUID)) because the GUID may have padding between its different data segments. + const int GUID_FLAT_SIZE = sizeof(INT32) + sizeof(INT16) + sizeof(INT16) + sizeof(INT64); + static_assert(GUID_FLAT_SIZE == 128 / 8, "Incorrect flat GUID size."); + + BYTE buffer[GUID_FLAT_SIZE] = {0}; + int offset = 0; + + memcpy(&buffer[offset], &first.Data1, sizeof(INT32)); + offset += sizeof(INT32); + memcpy(&buffer[offset], &first.Data2, sizeof(INT16)); + offset += sizeof(INT16); + memcpy(&buffer[offset], &first.Data3, sizeof(INT16)); + offset += sizeof(INT16); + memcpy(&buffer[offset], first.Data4, sizeof(INT64)); + + data[index].ptr = reinterpret_cast(buffer); + data[index].size = static_cast(GUID_FLAT_SIZE); + data[index].reserved = 0; + + return WritePayload(data, rest...); +} + template template std::vector ProfilerEvent::GetEventBuffer(const std::vector& data) diff --git a/src/Profilers/MonitorProfiler/Stacks/StacksEventProvider.cpp b/src/Profilers/MonitorProfiler/Stacks/StacksEventProvider.cpp index d3f69b4599a..5f148ee4520 100644 --- a/src/Profilers/MonitorProfiler/Stacks/StacksEventProvider.cpp +++ b/src/Profilers/MonitorProfiler/Stacks/StacksEventProvider.cpp @@ -53,6 +53,7 @@ HRESULT StacksEventProvider::WriteFunctionData(FunctionID functionId, const Func { return _functionEvent->WritePayload( static_cast(functionId), + functionData.GetMethodToken(), static_cast(functionData.GetClass()), functionData.GetClassToken(), static_cast(functionData.GetModuleId()), @@ -63,7 +64,10 @@ HRESULT StacksEventProvider::WriteFunctionData(FunctionID functionId, const Func HRESULT StacksEventProvider::WriteModuleData(ModuleID moduleId, const ModuleData& moduleData) { - return _moduleEvent->WritePayload(moduleId, moduleData.GetName()); + return _moduleEvent->WritePayload( + moduleId, + moduleData.GetMvid(), + moduleData.GetName()); } HRESULT StacksEventProvider::WriteTokenData(ModuleID moduleId, mdTypeDef typeDef, const TokenData& tokenData) diff --git a/src/Profilers/MonitorProfiler/Stacks/StacksEventProvider.h b/src/Profilers/MonitorProfiler/Stacks/StacksEventProvider.h index 4a66cfdc0d1..e2d6af6ce45 100644 --- a/src/Profilers/MonitorProfiler/Stacks/StacksEventProvider.h +++ b/src/Profilers/MonitorProfiler/Stacks/StacksEventProvider.h @@ -42,8 +42,8 @@ class StacksEventProvider std::unique_ptr, std::vector>> _callstackEvent; //Note we will either send a ClassId or a ClassToken. For Shared generic functions, there is no ClassID. - const WCHAR* FunctionPayloads[7] = { _T("FunctionId"), _T("ClassId"), _T("ClassToken"), _T("ModuleId"), _T("Name"), _T("TypeArgs"), _T("ParameterTypes") }; - std::unique_ptr, std::vector>> _functionEvent; + const WCHAR* FunctionPayloads[8] = { _T("FunctionId"), _T("MethodToken"), _T("ClassId"), _T("ClassToken"), _T("ModuleId"), _T("Name"), _T("TypeArgs"), _T("ParameterTypes") }; + std::unique_ptr, std::vector>> _functionEvent; //We cannot retrieve detailed information for some ClassIds. Flags is used to indicate these conditions. const WCHAR* ClassPayloads[5] = { _T("ClassId"), _T("ModuleId"), _T("Token"), _T("Flags"), _T("TypeArgs") }; @@ -52,8 +52,8 @@ class StacksEventProvider const WCHAR* TokenPayloads[5] = { _T("ModuleId"), _T("Token"), _T("OuterToken"), _T("Name"), _T("Namespace") }; std::unique_ptr> _tokenEvent; - const WCHAR* ModulePayloads[2] = { _T("ModuleId"), _T("Name") }; - std::unique_ptr> _moduleEvent; + const WCHAR* ModulePayloads[3] = { _T("ModuleId"), _T("ModuleVersionId"), _T("Name") }; + std::unique_ptr> _moduleEvent; //TODO Once ProfilerEvent supports it, use an event with no payload. const WCHAR* EndPayloads[1] = { _T("Unused") }; diff --git a/src/Tests/Microsoft.Diagnostics.Monitoring.AzureBlobStorageTests.UnitTests/AzureBlobEgressProviderTests.cs b/src/Tests/Microsoft.Diagnostics.Monitoring.AzureBlobStorageTests.UnitTests/AzureBlobEgressProviderTests.cs index ecc99cce7e9..6636862dcee 100644 --- a/src/Tests/Microsoft.Diagnostics.Monitoring.AzureBlobStorageTests.UnitTests/AzureBlobEgressProviderTests.cs +++ b/src/Tests/Microsoft.Diagnostics.Monitoring.AzureBlobStorageTests.UnitTests/AzureBlobEgressProviderTests.cs @@ -234,7 +234,7 @@ public async Task AzureBlobEgress_DoesNotThrowWhen_QueueDoesNotExistAndUsingRest Assert.Empty(messages); } - [ConditionalFact(Timeout = EgressUnitTestTimeoutMs)] + [Fact] public void AzureBlobEgress_DefaultCredentials() { // These are auth methods we know about. If this test fails, it means a new auth method was added and we need to update the test. diff --git a/src/Tests/Microsoft.Diagnostics.Monitoring.HostingStartup.UnitTests/Microsoft.Diagnostics.Monitoring.HostingStartup.UnitTests.csproj b/src/Tests/Microsoft.Diagnostics.Monitoring.HostingStartup.UnitTests/Microsoft.Diagnostics.Monitoring.HostingStartup.UnitTests.csproj deleted file mode 100644 index b8488616b15..00000000000 --- a/src/Tests/Microsoft.Diagnostics.Monitoring.HostingStartup.UnitTests/Microsoft.Diagnostics.Monitoring.HostingStartup.UnitTests.csproj +++ /dev/null @@ -1,12 +0,0 @@ - - - - $(TestTargetFrameworks) - True - - - - - - - diff --git a/src/Tests/Microsoft.Diagnostics.Monitoring.HostingStartup.UnitTests/ParameterCapturing/MethodTemplateStringTests.cs b/src/Tests/Microsoft.Diagnostics.Monitoring.HostingStartup.UnitTests/ParameterCapturing/MethodTemplateStringTests.cs deleted file mode 100644 index ef38ab3c30c..00000000000 --- a/src/Tests/Microsoft.Diagnostics.Monitoring.HostingStartup.UnitTests/ParameterCapturing/MethodTemplateStringTests.cs +++ /dev/null @@ -1,43 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -using Microsoft.Diagnostics.Monitoring.HostingStartup.ParameterCapturing; -using Microsoft.Diagnostics.Monitoring.TestCommon; -using SampleMethods; -using System; -using System.Reflection; -using Xunit; - -namespace Microsoft.Diagnostics.Monitoring.HostingStartup.UnitTests.ParameterCapturing -{ - [TargetFrameworkMonikerTrait(TargetFrameworkMonikerExtensions.CurrentTargetFrameworkMoniker)] - public class MethodTemplateStringTests - { - [Theory] - [InlineData(typeof(TestMethodSignatures), nameof(TestMethodSignatures.ImplicitThis), "SampleMethods.TestMethodSignatures.ImplicitThis(this: {this})")] - [InlineData(typeof(StaticTestMethodSignatures), nameof(StaticTestMethodSignatures.Arrays), "SampleMethods.StaticTestMethodSignatures.Arrays(intArray: {intArray}, multidimensionalArray: {multidimensionalArray})")] - [InlineData(typeof(StaticTestMethodSignatures), nameof(StaticTestMethodSignatures.Delegate), "SampleMethods.StaticTestMethodSignatures.Delegate(func: {func})")] - [InlineData(typeof(StaticTestMethodSignatures), nameof(StaticTestMethodSignatures.InParam), "SampleMethods.StaticTestMethodSignatures.InParam(in i: {i})")] - [InlineData(typeof(StaticTestMethodSignatures), nameof(StaticTestMethodSignatures.OutParam), "SampleMethods.StaticTestMethodSignatures.OutParam(out i: {i})")] - [InlineData(typeof(StaticTestMethodSignatures), nameof(StaticTestMethodSignatures.RefParam), "SampleMethods.StaticTestMethodSignatures.RefParam(ref i: {i})")] - [InlineData(typeof(StaticTestMethodSignatures), nameof(StaticTestMethodSignatures.RefStruct), "SampleMethods.StaticTestMethodSignatures.RefStruct(ref myRefStruct: {myRefStruct})")] - [InlineData(typeof(StaticTestMethodSignatures), nameof(StaticTestMethodSignatures.GenericParameters), "SampleMethods.StaticTestMethodSignatures.GenericParameters(t: {t}, k: {k})")] - [InlineData(typeof(StaticTestMethodSignatures), nameof(StaticTestMethodSignatures.VarArgs), "SampleMethods.StaticTestMethodSignatures.VarArgs(b: {b}, myInts: {myInts})")] - [InlineData(typeof(StaticTestMethodSignatures), nameof(StaticTestMethodSignatures.Unicode_ΦΨ), "SampleMethods.StaticTestMethodSignatures.Unicode_ΦΨ(δ: {δ})")] - [InlineData(typeof(StaticTestMethodSignatures.SampleNestedStruct), nameof(StaticTestMethodSignatures.SampleNestedStruct.DoWork), "SampleMethods.StaticTestMethodSignatures+SampleNestedStruct.DoWork(this: {this}, i: {i})")] - public void MethodTemplateString(Type declaringType, string methodName, string templateString) - { - // Arrange - MethodInfo method = declaringType.GetMethod(methodName); - Assert.NotNull(method); - - // Act - string actualTemplateString = new MethodTemplateString(method).Template; - - // Assert - Assert.NotNull(actualTemplateString); - actualTemplateString = actualTemplateString.ReplaceLineEndings("").Replace("\t", ""); - Assert.Equal(templateString, actualTemplateString); - } - } -} diff --git a/src/Tests/Microsoft.Diagnostics.Monitoring.HostingStartup.UnitTests/ParameterCapturing/ParameterCapturingLoggerTests.cs b/src/Tests/Microsoft.Diagnostics.Monitoring.HostingStartup.UnitTests/ParameterCapturing/ParameterCapturingLoggerTests.cs deleted file mode 100644 index 1d897e48cc8..00000000000 --- a/src/Tests/Microsoft.Diagnostics.Monitoring.HostingStartup.UnitTests/ParameterCapturing/ParameterCapturingLoggerTests.cs +++ /dev/null @@ -1,102 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -using Microsoft.Diagnostics.Monitoring.HostingStartup.ParameterCapturing; -using Microsoft.Diagnostics.Monitoring.HostingStartup.ParameterCapturing.FunctionProbes; -using Microsoft.Diagnostics.Monitoring.TestCommon; -using Microsoft.Extensions.Logging; -using System; -using System.Collections.Generic; -using System.Diagnostics; -using System.Reflection; -using Xunit; - -namespace Microsoft.Diagnostics.Monitoring.HostingStartup.UnitTests.ParameterCapturing -{ - [TargetFrameworkMonikerTrait(TargetFrameworkMonikerExtensions.CurrentTargetFrameworkMoniker)] - public class ParameterCapturingLoggerTests - { - private readonly MethodInfo _testMethod = typeof(ParameterCapturingLoggerTests).GetMethod(nameof(TestMethod), BindingFlags.Static | BindingFlags.NonPublic); - private static void TestMethod() { } - - [Theory] - [InlineData(ParameterCaptureMode.Inline, typeof(DotnetMonitor.ParameterCapture.UserCode))] - [InlineData(ParameterCaptureMode.Background, typeof(DotnetMonitor.ParameterCapture.SystemCode))] - internal void LoggingCategories(ParameterCaptureMode mode, Type categoryType) - { - // Arrange & Act - IList entries = TestCore(mode); - - // Assert - LogRecordEntry entry = Assert.Single(entries); - Assert.Equal(categoryType.FullName, entry.Category); - - return; - } - - [Theory] - [InlineData(ParameterCaptureMode.Inline)] - [InlineData(ParameterCaptureMode.Background)] - internal void ScopeData(ParameterCaptureMode mode) - { - // Arrange - using Activity loggingActivity = new("ScopeDataTest"); - Activity.Current = loggingActivity; - loggingActivity.Start(); - - Dictionary expectedScope = new() - { - { ParameterCapturingLogger.Scopes.ActivityId, loggingActivity.Id }, - { ParameterCapturingLogger.Scopes.ActivityIdFormat, loggingActivity.IdFormat }, - { ParameterCapturingLogger.Scopes.ThreadId, Environment.CurrentManagedThreadId }, - { ParameterCapturingLogger.Scopes.CaptureSite.MethodName, _testMethod.Name }, - { ParameterCapturingLogger.Scopes.CaptureSite.TypeName, _testMethod.DeclaringType.FullName }, - { ParameterCapturingLogger.Scopes.CaptureSite.ModuleName, _testMethod.Module.Name } - }; - - // Act - IList entries = TestCore(mode); - - // Assert - LogRecordEntry entry = Assert.Single(entries); - IReadOnlyList> rawScope = Assert.Single(entry.Scopes); - - Dictionary scopeData = new(rawScope); - - // Validate variant data first. - - // Timestamp - Assert.True(scopeData.Remove(ParameterCapturingLogger.Scopes.TimeStamp, out object rawTimeStamp)); - string timeStampStr = Assert.IsType(rawTimeStamp); - Assert.True(DateTime.TryParse(timeStampStr, out _)); - - // Static data - Assert.Equal(expectedScope, scopeData); - - return; - } - - private IList TestCore(ParameterCaptureMode mode) - { - Assert.NotNull(_testMethod); - - // Arrange - LogRecord logRecord = new(); - ILoggerFactory factory = LoggerFactory.Create(builder => builder.AddProvider(new TestLoggerProvider(logRecord))); - - MethodTemplateString message = new(_testMethod); - - // Act - using (ParameterCapturingLogger logger = new(factory.CreateLogger(), factory.CreateLogger())) - { - logger.Log(mode, message, Array.Empty()); - - // Force the logger to drain the background queue before we dispose it. - logger.Complete(); - } - - // Assert - return logRecord.Events; - } - } -} diff --git a/src/Tests/Microsoft.Diagnostics.Monitoring.StartupHook.UnitTests/BackgroundService/BackgroundServiceTests.cs b/src/Tests/Microsoft.Diagnostics.Monitoring.StartupHook.UnitTests/BackgroundService/BackgroundServiceTests.cs new file mode 100644 index 00000000000..bd4be15f272 --- /dev/null +++ b/src/Tests/Microsoft.Diagnostics.Monitoring.StartupHook.UnitTests/BackgroundService/BackgroundServiceTests.cs @@ -0,0 +1,129 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +using Microsoft.Diagnostics.Monitoring.TestCommon; +using System; +using System.Threading; +using System.Threading.Tasks; +using Xunit; + +namespace Microsoft.Diagnostics.Monitoring.StartupHook +{ + [TargetFrameworkMonikerTrait(TargetFrameworkMonikerExtensions.CurrentTargetFrameworkMoniker)] + public sealed class BackgroundServiceTests + { + [Fact] + public void ConstructionWorks() + { + using BackgroundService _ = new MockBackgroundService(); + } + + [Fact] + public async Task Start_RunsBackgroundTask() + { + // Arrange + using CancellationTokenSource cts = new(CommonTestTimeouts.GeneralTimeout); + using MockBackgroundService service = new MockBackgroundService(); + + // Act + service.Start(); + + // Assert + await service.BackgroundTaskStarted.Task.WaitAsync(cts.Token); + } + + [Fact] + public async Task Stop_TriggersCancellation() + { + // Arrange + using CancellationTokenSource cts = new(CommonTestTimeouts.GeneralTimeout); + using MockBackgroundService service = new MockBackgroundService(async (CancellationToken stoppingToken) => + { + await Task.Delay(Timeout.Infinite, stoppingToken); + }); + + // Act + service.Start(); + await service.BackgroundTaskStarted.Task.WaitAsync(cts.Token); + service.Stop(); + + // Assert + Assert.NotNull(service.ExecutingTask); + await Assert.ThrowsAnyAsync(() => service.ExecutingTask); + } + + [Fact] + public async Task Stop_WaitsForTheBackgroundTask() + { + // Arrange + using CancellationTokenSource cts = new(CommonTestTimeouts.GeneralTimeout); + object lockObj = new(); + bool stopCompleted = false; + bool taskCompleted = false; + TaskCompletionSource backgroundTaskCompletion = new(TaskCreationOptions.RunContinuationsAsynchronously); + TaskCompletionSource beforeStopCompletion = new(TaskCreationOptions.RunContinuationsAsynchronously); + + MockBackgroundService service = new MockBackgroundService(async _ => + { + await backgroundTaskCompletion.Task.WaitAsync(cts.Token); + lock (lockObj) + { + Assert.False(stopCompleted, "Stop completed before the background task."); + taskCompleted = true; + } + }); + + // Act + service.Start(); + await service.BackgroundTaskStarted.Task.WaitAsync(cts.Token); + + Task stopTask = Task.Run(async () => + { + await Task.Yield(); + beforeStopCompletion.SetResult(); + service.Stop(); + + lock (lockObj) + { + Assert.True(taskCompleted, "Stop completed before the background task."); + stopCompleted = true; + } + }); + + await beforeStopCompletion.Task.WaitAsync(cts.Token); + // Wait a bit to ensure Stop() is waiting for the background task to complete + await Task.Delay(TimeSpan.FromMilliseconds(100)); + + backgroundTaskCompletion.SetResult(); + + await stopTask.WaitAsync(cts.Token); + + // Assert + Assert.NotNull(service.ExecutingTask); + Assert.False(service.ExecutingTask.IsFaulted); + } + + [Fact] + public async Task WorkerThrows_TaskExceptionIsCaptured() + { + // Arrange + using CancellationTokenSource cts = new(CommonTestTimeouts.GeneralTimeout); + MockBackgroundService service = new MockBackgroundService(async _ => + { + await Task.Yield(); + throw new NotImplementedException(); + }); + + // Act + service.Start(); + await service.BackgroundTaskStarted.Task.WaitAsync(cts.Token); + + service.Stop(); + service.Dispose(); + + // Assert + Assert.NotNull(service.ExecutingTask); + await Assert.ThrowsAsync(() => service.ExecutingTask); + } + } +} diff --git a/src/Tests/Microsoft.Diagnostics.Monitoring.StartupHook.UnitTests/BackgroundService/MockBackgroundService.cs b/src/Tests/Microsoft.Diagnostics.Monitoring.StartupHook.UnitTests/BackgroundService/MockBackgroundService.cs new file mode 100644 index 00000000000..b750d6a4247 --- /dev/null +++ b/src/Tests/Microsoft.Diagnostics.Monitoring.StartupHook.UnitTests/BackgroundService/MockBackgroundService.cs @@ -0,0 +1,38 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +using System; +using System.Threading; +using System.Threading.Tasks; + +namespace Microsoft.Diagnostics.Monitoring.StartupHook +{ + internal sealed class MockBackgroundService : BackgroundService, IDisposable + { + private readonly Func _backgroundFunc; + + public MockBackgroundService() + { + _backgroundFunc = _ => Task.CompletedTask; + } + + public MockBackgroundService(Func backgroundFunc) + { + _backgroundFunc = backgroundFunc; + } + + protected override async Task ExecuteAsync(CancellationToken stoppingToken) + { + BackgroundTaskStarted.SetResult(); + + await _backgroundFunc(stoppingToken); + } + + public override void Dispose() + { + base.Dispose(); + } + + public TaskCompletionSource BackgroundTaskStarted { get; } = new(TaskCreationOptions.RunContinuationsAsynchronously); + } +} diff --git a/src/Tests/Microsoft.Diagnostics.Monitoring.StartupHook.UnitTests/Exceptions/Eventing/ExceptionsEventListener.cs b/src/Tests/Microsoft.Diagnostics.Monitoring.StartupHook.UnitTests/Exceptions/Eventing/ExceptionsEventListener.cs index 3d1458faffb..c9444ab823d 100644 --- a/src/Tests/Microsoft.Diagnostics.Monitoring.StartupHook.UnitTests/Exceptions/Eventing/ExceptionsEventListener.cs +++ b/src/Tests/Microsoft.Diagnostics.Monitoring.StartupHook.UnitTests/Exceptions/Eventing/ExceptionsEventListener.cs @@ -68,6 +68,7 @@ protected override void OnEventWritten(EventWrittenEventArgs eventData) ToUInt64(eventData.Payload[NameIdentificationEvents.FunctionDescPayloads.FunctionId]), new FunctionData( ToString(eventData.Payload[NameIdentificationEvents.FunctionDescPayloads.Name]), + ToUInt32(eventData.Payload[NameIdentificationEvents.FunctionDescPayloads.MethodToken]), ToUInt64(eventData.Payload[NameIdentificationEvents.FunctionDescPayloads.ClassId]), ToUInt32(eventData.Payload[NameIdentificationEvents.FunctionDescPayloads.ClassToken]), ToUInt64(eventData.Payload[NameIdentificationEvents.FunctionDescPayloads.ModuleId]), @@ -78,7 +79,9 @@ protected override void OnEventWritten(EventWrittenEventArgs eventData) NameCache.ModuleData.TryAdd( ToUInt64(eventData.Payload[NameIdentificationEvents.ModuleDescPayloads.ModuleId]), new ModuleData( - ToString(eventData.Payload[NameIdentificationEvents.ModuleDescPayloads.Name]))); + ToString(eventData.Payload[NameIdentificationEvents.ModuleDescPayloads.Name]), + ToGuid(eventData.Payload[NameIdentificationEvents.ModuleDescPayloads.ModuleVersionId]) + )); break; case ExceptionEvents.EventIds.StackFrameDescription: StackFrameIdentifiers.TryAdd( @@ -104,6 +107,11 @@ protected override void OnEventWritten(EventWrittenEventArgs eventData) } } + private static Guid ToGuid(object? value) + { + return ToType(value); + } + private static int ToInt32(object? value) { return ToType(value); diff --git a/src/Tests/Microsoft.Diagnostics.Monitoring.StartupHook.UnitTests/Exceptions/Eventing/ExceptionsEventSourceTests.cs b/src/Tests/Microsoft.Diagnostics.Monitoring.StartupHook.UnitTests/Exceptions/Eventing/ExceptionsEventSourceTests.cs index ccf242c404a..d2f156fb57d 100644 --- a/src/Tests/Microsoft.Diagnostics.Monitoring.StartupHook.UnitTests/Exceptions/Eventing/ExceptionsEventSourceTests.cs +++ b/src/Tests/Microsoft.Diagnostics.Monitoring.StartupHook.UnitTests/Exceptions/Eventing/ExceptionsEventSourceTests.cs @@ -145,6 +145,58 @@ public void ExceptionsEventSource_WriteStackFrame_Event(ulong id, ulong methodId Assert.Equal(ilOffset, frameIdentifier.ILOffset); } + [Theory] + [InlineData(0, 0, 0, 0, 0, "", new ulong[0], new ulong[0])] + [InlineData(1, 100663639, 128, 256, 512, "ThrowObjectDisposedException", new ulong[1] { 1024 }, new ulong[2] { 2048, 4096 })] + public void ExceptionsEventSource_WriteFunction_Event( + ulong functionId, + uint methodToken, + ulong classId, + uint classToken, + ulong moduleId, + string name, + ulong[] typeArgs, + ulong[] parameterTypes) + { + using ExceptionsEventSource source = new(); + + using ExceptionsEventListener listener = new(); + listener.EnableEvents(source, EventLevel.Informational); + + source.FunctionDescription(functionId, methodToken, classId, classToken, moduleId, name, typeArgs, parameterTypes); + + Assert.True(listener.NameCache.FunctionData.TryGetValue(functionId, out FunctionData? function)); + Assert.Equal(methodToken, function.MethodToken); + Assert.Equal(classId, function.ParentClass); + Assert.Equal(classToken, function.ParentClassToken); + Assert.Equal(moduleId, function.ModuleId); + Assert.Equal(name, function.Name); + // We would normally expect the following to return an array of the stack frame IDs + // but in-process listener doesn't decode non-byte arrays correctly. + Assert.Equal(Array.Empty(), function.TypeArgs); + Assert.Equal(Array.Empty(), function.ParameterTypes); + } + + [Theory] + [InlineData(0, "00000000-0000-0000-0000-000000000000", "")] + [InlineData(1, NonEmptyGuidString, "Module")] + public void ExceptionsEventSource_WriteModule_Event( + ulong moduleId, + Guid moduleVersionId, + string name) + { + using ExceptionsEventSource source = new(); + + using ExceptionsEventListener listener = new(); + listener.EnableEvents(source, EventLevel.Informational); + + source.ModuleDescription(moduleId, moduleVersionId, name); + + Assert.True(listener.NameCache.ModuleData.TryGetValue(moduleId, out ModuleData? module)); + Assert.Equal(moduleVersionId, module.ModuleVersionId); + Assert.Equal(name, module.Name); + } + private static string CoalesceNull(string? value) { return value ?? ExceptionsEventListener.NullValue; diff --git a/src/Tests/Microsoft.Diagnostics.Monitoring.StartupHook.UnitTests/Exceptions/Identification/ExceptionGroupIdentifierCacheTests.cs b/src/Tests/Microsoft.Diagnostics.Monitoring.StartupHook.UnitTests/Exceptions/Identification/ExceptionGroupIdentifierCacheTests.cs index 798086c179d..9a5917eb2b2 100644 --- a/src/Tests/Microsoft.Diagnostics.Monitoring.StartupHook.UnitTests/Exceptions/Identification/ExceptionGroupIdentifierCacheTests.cs +++ b/src/Tests/Microsoft.Diagnostics.Monitoring.StartupHook.UnitTests/Exceptions/Identification/ExceptionGroupIdentifierCacheTests.cs @@ -178,7 +178,7 @@ public void ExceptionGroupIdentifierCache_ThrownException() // Validate throwing method remaining properties Assert.Equal(nameof(ExceptionGroupIdentifierCache_ThrownException), throwingMethodData.Name); Assert.NotEqual(InvalidId, throwingMethodData.ParentClass); - Assert.NotEqual(InvalidToken, throwingMethodData.ParentToken); + Assert.NotEqual(InvalidToken, throwingMethodData.ParentClassToken); Assert.Empty(throwingMethodData.TypeArgs); // Validate stack frame data diff --git a/src/Tests/Microsoft.Diagnostics.Monitoring.HostingStartup.UnitTests/ParameterCapturing/Boxing/BoxingInstructionsTests.cs b/src/Tests/Microsoft.Diagnostics.Monitoring.StartupHook.UnitTests/ParameterCapturing/Boxing/BoxingInstructionsTests.cs similarity index 88% rename from src/Tests/Microsoft.Diagnostics.Monitoring.HostingStartup.UnitTests/ParameterCapturing/Boxing/BoxingInstructionsTests.cs rename to src/Tests/Microsoft.Diagnostics.Monitoring.StartupHook.UnitTests/ParameterCapturing/Boxing/BoxingInstructionsTests.cs index 9526804f721..122337297a1 100644 --- a/src/Tests/Microsoft.Diagnostics.Monitoring.HostingStartup.UnitTests/ParameterCapturing/Boxing/BoxingInstructionsTests.cs +++ b/src/Tests/Microsoft.Diagnostics.Monitoring.StartupHook.UnitTests/ParameterCapturing/Boxing/BoxingInstructionsTests.cs @@ -1,8 +1,8 @@ // Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. -using Microsoft.Diagnostics.Monitoring.HostingStartup.ParameterCapturing.Boxing; -using Microsoft.Diagnostics.Monitoring.HostingStartup.ParameterCapturing.FunctionProbes; +using Microsoft.Diagnostics.Monitoring.StartupHook.ParameterCapturing.Boxing; +using Microsoft.Diagnostics.Monitoring.StartupHook.ParameterCapturing.FunctionProbes; using Microsoft.Diagnostics.Monitoring.TestCommon; using SampleMethods; using System; @@ -10,7 +10,7 @@ using Xunit; using Xunit.Abstractions; -namespace Microsoft.Diagnostics.Monitoring.HostingStartup.UnitTests.ParameterCapturing.Boxing +namespace Microsoft.Diagnostics.Monitoring.StartupHook.UnitTests.ParameterCapturing.Boxing { [TargetFrameworkMonikerTrait(TargetFrameworkMonikerExtensions.CurrentTargetFrameworkMoniker)] public class BoxingInstructionsTests @@ -49,7 +49,8 @@ public BoxingInstructionsTests(ITestOutputHelper outputHelper) public void GetBoxingInstructions_Detects_UnsupportedParameters(Type declaringType, string methodName, params bool[] supported) { // Arrange - MethodInfo method = declaringType.GetMethod(methodName); + MethodInfo? method = declaringType.GetMethod(methodName); + Assert.NotNull(method); // Act bool[] supportedParameters = BoxingInstructions.AreParametersSupported(BoxingInstructions.GetBoxingInstructions(method)); @@ -62,7 +63,8 @@ public void GetBoxingInstructions_Detects_UnsupportedParameters(Type declaringTy public void GetBoxingInstructions_Handles_GenericParameters() { // Arrange - MethodInfo method = Type.GetType($"{nameof(SampleMethods)}.GenericTestMethodSignatures`2").GetMethod("GenericParameters"); + MethodInfo? method = Type.GetType($"{nameof(SampleMethods)}.GenericTestMethodSignatures`2")?.GetMethod("GenericParameters"); + Assert.NotNull(method); bool[] supported = new bool[] { true, true, true, true }; // Act @@ -90,7 +92,8 @@ public void GetBoxingInstructions_Handles_Primitives() SpecialCaseBoxingTypes.Single, SpecialCaseBoxingTypes.Double, ]; - MethodInfo method = typeof(StaticTestMethodSignatures).GetMethod(nameof(StaticTestMethodSignatures.Primitives)); + MethodInfo? method = typeof(StaticTestMethodSignatures).GetMethod(nameof(StaticTestMethodSignatures.Primitives)); + Assert.NotNull(method); // Act ParameterBoxingInstructions[] actualInstructions = BoxingInstructions.GetBoxingInstructions(method); @@ -108,7 +111,8 @@ public void GetBoxingInstructions_Handles_BuiltInReferenceTypes() SpecialCaseBoxingTypes.Object, SpecialCaseBoxingTypes.Object, ]; - MethodInfo method = typeof(StaticTestMethodSignatures).GetMethod(nameof(StaticTestMethodSignatures.BuiltInReferenceTypes)); + MethodInfo? method = typeof(StaticTestMethodSignatures).GetMethod(nameof(StaticTestMethodSignatures.BuiltInReferenceTypes)); + Assert.NotNull(method); // Act ParameterBoxingInstructions[] actualInstructions = BoxingInstructions.GetBoxingInstructions(method); @@ -140,14 +144,14 @@ public void GetBoxingInstructions_Handles_BuiltInReferenceTypes() [InlineData(typeof(StaticTestMethodSignatures), nameof(StaticTestMethodSignatures.VarArgs))] public void ReflectionAndSignatureDecoder_Contract_InSync(Type declaringType, string methodName) { - MethodInfo method = declaringType.GetMethod(methodName); + MethodInfo? method = declaringType.GetMethod(methodName); ReflectionAndSignatureDecoder_Contract_InSyncCore(method); } [Fact] public void ReflectionAndSignatureDecoder_Contract_Generics_InSync() { - MethodInfo method = Type.GetType($"{nameof(SampleMethods)}.GenericTestMethodSignatures`2").GetMethod("GenericParameters"); + MethodInfo? method = Type.GetType($"{nameof(SampleMethods)}.GenericTestMethodSignatures`2")?.GetMethod("GenericParameters"); ReflectionAndSignatureDecoder_Contract_InSyncCore(method); } @@ -155,13 +159,13 @@ public void ReflectionAndSignatureDecoder_Contract_Generics_InSync() /// Tests if GetBoxingInstructionsFromReflection is in sync with the signature decoder support for a given method's parameters. /// /// The method whose parameters to test. - private static void ReflectionAndSignatureDecoder_Contract_InSyncCore(MethodInfo method) + private static void ReflectionAndSignatureDecoder_Contract_InSyncCore(MethodInfo? method) { Assert.NotNull(method); ParameterInfo[] parameters = method.GetParameters(); - ParameterBoxingInstructions[] signatureDecoderInstructions = BoxingInstructions.GetAncillaryBoxingInstructionsFromMethodSignature(method); ; + ParameterBoxingInstructions[]? signatureDecoderInstructions = BoxingInstructions.GetAncillaryBoxingInstructionsFromMethodSignature(method); Assert.NotNull(signatureDecoderInstructions); Assert.Equal(parameters.Length, signatureDecoderInstructions.Length); @@ -174,7 +178,7 @@ private static void ReflectionAndSignatureDecoder_Contract_InSyncCore(MethodInfo // // // NOTE: The signature decoder may produce a superset of boxing instructions compared to what GetBoxingInstructionsFromReflection needs. - // This is okay as GetBoxingInstructionsFromReflection determines when to leverage the signature decoder. + // This is okay as GetBoxingInstructionsFromReflection determines when to leverage the signature decoder. // ParameterBoxingInstructions reflectionInstructions = BoxingInstructions.GetBoxingInstructionsFromReflection(method, parameters[i].ParameterType, out bool canUseSignatureDecoder); if (canUseSignatureDecoder) diff --git a/src/Tests/Microsoft.Diagnostics.Monitoring.HostingStartup.UnitTests/ParameterCapturing/Boxing/MethodDefinitionExtensionsTests.cs b/src/Tests/Microsoft.Diagnostics.Monitoring.StartupHook.UnitTests/ParameterCapturing/Boxing/MethodDefinitionExtensionsTests.cs similarity index 82% rename from src/Tests/Microsoft.Diagnostics.Monitoring.HostingStartup.UnitTests/ParameterCapturing/Boxing/MethodDefinitionExtensionsTests.cs rename to src/Tests/Microsoft.Diagnostics.Monitoring.StartupHook.UnitTests/ParameterCapturing/Boxing/MethodDefinitionExtensionsTests.cs index 459405fb657..101c54c9f23 100644 --- a/src/Tests/Microsoft.Diagnostics.Monitoring.HostingStartup.UnitTests/ParameterCapturing/Boxing/MethodDefinitionExtensionsTests.cs +++ b/src/Tests/Microsoft.Diagnostics.Monitoring.StartupHook.UnitTests/ParameterCapturing/Boxing/MethodDefinitionExtensionsTests.cs @@ -1,8 +1,8 @@ // Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. -using Microsoft.Diagnostics.Monitoring.HostingStartup.ParameterCapturing.Boxing; -using Microsoft.Diagnostics.Monitoring.HostingStartup.ParameterCapturing.FunctionProbes; +using Microsoft.Diagnostics.Monitoring.StartupHook.ParameterCapturing.Boxing; +using Microsoft.Diagnostics.Monitoring.StartupHook.ParameterCapturing.FunctionProbes; using Microsoft.Diagnostics.Monitoring.TestCommon; using SampleMethods; using System; @@ -11,7 +11,7 @@ using System.Reflection.Metadata; using Xunit; -namespace Microsoft.Diagnostics.Monitoring.HostingStartup.UnitTests.ParameterCapturing.Boxing +namespace Microsoft.Diagnostics.Monitoring.StartupHook.UnitTests.ParameterCapturing.Boxing { [TargetFrameworkMonikerTrait(TargetFrameworkMonikerExtensions.CurrentTargetFrameworkMoniker)] public class MethodDefinitionExtensionsTests @@ -21,14 +21,16 @@ public class MethodDefinitionExtensionsTests [InlineData(typeof(StaticTestMethodSignatures), nameof(StaticTestMethodSignatures.ValueType_TypeSpec), 6, 17)] public void GetParameterBoxingInstructions_Captures_MemoryRegion_ForTypeSpecs(Type declaringType, string methodName, params int[] parameterSignatureLengths) { - MethodInfo method = declaringType.GetMethod(methodName); + MethodInfo? method = declaringType.GetMethod(methodName); + Assert.NotNull(method); TestCore(method, parameterSignatureLengths); } [Fact] public void GetParameterBoxingInstructions_Captures_MemoryRegion_ForTypeGenerics() { - MethodInfo method = Type.GetType($"{nameof(SampleMethods)}.GenericTestMethodSignatures`2").GetMethod("GenericParameters"); + MethodInfo? method = Type.GetType($"{nameof(SampleMethods)}.GenericTestMethodSignatures`2")?.GetMethod("GenericParameters"); + Assert.NotNull(method); int[] parameterSignatureLengths = [2, 2, 2]; TestCore(method, parameterSignatureLengths); } diff --git a/src/Tests/Microsoft.Diagnostics.Monitoring.HostingStartup.UnitTests/ParameterCapturing/FunctionProbes/ProfilerAbiTests.cs b/src/Tests/Microsoft.Diagnostics.Monitoring.StartupHook.UnitTests/ParameterCapturing/FunctionProbes/ProfilerAbiTests.cs similarity index 87% rename from src/Tests/Microsoft.Diagnostics.Monitoring.HostingStartup.UnitTests/ParameterCapturing/FunctionProbes/ProfilerAbiTests.cs rename to src/Tests/Microsoft.Diagnostics.Monitoring.StartupHook.UnitTests/ParameterCapturing/FunctionProbes/ProfilerAbiTests.cs index d9d2beb694e..8e9971ec35e 100644 --- a/src/Tests/Microsoft.Diagnostics.Monitoring.HostingStartup.UnitTests/ParameterCapturing/FunctionProbes/ProfilerAbiTests.cs +++ b/src/Tests/Microsoft.Diagnostics.Monitoring.StartupHook.UnitTests/ParameterCapturing/FunctionProbes/ProfilerAbiTests.cs @@ -1,12 +1,12 @@ // Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. -using Microsoft.Diagnostics.Monitoring.HostingStartup.ParameterCapturing.FunctionProbes; +using Microsoft.Diagnostics.Monitoring.StartupHook.ParameterCapturing.FunctionProbes; using Microsoft.Diagnostics.Monitoring.TestCommon; using System.Reflection; using Xunit; -namespace Microsoft.Diagnostics.Monitoring.HostingStartup.UnitTests.ParameterCapturing.FunctionProbes +namespace Microsoft.Diagnostics.Monitoring.StartupHook.UnitTests.ParameterCapturing.FunctionProbes { [TargetFrameworkMonikerTrait(TargetFrameworkMonikerExtensions.CurrentTargetFrameworkMoniker)] public class ProfilerAbiTests diff --git a/src/Tests/Microsoft.Diagnostics.Monitoring.HostingStartup.UnitTests/ParameterCapturing/MethodResolverTests.cs b/src/Tests/Microsoft.Diagnostics.Monitoring.StartupHook.UnitTests/ParameterCapturing/MethodResolverTests.cs similarity index 95% rename from src/Tests/Microsoft.Diagnostics.Monitoring.HostingStartup.UnitTests/ParameterCapturing/MethodResolverTests.cs rename to src/Tests/Microsoft.Diagnostics.Monitoring.StartupHook.UnitTests/ParameterCapturing/MethodResolverTests.cs index a70ffdd0f75..8dfc044d78e 100644 --- a/src/Tests/Microsoft.Diagnostics.Monitoring.HostingStartup.UnitTests/ParameterCapturing/MethodResolverTests.cs +++ b/src/Tests/Microsoft.Diagnostics.Monitoring.StartupHook.UnitTests/ParameterCapturing/MethodResolverTests.cs @@ -1,8 +1,8 @@ // Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. -using Microsoft.Diagnostics.Monitoring.HostingStartup.ParameterCapturing; -using Microsoft.Diagnostics.Monitoring.HostingStartup.ParameterCapturing.Boxing; +using Microsoft.Diagnostics.Monitoring.StartupHook.ParameterCapturing; +using Microsoft.Diagnostics.Monitoring.StartupHook.ParameterCapturing.Boxing; using Microsoft.Diagnostics.Monitoring.StartupHook.MonitorMessageDispatcher.Models; using Microsoft.Diagnostics.Monitoring.TestCommon; using SampleMethods; @@ -13,7 +13,7 @@ using Xunit; using Xunit.Abstractions; -namespace Microsoft.Diagnostics.Monitoring.HostingStartup.UnitTests.ParameterCapturing +namespace Microsoft.Diagnostics.Monitoring.StartupHook.UnitTests.ParameterCapturing { [TargetFrameworkMonikerTrait(TargetFrameworkMonikerExtensions.CurrentTargetFrameworkMoniker)] public class MethodResolverTests @@ -162,7 +162,7 @@ private static MethodDescription GetMethodDescription(Type declaringType, string return new MethodDescription { ModuleName = declaringType.Module.Name, - TypeName = declaringType.FullName, + TypeName = declaringType.FullName ?? string.Empty, MethodName = methodName }; } diff --git a/src/Tests/Microsoft.Diagnostics.Monitoring.HostingStartup.UnitTests/ParameterCapturing/MethodSignatureTests.cs b/src/Tests/Microsoft.Diagnostics.Monitoring.StartupHook.UnitTests/ParameterCapturing/MethodSignatureTests.cs similarity index 93% rename from src/Tests/Microsoft.Diagnostics.Monitoring.HostingStartup.UnitTests/ParameterCapturing/MethodSignatureTests.cs rename to src/Tests/Microsoft.Diagnostics.Monitoring.StartupHook.UnitTests/ParameterCapturing/MethodSignatureTests.cs index 7d5ce63f149..6f650262492 100644 --- a/src/Tests/Microsoft.Diagnostics.Monitoring.HostingStartup.UnitTests/ParameterCapturing/MethodSignatureTests.cs +++ b/src/Tests/Microsoft.Diagnostics.Monitoring.StartupHook.UnitTests/ParameterCapturing/MethodSignatureTests.cs @@ -1,14 +1,14 @@ // Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. -using Microsoft.Diagnostics.Monitoring.HostingStartup.ParameterCapturing; +using Microsoft.Diagnostics.Monitoring.StartupHook.ParameterCapturing; using Microsoft.Diagnostics.Monitoring.TestCommon; using SampleMethods; using System; using System.Reflection; using Xunit; -namespace Microsoft.Diagnostics.Monitoring.HostingStartup.UnitTests.ParameterCapturing +namespace Microsoft.Diagnostics.Monitoring.StartupHook.UnitTests.ParameterCapturing { [TargetFrameworkMonikerTrait(TargetFrameworkMonikerExtensions.CurrentTargetFrameworkMoniker)] public class MethodSignatureTests @@ -219,11 +219,11 @@ public void NestedStructs() => ]); private static void TestCore( - MethodInfo methodInfo, - string expectedMethodName, - string expectedDeclaringType, - string expectedDeclaringTypeModuleName, - ExpectedParameterSignature[] expectedParameters) + MethodInfo? methodInfo, + string expectedMethodName, + string expectedDeclaringType, + string expectedDeclaringTypeModuleName, + ExpectedParameterSignature[] expectedParameters) { // Arrange Assert.NotNull(methodInfo); @@ -249,9 +249,9 @@ private static void TestCore( private sealed record ExpectedParameterSignature(Type paramType) { - public string Name; + public string? Name; - public string Type; + public string? Type; public string TypeModuleName = paramType.Module.Name; diff --git a/src/Tests/Microsoft.Diagnostics.Monitoring.HostingStartup.UnitTests/ParameterCapturing/ObjectFormatting/Formatters/DebuggerDisplay/DebuggerDisplayFormatterTests.cs b/src/Tests/Microsoft.Diagnostics.Monitoring.StartupHook.UnitTests/ParameterCapturing/ObjectFormatting/Formatters/DebuggerDisplay/DebuggerDisplayFormatterTests.cs similarity index 81% rename from src/Tests/Microsoft.Diagnostics.Monitoring.HostingStartup.UnitTests/ParameterCapturing/ObjectFormatting/Formatters/DebuggerDisplay/DebuggerDisplayFormatterTests.cs rename to src/Tests/Microsoft.Diagnostics.Monitoring.StartupHook.UnitTests/ParameterCapturing/ObjectFormatting/Formatters/DebuggerDisplay/DebuggerDisplayFormatterTests.cs index 3976c944bbc..056431cb142 100644 --- a/src/Tests/Microsoft.Diagnostics.Monitoring.HostingStartup.UnitTests/ParameterCapturing/ObjectFormatting/Formatters/DebuggerDisplay/DebuggerDisplayFormatterTests.cs +++ b/src/Tests/Microsoft.Diagnostics.Monitoring.StartupHook.UnitTests/ParameterCapturing/ObjectFormatting/Formatters/DebuggerDisplay/DebuggerDisplayFormatterTests.cs @@ -1,16 +1,16 @@ // Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. -using Microsoft.Diagnostics.Monitoring.HostingStartup.ParameterCapturing.ObjectFormatting; -using Microsoft.Diagnostics.Monitoring.HostingStartup.ParameterCapturing.ObjectFormatting.Formatters.DebuggerDisplay; +using Microsoft.Diagnostics.Monitoring.StartupHook.ParameterCapturing.ObjectFormatting; +using Microsoft.Diagnostics.Monitoring.StartupHook.ParameterCapturing.ObjectFormatting.Formatters.DebuggerDisplay; using Microsoft.Diagnostics.Monitoring.TestCommon; using System; using System.Diagnostics; using Xunit; -using static Microsoft.Diagnostics.Monitoring.HostingStartup.ParameterCapturing.ObjectFormatting.Formatters.DebuggerDisplay.DebuggerDisplayFormatter; +using static Microsoft.Diagnostics.Monitoring.StartupHook.ParameterCapturing.ObjectFormatting.Formatters.DebuggerDisplay.DebuggerDisplayFormatter; using static Microsoft.Diagnostics.Tools.Monitor.ParameterCapturing.ParameterCapturingEvents; -namespace Microsoft.Diagnostics.Monitoring.HostingStartup.UnitTests.ParameterCapturing.ObjectFormatting.Formatters.DebuggerDisplay +namespace Microsoft.Diagnostics.Monitoring.StartupHook.UnitTests.ParameterCapturing.ObjectFormatting.Formatters.DebuggerDisplay { [TargetFrameworkMonikerTrait(TargetFrameworkMonikerExtensions.CurrentTargetFrameworkMoniker)] public class DebuggerDisplayFormatterTests @@ -28,14 +28,16 @@ private sealed class DebuggerDisplayClassWithNullField { public int Count { get; set; } +#pragma warning disable CS8603 // Possible null reference return. public static string NullField => null; +#pragma warning restore CS8603 // Possible null reference return. } [Theory] [InlineData(typeof(NoDebuggerDisplay), null)] [InlineData(typeof(DebuggerDisplayClass), "Count = {Count}")] [InlineData(typeof(DerivedWithBaseDebuggerDisplay), "Count = {Count}")] - public void GetDebuggerDisplayAttribute(Type type, string expected) + public void GetDebuggerDisplayAttribute(Type type, string? expected) { // Act DebuggerDisplayAttributeValue? attribute = DebuggerDisplayFormatter.GetDebuggerDisplayAttribute(type); @@ -80,7 +82,7 @@ public void GetDebuggerDisplayFormatter_ReturnsWorkingFormatter() Count = 10 }; - FormatterFactoryResult factoryResult = DebuggerDisplayFormatter.GetDebuggerDisplayFormatter(testObj.GetType()); + FormatterFactoryResult? factoryResult = DebuggerDisplayFormatter.GetDebuggerDisplayFormatter(testObj.GetType()); Assert.NotNull(factoryResult); // Act @@ -100,7 +102,7 @@ public void GetDebuggerDisplayFormatter_FormatsNull() Count = 10 }; - FormatterFactoryResult factoryResult = DebuggerDisplayFormatter.GetDebuggerDisplayFormatter(testObj.GetType()); + FormatterFactoryResult? factoryResult = DebuggerDisplayFormatter.GetDebuggerDisplayFormatter(testObj.GetType()); Assert.NotNull(factoryResult); // Act diff --git a/src/Tests/Microsoft.Diagnostics.Monitoring.HostingStartup.UnitTests/ParameterCapturing/ObjectFormatting/Formatters/DebuggerDisplay/DebuggerDisplayParserTests.cs b/src/Tests/Microsoft.Diagnostics.Monitoring.StartupHook.UnitTests/ParameterCapturing/ObjectFormatting/Formatters/DebuggerDisplay/DebuggerDisplayParserTests.cs similarity index 87% rename from src/Tests/Microsoft.Diagnostics.Monitoring.HostingStartup.UnitTests/ParameterCapturing/ObjectFormatting/Formatters/DebuggerDisplay/DebuggerDisplayParserTests.cs rename to src/Tests/Microsoft.Diagnostics.Monitoring.StartupHook.UnitTests/ParameterCapturing/ObjectFormatting/Formatters/DebuggerDisplay/DebuggerDisplayParserTests.cs index e8a27df110d..cb42ad717d9 100644 --- a/src/Tests/Microsoft.Diagnostics.Monitoring.HostingStartup.UnitTests/ParameterCapturing/ObjectFormatting/Formatters/DebuggerDisplay/DebuggerDisplayParserTests.cs +++ b/src/Tests/Microsoft.Diagnostics.Monitoring.StartupHook.UnitTests/ParameterCapturing/ObjectFormatting/Formatters/DebuggerDisplay/DebuggerDisplayParserTests.cs @@ -1,15 +1,15 @@ // Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. -using Microsoft.Diagnostics.Monitoring.HostingStartup.ParameterCapturing.ObjectFormatting; -using Microsoft.Diagnostics.Monitoring.HostingStartup.ParameterCapturing.ObjectFormatting.Formatters.DebuggerDisplay; +using Microsoft.Diagnostics.Monitoring.StartupHook.ParameterCapturing.ObjectFormatting; +using Microsoft.Diagnostics.Monitoring.StartupHook.ParameterCapturing.ObjectFormatting.Formatters.DebuggerDisplay; using Microsoft.Diagnostics.Monitoring.TestCommon; using System; using System.Linq; using Xunit; -using static Microsoft.Diagnostics.Monitoring.HostingStartup.ParameterCapturing.ObjectFormatting.Formatters.DebuggerDisplay.DebuggerDisplayParser; +using static Microsoft.Diagnostics.Monitoring.StartupHook.ParameterCapturing.ObjectFormatting.Formatters.DebuggerDisplay.DebuggerDisplayParser; -namespace Microsoft.Diagnostics.Monitoring.HostingStartup.UnitTests.ParameterCapturing.ObjectFormatting.Formatters.DebuggerDisplay +namespace Microsoft.Diagnostics.Monitoring.StartupHook.UnitTests.ParameterCapturing.ObjectFormatting.Formatters.DebuggerDisplay { [TargetFrameworkMonikerTrait(TargetFrameworkMonikerExtensions.CurrentTargetFrameworkMoniker)] public class DebuggerDisplayParserTests @@ -36,7 +36,7 @@ public class DebuggerDisplayParserTests [InlineData("Test: {prop1} - {prop2} - {method()}", "Test: {0} - {1} - {2}", "prop1", "prop2", "method()")] // Complex expressions [InlineData("Test: {propertyName - 2}", "Test: {0}", "propertyName - 2")] - public void ParseDebuggerDisplay(string debuggerDisplay, string formatString, params string[] expressions) + public void ParseDebuggerDisplay(string debuggerDisplay, string? formatString, params string[] expressions) { // Act ParsedDebuggerDisplay? parsed = DebuggerDisplayParser.ParseDebuggerDisplay(debuggerDisplay); @@ -62,7 +62,7 @@ public void ParseDebuggerDisplay(string debuggerDisplay, string formatString, pa [InlineData("{((a)}", null, FormatSpecifier.None)] [InlineData("{\\}}", null, FormatSpecifier.None)] [InlineData("{a}", "a", FormatSpecifier.None)] - internal void ParseExpression(string rawExpression, string expressionString, FormatSpecifier formatSpecifier) + internal void ParseExpression(string rawExpression, string? expressionString, FormatSpecifier formatSpecifier) { // Act Expression? expression = DebuggerDisplayParser.ParseExpression(rawExpression.AsMemory(), out _); diff --git a/src/Tests/Microsoft.Diagnostics.Monitoring.HostingStartup.UnitTests/ParameterCapturing/ObjectFormatting/Formatters/DebuggerDisplay/ExpressionBinderTests.cs b/src/Tests/Microsoft.Diagnostics.Monitoring.StartupHook.UnitTests/ParameterCapturing/ObjectFormatting/Formatters/DebuggerDisplay/ExpressionBinderTests.cs similarity index 83% rename from src/Tests/Microsoft.Diagnostics.Monitoring.HostingStartup.UnitTests/ParameterCapturing/ObjectFormatting/Formatters/DebuggerDisplay/ExpressionBinderTests.cs rename to src/Tests/Microsoft.Diagnostics.Monitoring.StartupHook.UnitTests/ParameterCapturing/ObjectFormatting/Formatters/DebuggerDisplay/ExpressionBinderTests.cs index cdeb5ba459e..0633204a781 100644 --- a/src/Tests/Microsoft.Diagnostics.Monitoring.HostingStartup.UnitTests/ParameterCapturing/ObjectFormatting/Formatters/DebuggerDisplay/ExpressionBinderTests.cs +++ b/src/Tests/Microsoft.Diagnostics.Monitoring.StartupHook.UnitTests/ParameterCapturing/ObjectFormatting/Formatters/DebuggerDisplay/ExpressionBinderTests.cs @@ -1,13 +1,13 @@ // Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. -using Microsoft.Diagnostics.Monitoring.HostingStartup.ParameterCapturing.ObjectFormatting.Formatters.DebuggerDisplay; +using Microsoft.Diagnostics.Monitoring.StartupHook.ParameterCapturing.ObjectFormatting.Formatters.DebuggerDisplay; using Microsoft.Diagnostics.Monitoring.TestCommon; using System; using Xunit; -using static Microsoft.Diagnostics.Monitoring.HostingStartup.ParameterCapturing.ObjectFormatting.Formatters.DebuggerDisplay.ExpressionBinder; +using static Microsoft.Diagnostics.Monitoring.StartupHook.ParameterCapturing.ObjectFormatting.Formatters.DebuggerDisplay.ExpressionBinder; -namespace Microsoft.Diagnostics.Monitoring.HostingStartup.UnitTests.ParameterCapturing.ObjectFormatting.Formatters.DebuggerDisplay +namespace Microsoft.Diagnostics.Monitoring.StartupHook.UnitTests.ParameterCapturing.ObjectFormatting.Formatters.DebuggerDisplay { [TargetFrameworkMonikerTrait(TargetFrameworkMonikerExtensions.CurrentTargetFrameworkMoniker)] public class ExpressionBinderTests @@ -52,7 +52,7 @@ public string GetCountAsString() [InlineData("Recursion().RecursionProp.MyUri.Host", true, "www.example.com")] // Chained expression with static property [InlineData("Recursion().StaticProperty.Host", true, "www.example.com")] - public void BindExpression(string expression, bool doesBind, object expected) + public void BindExpression(string expression, bool doesBind, object? expected) { // Arrange DebuggerDisplayClass obj = new("https://www.example.com/abc"); @@ -66,7 +66,7 @@ public void BindExpression(string expression, bool doesBind, object expected) } Assert.NotNull(evaluator); - object result = evaluator.Value.Evaluate(obj); + object? result = evaluator.Value.Evaluate(obj); // Assert Assert.Equal(expected, result); diff --git a/src/Tests/Microsoft.Diagnostics.Monitoring.HostingStartup.UnitTests/ParameterCapturing/ObjectFormatting/Formatters/RuntimeFormattersTests.cs b/src/Tests/Microsoft.Diagnostics.Monitoring.StartupHook.UnitTests/ParameterCapturing/ObjectFormatting/Formatters/RuntimeFormattersTests.cs similarity index 93% rename from src/Tests/Microsoft.Diagnostics.Monitoring.HostingStartup.UnitTests/ParameterCapturing/ObjectFormatting/Formatters/RuntimeFormattersTests.cs rename to src/Tests/Microsoft.Diagnostics.Monitoring.StartupHook.UnitTests/ParameterCapturing/ObjectFormatting/Formatters/RuntimeFormattersTests.cs index 6644d5d7991..3a8be64ba5b 100644 --- a/src/Tests/Microsoft.Diagnostics.Monitoring.HostingStartup.UnitTests/ParameterCapturing/ObjectFormatting/Formatters/RuntimeFormattersTests.cs +++ b/src/Tests/Microsoft.Diagnostics.Monitoring.StartupHook.UnitTests/ParameterCapturing/ObjectFormatting/Formatters/RuntimeFormattersTests.cs @@ -1,14 +1,14 @@ // Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. -using Microsoft.Diagnostics.Monitoring.HostingStartup.ParameterCapturing.ObjectFormatting; +using Microsoft.Diagnostics.Monitoring.StartupHook.ParameterCapturing.ObjectFormatting; using Microsoft.Diagnostics.Monitoring.TestCommon; using SampleMethods; using System; using Xunit; using static Microsoft.Diagnostics.Tools.Monitor.ParameterCapturing.ParameterCapturingEvents; -namespace Microsoft.Diagnostics.Monitoring.HostingStartup.UnitTests.ParameterCapturing.ObjectFormatting.Formatters +namespace Microsoft.Diagnostics.Monitoring.StartupHook.UnitTests.ParameterCapturing.ObjectFormatting.Formatters { [TargetFrameworkMonikerTrait(TargetFrameworkMonikerExtensions.CurrentTargetFrameworkMoniker)] public class RuntimeFormattersTests diff --git a/src/Tests/Microsoft.Diagnostics.Monitoring.HostingStartup.UnitTests/ParameterCapturing/ObjectFormatting/ObjectFormatterFactoryTests.cs b/src/Tests/Microsoft.Diagnostics.Monitoring.StartupHook.UnitTests/ParameterCapturing/ObjectFormatting/ObjectFormatterFactoryTests.cs similarity index 86% rename from src/Tests/Microsoft.Diagnostics.Monitoring.HostingStartup.UnitTests/ParameterCapturing/ObjectFormatting/ObjectFormatterFactoryTests.cs rename to src/Tests/Microsoft.Diagnostics.Monitoring.StartupHook.UnitTests/ParameterCapturing/ObjectFormatting/ObjectFormatterFactoryTests.cs index 11aa53b0e02..eac1a1e6592 100644 --- a/src/Tests/Microsoft.Diagnostics.Monitoring.HostingStartup.UnitTests/ParameterCapturing/ObjectFormatting/ObjectFormatterFactoryTests.cs +++ b/src/Tests/Microsoft.Diagnostics.Monitoring.StartupHook.UnitTests/ParameterCapturing/ObjectFormatting/ObjectFormatterFactoryTests.cs @@ -1,14 +1,14 @@ // Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. -using Microsoft.Diagnostics.Monitoring.HostingStartup.ParameterCapturing.ObjectFormatting; +using Microsoft.Diagnostics.Monitoring.StartupHook.ParameterCapturing.ObjectFormatting; using Microsoft.Diagnostics.Monitoring.TestCommon; using SampleMethods; using System; using System.Reflection; using Xunit; -namespace Microsoft.Diagnostics.Monitoring.HostingStartup.UnitTests.ParameterCapturing +namespace Microsoft.Diagnostics.Monitoring.StartupHook.UnitTests.ParameterCapturing { [TargetFrameworkMonikerTrait(TargetFrameworkMonikerExtensions.CurrentTargetFrameworkMoniker)] public class ObjectFormatterFactoryTests diff --git a/src/Tests/Microsoft.Diagnostics.Monitoring.HostingStartup.UnitTests/ParameterCapturing/ObjectFormatting/ObjectFormatterTests.cs b/src/Tests/Microsoft.Diagnostics.Monitoring.StartupHook.UnitTests/ParameterCapturing/ObjectFormatting/ObjectFormatterTests.cs similarity index 92% rename from src/Tests/Microsoft.Diagnostics.Monitoring.HostingStartup.UnitTests/ParameterCapturing/ObjectFormatting/ObjectFormatterTests.cs rename to src/Tests/Microsoft.Diagnostics.Monitoring.StartupHook.UnitTests/ParameterCapturing/ObjectFormatting/ObjectFormatterTests.cs index dc1a447414e..607088b7541 100644 --- a/src/Tests/Microsoft.Diagnostics.Monitoring.HostingStartup.UnitTests/ParameterCapturing/ObjectFormatting/ObjectFormatterTests.cs +++ b/src/Tests/Microsoft.Diagnostics.Monitoring.StartupHook.UnitTests/ParameterCapturing/ObjectFormatting/ObjectFormatterTests.cs @@ -1,13 +1,13 @@ // Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. -using Microsoft.Diagnostics.Monitoring.HostingStartup.ParameterCapturing.ObjectFormatting; +using Microsoft.Diagnostics.Monitoring.StartupHook.ParameterCapturing.ObjectFormatting; using Microsoft.Diagnostics.Monitoring.TestCommon; using System; using Xunit; using static Microsoft.Diagnostics.Tools.Monitor.ParameterCapturing.ParameterCapturingEvents; -namespace Microsoft.Diagnostics.Monitoring.HostingStartup.UnitTests.ParameterCapturing +namespace Microsoft.Diagnostics.Monitoring.StartupHook.UnitTests.ParameterCapturing { [TargetFrameworkMonikerTrait(TargetFrameworkMonikerExtensions.CurrentTargetFrameworkMoniker)] public class ObjectFormatterTests diff --git a/src/Tests/Microsoft.Diagnostics.Monitoring.HostingStartup.UnitTests/ParameterCapturing/Pipeline/CaptureLimitPolicyProbesTests.cs b/src/Tests/Microsoft.Diagnostics.Monitoring.StartupHook.UnitTests/ParameterCapturing/Pipeline/CaptureLimitPolicyProbesTests.cs similarity index 93% rename from src/Tests/Microsoft.Diagnostics.Monitoring.HostingStartup.UnitTests/ParameterCapturing/Pipeline/CaptureLimitPolicyProbesTests.cs rename to src/Tests/Microsoft.Diagnostics.Monitoring.StartupHook.UnitTests/ParameterCapturing/Pipeline/CaptureLimitPolicyProbesTests.cs index 1e196a890f3..5852757efac 100644 --- a/src/Tests/Microsoft.Diagnostics.Monitoring.HostingStartup.UnitTests/ParameterCapturing/Pipeline/CaptureLimitPolicyProbesTests.cs +++ b/src/Tests/Microsoft.Diagnostics.Monitoring.StartupHook.UnitTests/ParameterCapturing/Pipeline/CaptureLimitPolicyProbesTests.cs @@ -1,7 +1,7 @@ // Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. -using Microsoft.Diagnostics.Monitoring.HostingStartup.ParameterCapturing.Pipeline; +using Microsoft.Diagnostics.Monitoring.StartupHook.ParameterCapturing.Pipeline; using Microsoft.Diagnostics.Monitoring.TestCommon; using System; using System.Collections.Generic; @@ -10,7 +10,7 @@ using System.Threading.Tasks; using Xunit; -namespace Microsoft.Diagnostics.Monitoring.HostingStartup.UnitTests.ParameterCapturing.Pipeline +namespace Microsoft.Diagnostics.Monitoring.StartupHook.UnitTests.ParameterCapturing.Pipeline { [TargetFrameworkMonikerTrait(TargetFrameworkMonikerExtensions.CurrentTargetFrameworkMoniker)] public class CaptureLimitPolicyProbesTests @@ -88,8 +88,8 @@ public void EnterProbe_ShortCircuits_WhenLimitReached() public void CacheMethods_PassesThrough() { // Arrange - List expectedMethods = [(MethodInfo)MethodBase.GetCurrentMethod()]; - IList actualMethods = null; + List expectedMethods = [(MethodInfo)MethodBase.GetCurrentMethod()!]; + IList actualMethods = []; TaskCompletionSource requestStop = new(); CaptureLimitPolicyProbes probes = new(new TestFunctionProbes( @@ -113,7 +113,7 @@ public void EnterProbe_PassesThrough() object[] expectedArgs = [new Uri("https://www.example.com"), 10]; ulong? actualUniquifier = null; - object[] actualArgs = null; + object[] actualArgs = []; TaskCompletionSource requestStop = new(); CaptureLimitPolicyProbes probes = new(new TestFunctionProbes( diff --git a/src/Tests/Microsoft.Diagnostics.Monitoring.HostingStartup.UnitTests/ParameterCapturing/Pipeline/ParameterCapturingPipelineTests.cs b/src/Tests/Microsoft.Diagnostics.Monitoring.StartupHook.UnitTests/ParameterCapturing/Pipeline/ParameterCapturingPipelineTests.cs similarity index 93% rename from src/Tests/Microsoft.Diagnostics.Monitoring.HostingStartup.UnitTests/ParameterCapturing/Pipeline/ParameterCapturingPipelineTests.cs rename to src/Tests/Microsoft.Diagnostics.Monitoring.StartupHook.UnitTests/ParameterCapturing/Pipeline/ParameterCapturingPipelineTests.cs index b703a9b8641..9fcc5192107 100644 --- a/src/Tests/Microsoft.Diagnostics.Monitoring.HostingStartup.UnitTests/ParameterCapturing/Pipeline/ParameterCapturingPipelineTests.cs +++ b/src/Tests/Microsoft.Diagnostics.Monitoring.StartupHook.UnitTests/ParameterCapturing/Pipeline/ParameterCapturingPipelineTests.cs @@ -1,10 +1,10 @@ // Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. -using Microsoft.Diagnostics.Monitoring.HostingStartup.ParameterCapturing; -using Microsoft.Diagnostics.Monitoring.HostingStartup.ParameterCapturing.Boxing; -using Microsoft.Diagnostics.Monitoring.HostingStartup.ParameterCapturing.FunctionProbes; -using Microsoft.Diagnostics.Monitoring.HostingStartup.ParameterCapturing.Pipeline; +using Microsoft.Diagnostics.Monitoring.StartupHook.ParameterCapturing; +using Microsoft.Diagnostics.Monitoring.StartupHook.ParameterCapturing.Boxing; +using Microsoft.Diagnostics.Monitoring.StartupHook.ParameterCapturing.FunctionProbes; +using Microsoft.Diagnostics.Monitoring.StartupHook.ParameterCapturing.Pipeline; using Microsoft.Diagnostics.Monitoring.StartupHook.MonitorMessageDispatcher.Models; using Microsoft.Diagnostics.Monitoring.TestCommon; using Microsoft.Diagnostics.Tools.Monitor.ParameterCapturing; @@ -17,16 +17,16 @@ using Xunit; using Xunit.Abstractions; -namespace Microsoft.Diagnostics.Monitoring.HostingStartup.UnitTests.ParameterCapturing.Pipeline +namespace Microsoft.Diagnostics.Monitoring.StartupHook.UnitTests.ParameterCapturing.Pipeline { internal sealed class TestFunctionProbesManager : IFunctionProbesManager { - private readonly Action, IFunctionProbes> _onStart; - private readonly Action _onStop; + private readonly Action, IFunctionProbes>? _onStart; + private readonly Action? _onStop; - public event EventHandler OnProbeFault; + public event EventHandler? OnProbeFault; - public TestFunctionProbesManager(Action, IFunctionProbes> onStart = null, Action onStop = null) + public TestFunctionProbesManager(Action, IFunctionProbes>? onStart = null, Action? onStop = null) { _onStart = onStart; _onStop = onStop; @@ -57,16 +57,16 @@ public void Dispose() internal sealed class TestParameterCapturingCallbacks : IParameterCapturingPipelineCallbacks { - private readonly Action> _onCapturingStart; - private readonly Action _onCapturingStop; - private readonly Action _onCapturingFailed; - private readonly Action _onProbeFault; + private readonly Action>? _onCapturingStart; + private readonly Action? _onCapturingStop; + private readonly Action? _onCapturingFailed; + private readonly Action? _onProbeFault; public TestParameterCapturingCallbacks( - Action> onCapturingStart = null, - Action onCapturingStop = null, - Action onCapturingFailed = null, - Action onProbeFault = null) + Action>? onCapturingStart = null, + Action? onCapturingStop = null, + Action? onCapturingFailed = null, + Action? onProbeFault = null) { _onCapturingStart = onCapturingStart; _onCapturingStop = onCapturingStop; @@ -97,8 +97,8 @@ public void ProbeFault(Guid requestId, InstrumentedMethod faultingMethod) internal sealed class TestMethodDescriptionValidator : IMethodDescriptionValidator { - private readonly Func _onValidateMethods; - public TestMethodDescriptionValidator(Func onValidateMethods = null) + private readonly Func? _onValidateMethods; + public TestMethodDescriptionValidator(Func? onValidateMethods = null) { _onValidateMethods = onValidateMethods; } @@ -476,7 +476,7 @@ private StartCapturingParametersPayload CreateStartCapturingPayload(TimeSpan dur string moduleName = typeof(ParameterCapturingPipelineTests).Module.Name; Assert.NotNull(moduleName); - string typeName = typeof(ParameterCapturingPipelineTests).FullName; + string? typeName = typeof(ParameterCapturingPipelineTests).FullName; Assert.NotNull(typeName); return new StartCapturingParametersPayload() diff --git a/src/Tests/Microsoft.Diagnostics.Monitoring.HostingStartup.UnitTests/ParameterCapturing/Pipeline/TestFunctionProbes.cs b/src/Tests/Microsoft.Diagnostics.Monitoring.StartupHook.UnitTests/ParameterCapturing/Pipeline/TestFunctionProbes.cs similarity index 61% rename from src/Tests/Microsoft.Diagnostics.Monitoring.HostingStartup.UnitTests/ParameterCapturing/Pipeline/TestFunctionProbes.cs rename to src/Tests/Microsoft.Diagnostics.Monitoring.StartupHook.UnitTests/ParameterCapturing/Pipeline/TestFunctionProbes.cs index 664e6a84473..af79d704560 100644 --- a/src/Tests/Microsoft.Diagnostics.Monitoring.HostingStartup.UnitTests/ParameterCapturing/Pipeline/TestFunctionProbes.cs +++ b/src/Tests/Microsoft.Diagnostics.Monitoring.StartupHook.UnitTests/ParameterCapturing/Pipeline/TestFunctionProbes.cs @@ -1,19 +1,19 @@ // Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. -using Microsoft.Diagnostics.Monitoring.HostingStartup.ParameterCapturing.FunctionProbes; +using Microsoft.Diagnostics.Monitoring.StartupHook.ParameterCapturing.FunctionProbes; using System; using System.Collections.Generic; using System.Reflection; -namespace Microsoft.Diagnostics.Monitoring.HostingStartup.UnitTests.ParameterCapturing.Pipeline +namespace Microsoft.Diagnostics.Monitoring.StartupHook.UnitTests.ParameterCapturing.Pipeline { internal sealed class TestFunctionProbes : IFunctionProbes { - private readonly Func _onEnterProbe; - private readonly Action> _onCacheMethods; + private readonly Func? _onEnterProbe; + private readonly Action>? _onCacheMethods; - public TestFunctionProbes(Func onEnterProbe = null, Action> onCacheMethods = null) + public TestFunctionProbes(Func? onEnterProbe = null, Action>? onCacheMethods = null) { _onEnterProbe = onEnterProbe; _onCacheMethods = onCacheMethods; diff --git a/src/Tests/Microsoft.Diagnostics.Monitoring.HostingStartup.UnitTests/ParameterCapturing/SampleMethods.cs b/src/Tests/Microsoft.Diagnostics.Monitoring.StartupHook.UnitTests/ParameterCapturing/SampleMethods.cs similarity index 98% rename from src/Tests/Microsoft.Diagnostics.Monitoring.HostingStartup.UnitTests/ParameterCapturing/SampleMethods.cs rename to src/Tests/Microsoft.Diagnostics.Monitoring.StartupHook.UnitTests/ParameterCapturing/SampleMethods.cs index e12eef7f172..f262658d303 100644 --- a/src/Tests/Microsoft.Diagnostics.Monitoring.HostingStartup.UnitTests/ParameterCapturing/SampleMethods.cs +++ b/src/Tests/Microsoft.Diagnostics.Monitoring.StartupHook.UnitTests/ParameterCapturing/SampleMethods.cs @@ -79,7 +79,7 @@ public static string ExceptionRegionAtBeginningOfMethod(object myObject) { try { - return myObject.ToString(); + return myObject.ToString() ?? string.Empty; } catch { diff --git a/src/Tests/Microsoft.Diagnostics.Monitoring.HostingStartup.UnitTests/ParameterCapturing/TypeUtilsTests.cs b/src/Tests/Microsoft.Diagnostics.Monitoring.StartupHook.UnitTests/ParameterCapturing/TypeUtilsTests.cs similarity index 86% rename from src/Tests/Microsoft.Diagnostics.Monitoring.HostingStartup.UnitTests/ParameterCapturing/TypeUtilsTests.cs rename to src/Tests/Microsoft.Diagnostics.Monitoring.StartupHook.UnitTests/ParameterCapturing/TypeUtilsTests.cs index 8f9ea43b4d8..bde6433d900 100644 --- a/src/Tests/Microsoft.Diagnostics.Monitoring.HostingStartup.UnitTests/ParameterCapturing/TypeUtilsTests.cs +++ b/src/Tests/Microsoft.Diagnostics.Monitoring.StartupHook.UnitTests/ParameterCapturing/TypeUtilsTests.cs @@ -1,11 +1,11 @@ // Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. -using Microsoft.Diagnostics.Monitoring.HostingStartup.ParameterCapturing; +using Microsoft.Diagnostics.Monitoring.StartupHook.ParameterCapturing; using Microsoft.Diagnostics.Monitoring.TestCommon; using Xunit; -namespace Microsoft.Diagnostics.Monitoring.HostingStartup.UnitTests.ParameterCapturing +namespace Microsoft.Diagnostics.Monitoring.StartupHook.UnitTests.ParameterCapturing { [TargetFrameworkMonikerTrait(TargetFrameworkMonikerExtensions.CurrentTargetFrameworkMoniker)] public class TypeUtilsTests diff --git a/src/Tests/Microsoft.Diagnostics.Monitoring.TestCommon/Microsoft.Diagnostics.Monitoring.TestCommon.csproj b/src/Tests/Microsoft.Diagnostics.Monitoring.TestCommon/Microsoft.Diagnostics.Monitoring.TestCommon.csproj index a8410dac814..3544d5bfdd2 100644 --- a/src/Tests/Microsoft.Diagnostics.Monitoring.TestCommon/Microsoft.Diagnostics.Monitoring.TestCommon.csproj +++ b/src/Tests/Microsoft.Diagnostics.Monitoring.TestCommon/Microsoft.Diagnostics.Monitoring.TestCommon.csproj @@ -33,7 +33,6 @@ - diff --git a/src/Tests/Microsoft.Diagnostics.Monitoring.TestCommon/TestAppScenarios.cs b/src/Tests/Microsoft.Diagnostics.Monitoring.TestCommon/TestAppScenarios.cs index f73606f941e..fe4766ef238 100644 --- a/src/Tests/Microsoft.Diagnostics.Monitoring.TestCommon/TestAppScenarios.cs +++ b/src/Tests/Microsoft.Diagnostics.Monitoring.TestCommon/TestAppScenarios.cs @@ -120,18 +120,6 @@ public static class SubScenarios } } - public static class HostingStartup - { - public const string Name = nameof(HostingStartup); - - public static class SubScenarios - { - public const string VerifyAspNetAppWithoutHostingStartup = nameof(VerifyAspNetAppWithoutHostingStartup); - public const string VerifyAspNetApp = nameof(VerifyAspNetApp); - public const string VerifyNonAspNetAppNotImpacted = nameof(VerifyNonAspNetAppNotImpacted); - } - } - public static class Stacks { public const string Name = nameof(Stacks); diff --git a/src/Tests/Microsoft.Diagnostics.Monitoring.Tool.FunctionalTests/ExceptionsTests.cs b/src/Tests/Microsoft.Diagnostics.Monitoring.Tool.FunctionalTests/ExceptionsTests.cs index e2d6da9a396..f643f52aa5c 100644 --- a/src/Tests/Microsoft.Diagnostics.Monitoring.Tool.FunctionalTests/ExceptionsTests.cs +++ b/src/Tests/Microsoft.Diagnostics.Monitoring.Tool.FunctionalTests/ExceptionsTests.cs @@ -15,6 +15,7 @@ using System.IO; using System.Linq; using System.Net.Http; +using System.Reflection; using System.Runtime.InteropServices; using System.Text.Json; using System.Threading.Tasks; @@ -130,12 +131,20 @@ await ScenarioRunner.SingleTarget( var topFrame = callStackResultsRootElement.GetProperty("frames").EnumerateArray().FirstOrDefault(); + MethodInfo methodInfo = typeof(Microsoft.Diagnostics.Monitoring.UnitTestApp.Scenarios.ExceptionsScenario).GetMethod( + FrameMethodName, + BindingFlags.Static | BindingFlags.NonPublic, + [typeof(bool), typeof(bool)]); + Assert.NotNull(methodInfo); + Assert.Equal(FrameMethodName, topFrame.GetProperty("methodName").ToString()); + Assert.Equal((uint)methodInfo.MetadataToken, topFrame.GetProperty("methodToken").GetUInt32()); Assert.Equal(2, topFrame.GetProperty("parameterTypes").GetArrayLength()); Assert.Equal(FrameParameterType, topFrame.GetProperty("parameterTypes")[0].ToString()); Assert.Equal(FrameParameterType, topFrame.GetProperty("parameterTypes")[1].ToString()); Assert.Equal(FrameTypeName, topFrame.GetProperty("typeName").ToString()); Assert.Equal(UnitTestAppModule, topFrame.GetProperty("moduleName").ToString()); + Assert.Equal(methodInfo.Module.ModuleVersionId, topFrame.GetProperty("moduleVersionId").GetGuid()); }, configureApp: runner => { diff --git a/src/Tests/Microsoft.Diagnostics.Monitoring.Tool.FunctionalTests/FunctionProbesTests.cs b/src/Tests/Microsoft.Diagnostics.Monitoring.Tool.FunctionalTests/FunctionProbesTests.cs index b087474d61a..cea57664c78 100644 --- a/src/Tests/Microsoft.Diagnostics.Monitoring.Tool.FunctionalTests/FunctionProbesTests.cs +++ b/src/Tests/Microsoft.Diagnostics.Monitoring.Tool.FunctionalTests/FunctionProbesTests.cs @@ -2,20 +2,26 @@ // The .NET Foundation licenses this file to you under the MIT license. using Microsoft.Diagnostics.Monitoring.TestCommon; -using Microsoft.Diagnostics.Monitoring.TestCommon.Options; +using Microsoft.Diagnostics.Monitoring.TestCommon.Runners; using Microsoft.Diagnostics.Monitoring.Tool.FunctionalTests.Fixtures; -using Microsoft.Diagnostics.Monitoring.Tool.FunctionalTests.Runners; -using Microsoft.Diagnostics.Monitoring.WebApi; +using Microsoft.Diagnostics.Tools.Monitor.StartupHook; using Microsoft.Extensions.DependencyInjection; -using Microsoft.Extensions.Logging; using System.Collections.Generic; using System.Linq; using System.Net.Http; +using System.Reflection; using System.Runtime.InteropServices; using System.Threading.Tasks; using Xunit; using Xunit.Abstractions; +#if !NET7_0_OR_GREATER +using Microsoft.Diagnostics.Monitoring.TestCommon.Options; +using Microsoft.Diagnostics.Monitoring.Tool.FunctionalTests.Runners; +using Microsoft.Diagnostics.Monitoring.WebApi; +using Microsoft.Extensions.Logging; +#endif + namespace Microsoft.Diagnostics.Monitoring.Tool.FunctionalTests { [TargetFrameworkMonikerTrait(TargetFrameworkMonikerExtensions.CurrentTargetFrameworkMoniker)] @@ -38,7 +44,6 @@ public FunctionProbesTests(ITestOutputHelper outputHelper, ServiceProviderFixtur public static IEnumerable GetAllTestScenarios() { List arguments = new(); - IEnumerable testArchitectures = ProfilerHelper.GetArchitecture(); List commands = typeof(TestAppScenarios.FunctionProbes.SubScenarios).GetFields(System.Reflection.BindingFlags.Public | System.Reflection.BindingFlags.Static) .Select(p => p.Name) @@ -57,9 +62,41 @@ public static IEnumerable GetAllTestScenarios() return arguments; } +#if !NET7_0_OR_GREATER + [Theory(Skip ="This test installs the mutating profiler which is not enabled on net6 or lower.")] +#else [Theory] +#endif [MemberData(nameof(FunctionProbesTests.GetAllTestScenarios), MemberType = typeof(FunctionProbesTests))] public async Task RunTestScenario(Architecture targetArchitecture, string subScenario) + { + await using AppRunner appRunner = new(_outputHelper, Assembly.GetExecutingAssembly()) + { + Architecture = targetArchitecture, + ScenarioName = TestAppScenarios.FunctionProbes.Name, + SubScenarioName = subScenario + }; + + // Enable the mutating profiler + string profilerPath = NativeLibraryHelper.GetSharedLibraryPath(targetArchitecture, ProfilerIdentifiers.MutatingProfiler.LibraryRootFileName); + appRunner.Environment.Add(ProfilerHelper.ClrEnvVarEnableNotificationProfilers, ProfilerHelper.ClrEnvVarEnabledValue); + appRunner.Environment.Add(ProfilerHelper.ClrEnvVarEnableProfiling, ProfilerHelper.ClrEnvVarEnabledValue); + appRunner.Environment.Add(ProfilerHelper.ClrEnvVarProfiler, ProfilerIdentifiers.MutatingProfiler.Clsid.StringWithBraces); + appRunner.Environment.Add(ProfilerHelper.ClrEnvVarProfilerPath, profilerPath); + appRunner.Environment.Add(ProfilerIdentifiers.MutatingProfiler.EnvironmentVariables.ModulePath, profilerPath); + + // The profiler checks this env variable to enable parameter capturing features. + appRunner.Environment.Add(InProcessFeaturesIdentifiers.EnvironmentVariables.ParameterCapturing.Enable, "1"); + + await appRunner.ExecuteAsync(() => Task.CompletedTask); + + Assert.Equal(0, appRunner.ExitCode); + } + +#if !NET7_0_OR_GREATER + [Theory] + [MemberData(nameof(ProfilerHelper.GetArchitecture), MemberType = typeof(ProfilerHelper))] + public async Task ValidateProfilerIsNotInstalledOnNet6(Architecture targetArchitecture) { await ScenarioRunner.SingleTarget( _outputHelper, @@ -80,7 +117,8 @@ await ScenarioRunner.SingleTarget( }; }, profilerLogLevel: LogLevel.Trace, - subScenarioName: subScenario); + subScenarioName: TestAppScenarios.FunctionProbes.SubScenarios.ValidateNoMutatingProfiler); } +#endif // NET7_0_OR_GREATER } } diff --git a/src/Tests/Microsoft.Diagnostics.Monitoring.Tool.FunctionalTests/HostingStartupTests.cs b/src/Tests/Microsoft.Diagnostics.Monitoring.Tool.FunctionalTests/HostingStartupTests.cs deleted file mode 100644 index fee42ee1bfd..00000000000 --- a/src/Tests/Microsoft.Diagnostics.Monitoring.Tool.FunctionalTests/HostingStartupTests.cs +++ /dev/null @@ -1,62 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -using Microsoft.Diagnostics.Monitoring.TestCommon; -using Microsoft.Diagnostics.Monitoring.TestCommon.Options; -using Microsoft.Diagnostics.Monitoring.Tool.FunctionalTests.Fixtures; -using Microsoft.Diagnostics.Monitoring.Tool.FunctionalTests.Runners; -using Microsoft.Diagnostics.Monitoring.WebApi; -using Microsoft.Extensions.DependencyInjection; -using Microsoft.Extensions.Logging; -using System.Net.Http; -using System.Threading.Tasks; -using Xunit; -using Xunit.Abstractions; - -namespace Microsoft.Diagnostics.Monitoring.Tool.FunctionalTests -{ - [TargetFrameworkMonikerTrait(TargetFrameworkMonikerExtensions.CurrentTargetFrameworkMoniker)] - [Collection(DefaultCollectionFixture.Name)] - public class HostingStartupTests - { - private readonly IHttpClientFactory _httpClientFactory; - private readonly ITestOutputHelper _outputHelper; - - public HostingStartupTests(ITestOutputHelper outputHelper, ServiceProviderFixture serviceProviderFixture) - { - _httpClientFactory = serviceProviderFixture.ServiceProvider.GetService(); - _outputHelper = outputHelper; - } - - - [Theory] - [InlineData(TestAppScenarios.HostingStartup.SubScenarios.VerifyAspNetApp, true)] - [InlineData(TestAppScenarios.HostingStartup.SubScenarios.VerifyAspNetAppWithoutHostingStartup, false)] - [InlineData(TestAppScenarios.HostingStartup.SubScenarios.VerifyNonAspNetAppNotImpacted, true)] - - public async Task HostingStartupLoadTests(string subScenario, bool tryLoadHostingStartup) - { - await ScenarioRunner.SingleTarget( - _outputHelper, - _httpClientFactory, - DiagnosticPortConnectionMode.Listen, - TestAppScenarios.HostingStartup.Name, - appValidate: (runner, client) => { return Task.CompletedTask; }, - configureApp: runner => - { - runner.EnableMonitorStartupHook = true; - }, - configureTool: runner => - { - runner.ConfigurationFromEnvironment.EnableInProcessFeatures(); - // Enable a feature that requires the hosting startup assembly. - runner.ConfigurationFromEnvironment.InProcessFeatures.ParameterCapturing = new() - { - Enabled = tryLoadHostingStartup - }; - }, - profilerLogLevel: LogLevel.Trace, - subScenarioName: subScenario); - } - } -} diff --git a/src/Tests/Microsoft.Diagnostics.Monitoring.Tool.FunctionalTests/Microsoft.Diagnostics.Monitoring.Tool.FunctionalTests.csproj b/src/Tests/Microsoft.Diagnostics.Monitoring.Tool.FunctionalTests/Microsoft.Diagnostics.Monitoring.Tool.FunctionalTests.csproj index e794b2c35a8..24b86ff27e4 100644 --- a/src/Tests/Microsoft.Diagnostics.Monitoring.Tool.FunctionalTests/Microsoft.Diagnostics.Monitoring.Tool.FunctionalTests.csproj +++ b/src/Tests/Microsoft.Diagnostics.Monitoring.Tool.FunctionalTests/Microsoft.Diagnostics.Monitoring.Tool.FunctionalTests.csproj @@ -85,7 +85,6 @@ - @@ -95,6 +94,7 @@ TargetFramework=net9.0 + diff --git a/src/Tests/Microsoft.Diagnostics.Monitoring.Tool.FunctionalTests/ParameterCapturingTests.cs b/src/Tests/Microsoft.Diagnostics.Monitoring.Tool.FunctionalTests/ParameterCapturingTests.cs index ee16752cbf5..55da1356767 100644 --- a/src/Tests/Microsoft.Diagnostics.Monitoring.Tool.FunctionalTests/ParameterCapturingTests.cs +++ b/src/Tests/Microsoft.Diagnostics.Monitoring.Tool.FunctionalTests/ParameterCapturingTests.cs @@ -51,7 +51,12 @@ public ParameterCapturingTests(ITestOutputHelper outputHelper, ServiceProviderFi [MemberData(nameof(ProfilerHelper.GetArchitecture), MemberType = typeof(ProfilerHelper))] public async Task UnresolvableMethodsFailsOperation(Architecture targetArchitecture) { - await RunTestCaseCore(TestAppScenarios.ParameterCapturing.SubScenarios.AspNetApp, targetArchitecture, async (appRunner, apiClient) => + await RunTestCaseCore( + TestAppScenarios.ParameterCapturing.SubScenarios.AspNetApp, + targetArchitecture, + shouldSuspendTargetApp: true, + enableStartupHook: true, + async (appRunner, apiClient) => { int processId = await appRunner.ProcessIdTask; @@ -77,53 +82,53 @@ await RunTestCaseCore(TestAppScenarios.ParameterCapturing.SubScenarios.AspNetApp [Theory] [MemberData(nameof(ProfilerHelper.GetArchitecture), MemberType = typeof(ProfilerHelper))] - public async Task NonAspNetAppFailsOperation(Architecture targetArchitecture) - { - await RunTestCaseCore(TestAppScenarios.ParameterCapturing.SubScenarios.NonAspNetApp, targetArchitecture, async (appRunner, apiClient) => - { - int processId = await appRunner.ProcessIdTask; - - CaptureParametersConfiguration config = GetValidConfiguration(); - - ValidationProblemDetailsException validationException = await Assert.ThrowsAsync(() => apiClient.CaptureParametersAsync(processId, Timeout.InfiniteTimeSpan, config)); - Assert.Equal(HttpStatusCode.BadRequest, validationException.StatusCode); - - await appRunner.SendCommandAsync(TestAppScenarios.ParameterCapturing.Commands.Continue); - }); - } + public Task CapturesParametersInNonAspNetApps(Architecture targetArchitecture) => + CapturesParametersCore(TestAppScenarios.ParameterCapturing.SubScenarios.NonAspNetApp, targetArchitecture, CapturedParameterFormat.JsonSequence, shouldSuspendTargetApp: true, enableStartupHook: true); [Theory] [MemberData(nameof(ProfilerHelper.GetArchitecture), MemberType = typeof(ProfilerHelper))] public Task CapturesParametersAndOutputJsonSequence(Architecture targetArchitecture) => - CapturesParametersCore(targetArchitecture, CapturedParameterFormat.JsonSequence); + CapturesParametersCore(TestAppScenarios.ParameterCapturing.SubScenarios.AspNetApp, targetArchitecture, CapturedParameterFormat.JsonSequence, shouldSuspendTargetApp: true, enableStartupHook: true); [Theory] [MemberData(nameof(ProfilerHelper.GetArchitecture), MemberType = typeof(ProfilerHelper))] public Task CapturesParametersAndOutputNewlineDelimitedJson(Architecture targetArchitecture) => - CapturesParametersCore(targetArchitecture, CapturedParameterFormat.NewlineDelimitedJson); + CapturesParametersCore(TestAppScenarios.ParameterCapturing.SubScenarios.AspNetApp, targetArchitecture, CapturedParameterFormat.NewlineDelimitedJson, shouldSuspendTargetApp: true, enableStartupHook: true); -#else // NET7_0_OR_GREATER +#if NET8_0_OR_GREATER [Theory] [MemberData(nameof(ProfilerHelper.GetArchitecture), MemberType = typeof(ProfilerHelper))] - public async Task Net6AppFailsOperation(Architecture targetArchitecture) - { - await RunTestCaseCore(TestAppScenarios.ParameterCapturing.SubScenarios.AspNetApp, targetArchitecture, async (appRunner, apiClient) => - { - int processId = await appRunner.ProcessIdTask; + public Task CapturesParametersNoSuspend(Architecture targetArchitecture) => + CapturesParametersCore(TestAppScenarios.ParameterCapturing.SubScenarios.AspNetApp, targetArchitecture, CapturedParameterFormat.JsonSequence, shouldSuspendTargetApp: false, enableStartupHook: false); - CaptureParametersConfiguration config = GetValidConfiguration(); +#endif // NET8_0_OR_GREATER - ValidationProblemDetailsException validationException = await Assert.ThrowsAsync(() => apiClient.CaptureParametersAsync(processId, Timeout.InfiniteTimeSpan, config)); - Assert.Equal(HttpStatusCode.BadRequest, validationException.StatusCode); + [Theory] + [MemberData(nameof(ProfilerHelper.GetArchitecture), MemberType = typeof(ProfilerHelper))] + public Task AppWithStartupHookFailsInNoSuspend(Architecture targetArchitecture) => + ValidateBadRequestFailure(TestAppScenarios.ParameterCapturing.SubScenarios.AspNetApp, targetArchitecture, shouldSuspendTargetApp: false, enableStartupHook: true); + +#else // NET7_0_OR_GREATER + [Theory] + [MemberData(nameof(ProfilerHelper.GetArchitecture), MemberType = typeof(ProfilerHelper))] + public Task Net6AppFailsOperation(Architecture targetArchitecture) => + ValidateBadRequestFailure(TestAppScenarios.ParameterCapturing.SubScenarios.AspNetApp, targetArchitecture, shouldSuspendTargetApp: true, enableStartupHook: true); - await appRunner.SendCommandAsync(TestAppScenarios.ParameterCapturing.Commands.Continue); - }); - } #endif // NET7_0_OR_GREATER - private async Task CapturesParametersCore(Architecture targetArchitecture, CapturedParameterFormat format) + private async Task CapturesParametersCore( + string subScenarioName, + Architecture targetArchitecture, + CapturedParameterFormat format, + bool shouldSuspendTargetApp, + bool enableStartupHook) { - await RunTestCaseCore(TestAppScenarios.ParameterCapturing.SubScenarios.AspNetApp, targetArchitecture, async (appRunner, apiClient) => + await RunTestCaseCore( + subScenarioName, + targetArchitecture, + shouldSuspendTargetApp: shouldSuspendTargetApp, + enableStartupHook: enableStartupHook, + async (appRunner, apiClient) => { int processId = await appRunner.ProcessIdTask; @@ -155,7 +160,36 @@ await RunTestCaseCore(TestAppScenarios.ParameterCapturing.SubScenarios.AspNetApp }); } - private async Task RunTestCaseCore(string subScenarioName, Architecture targetArchitecture, Func appValidate) + private async Task ValidateBadRequestFailure( + string subScenarioName, + Architecture targetArchitecture, + bool shouldSuspendTargetApp, + bool enableStartupHook) + { + await RunTestCaseCore( + subScenarioName, + targetArchitecture, + shouldSuspendTargetApp: shouldSuspendTargetApp, + enableStartupHook: enableStartupHook, + async (appRunner, apiClient) => + { + int processId = await appRunner.ProcessIdTask; + + CaptureParametersConfiguration config = GetValidConfiguration(); + + ValidationProblemDetailsException validationException = await Assert.ThrowsAsync(() => apiClient.CaptureParametersAsync(processId, Timeout.InfiniteTimeSpan, config)); + Assert.Equal(HttpStatusCode.BadRequest, validationException.StatusCode); + + await appRunner.SendCommandAsync(TestAppScenarios.ParameterCapturing.Commands.Continue); + }); + } + + private async Task RunTestCaseCore( + string subScenarioName, + Architecture targetArchitecture, + bool shouldSuspendTargetApp, + bool enableStartupHook, + Func appValidate) { await ScenarioRunner.SingleTarget( _outputHelper, @@ -165,8 +199,9 @@ await ScenarioRunner.SingleTarget( appValidate: appValidate, configureApp: runner => { - runner.EnableMonitorStartupHook = true; + runner.EnableMonitorStartupHook = enableStartupHook; runner.Architecture = targetArchitecture; + runner.DiagnosticPortSuspend = shouldSuspendTargetApp; }, configureTool: (toolRunner) => { @@ -178,7 +213,8 @@ await ScenarioRunner.SingleTarget( toolRunner.WriteKeyPerValueConfiguration(new RootOptions().AddFileSystemEgress(FileProviderName, _tempDirectory.FullName)); }, profilerLogLevel: LogLevel.Trace, - subScenarioName: subScenarioName); + subScenarioName: subScenarioName, + startAppBeforeTool: !shouldSuspendTargetApp); } private static CaptureParametersConfiguration GetValidConfiguration() diff --git a/src/Tests/Microsoft.Diagnostics.Monitoring.Tool.FunctionalTests/Runners/ScenarioRunner.cs b/src/Tests/Microsoft.Diagnostics.Monitoring.Tool.FunctionalTests/Runners/ScenarioRunner.cs index 341e3ad526a..ce60896f26b 100644 --- a/src/Tests/Microsoft.Diagnostics.Monitoring.Tool.FunctionalTests/Runners/ScenarioRunner.cs +++ b/src/Tests/Microsoft.Diagnostics.Monitoring.Tool.FunctionalTests/Runners/ScenarioRunner.cs @@ -28,7 +28,8 @@ public static async Task SingleTarget( Action configureTool = null, bool disableHttpEgress = false, LogLevel profilerLogLevel = LogLevel.Error, - string subScenarioName = null) + string subScenarioName = null, + bool startAppBeforeTool = false) { DiagnosticPortHelper.Generate( mode, @@ -43,37 +44,66 @@ public static async Task SingleTarget( configureTool?.Invoke(toolRunner); - await toolRunner.StartAsync(); - - using HttpClient httpClient = await toolRunner.CreateHttpClientDefaultAddressAsync(httpClientFactory); - ApiClient apiClient = new(outputHelper, httpClient); - - await using AppRunner appRunner = new(outputHelper, Assembly.GetExecutingAssembly()); - if (profilerLogLevel != LogLevel.None) + if (!startAppBeforeTool) { - appRunner.ProfilerLogLevel = profilerLogLevel.ToString("G"); + await toolRunner.StartAsync(); } - appRunner.ConnectionMode = appConnectionMode; - appRunner.DiagnosticPortPath = diagnosticPortPath; - appRunner.ScenarioName = scenarioName; - appRunner.SubScenarioName = subScenarioName; - configureApp?.Invoke(appRunner); +#nullable enable + HttpClient? httpClient = null; + ApiClient? apiClient = null; - await appRunner.ExecuteAsync(async () => + try { - // Wait for the process to be discovered. - int processId = await appRunner.ProcessIdTask; - _ = await apiClient.GetProcessWithRetryAsync(outputHelper, pid: processId); + if (!startAppBeforeTool) + { + httpClient = await toolRunner.CreateHttpClientDefaultAddressAsync(httpClientFactory); + apiClient = new(outputHelper, httpClient); + } + + await using AppRunner appRunner = new(outputHelper, Assembly.GetExecutingAssembly()); + if (profilerLogLevel != LogLevel.None) + { + appRunner.ProfilerLogLevel = profilerLogLevel.ToString("G"); + } + appRunner.ConnectionMode = appConnectionMode; + appRunner.DiagnosticPortPath = diagnosticPortPath; + appRunner.ScenarioName = scenarioName; + appRunner.SubScenarioName = subScenarioName; + + configureApp?.Invoke(appRunner); + + await appRunner.ExecuteAsync(async () => + { + if (startAppBeforeTool) + { + await toolRunner.StartAsync(); + httpClient = await toolRunner.CreateHttpClientDefaultAddressAsync(httpClientFactory); + apiClient = new(outputHelper, httpClient); + } - await appValidate(appRunner, apiClient); - }); - Assert.Equal(0, appRunner.ExitCode); + // Wait for the process to be discovered. + int processId = await appRunner.ProcessIdTask; + _ = await apiClient.GetProcessWithRetryAsync(outputHelper, pid: processId); - if (null != postAppValidate) + Assert.NotNull(apiClient); + + await appValidate(appRunner, apiClient); + }); + Assert.Equal(0, appRunner.ExitCode); + + Assert.NotNull(apiClient); + + if (null != postAppValidate) + { + await postAppValidate(apiClient, await appRunner.ProcessIdTask); + } + } + finally { - await postAppValidate(apiClient, await appRunner.ProcessIdTask); + httpClient?.Dispose(); } +#nullable disable } } } diff --git a/src/Tests/Microsoft.Diagnostics.Monitoring.Tool.FunctionalTests/StacksTests.cs b/src/Tests/Microsoft.Diagnostics.Monitoring.Tool.FunctionalTests/StacksTests.cs index 100f281177c..0a8631cbcae 100644 --- a/src/Tests/Microsoft.Diagnostics.Monitoring.Tool.FunctionalTests/StacksTests.cs +++ b/src/Tests/Microsoft.Diagnostics.Monitoring.Tool.FunctionalTests/StacksTests.cs @@ -40,6 +40,23 @@ public class StacksTests private const string NativeFrame = "[NativeFrame]"; private const string ExpectedThreadName = "TestThread"; + private static MethodInfo GetMethodInfo(string methodName) + { + // Strip off any generic type information. + if (methodName.Contains('[')) + { + methodName = methodName[..methodName.IndexOf('[')]; + } + + // Return null on psuedo frames (e.g. [NativeFrame]) + if (methodName.Length == 0) + { + return null; + } + + return typeof(Microsoft.Diagnostics.Monitoring.UnitTestApp.Scenarios.StacksWorker.StacksWorkerNested).GetMethod(methodName); + } + public StacksTests(ITestOutputHelper outputHelper, ServiceProviderFixture serviceProviderFixture) { _httpClientFactory = serviceProviderFixture.ServiceProvider.GetService(); @@ -452,8 +469,17 @@ await appRunner.ExecuteAsync(async () => private static string FormatFrame(string module, string @class, string function) => FormattableString.Invariant($"{module}!{@class}.{function}"); - private static bool AreFramesEqual(WebApi.Models.CallStackFrame left, WebApi.Models.CallStackFrame right) => - (left.ModuleName == right.ModuleName) && (left.TypeName == right.TypeName) && (left.MethodName == right.MethodName); + private static bool AreFramesEqual(WebApi.Models.CallStackFrame expected, WebApi.Models.CallStackFrame actual) + { + MethodInfo expectedMethodInfo = GetMethodInfo(expected.MethodName); + + return (expected.ModuleName == actual.ModuleName) && + (expected.TypeName == actual.TypeName) && + (expected.MethodName == actual.MethodName) && + ((expectedMethodInfo?.MetadataToken ?? 0) == actual.MethodToken) && + ((expectedMethodInfo?.Module.ModuleVersionId ?? Guid.Empty) == actual.ModuleVersionId); + + } private static bool AreFramesEqual(WebApi.Models.ProfileEvent left, WebApi.Models.ProfileEvent right) => (left.Frame == right.Frame) && (left.At == right.At) && (left.Type == right.Type); @@ -535,24 +561,24 @@ private static (WebApi.Models.CallStack, IList) Ge private static WebApi.Models.CallStackFrame[] ExpectedFrames() => new WebApi.Models.CallStackFrame[] { - new WebApi.Models.CallStackFrame - { - ModuleName = ExpectedModule, - TypeName = ExpectedClass, - MethodName = ExpectedCallbackFunction - }, - new WebApi.Models.CallStackFrame - { - ModuleName = NativeFrame, - TypeName = NativeFrame, - MethodName = NativeFrame - }, - new WebApi.Models.CallStackFrame - { - ModuleName = ExpectedModule, - TypeName = ExpectedClass, - MethodName = ExpectedFunction - } + new WebApi.Models.CallStackFrame + { + ModuleName = ExpectedModule, + TypeName = ExpectedClass, + MethodName = ExpectedCallbackFunction, + }, + new WebApi.Models.CallStackFrame + { + ModuleName = NativeFrame, + TypeName = NativeFrame, + MethodName = NativeFrame, + }, + new WebApi.Models.CallStackFrame + { + ModuleName = ExpectedModule, + TypeName = ExpectedClass, + MethodName = ExpectedFunction, + } }; } } diff --git a/src/Tests/Microsoft.Diagnostics.Monitoring.Tool.UnitTests/StartupHookTests.cs b/src/Tests/Microsoft.Diagnostics.Monitoring.Tool.UnitTests/StartupHookTests.cs index 25358ee9d2e..d9cf19c2681 100644 --- a/src/Tests/Microsoft.Diagnostics.Monitoring.Tool.UnitTests/StartupHookTests.cs +++ b/src/Tests/Microsoft.Diagnostics.Monitoring.Tool.UnitTests/StartupHookTests.cs @@ -4,7 +4,7 @@ using Microsoft.Diagnostics.Monitoring.TestCommon; using Microsoft.Diagnostics.Monitoring.TestCommon.Runners; using Microsoft.Diagnostics.NETCore.Client; -using Microsoft.Diagnostics.Tools.Monitor.HostingStartup; +using Microsoft.Diagnostics.Tools.Monitor.StartupHook; using Microsoft.Extensions.Logging; using System; using System.Collections.Generic; diff --git a/src/Tests/Microsoft.Diagnostics.Monitoring.Tool.UnitTests/TemplatesTests.cs b/src/Tests/Microsoft.Diagnostics.Monitoring.Tool.UnitTests/TemplatesTests.cs index cb6d2aa6742..307bedde981 100644 --- a/src/Tests/Microsoft.Diagnostics.Monitoring.Tool.UnitTests/TemplatesTests.cs +++ b/src/Tests/Microsoft.Diagnostics.Monitoring.Tool.UnitTests/TemplatesTests.cs @@ -15,6 +15,7 @@ using System.IO; using System.Linq; using System.Reflection; +using System.Threading.Tasks; using Xunit; using Xunit.Abstractions; @@ -39,7 +40,7 @@ public TemplatesTests(ITestOutputHelper outputHelper) /// Tests that Templates are correctly translated from JSON to CollectionRuleOptions. /// [Fact] - public async void TemplatesTranslationSuccessTest() + public async Task TemplatesTranslationSuccessTest() { using TemporaryDirectory userConfigDir = new(_outputHelper); @@ -84,7 +85,7 @@ await TestHostHelper.CreateCollectionRulesHost(_outputHelper, rootOptions => { } /// Tests that incorrectly referenced Templates error correctly. /// [Fact] - public async void TemplatesTranslationFailTest() + public async Task TemplatesTranslationFailTest() { using TemporaryDirectory userConfigDir = new(_outputHelper); diff --git a/src/Tests/Microsoft.Diagnostics.Monitoring.UnitTestApp/Microsoft.Diagnostics.Monitoring.UnitTestApp.csproj b/src/Tests/Microsoft.Diagnostics.Monitoring.UnitTestApp/Microsoft.Diagnostics.Monitoring.UnitTestApp.csproj index 417ff0bf4b0..185ac82e527 100644 --- a/src/Tests/Microsoft.Diagnostics.Monitoring.UnitTestApp/Microsoft.Diagnostics.Monitoring.UnitTestApp.csproj +++ b/src/Tests/Microsoft.Diagnostics.Monitoring.UnitTestApp/Microsoft.Diagnostics.Monitoring.UnitTestApp.csproj @@ -1,4 +1,4 @@ - + Exe @@ -7,17 +7,21 @@ true + + + + - + - + diff --git a/src/Tests/Microsoft.Diagnostics.Monitoring.UnitTestApp/Program.cs b/src/Tests/Microsoft.Diagnostics.Monitoring.UnitTestApp/Program.cs index 256bdd5cf47..f5cfd0d8d36 100644 --- a/src/Tests/Microsoft.Diagnostics.Monitoring.UnitTestApp/Program.cs +++ b/src/Tests/Microsoft.Diagnostics.Monitoring.UnitTestApp/Program.cs @@ -22,7 +22,6 @@ public static Task Main(string[] args) FunctionProbesScenario.Command(), LoggerScenario.Command(), ParameterCapturingScenario.Command(), - HostingStartupScenario.Command(), SpinWaitScenario.Command(), EnvironmentVariablesScenario.Command(), StacksScenario.Command(), diff --git a/src/Tests/Microsoft.Diagnostics.Monitoring.UnitTestApp/Scenarios/FunctionProbes/FunctionProbesScenario.cs b/src/Tests/Microsoft.Diagnostics.Monitoring.UnitTestApp/Scenarios/FunctionProbes/FunctionProbesScenario.cs index 65de7d25c9b..f4962615ad5 100644 --- a/src/Tests/Microsoft.Diagnostics.Monitoring.UnitTestApp/Scenarios/FunctionProbes/FunctionProbesScenario.cs +++ b/src/Tests/Microsoft.Diagnostics.Monitoring.UnitTestApp/Scenarios/FunctionProbes/FunctionProbesScenario.cs @@ -1,8 +1,8 @@ // Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. -using Microsoft.Diagnostics.Monitoring.HostingStartup.ParameterCapturing; -using Microsoft.Diagnostics.Monitoring.HostingStartup.ParameterCapturing.FunctionProbes; +using Microsoft.Diagnostics.Monitoring.StartupHook.ParameterCapturing; +using Microsoft.Diagnostics.Monitoring.StartupHook.ParameterCapturing.FunctionProbes; using Microsoft.Diagnostics.Monitoring.StartupHook; using Microsoft.Diagnostics.Monitoring.TestCommon; using SampleMethods; @@ -70,10 +70,10 @@ public static CliCommand Command() CliCommand testCaseCommand = new(subCommand); testCaseCommand.SetAction((result, token) => { - return ScenarioHelpers.RunScenarioAsync(async logger => + return ScenarioHelpers.RunScenarioAsync(async _ => { PerFunctionProbeProxy probeProxy = new PerFunctionProbeProxy(); - using FunctionProbesManager probeManager = new(logger); + using FunctionProbesManager probeManager = new(); await testCase(probeManager, probeProxy, token); @@ -389,9 +389,9 @@ private static async Task Test_DontProbeInMonitorContextAsync(FunctionProbesMana public static Task ValidateNoMutatingProfilerAsync(ParseResult result, CancellationToken token) { - return ScenarioHelpers.RunScenarioAsync(logger => + return ScenarioHelpers.RunScenarioAsync(_ => { - Assert.Throws(() => new FunctionProbesManager(logger)); + Assert.Throws(() => new FunctionProbesManager()); return Task.FromResult(0); }, token); diff --git a/src/Tests/Microsoft.Diagnostics.Monitoring.UnitTestApp/Scenarios/FunctionProbes/PerFunctionProbeProxy.cs b/src/Tests/Microsoft.Diagnostics.Monitoring.UnitTestApp/Scenarios/FunctionProbes/PerFunctionProbeProxy.cs index 64fd7b69f5e..275d7c4491a 100644 --- a/src/Tests/Microsoft.Diagnostics.Monitoring.UnitTestApp/Scenarios/FunctionProbes/PerFunctionProbeProxy.cs +++ b/src/Tests/Microsoft.Diagnostics.Monitoring.UnitTestApp/Scenarios/FunctionProbes/PerFunctionProbeProxy.cs @@ -8,7 +8,7 @@ using System.Threading; using Xunit.Sdk; -namespace Microsoft.Diagnostics.Monitoring.HostingStartup.ParameterCapturing.FunctionProbes +namespace Microsoft.Diagnostics.Monitoring.StartupHook.ParameterCapturing.FunctionProbes { internal sealed class PerFunctionProbeWrapper { diff --git a/src/Tests/Microsoft.Diagnostics.Monitoring.UnitTestApp/Scenarios/HostingStartupScenario.cs b/src/Tests/Microsoft.Diagnostics.Monitoring.UnitTestApp/Scenarios/HostingStartupScenario.cs deleted file mode 100644 index 582aeab617d..00000000000 --- a/src/Tests/Microsoft.Diagnostics.Monitoring.UnitTestApp/Scenarios/HostingStartupScenario.cs +++ /dev/null @@ -1,81 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -using Microsoft.AspNetCore.Builder; -using Microsoft.AspNetCore.Hosting; -using Microsoft.AspNetCore.Http; -using Microsoft.Diagnostics.Monitoring.TestCommon; -using Microsoft.Extensions.DependencyInjection; -using System.CommandLine; -using System.Threading; -using System.Threading.Tasks; -using Xunit; - -namespace Microsoft.Diagnostics.Monitoring.UnitTestApp.Scenarios -{ - internal sealed class HostingStartupScenario - { - public static CliCommand Command() - { - CliCommand aspnetAppNoHostingStartupCommand = new(TestAppScenarios.HostingStartup.SubScenarios.VerifyAspNetAppWithoutHostingStartup); - aspnetAppNoHostingStartupCommand.SetAction(VerifyAspNetAppWithoutHostingStartupAsync); - - CliCommand aspnetAppCommand = new(TestAppScenarios.HostingStartup.SubScenarios.VerifyAspNetApp); - aspnetAppCommand.SetAction(VerifyAspNetAppAsync); - - CliCommand nonAspNetAppCommand = new(TestAppScenarios.HostingStartup.SubScenarios.VerifyNonAspNetAppNotImpacted); - nonAspNetAppCommand.SetAction(VerifyNonAspNetAppNotImpactedAsync); - - CliCommand scenarioCommand = new(TestAppScenarios.HostingStartup.Name); - scenarioCommand.Subcommands.Add(aspnetAppNoHostingStartupCommand); - scenarioCommand.Subcommands.Add(aspnetAppCommand); - scenarioCommand.Subcommands.Add(nonAspNetAppCommand); - return scenarioCommand; - } - - public static Task VerifyNonAspNetAppNotImpactedAsync(ParseResult result, CancellationToken token) - { - return ScenarioHelpers.RunScenarioAsync(logger => - { - Assert.Equal(0, HostingStartup.HostingStartup.InvocationCount); - return Task.FromResult(0); - }, token); - } - - public static Task VerifyAspNetAppWithoutHostingStartupAsync(ParseResult result, CancellationToken token) - { - return ScenarioHelpers.RunWebScenarioAsync(logger => - { - Assert.Equal(0, HostingStartup.HostingStartup.InvocationCount); - return Task.FromResult(0); - }, token); - } - - public static Task VerifyAspNetAppAsync(ParseResult result, CancellationToken token) - { - return ScenarioHelpers.RunWebScenarioAsync(logger => - { - Assert.Equal(1, HostingStartup.HostingStartup.InvocationCount); - return Task.FromResult(0); - }, token); - } - - private sealed class Startup - { - public static void ConfigureServices(IServiceCollection services) - { - services.AddControllers(); - } - - public static void Configure(IApplicationBuilder app, IWebHostEnvironment env) - { - app.UseRouting(); - - app.UseEndpoints(endpoints => - { - endpoints.MapGet("/", () => Results.Ok()); - }); - } - } - } -} diff --git a/src/Tests/Microsoft.Diagnostics.Monitoring.UnitTestApp/Scenarios/ParameterCapturingScenario.cs b/src/Tests/Microsoft.Diagnostics.Monitoring.UnitTestApp/Scenarios/ParameterCapturingScenario.cs index c4030d4f1f6..ae9a0973382 100644 --- a/src/Tests/Microsoft.Diagnostics.Monitoring.UnitTestApp/Scenarios/ParameterCapturingScenario.cs +++ b/src/Tests/Microsoft.Diagnostics.Monitoring.UnitTestApp/Scenarios/ParameterCapturingScenario.cs @@ -48,6 +48,9 @@ public static Task NonAspNetAppAsync(ParseResult result, CancellationToken func: async logger => { await ScenarioHelpers.WaitForCommandAsync(TestAppScenarios.ParameterCapturing.Commands.Continue, logger); + + SampleMethods.StaticTestMethodSignatures.NoArgs(); + return 0; }, token); } diff --git a/src/Tools/dotnet-monitor/Commands/CollectCommandHandler.cs b/src/Tools/dotnet-monitor/Commands/CollectCommandHandler.cs index f3282419c73..20134f09fab 100644 --- a/src/Tools/dotnet-monitor/Commands/CollectCommandHandler.cs +++ b/src/Tools/dotnet-monitor/Commands/CollectCommandHandler.cs @@ -131,12 +131,15 @@ private static IHostBuilder Configure(this IHostBuilder builder, StartupAuthenti services.AddSingleton(); services.ConfigureCollectionRules(); services.ConfigureLibrarySharing(); + /* + * ConfigureInProcessFeatures needs to be called before ConfigureProfiler + * because the profiler needs to have access to environment variables set by in process features. + */ + services.ConfigureInProcessFeatures(context.Configuration); services.ConfigureProfiler(); services.ConfigureStartupHook(); - services.ConfigureHostingStartup(); services.ConfigureExceptions(); services.ConfigureStartupLoggers(authConfigurator); - services.ConfigureInProcessFeatures(context.Configuration); services.AddSingleton(); services.AddSingleton(); services.AddSingleton(); diff --git a/src/Tools/dotnet-monitor/Exceptions/EventExceptionsPipeline.cs b/src/Tools/dotnet-monitor/Exceptions/EventExceptionsPipeline.cs index c98d758d853..d302e5d6c02 100644 --- a/src/Tools/dotnet-monitor/Exceptions/EventExceptionsPipeline.cs +++ b/src/Tools/dotnet-monitor/Exceptions/EventExceptionsPipeline.cs @@ -94,6 +94,7 @@ private void Callback(TraceEvent traceEvent) case "FunctionDescription": _cache.AddFunction( traceEvent.GetPayload(NameIdentificationEvents.FunctionDescPayloads.FunctionId), + traceEvent.GetPayload(NameIdentificationEvents.FunctionDescPayloads.MethodToken), traceEvent.GetPayload(NameIdentificationEvents.FunctionDescPayloads.ClassId), traceEvent.GetPayload(NameIdentificationEvents.FunctionDescPayloads.ClassToken), traceEvent.GetPayload(NameIdentificationEvents.FunctionDescPayloads.ModuleId), @@ -105,6 +106,7 @@ private void Callback(TraceEvent traceEvent) case "ModuleDescription": _cache.AddModule( traceEvent.GetPayload(NameIdentificationEvents.ModuleDescPayloads.ModuleId), + traceEvent.GetPayload(NameIdentificationEvents.ModuleDescPayloads.ModuleVersionId), traceEvent.GetPayload(NameIdentificationEvents.ModuleDescPayloads.Name) ); break; diff --git a/src/Tools/dotnet-monitor/Exceptions/EventExceptionsPipelineNameCache.cs b/src/Tools/dotnet-monitor/Exceptions/EventExceptionsPipelineNameCache.cs index 8f761b50c40..3660d68925b 100644 --- a/src/Tools/dotnet-monitor/Exceptions/EventExceptionsPipelineNameCache.cs +++ b/src/Tools/dotnet-monitor/Exceptions/EventExceptionsPipelineNameCache.cs @@ -26,9 +26,9 @@ public void AddExceptionGroup(ulong id, ulong exceptionClassId, ulong throwingMe _exceptionGroupMap.Add(id, new ExceptionGroup(exceptionClassId, throwingMethodId, ilOffset)); } - public void AddFunction(ulong id, ulong classId, uint classToken, ulong moduleId, string name, ulong[] typeArgs, ulong[] parameterTypes) + public void AddFunction(ulong id, uint methodToken, ulong classId, uint classToken, ulong moduleId, string name, ulong[] typeArgs, ulong[] parameterTypes) { - _nameCache.FunctionData.TryAdd(id, new FunctionData(name, classId, classToken, moduleId, typeArgs ?? Array.Empty(), parameterTypes ?? Array.Empty())); + _nameCache.FunctionData.TryAdd(id, new FunctionData(name, methodToken, classId, classToken, moduleId, typeArgs ?? Array.Empty(), parameterTypes ?? Array.Empty())); } public void AddStackFrame(ulong id, ulong functionId, int ilOffset) @@ -36,9 +36,9 @@ public void AddStackFrame(ulong id, ulong functionId, int ilOffset) _stackFrames.Add(id, new StackFrameInstance(functionId, ilOffset)); } - public void AddModule(ulong id, string moduleName) + public void AddModule(ulong id, Guid moduleVersionId, string moduleName) { - _nameCache.ModuleData.TryAdd(id, new ModuleData(moduleName)); + _nameCache.ModuleData.TryAdd(id, new ModuleData(moduleName, moduleVersionId)); } public void AddToken(ulong moduleId, uint token, uint outerToken, string name, string @namespace) diff --git a/src/Tools/dotnet-monitor/Exceptions/ExceptionsOperation.cs b/src/Tools/dotnet-monitor/Exceptions/ExceptionsOperation.cs index f8063f2a13f..bd1ee3eb0cc 100644 --- a/src/Tools/dotnet-monitor/Exceptions/ExceptionsOperation.cs +++ b/src/Tools/dotnet-monitor/Exceptions/ExceptionsOperation.cs @@ -195,6 +195,7 @@ private async Task WriteJsonInstance(Stream stream, IExceptionInstance instance, assembledMethodName += builder.ToString(); } writer.WriteString("methodName", assembledMethodName); + writer.WriteNumber("methodToken", frame.MethodToken); writer.WriteStartArray("parameterTypes"); foreach (string parameterType in frame.FullParameterTypes) { @@ -203,6 +204,7 @@ private async Task WriteJsonInstance(Stream stream, IExceptionInstance instance, writer.WriteEndArray(); // end parameterTypes writer.WriteString("typeName", frame.TypeName); writer.WriteString("moduleName", frame.ModuleName); + writer.WriteString("moduleVersionId", frame.ModuleVersionId.ToString("D")); writer.WriteEndObject(); } diff --git a/src/Tools/dotnet-monitor/HostingStartup/HostingStartupService.cs b/src/Tools/dotnet-monitor/HostingStartup/HostingStartupService.cs deleted file mode 100644 index 9836d4b2fba..00000000000 --- a/src/Tools/dotnet-monitor/HostingStartup/HostingStartupService.cs +++ /dev/null @@ -1,91 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -using Microsoft.Diagnostics.Monitoring.WebApi; -using Microsoft.Diagnostics.NETCore.Client; -using Microsoft.Diagnostics.Tools.Monitor.LibrarySharing; -using Microsoft.Diagnostics.Tools.Monitor.StartupHook; -using Microsoft.Extensions.FileProviders; -using Microsoft.Extensions.Logging; -using System; -using System.IO; -using System.Threading; -using System.Threading.Tasks; - -namespace Microsoft.Diagnostics.Tools.Monitor.HostingStartup -{ - internal sealed class HostingStartupService - : IDiagnosticLifetimeService - { - // Intent is to ship a single TFM of the hosting startup, which should be the lowest supported version. - private const string HostingStartupFileName = "Microsoft.Diagnostics.Monitoring.HostingStartup.dll"; - private const string HostingStartupTargetFramework = "net6.0"; - - private readonly IEndpointInfo _endpointInfo; - private readonly StartupHookService _startupHookService; - private readonly IInProcessFeatures _inProcessFeatures; - private readonly ISharedLibraryService _sharedLibraryService; - private readonly ILogger _logger; - - public HostingStartupService( - IEndpointInfo endpointInfo, - StartupHookService startupHookService, - ISharedLibraryService sharedLibraryService, - IInProcessFeatures inProcessFeatures, - ILogger logger) - { - _endpointInfo = endpointInfo; - _startupHookService = startupHookService; - _inProcessFeatures = inProcessFeatures; - _sharedLibraryService = sharedLibraryService; - _logger = logger; - } - - public async ValueTask StartAsync(CancellationToken cancellationToken) - { - if (!_inProcessFeatures.IsHostingStartupRequired) - { - return; - } - - // Hosting startup is only supported on .NET 6+ - if (_endpointInfo.RuntimeVersion == null || _endpointInfo.RuntimeVersion.Major < 6) - { - return; - } - - try - { - // Hosting startup requires the startup hook - if (!await _startupHookService.Applied.WaitAsync(cancellationToken)) - { - return; - } - - IFileProviderFactory fileProviderFactory = await _sharedLibraryService.GetFactoryAsync(cancellationToken); - IFileProvider managedFileProvider = fileProviderFactory.CreateManaged(HostingStartupTargetFramework); - - IFileInfo hostingStartupLibraryFileInfo = managedFileProvider.GetFileInfo(HostingStartupFileName); - if (!hostingStartupLibraryFileInfo.Exists) - { - throw new FileNotFoundException(Strings.ErrorMessage_UnableToFindHostingStartupAssembly, hostingStartupLibraryFileInfo.Name); - } - - DiagnosticsClient client = new DiagnosticsClient(_endpointInfo.Endpoint); - await client.SetEnvironmentVariableAsync( - StartupHookIdentifiers.EnvironmentVariables.HostingStartupPath, - hostingStartupLibraryFileInfo.PhysicalPath, - cancellationToken); - } - catch (Exception ex) - { - _logger.UnableToApplyHostingStartup(ex); - } - } - - public ValueTask StopAsync(CancellationToken cancellationToken) - { - return ValueTask.CompletedTask; - } - } -} diff --git a/src/Tools/dotnet-monitor/InProcessFeatures/InProcessFeatures.cs b/src/Tools/dotnet-monitor/InProcessFeatures/InProcessFeatures.cs index 55f99c6d780..8d48f0313a2 100644 --- a/src/Tools/dotnet-monitor/InProcessFeatures/InProcessFeatures.cs +++ b/src/Tools/dotnet-monitor/InProcessFeatures/InProcessFeatures.cs @@ -32,10 +32,8 @@ public InProcessFeatures( public bool IsMutatingProfilerRequired => IsParameterCapturingEnabled; - public bool IsStartupHookRequired => IsHostingStartupRequired || IsExceptionsEnabled; + public bool IsStartupHookRequired => IsParameterCapturingEnabled || IsExceptionsEnabled; - public bool IsHostingStartupRequired => IsParameterCapturingEnabled; - - public bool IsLibrarySharingRequired => IsProfilerRequired || IsStartupHookRequired || IsHostingStartupRequired; + public bool IsLibrarySharingRequired => IsProfilerRequired || IsStartupHookRequired; } } diff --git a/src/Tools/dotnet-monitor/InProcessFeatures/InProcessFeaturesEndpointInfoSourceCallbacks.cs b/src/Tools/dotnet-monitor/InProcessFeatures/InProcessFeaturesEndpointInfoSourceCallbacks.cs index f194c6bf7fe..0c3aa44491c 100644 --- a/src/Tools/dotnet-monitor/InProcessFeatures/InProcessFeaturesEndpointInfoSourceCallbacks.cs +++ b/src/Tools/dotnet-monitor/InProcessFeatures/InProcessFeaturesEndpointInfoSourceCallbacks.cs @@ -5,7 +5,7 @@ using System.Threading; using System.Threading.Tasks; -namespace Microsoft.Diagnostics.Tools.Monitor.HostingStartup +namespace Microsoft.Diagnostics.Tools.Monitor.StartupHook { internal sealed class InProcessFeaturesEndpointInfoSourceCallbacks : IEndpointInfoSourceCallbacks { diff --git a/src/Tools/dotnet-monitor/InProcessFeatures/InProcessFeaturesIdentifiers.cs b/src/Tools/dotnet-monitor/InProcessFeatures/InProcessFeaturesIdentifiers.cs index 3e2606a040a..c4e2118d210 100644 --- a/src/Tools/dotnet-monitor/InProcessFeatures/InProcessFeaturesIdentifiers.cs +++ b/src/Tools/dotnet-monitor/InProcessFeatures/InProcessFeaturesIdentifiers.cs @@ -1,7 +1,7 @@ // Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. -namespace Microsoft.Diagnostics.Tools.Monitor.HostingStartup +namespace Microsoft.Diagnostics.Tools.Monitor.StartupHook { public static class InProcessFeaturesIdentifiers { @@ -26,7 +26,6 @@ public static class AvailableInfrastructure private const string AvailableInfrastructurePrefix = InProcessFeaturesPrefix + "AvailableInfrastructure_"; public const string ManagedMessaging = AvailableInfrastructurePrefix + nameof(ManagedMessaging); public const string StartupHook = AvailableInfrastructurePrefix + nameof(StartupHook); - public const string HostingStartup = AvailableInfrastructurePrefix + nameof(HostingStartup); } } } diff --git a/src/Tools/dotnet-monitor/InProcessFeatures/InProcessFeaturesService.cs b/src/Tools/dotnet-monitor/InProcessFeatures/InProcessFeaturesService.cs index bd5d37b83e5..4311f8a5b7f 100644 --- a/src/Tools/dotnet-monitor/InProcessFeatures/InProcessFeaturesService.cs +++ b/src/Tools/dotnet-monitor/InProcessFeatures/InProcessFeaturesService.cs @@ -11,7 +11,7 @@ using System.Threading; using System.Threading.Tasks; -namespace Microsoft.Diagnostics.Tools.Monitor.HostingStartup +namespace Microsoft.Diagnostics.Tools.Monitor.StartupHook { internal sealed class InProcessFeaturesService { diff --git a/src/Tools/dotnet-monitor/LoggingExtensions.cs b/src/Tools/dotnet-monitor/LoggingExtensions.cs index 0a44b655669..5578be3cee7 100644 --- a/src/Tools/dotnet-monitor/LoggingExtensions.cs +++ b/src/Tools/dotnet-monitor/LoggingExtensions.cs @@ -512,12 +512,6 @@ internal static class LoggingExtensions logLevel: LogLevel.Debug, formatString: Strings.LogFormatString_EndpointRemovalFailed); - private static readonly Action _unableToApplyHostingStartup = - LoggerMessage.Define( - eventId: LoggingEventIds.UnableToApplyHostingStartup.EventId(), - logLevel: LogLevel.Error, - formatString: Strings.LogFormatString_UnableToApplyHostingStartup); - private static readonly Action _unableToApplyInProcessFeatureFlags = LoggerMessage.Define( eventId: LoggingEventIds.UnableToApplyInProcessFeatureFlags.EventId(), @@ -954,11 +948,6 @@ public static void EndpointRemovalFailed(this ILogger logger, int processId, Exc _endpointRemovalFailed(logger, processId, ex); } - public static void UnableToApplyHostingStartup(this ILogger logger, Exception ex) - { - _unableToApplyHostingStartup(logger, ex); - } - public static void UnableToApplyInProcessFeatureFlags(this ILogger logger, Exception ex) { _unableToApplyInProcessFeatureFlags(logger, ex); diff --git a/src/Tools/dotnet-monitor/ParameterCapturing/CaptureParametersOperation.cs b/src/Tools/dotnet-monitor/ParameterCapturing/CaptureParametersOperation.cs index e1d4c74388a..12c32830bf8 100644 --- a/src/Tools/dotnet-monitor/ParameterCapturing/CaptureParametersOperation.cs +++ b/src/Tools/dotnet-monitor/ParameterCapturing/CaptureParametersOperation.cs @@ -6,8 +6,8 @@ using Microsoft.Diagnostics.Monitoring.WebApi; using Microsoft.Diagnostics.Monitoring.WebApi.Models; using Microsoft.Diagnostics.NETCore.Client; -using Microsoft.Diagnostics.Tools.Monitor.HostingStartup; using Microsoft.Diagnostics.Tools.Monitor.Profiler; +using Microsoft.Diagnostics.Tools.Monitor.StartupHook; using Microsoft.Extensions.Logging; using System; using System.Collections.Generic; @@ -94,23 +94,16 @@ static Exception getNotAvailableException(string reason) IDictionary env = await client.GetProcessEnvironmentAsync(token); - const string PreventHostingStartupEnvName = "ASPNETCORE_PREVENTHOSTINGSTARTUP"; - if (env.TryGetValue(PreventHostingStartupEnvName, out string preventHostingStartupEnvValue) && - ToolIdentifiers.IsEnvVarValueEnabled(preventHostingStartupEnvValue)) - { - throw getNotAvailableException(Strings.ParameterCapturingNotAvailable_Reason_PreventedHostingStartup); - } - if (!env.TryGetValue(InProcessFeaturesIdentifiers.EnvironmentVariables.AvailableInfrastructure.ManagedMessaging, out string isManagedMessagingAvailable) || !ToolIdentifiers.IsEnvVarValueEnabled(isManagedMessagingAvailable)) { throw getNotAvailableException(Strings.ParameterCapturingNotAvailable_Reason_ManagedMessagingDidNotLoad); } - if (!env.TryGetValue(InProcessFeaturesIdentifiers.EnvironmentVariables.AvailableInfrastructure.HostingStartup, out string isHostingStartupAvailable) || - !ToolIdentifiers.IsEnvVarValueEnabled(isHostingStartupAvailable)) + if (!env.TryGetValue(InProcessFeaturesIdentifiers.EnvironmentVariables.AvailableInfrastructure.StartupHook, out string isStartupHookAvailable) || + !ToolIdentifiers.IsEnvVarValueEnabled(isStartupHookAvailable)) { - throw getNotAvailableException(Strings.ParameterCapturingNotAvailable_Reason_HostingStartupDidNotLoad); + throw getNotAvailableException(Strings.ParameterCapturingNotAvailable_Reason_StartupHookDidNotLoad); } const string EditAndContinueEnvName = "COMPLUS_ForceEnc"; diff --git a/src/Tools/dotnet-monitor/ParameterCapturing/ParameterCapturingEvents.cs b/src/Tools/dotnet-monitor/ParameterCapturing/ParameterCapturingEvents.cs index f5deb7c7000..1975a8d085e 100644 --- a/src/Tools/dotnet-monitor/ParameterCapturing/ParameterCapturingEvents.cs +++ b/src/Tools/dotnet-monitor/ParameterCapturing/ParameterCapturingEvents.cs @@ -52,7 +52,8 @@ public enum CapturingFailedReason : uint UnresolvedMethods = 0, InvalidRequest, TooManyRequests, - InternalError + InternalError, + ProbeFaulted } public static class CapturingFailedPayloads diff --git a/src/Tools/dotnet-monitor/Profiler/ProfilerMessagePayloads.cs b/src/Tools/dotnet-monitor/Profiler/ProfilerMessagePayloads.cs index ded6c17f014..ed648f8ad8d 100644 --- a/src/Tools/dotnet-monitor/Profiler/ProfilerMessagePayloads.cs +++ b/src/Tools/dotnet-monitor/Profiler/ProfilerMessagePayloads.cs @@ -1,7 +1,7 @@ // Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. -#if STARTUPHOOK || HOSTINGSTARTUP +#if STARTUPHOOK using Microsoft.Diagnostics.Monitoring.StartupHook.MonitorMessageDispatcher.Models; #else using Microsoft.Diagnostics.Monitoring.WebApi.Models; diff --git a/src/Tools/dotnet-monitor/ServiceCollectionExtensions.cs b/src/Tools/dotnet-monitor/ServiceCollectionExtensions.cs index 606cc93adf3..834966d70e5 100644 --- a/src/Tools/dotnet-monitor/ServiceCollectionExtensions.cs +++ b/src/Tools/dotnet-monitor/ServiceCollectionExtensions.cs @@ -26,7 +26,6 @@ using Microsoft.Diagnostics.Tools.Monitor.Egress.FileSystem; using Microsoft.Diagnostics.Tools.Monitor.Exceptions; using Microsoft.Diagnostics.Tools.Monitor.Extensibility; -using Microsoft.Diagnostics.Tools.Monitor.HostingStartup; using Microsoft.Diagnostics.Tools.Monitor.LibrarySharing; using Microsoft.Diagnostics.Tools.Monitor.ParameterCapturing; using Microsoft.Diagnostics.Tools.Monitor.Profiler; @@ -359,13 +358,6 @@ public static IServiceCollection ConfigureExceptions(this IServiceCollection ser return services; } - public static IServiceCollection ConfigureHostingStartup(this IServiceCollection services) - { - services.AddScoped(); - services.AddScopedForwarder(); - return services; - } - public static IServiceCollection ConfigureRequestLimits(this IServiceCollection services) { services.AddSingleton(); diff --git a/src/Tools/dotnet-monitor/StartupHook/StartupHookIdentifiers.cs b/src/Tools/dotnet-monitor/StartupHook/StartupHookIdentifiers.cs deleted file mode 100644 index 5c581892070..00000000000 --- a/src/Tools/dotnet-monitor/StartupHook/StartupHookIdentifiers.cs +++ /dev/null @@ -1,16 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -namespace Microsoft.Diagnostics.Tools.Monitor.StartupHook -{ - public static class StartupHookIdentifiers - { - public static class EnvironmentVariables - { - private const string StartupHookPrefix = ToolIdentifiers.StandardPrefix + "StartupHook_"; - - // The full path of a HostingStartup assembly to load into a target process. - public const string HostingStartupPath = StartupHookPrefix + nameof(HostingStartupPath); - } - } -} diff --git a/src/Tools/dotnet-monitor/Strings.Designer.cs b/src/Tools/dotnet-monitor/Strings.Designer.cs index e6468279b8f..bf9c5d8a90a 100644 --- a/src/Tools/dotnet-monitor/Strings.Designer.cs +++ b/src/Tools/dotnet-monitor/Strings.Designer.cs @@ -538,15 +538,6 @@ internal static string ErrorMessage_UnableToDetermineTargetPlatform { } } - /// - /// Looks up a localized string similar to Unable to find hosting startup assembly at determined path.. - /// - internal static string ErrorMessage_UnableToFindHostingStartupAssembly { - get { - return ResourceManager.GetString("ErrorMessage_UnableToFindHostingStartupAssembly", resourceCulture); - } - } - /// /// Looks up a localized string similar to Unable to find profiler assembly at determined path.. /// @@ -1519,15 +1510,6 @@ internal static string LogFormatString_StartupHookInstructions { } } - /// - /// Looks up a localized string similar to Unable to apply hosting startup.. - /// - internal static string LogFormatString_UnableToApplyHostingStartup { - get { - return ResourceManager.GetString("LogFormatString_UnableToApplyHostingStartup", resourceCulture); - } - } - /// /// Looks up a localized string similar to Unable to apply in process feature flags.. /// @@ -1654,15 +1636,6 @@ internal static string Message_ShowSources { } } - /// - /// Looks up a localized string similar to This feature is only available on processes using ASP.NET Core. If the process is using ASP.NET Core and has successfully started, ensure that it has not been configured to prevent hosting startup assemblies from loading.. - /// - internal static string ParameterCapturingNotAvailable_Reason_HostingStartupDidNotLoad { - get { - return ResourceManager.GetString("ParameterCapturingNotAvailable_Reason_HostingStartupDidNotLoad", resourceCulture); - } - } - /// /// Looks up a localized string similar to The process has Hot Reload enabled.. /// @@ -1682,11 +1655,11 @@ internal static string ParameterCapturingNotAvailable_Reason_ManagedMessagingDid } /// - /// Looks up a localized string similar to The process has prevented hosting startup assemblies from loading using the ASPNETCORE_PREVENTHOSTINGSTARTUP environment variable.. + /// Looks up a localized string similar to This feature requires the startup hook to be loaded in the target process.. /// - internal static string ParameterCapturingNotAvailable_Reason_PreventedHostingStartup { + internal static string ParameterCapturingNotAvailable_Reason_StartupHookDidNotLoad { get { - return ResourceManager.GetString("ParameterCapturingNotAvailable_Reason_PreventedHostingStartup", resourceCulture); + return ResourceManager.GetString("ParameterCapturingNotAvailable_Reason_StartupHookDidNotLoad", resourceCulture); } } diff --git a/src/Tools/dotnet-monitor/Strings.resx b/src/Tools/dotnet-monitor/Strings.resx index 8616e168143..149fd3abebe 100644 --- a/src/Tools/dotnet-monitor/Strings.resx +++ b/src/Tools/dotnet-monitor/Strings.resx @@ -1,17 +1,17 @@  - @@ -897,12 +897,6 @@ 0. providerName: The name of the provider that failed validation. 1. errorMessage: The validation failure message - - Unable to find hosting startup assembly at determined path. - - - Unable to apply hosting startup. - Unable to apply in process feature flags. @@ -927,11 +921,8 @@ 1 Format Parameters: 0. reason: The reason why the feature is unavailable. - - The process has prevented hosting startup assemblies from loading using the ASPNETCORE_PREVENTHOSTINGSTARTUP environment variable. - - - This feature is only available on processes using ASP.NET Core. If the process is using ASP.NET Core and has successfully started, ensure that it has not been configured to prevent hosting startup assemblies from loading. + + This feature requires the startup hook to be loaded in the target process. An internal error occurred that has prevented communication with the process. @@ -949,4 +940,4 @@ The expiration time on or after the generated key will no longer be accepted. This is a time span offset (e.g. "7.00:00:00" for 7 days) that will be added to the current date time to create the expiration date time. Gets the string to display in help that explains what the '--expiration' option does. - \ No newline at end of file + diff --git a/src/Tools/dotnet-monitor/dotnet-monitor.csproj b/src/Tools/dotnet-monitor/dotnet-monitor.csproj index de82ee8efdc..241ee397586 100644 --- a/src/Tools/dotnet-monitor/dotnet-monitor.csproj +++ b/src/Tools/dotnet-monitor/dotnet-monitor.csproj @@ -73,7 +73,6 @@ - @@ -118,13 +117,6 @@ tools/$(TargetFramework)/any/shared/any/$(StartupHookTargetFramework) - - - tools/$(TargetFramework)/any/shared/any/$(HostingStartupTargetFramework) - - - tools/$(TargetFramework)/any/shared/any/$(HostingStartupTargetFramework) - diff --git a/src/archives/dotnet-monitor-base/Package.props b/src/archives/dotnet-monitor-base/Package.props index 6a317e71722..b82800d81e1 100644 --- a/src/archives/dotnet-monitor-base/Package.props +++ b/src/archives/dotnet-monitor-base/Package.props @@ -1,7 +1,6 @@ - dotnet-monitor