diff --git a/website/src/docs/docs.json b/website/src/docs/docs.json index 2372e7d5a63..089507cb0dc 100644 --- a/website/src/docs/docs.json +++ b/website/src/docs/docs.json @@ -240,6 +240,10 @@ } ] }, + { + "path": "analyzers", + "title": "Analyzers" + }, { "path": "settings", "title": "Settings", @@ -257,6 +261,16 @@ "title": "Key Bindings" } ] + }, + { + "path": "migration", + "title": "Migration", + "items": [ + { + "path": "migrate-from-1-to-16", + "title": "Migrate from 1 to 16" + } + ] } ] } diff --git a/website/src/docs/fusion/v16/deployment-and-ci-cd.md b/website/src/docs/fusion/v16/deployment-and-ci-cd.md index 3a9295cb047..cbedcc70209 100644 --- a/website/src/docs/fusion/v16/deployment-and-ci-cd.md +++ b/website/src/docs/fusion/v16/deployment-and-ci-cd.md @@ -4,7 +4,7 @@ title: "Deployment and CI/CD" This page covers the CI/CD pipelines that ship a Fusion gateway in production: uploading source schemas to Nitro from each subgraph repository, publishing a Fusion configuration to a stage after a deployment, and validating composition on pull requests before merge. Composition runs in CI, the gateway pulls the latest archive from Nitro at runtime, and no archive file is ever shipped by hand. -The gateway closes the loop with `AddNitro().AddFusion()`, which subscribes to the latest archive on the configured stage and hot-swaps it without a restart. +The gateway closes the loop with `AddNitro().AddDefaults()`, which subscribes to the latest archive on the configured stage and hot-swaps it without a restart. # Prerequisites @@ -24,7 +24,7 @@ The deployment pipeline is split across two jobs. The **build job** compiles eac The runtime side is configured once on the gateway: ```csharp -builder.Services.AddNitro().AddFusion(); +builder.Services.AddNitro().AddDefaults(); builder.Services .AddGraphQLGatewayServer() @@ -36,6 +36,8 @@ builder.Services }); ``` +> **Note:** `AddDefaults()` is generated by a source generator in the `ChilliCream.Nitro` package. It requires the `ChilliCream.Nitro.Fusion` package to be referenced in your project. If `AddDefaults()` is not available, verify your package references or use the explicit `.AddFusion()` method instead. See the [Analyzers](/docs/nitro/analyzers) page for details. + With the runtime in place, every successful `nitro fusion publish` becomes the new configuration the gateway serves traffic against. You don't ship the archive yourself. ## Upload the source schema diff --git a/website/src/docs/fusion/v16/guides/first-party-api.md b/website/src/docs/fusion/v16/guides/first-party-api.md index d7e2e765fe7..665022bceb1 100644 --- a/website/src/docs/fusion/v16/guides/first-party-api.md +++ b/website/src/docs/fusion/v16/guides/first-party-api.md @@ -30,6 +30,7 @@ The Fusion gateway does not need `UsePersistedOperationPipeline()` because the g First, add the `ChilliCream.Nitro.Fusion` package to your gateway project: ```bash +dotnet add package ChilliCream.Nitro dotnet add package ChilliCream.Nitro.Fusion ``` @@ -38,9 +39,10 @@ Then configure the gateway: ```csharp var builder = WebApplication.CreateBuilder(args); +builder.Services.AddNitro().AddDefaults(); + builder .AddGraphQLGateway() - .AddNitro() .ModifyRequestOptions(o => { o.PersistedOperations.OnlyAllowPersistedDocuments = true; @@ -59,6 +61,8 @@ app.MapGraphQLPersistedOperations(); app.Run(); ``` +> **Note:** `AddDefaults()` is generated by a source generator in the `ChilliCream.Nitro` package. It requires the `ChilliCream.Nitro.Fusion` package to be referenced in your project. If `AddDefaults()` is not available, verify your package references or use the explicit `.AddFusion()` method instead. See the [Analyzers](/docs/nitro/analyzers) page for details. + `MapGraphQL()` is only registered in development. It exposes the standard GraphQL endpoint that client tooling needs: ad-hoc operations, introspection, and the schema endpoint at `/graphql/schema.graphql`. In production, only `MapGraphQLPersistedOperations()` is registered. The gateway exclusively accepts requests that reference a registered operation ID by URL, and the HTTP request parser skips reading the `query` field entirely. # What the settings do @@ -110,9 +114,10 @@ Use an HTTP request interceptor to allow ad-hoc operations in development while ```csharp var builder = WebApplication.CreateBuilder(args); +builder.Services.AddNitro().AddDefaults(); + builder .AddGraphQLGateway() - .AddNitro() .AddHttpRequestInterceptor() .ModifyRequestOptions(o => { @@ -189,9 +194,10 @@ builder.Services builder.Services.AddAuthorization(); +builder.Services.AddNitro().AddDefaults(); + builder .AddGraphQLGateway() - .AddNitro() .AddHttpRequestInterceptor() .ModifyRequestOptions(o => { diff --git a/website/src/docs/fusion/v16/migration/migrate-from-15-to-16.md b/website/src/docs/fusion/v16/migration/migrate-from-15-to-16.md index 0890c5dcbf7..3303a8cc9f2 100644 --- a/website/src/docs/fusion/v16/migration/migrate-from-15-to-16.md +++ b/website/src/docs/fusion/v16/migration/migrate-from-15-to-16.md @@ -649,19 +649,18 @@ The `watchFileForUpdates` parameter is gone — file watching is the default beh ### Nitro integration -Update all `ChilliCream.Nitro.*` packages to the same version as the `HotChocolate.Fusion.AspNetCore` package. If you're referencing any packages besides `ChilliCream.Nitro.Fusion` change the package references as shown below: +The packages have been restructured in v16. Versions now align with the rest of the platform, so you are migrating from `1.x` to `16.x`. For the full migration guide covering all package renames, API changes, and complete before/after examples, see [Migrating Nitro from 1 to 16](/docs/nitro/migration/migrate-from-1-to-16). -| Old | New | -| ------------------------------ | ------------------------------------------ | -| `ChilliCream.Nitro.Core` | `ChilliCream.Nitro.GraphQL` | -| `ChilliCream.Nitro` | `ChilliCream.Nitro.HotChocolate` | -| `ChilliCream.Nitro.Telemetry` | `ChilliCream.Nitro.OpenTelemetry` | -| `ChilliCream.Nitro.Azure.Core` | `ChilliCream.Nitro.Azure` | -| `ChilliCream.Nitro.*.Azure` | `ChilliCream.Nitro.Azure` (single package) | +The key changes for Fusion projects: -> Note: If you are self-hosting the Nitro backend, make sure to update it to the latest version as well. `10.1.0` is the minimum version required to work with the `ChilliCream.Nitro.*` packages. +- **Package rename:** `ChilliCream.Nitro.Core` becomes `ChilliCream.Nitro.GraphQL`, `ChilliCream.Nitro.Telemetry` becomes `ChilliCream.Nitro.OpenTelemetry`, and Azure packages are consolidated into `ChilliCream.Nitro.Azure`. +- **`ConfigureFromCloud()`** is replaced by `AddNitro().AddDefaults()` on the service collection. +- **Per-gateway feature options** are configured via `ModifyNitroOptions()` on the gateway builder. +- **`AddNitroExporter()`** is replaced by `AddOpenTelemetry()` on the `INitroBuilder`. +- **Asset cache** is now configured globally on `INitroBuilder` instead of per-gateway. +- **`AddDefaults()`** is a source-generated method that wires up the default integration when the correct packages are referenced. -v16 changes how Nitro is configured instead of the per gateway configuration `ConfigureFromCloud` call, you configure Nitro once on the service collection and then apply optional per gateway setting overrides. +> Note: If you are self-hosting the Nitro backend, make sure to update it to the latest version as well. `10.1.0` is the minimum version required to work with the `ChilliCream.Nitro.*` packages. **Before** @@ -686,101 +685,11 @@ builder.Services o.ApiKey = "..."; o.Stage = "..."; }) - .AddFusion(); + .AddDefaults(); builder.Services.AddGraphQLGatewayServer(); ``` -Per gateway settings can be overridden via the `ModifyNitroOptions` API. There have also been some changes to the structure of options. - -**Before** - -```csharp -builder.Services - .AddFusionGatewayServer() - .ConfigureFromCloud(o => - { - o.EnablePersistedQueries = true; - o.DefaultQueryCacheExpiration = TimeSpan.FromSeconds(30); - o.NotFoundQueryCacheExpiration = TimeSpan.FromSeconds(10); - - o.LocalFusionConfigurationFile = "gateway.fgp"; - - o.Metrics.Enabled = true; - o.Metrics.ExportIntervalMilliseconds = 1000; - o.Metrics.ExportTimeoutMilliseconds = 400; - - o.EnableOperationReporting = true; - }); -``` - -**After** - -```csharp -builder.Services - .AddGraphQLGatewayServer() - .ModifyNitroOptions(o => - { - o.PersistedOperations.Enabled = true; - o.PersistedOperations.DefaultQueryCacheExpiration = TimeSpan.FromSeconds(30); - o.PersistedOperations.NotFoundQueryCacheExpiration = TimeSpan.FromSeconds(10); - - o.LocalFusionConfigurationFile = "gateway.fgp"; - - o.Metrics.Enabled = true; - o.Metrics.ExportIntervalMilliseconds = 1000; - o.Metrics.ExportTimeoutMilliseconds = 400; - - o.OperationReporting.Enabled = true; - }); -``` - -If you were previously registering an asset cache you now do that on the `INitroBuilder` returned from `AddNitro()`: - -**Before** - -```csharp -builder.Services - .AddFusionGatewayServer() - .AddFileSystemAssetCache() - // or - .AddBlobStorageAssetCache() - // or - .AddAssetCache() -``` - -**After** - -```csharp -builder.Services - .AddNitro() - .AddFusion() - .AddFileSystemAssetCache() - // or - .AddBlobStorageAssetCache() - // or - .AddAssetCache() -``` - -If you were previously hand-rolling the `ConfigureOpenTelemetry*Provider(...)` configuration with `AddNitroExporter()`, you can also switch to a new `AddOpenTelemetry()` API on the `INitroBuilder` that handles the registration for you. - -**Before** - -```csharp -services.ConfigureOpenTelemetryMeterProvider(x => x.AddNitroExporter()); -services.ConfigureOpenTelemetryTracerProvider(x => x.AddNitroExporter()); -services.ConfigureOpenTelemetryLoggerProvider(x => x.AddNitroExporter()); -``` - -**After** - -```csharp -services - .AddNitro() - // ... - .AddOpenTelemetry(); -``` - ### Diagnostic listener API redesigned Fusion diagnostics were redesigned in v16. The high-level `ExecuteFederatedQuery`, `ResolveError`, `ResolveByKeyBatchError`, `QueryPlanExecutionError`, and `SubgraphRequestError` hooks are gone. The new API is execution-stage specific. diff --git a/website/src/docs/hotchocolate/v16/guides/private-api.md b/website/src/docs/hotchocolate/v16/guides/private-api.md index dea75387b56..e5d8841295c 100644 --- a/website/src/docs/hotchocolate/v16/guides/private-api.md +++ b/website/src/docs/hotchocolate/v16/guides/private-api.md @@ -31,6 +31,7 @@ First, add the `ChilliCream.Nitro` package to your project: ```bash dotnet add package ChilliCream.Nitro +dotnet add package ChilliCream.Nitro.HotChocolate ``` Then configure the server: @@ -38,10 +39,11 @@ Then configure the server: ```csharp var builder = WebApplication.CreateBuilder(args); +builder.Services.AddNitro(); + builder .AddGraphQL() .AddQueryType() - .AddNitro() .UsePersistedOperationPipeline() .ModifyRequestOptions(o => { @@ -135,10 +137,11 @@ public class DevToolsInterceptor : DefaultHttpRequestInterceptor Register the interceptor: ```csharp +builder.Services.AddNitro(); + builder .AddGraphQL() .AddQueryType() - .AddNitro() .AddHttpRequestInterceptor() .UsePersistedOperationPipeline() .ModifyRequestOptions(o => @@ -169,12 +172,13 @@ builder.Services builder.Services.AddAuthorization(); +builder.Services.AddNitro(); + builder .AddGraphQL() .AddQueryType() .AddMutationType() .AddAuthorization() - .AddNitro() .AddHttpRequestInterceptor() .UsePersistedOperationPipeline() .ModifyRequestOptions(o => diff --git a/website/src/docs/hotchocolate/v16/migrating/migrate-from-15-to-16.md b/website/src/docs/hotchocolate/v16/migrating/migrate-from-15-to-16.md index d818000d415..8f6aa8f735f 100644 --- a/website/src/docs/hotchocolate/v16/migrating/migrate-from-15-to-16.md +++ b/website/src/docs/hotchocolate/v16/migrating/migrate-from-15-to-16.md @@ -759,22 +759,19 @@ The `DefaultHttpMethod` enum has been removed. Use the `UseGet` boolean property ## Nitro integration -Update all `ChilliCream.Nitro.*` packages to the same version as the `HotChocolate.AspNetCore` package. The package layout has changed in v16, so most projects will need to update their package IDs as well as their code. +The Nitro NuGet packages have been restructured in v16. Versions now align with the rest of the platform, so you are migrating from `1.x` to `16.x`. For the full migration guide covering all package renames, API changes, and complete before/after examples, see [Migrating Nitro from 1 to 16](/docs/nitro/migration/migrate-from-1-to-16). -| Old | New | -| ------------------------------ | ------------------------------------------ | -| `ChilliCream.Nitro` | `ChilliCream.Nitro.HotChocolate` | -| `ChilliCream.Nitro.Core` | `ChilliCream.Nitro.GraphQL` | -| `ChilliCream.Nitro.Telemetry` | `ChilliCream.Nitro.OpenTelemetry` | -| `ChilliCream.Nitro.Azure.Core` | `ChilliCream.Nitro.Azure` | -| `ChilliCream.Nitro.*.Azure` | `ChilliCream.Nitro.Azure` (single package) | +The key changes for HotChocolate projects: -The package you previously referenced as `ChilliCream.Nitro` is now `ChilliCream.Nitro.HotChocolate`. A new meta-package is published under the old `ChilliCream.Nitro` ID, so don't mix the two up when updating your `.csproj`. +- **Package rename:** The old `ChilliCream.Nitro` package is now `ChilliCream.Nitro.HotChocolate`. A new meta-package takes the old `ChilliCream.Nitro` ID. +- **Connection settings** are configured once on the service collection via `AddNitro()`. +- **Per-schema feature options** (persisted operations, metrics, operation reporting) are configured via `ModifyNitroOptions()` on the GraphQL builder. +- **`AddNitroExporter()`** is replaced by `AddOpenTelemetry()` on the `INitroBuilder`. +- **Asset cache** is now configured globally on `INitroBuilder` instead of per-schema. +- **`AddDefaults()`** is a source-generated method that wires up the default integration when the correct packages are referenced. > Note: If you are self-hosting the Nitro backend, make sure to update it to the latest version as well. `10.1.0` is the minimum version required to work with the `ChilliCream.Nitro.*` packages. -v16 changes how Nitro is configured. The connection settings are configured once on the service collection and per-schema feature options are applied through `ModifyNitroOptions` on the GraphQL server builder. - **Before** ```csharp @@ -785,16 +782,8 @@ builder.Services o.ApiId = "..."; o.ApiKey = "..."; o.Stage = "..."; - o.EnablePersistedQueries = true; - o.DefaultQueryCacheExpiration = TimeSpan.FromSeconds(30); - o.NotFoundQueryCacheExpiration = TimeSpan.FromSeconds(10); - o.Metrics.Enabled = true; - o.Metrics.ExportIntervalMilliseconds = 1000; - o.Metrics.ExportTimeoutMilliseconds = 400; - - o.EnableOperationReporting = true; }); ``` @@ -808,71 +797,17 @@ builder.Services o.ApiKey = "..."; o.Stage = "..."; }) - .AddHotChocolate(); + .AddDefaults(); builder.Services .AddGraphQLServer() .ModifyNitroOptions(o => { o.PersistedOperations.Enabled = true; - o.PersistedOperations.DefaultQueryCacheExpiration = TimeSpan.FromSeconds(30); - o.PersistedOperations.NotFoundQueryCacheExpiration = TimeSpan.FromSeconds(10); - o.Metrics.Enabled = true; - o.Metrics.ExportIntervalMilliseconds = 1000; - o.Metrics.ExportTimeoutMilliseconds = 400; - - o.OperationReporting.Enabled = true; }); ``` -If you were previously registering an asset cache on the GraphQL server builder, you now do that on the `INitroBuilder` returned from `AddNitro()`. - -**Before** - -```csharp -builder.Services - .AddGraphQLServer() - .AddNitro() - .AddFileSystemAssetCache() - // or - .AddBlobStorageAssetCache() - // or - .AddAssetCache(); -``` - -**After** - -```csharp -builder.Services - .AddNitro() - .AddHotChocolate() - .AddFileSystemAssetCache() - // or - .AddBlobStorageAssetCache() - // or - .AddAssetCache(); -``` - -If you were previously hand-rolling the `ConfigureOpenTelemetry*Provider(...)` configuration with `AddNitroExporter()`, you can also switch to a new `AddOpenTelemetry()` API on the `INitroBuilder` that handles the registration for you. - -**Before** - -```csharp -services.ConfigureOpenTelemetryMeterProvider(x => x.AddNitroExporter()); -services.ConfigureOpenTelemetryTracerProvider(x => x.AddNitroExporter()); -services.ConfigureOpenTelemetryLoggerProvider(x => x.AddNitroExporter()); -``` - -**After** - -```csharp -services - .AddNitro() - // ... - .AddOpenTelemetry(); -``` - ## Server options now configured via ModifyServerOptions `GraphQLServerOptions` (GET requests, multipart, batching, schema requests, etc.) are now configured at the schema level using `ModifyServerOptions` instead of per-endpoint: diff --git a/website/src/docs/mocha/v16/observability.md b/website/src/docs/mocha/v16/observability.md index d154cd92d76..9676f3fc53d 100644 --- a/website/src/docs/mocha/v16/observability.md +++ b/website/src/docs/mocha/v16/observability.md @@ -139,36 +139,34 @@ builder.Services.AddSingleton( # Configure with Nitro -Nitro provides a managed telemetry backend for your Mocha services. Add the `ChilliCream.Nitro.Telemetry` package and configure the exporter: +Nitro provides a managed telemetry backend for your Mocha services. Add the `ChilliCream.Nitro` and `ChilliCream.Nitro.OpenTelemetry` packages and configure the exporter: -```csharp -dotnet add package ChilliCream.Nitro.Telemetry +```shell +dotnet add package ChilliCream.Nitro +dotnet add package ChilliCream.Nitro.OpenTelemetry ``` ```csharp +builder.Services + .AddNitro() + .AddOpenTelemetry(); + builder.Services .AddOpenTelemetry() .WithTracing(tracing => { - tracing - .AddSource("Mocha") - .AddNitroExporter(); + tracing.AddSource("Mocha"); }) .WithMetrics(metrics => { - metrics - .AddMeter("Mocha") - .AddNitroExporter(); + metrics.AddMeter("Mocha"); }); builder.Logging.AddOpenTelemetry(logging => { logging.IncludeFormattedMessage = true; logging.IncludeScopes = true; - logging.AddNitroExporter(); }); - -builder.Services.AddNitroTelemetry(); ``` Configure credentials through environment variables: diff --git a/website/src/docs/nitro/analyzers.md b/website/src/docs/nitro/analyzers.md new file mode 100644 index 00000000000..b1f6f24fb64 --- /dev/null +++ b/website/src/docs/nitro/analyzers.md @@ -0,0 +1,60 @@ +--- +title: "Analyzers" +--- + +The `ChilliCream.Nitro` meta-package ships with a Roslyn source generator that simplifies Nitro integration setup. It provides compile-time warnings when required packages are missing and generates an `AddDefaults()` extension method that wires everything up in a single call. + +# Compile-time warnings + +If your project references HotChocolate or Fusion but is missing the corresponding Nitro integration package, you get a compile-time warning: + +| Warning | Trigger | +| ---------- | ----------------------------------------------------------------- | +| **NS0001** | HotChocolate referenced without `ChilliCream.Nitro.HotChocolate` | +| **NS0002** | HotChocolate.Fusion referenced without `ChilliCream.Nitro.Fusion` | + +# Generated `AddDefaults()` extension method + +When the correct integration package is referenced, the generator emits an `AddDefaults()` extension method on `INitroBuilder`. This method wires up the default Nitro integration with the GraphQL pipeline in a single call. + +```csharp +builder.Services + .AddNitro(options => + { + options.ApiId = "my-api"; + options.ApiKey = "my-key"; + options.Stage = "production"; + }) + .AddDefaults(); +``` + +You can still customize per-schema options by calling `ModifyNitroOptions()` on the builder afterwards: + +```csharp +builder.Services + .AddNitro(options => + { + options.ApiId = "my-api"; + options.ApiKey = "my-key"; + }) + .AddDefaults(); + +builder.Services + .AddGraphQLServer() + .AddQueryType() + .ModifyNitroOptions(options => + { + options.PersistedOperations.Enabled = true; + options.Metrics.Enabled = true; + }); +``` + +# Troubleshooting + +If `AddDefaults()` does not appear in IntelliSense: + +1. Verify that `ChilliCream.Nitro` is referenced (this is the meta-package containing the source generator). +2. Verify that the matching integration package is referenced (`ChilliCream.Nitro.HotChocolate` for HotChocolate projects, `ChilliCream.Nitro.Fusion` for Fusion projects). +3. Rebuild the project so the source generator can run. + +If you cannot use the source generator, call the explicit method instead: `.AddHotChocolate()` or `.AddFusion()` on the `INitroBuilder`. diff --git a/website/src/docs/nitro/apis/fusion.md b/website/src/docs/nitro/apis/fusion.md index dfda9ed4b0e..a468338a838 100644 --- a/website/src/docs/nitro/apis/fusion.md +++ b/website/src/docs/nitro/apis/fusion.md @@ -38,37 +38,40 @@ With Nitro you can automate this process. You can configure your gateway to auto ## Configure your gateway -To configure your Fusion gateway to pull the configuration from Nitro, you need to install the `ChilliCream.Nitro.Fusion` package. You can do this by running the following command in your project's root directory: +To configure your Fusion gateway to pull the configuration from Nitro, you need to install the `ChilliCream.Nitro` and `ChilliCream.Nitro.Fusion` packages. You can do this by running the following commands in your project's root directory: ```bash +dotnet add package ChilliCream.Nitro dotnet add package ChilliCream.Nitro.Fusion ``` After installing the package, you need to configure the services in your startup class. Below is a sample implementation in C#: ```csharp -builder - .AddGraphQLGateway() - .ConfigureFromCloud(x => +builder.Services + .AddNitro(x => { x.ApiKey = "<>"; x.ApiId = "QXBpCmc5NGYwZTIzNDZhZjQ0NjBmYTljNDNhZDA2ZmRkZDA2Ng=="; x.Stage = "dev"; }) + .AddDefaults(); ``` +> **Note:** `AddDefaults()` is generated by a source generator in the `ChilliCream.Nitro` package. It requires the `ChilliCream.Nitro.Fusion` package to be referenced in your project. If `AddDefaults()` is not available, verify your package references or use the explicit `.AddFusion()` method instead. See the [Analyzers](/docs/nitro/analyzers) page for details. + > **Tip: Using Environment Variables** > -> Alternatively, you can set the required values using environment variables. This method allows you to call `ConfigureFromCloud` without explicitly passing parameters. +> Alternatively, you can set the required values using environment variables. This method allows you to call `AddNitro` without explicitly passing parameters. > > - `NITRO_API_KEY` maps to `ApiKey` > - `NITRO_API_ID` maps to `ApiId` > - `NITRO_STAGE` maps to `Stage` > > ```csharp -> builder -> .AddGraphQLGateway() -> .ConfigureFromCloud(); +> builder.Services +> .AddNitro() +> .AddDefaults(); > ``` > > In this setup, the API key, ID, and stage are set through environment variables. @@ -81,10 +84,11 @@ To set up your subgraphs to be linked with your gateway, you need to follow thes ### Step 1: Install ChilliCream.Nitro Package -First, ensure that the `ChilliCream.Nitro` package is installed in your subgraph projects. If not, you can install it by running the following command in the root directory of each subgraph project: +First, ensure that the `ChilliCream.Nitro` and `ChilliCream.Nitro.HotChocolate` packages are installed in your subgraph projects. If not, you can install them by running the following commands in the root directory of each subgraph project: ```bash dotnet add package ChilliCream.Nitro +dotnet add package ChilliCream.Nitro.HotChocolate ``` ### Step 2: Configure Services in Startup @@ -93,14 +97,17 @@ After installing the package, configure the Nitro Services on your schema. Here ```csharp services - .AddGraphQL() - .AddQueryType() .AddNitro(x => { x.ApiKey = "<>"; x.ApiId = "<>"; x.Stage = "dev"; }) + .AddOpenTelemetry(); + +services + .AddGraphQL() + .AddQueryType() .AddInstrumentation(); // Enable GraphQL telemetry services @@ -109,7 +116,6 @@ services { x.AddHttpClientInstrumentation(); x.AddAspNetCoreInstrumentation(); - x.AddNitroExporter(); // Register more instrumentation providers such as Entity Framework Core, HttpClient, etc. }); ``` @@ -266,9 +272,12 @@ To enable telemetry for your gateway and subgraphs, all of them need to be confi To send telemetry data from the gateway you need to add the instrumentation and the exporter to your gateway. ```csharp +builder.Services + .AddNitro() + .AddOpenTelemetry(); + builder .AddGraphQLGateway() - .ConfigureFromCloud() .CoreBuilder .AddInstrumentation(); @@ -276,8 +285,7 @@ builder.Services .AddOpenTelemetry() .WithTracing(b => b .AddHttpClientInstrumentation() - .AddAspNetCoreInstrumentation() - .AddNitroExporter()); + .AddAspNetCoreInstrumentation()); ``` Now your gateway will send the telemetry data to Nitro. To connect your subgraphs to the gateway, you need to add an extension to your `subgraph-config.json`. You need to specify the `apiId` of the subgraph @@ -312,17 +320,22 @@ For GraphQL services: ```csharp services - .AddGraphQL() - .AddAssetCache() + .AddNitro() + .AddAssetCache(); + +services + .AddGraphQL(); ``` For fusion services: ```csharp services - .AddGraphQLGateway() - .ConfigureFromCloud() - .AddAssetCache() + .AddNitro() + .AddAssetCache(); + +services + .AddGraphQLGateway(); ``` ## `FileSystemCache` @@ -331,11 +344,14 @@ This default cache stores data in the `assets` folder of your project. You can c ```csharp services - .AddGraphQL() + .AddNitro() .AddFileSystemAssetCache(x => { x.CacheDirectory = "cache"; // Your cache folder - }) + }); + +services + .AddGraphQL(); ``` ## `BlobStorageCache` @@ -352,14 +368,17 @@ Set it up with: ```csharp services - .AddGraphQL() + .AddNitro() .AddBlobStorageAssetCache(x => { x.ContainerName = "your-container-name"; x.Client = new BlobServiceClient( new Uri("https://yourblobstorage.blob.core.windows.net/"), new DefaultAzureCredential()); - }) + }); + +services + .AddGraphQL(); ``` ## Custom `IAssetCache` diff --git a/website/src/docs/nitro/apis/operation-reporting.md b/website/src/docs/nitro/apis/operation-reporting.md index 79489ed5272..2773e399e74 100644 --- a/website/src/docs/nitro/apis/operation-reporting.md +++ b/website/src/docs/nitro/apis/operation-reporting.md @@ -14,6 +14,7 @@ To install the Nitro services, run the following command in your project's root ```bash dotnet add package ChilliCream.Nitro +dotnet add package ChilliCream.Nitro.HotChocolate ``` After installing the package, you need to configure the services in your startup class. Below is a sample implementation in C#: @@ -22,14 +23,17 @@ After installing the package, you need to configure the services in your startup public void ConfigureServices(IServiceCollection services) { services - .AddGraphQL() - .AddQueryType() .AddNitro(x => { x.ApiKey = "<>"; x.ApiId = "QXBpCmc5NGYwZTIzNDZhZjQ0NjBmYTljNDNhZDA2ZmRkZDA2Ng=="; x.Stage = "dev"; - }); + }) + .AddDefaults(); + + services + .AddGraphQL() + .AddQueryType(); } ``` @@ -45,9 +49,12 @@ public void ConfigureServices(IServiceCollection services) > public void ConfigureServices(IServiceCollection services) > { > services -> .AddGraphQL() -> .AddQueryType() > .AddNitro() +> .AddDefaults(); +> +> services +> .AddGraphQL() +> .AddQueryType(); > } > ``` > diff --git a/website/src/docs/nitro/migration/migrate-from-1-to-16.md b/website/src/docs/nitro/migration/migrate-from-1-to-16.md new file mode 100644 index 00000000000..7028d6e4c40 --- /dev/null +++ b/website/src/docs/nitro/migration/migrate-from-1-to-16.md @@ -0,0 +1,483 @@ +--- +title: "Migrating from 1 to 16" +--- + +Starting with version 16, the packages align their version numbers with the rest of the platform (HotChocolate, Fusion, Mocha). This means you are migrating from `1.x` to `16.x`. + +The packages have been restructured to separate connection settings from feature configuration. The old monolithic `NitroOptions` class has been replaced, feature options are now configured per platform component, and whenever possible, have been consolidated into common packages. + +# Update Package References + +| Old Package ID | New Package ID | +| ------------------------------ | --------------------------------- | +| `ChilliCream.Nitro.Core` | `ChilliCream.Nitro.GraphQL` | +| `ChilliCream.Nitro` | `ChilliCream.Nitro.HotChocolate` | +| `ChilliCream.Nitro.Telemetry` | `ChilliCream.Nitro.OpenTelemetry` | +| `ChilliCream.Nitro.Azure.Core` | `ChilliCream.Nitro.Azure` | + +`ChilliCream.Nitro.Abstractions` is unchanged. + +> **Watch out:** The old `ChilliCream.Nitro` package becomes `ChilliCream.Nitro.HotChocolate`. A new meta-package is published under the old `ChilliCream.Nitro` ID. Don't mix these up when referencing. + +## Azure packages consolidated + +The old per-component Azure packages (`ChilliCream.Nitro.HotChocolate.Azure`, `ChilliCream.Nitro.Fusion.Azure`) have been replaced by a single `ChilliCream.Nitro.Azure` package. Remove the old ones and add the new one. + +# API Changes + +## `services.AddNitro()` returns builder + +The return type changed from `IServiceCollection` to `INitroBuilder`. This enables fluent chaining for add-on packages like OpenTelemetry and Azure asset caching. + +If you were chaining off `IServiceCollection`, capture the builder or access `.Services`: + +```csharp +// Before +services + .AddNitro(options => { options.ApiId = "my-api"; }) + .AddSingleton(); + +// After +services.AddNitro(options => { options.ApiId = "my-api"; }); +services.AddSingleton(); +``` + +## `AddNitro()` configures connection settings only + +The `IServiceCollection.AddNitro()` overload accepts `Action`, which contains only connection properties. Feature configuration happens on the GraphQL builder via `ModifyNitroOptions()`. + +```csharp +services.AddNitro(options => +{ + // Connection settings + options.ApiId = "my-api"; + options.ApiKey = "my-key"; + options.Stage = "production"; + options.ServerUrl = "https://api.chillicream.com"; + options.TelemetryUrl = "https://otel.chillicream.com"; + + // Feature options like Metrics and PersistedOperations + // are no longer available here. +}); +``` + +## HotChocolate: `AddNitro()` is now `ModifyNitroOptions()` + +The method on `IRequestExecutorBuilder` has been renamed from `AddNitro()` to `ModifyNitroOptions()`, and the options type changed to `NitroHotChocolateOptions`. + +The `ModifyNitroOptions()` method is optional. If you don't need to configure any per-schema options, you can omit it entirely. + +**Before** + +```csharp +services + .AddGraphQLServer() + .AddNitro(options => + { + options.ApiId = "my-api"; + options.EnablePersistedQueries = true; + options.Metrics.Enabled = true; + }); +``` + +**After** + +```csharp +services.AddNitro(options => +{ + options.ApiId = "my-api"; +}); + +services + .AddGraphQLServer() + .ModifyNitroOptions(options => + { + options.PersistedOperations.Enabled = true; + options.Metrics.Enabled = true; + }); +``` + +If you do not need to modify any per-schema options, you can omit the `ModifyNitroOptions()` call entirely. + +## Fusion: `ConfigureFromCloud()` is now `AddNitro().AddDefaults()` + +**Before** + +```csharp +builder.Services + .AddFusionGatewayServer() + .ConfigureFromCloud(options => + { + options.ApiId = "my-gateway"; + options.ApiKey = "my-key"; + options.Stage = "production"; + }); +``` + +**After** + +```csharp +builder.Services + .AddNitro(options => + { + options.ApiId = "my-gateway"; + options.ApiKey = "my-key"; + options.Stage = "production"; + }) + .AddDefaults(); + +builder.Services.AddGraphQLGatewayServer(); +``` + +Per-gateway feature options can be overridden via `ModifyNitroOptions()`: + +```csharp +builder.Services + .AddGraphQLGatewayServer() + .ModifyNitroOptions(options => + { + options.PersistedOperations.Enabled = true; + options.Metrics.Enabled = true; + options.OperationReporting.Enabled = true; + }); +``` + +If you do not need to modify any per-gateway options, you can omit the `ModifyNitroOptions()` call entirely. + +## OTLP exporters: `AddNitroExporter()` replaced by `AddOpenTelemetry()` + +`AddOpenTelemetry()` on `INitroBuilder` registers the Nitro OTLP exporters on the meter, tracer, and logger providers. You no longer wire each exporter by hand. + +**Before** + +```csharp +services.ConfigureOpenTelemetryMeterProvider(x => x.AddNitroExporter()); +services.ConfigureOpenTelemetryTracerProvider(x => x.AddNitroExporter()); +services.ConfigureOpenTelemetryLoggerProvider(x => x.AddNitroExporter()); +``` + +**After** + +```csharp +services + .AddNitro(options => + { + options.ApiId = "my-api"; + options.TelemetryUrl = "https://otel.chillicream.com"; + }) + .AddOpenTelemetry(); +``` + +## `AddNitroTelemetry` replaced + +If you were using `AddNitroTelemetry` for non-GraphQL service monitoring, replace it with `AddNitro().AddOpenTelemetry()`: + +**Before** + +```csharp +services.AddNitroTelemetry(options => +{ + options.ApiId = apiId; + options.ApiKey = apiKey; + options.Stage = stage; +}); +``` + +**After** + +```csharp +services + .AddNitro(options => + { + options.ApiId = apiId; + options.ApiKey = apiKey; + options.Stage = stage; + }) + .AddOpenTelemetry(); +``` + +## Asset cache is now global on `INitroBuilder` + +The asset cache is no longer configured per-schema on the request executor builder. Instead, it is a global singleton configured on `INitroBuilder`. A default file system cache is registered automatically. + +**Before** + +```csharp +services + .AddGraphQLServer() + .AddNitro() + .AddBlobStorageAssetCache(o => + { + o.Client = blobServiceClient; + o.ContainerName = "my-container"; + }); +``` + +**After** + +```csharp +services + .AddNitro(options => + { + options.ApiId = "my-api"; + options.ApiKey = "my-key"; + }) + .AddBlobStorageAssetCache(o => + { + o.Client = blobServiceClient; + o.ContainerName = "my-container"; + }); +``` + +# Source Generator: `AddDefaults()` + +The `ChilliCream.Nitro` meta-package ships with a Roslyn source generator. + +## Compile-time warnings for missing integration packages + +If your project references HotChocolate or Fusion but is missing the corresponding Nitro integration package, you get a compile-time warning: + +| Warning | Trigger | Fix | +| ---------- | ----------------------------------------------------------------- | ------------------------- | +| **NS0001** | HotChocolate referenced without `ChilliCream.Nitro.HotChocolate` | Add the package reference | +| **NS0002** | HotChocolate.Fusion referenced without `ChilliCream.Nitro.Fusion` | Add the package reference | + +## Generated `AddDefaults()` extension method + +When the correct integration package is referenced, the generator emits an `AddDefaults()` extension method on `INitroBuilder`. This method wires up the default Nitro integration with the GraphQL pipeline in a single call. + +For HotChocolate projects, `AddDefaults()` is equivalent to calling `services.AddGraphQLServer().ModifyNitroOptions()`. For Fusion projects, it is equivalent to calling `services.AddFusionGatewayServer().ModifyNitroOptions()`. + +```csharp +builder.Services + .AddNitro(options => + { + options.ApiId = "my-api"; + options.ApiKey = "my-key"; + options.Stage = "production"; + }) + .AddDefaults(); +``` + +You can still customize per-schema options by calling `ModifyNitroOptions()` on the builder afterwards: + +```csharp +builder.Services + .AddNitro(options => + { + options.ApiId = "my-api"; + options.ApiKey = "my-key"; + }) + .AddDefaults(); + +builder.Services + .AddGraphQLServer() + .AddQueryType() + .ModifyNitroOptions(options => + { + options.PersistedOperations.Enabled = true; + options.Metrics.Enabled = true; + }); +``` + +# Complete Before/After Examples + +## HotChocolate Standalone + +**Before** + +```csharp +var builder = WebApplication.CreateBuilder(args); + +builder.Services + .AddNitro(options => + { + options.ApiId = "my-api"; + options.ApiKey = "my-key"; + options.Stage = "production"; + options.EnablePersistedQueries = true; + options.Metrics.Enabled = true; + }); + +builder.Services + .AddGraphQLServer() + .AddQueryType() + .AddNitro(); + +var app = builder.Build(); +app.MapGraphQL(); +app.Run(); +``` + +**After** + +```csharp +var builder = WebApplication.CreateBuilder(args); + +builder.Services + .AddNitro(options => + { + options.ApiId = "my-api"; + options.ApiKey = "my-key"; + options.Stage = "production"; + }) + .AddDefaults(); + +builder.Services + .AddGraphQLServer() + .AddQueryType() + .ModifyNitroOptions(options => + { + options.PersistedOperations.Enabled = true; + options.Metrics.Enabled = true; + }); + +var app = builder.Build(); +app.MapGraphQL(); +app.Run(); +``` + +## Fusion Gateway + +**Before** + +```csharp +var builder = WebApplication.CreateBuilder(args); + +builder.Services + .AddFusionGatewayServer() + .ConfigureFromCloud(options => + { + options.ApiId = "my-gateway"; + options.ApiKey = "my-key"; + options.Stage = "production"; + }); + +var app = builder.Build(); +app.MapGraphQL(); +app.Run(); +``` + +**After** + +```csharp +var builder = WebApplication.CreateBuilder(args); + +builder.Services + .AddNitro(options => + { + options.ApiId = "my-gateway"; + options.ApiKey = "my-key"; + options.Stage = "production"; + }) + .AddDefaults(); + +builder.Services.AddGraphQLGatewayServer(); + +var app = builder.Build(); +app.MapGraphQL(); +app.Run(); +``` + +## With OpenTelemetry + +**Before** + +```csharp +var builder = WebApplication.CreateBuilder(args); + +builder.Services + .AddGraphQLServer() + .AddQueryType() + .AddNitro(options => + { + options.ApiId = "my-api"; + options.Metrics.Enabled = true; + }); + +services.ConfigureOpenTelemetryMeterProvider(x => x.AddNitroExporter()); +services.ConfigureOpenTelemetryTracerProvider(x => x.AddNitroExporter()); +services.ConfigureOpenTelemetryLoggerProvider(x => x.AddNitroExporter()); + +var app = builder.Build(); +app.MapGraphQL(); +app.Run(); +``` + +**After** + +```csharp +var builder = WebApplication.CreateBuilder(args); + +builder.Services + .AddNitro(options => + { + options.ApiId = "my-api"; + options.ApiKey = "my-key"; + options.Stage = "production"; + options.TelemetryUrl = "https://otel.chillicream.com"; + }) + .AddDefaults() + .AddOpenTelemetry(); + +builder.Services + .AddGraphQLServer() + .AddQueryType() + .ModifyNitroOptions(options => + { + options.Metrics.Enabled = true; + }); + +var app = builder.Build(); +app.MapGraphQL(); +app.Run(); +``` + +## With Azure Blob Storage Asset Cache + +**Before** + +```csharp +var builder = WebApplication.CreateBuilder(args); + +builder.Services + .AddGraphQLServer() + .AddQueryType() + .AddNitro() + .AddBlobStorageAssetCache(o => + { + o.Client = blobServiceClient; + o.ContainerName = "assets"; + }); + +var app = builder.Build(); +app.MapGraphQL(); +app.Run(); +``` + +**After** + +```csharp +var builder = WebApplication.CreateBuilder(args); + +builder.Services + .AddNitro(options => + { + options.ApiId = "my-api"; + options.ApiKey = "my-key"; + }) + .AddDefaults() + .AddBlobStorageAssetCache(o => + { + o.Client = blobServiceClient; + o.ContainerName = "assets"; + }); + +builder.Services + .AddGraphQLServer() + .AddQueryType(); + +var app = builder.Build(); +app.MapGraphQL(); +app.Run(); +``` diff --git a/website/src/docs/nitro/nitro-services.md b/website/src/docs/nitro/nitro-services.md index 281c834fa94..8be7b0b2e4c 100644 --- a/website/src/docs/nitro/nitro-services.md +++ b/website/src/docs/nitro/nitro-services.md @@ -14,6 +14,7 @@ To get started, follow these steps: ```bash dotnet add package ChilliCream.Nitro +dotnet add package ChilliCream.Nitro.HotChocolate ``` 3. Configure your services as shown in the following code snippet: @@ -21,16 +22,18 @@ dotnet add package ChilliCream.Nitro ```csharp var builder = WebApplication.CreateBuilder(args); -builder - .AddGraphQL() - .AddQueryType() - .AddInstrumentation() // if you want to use telemetry +builder.Services .AddNitro(x => { x.ApiId = "VGhpcyBpcyBub3QgYSByZWFsIGFwaSBpZA=="; x.ApiKey = "Tm9wZSwgdGhpcyBpcyBhbHNvIG5vIHJlYWwga2V5IDspIA=="; x.Stage = "dev"; - }) + }); + +builder + .AddGraphQL() + .AddQueryType() + .AddInstrumentation() // if you want to use telemetry .UseOnlyPersistedOperationAllowed() // optional .UsePersistedOperationPipeline(); // if you want to use persisted operations diff --git a/website/src/docs/nitro/open-telemetry/logging.md b/website/src/docs/nitro/open-telemetry/logging.md index 6e398a43f28..f85cc6ed7a5 100644 --- a/website/src/docs/nitro/open-telemetry/logging.md +++ b/website/src/docs/nitro/open-telemetry/logging.md @@ -41,6 +41,8 @@ To install the Nitro services, run the following commands in your project's root ```bash dotnet add package ChilliCream.Nitro +dotnet add package ChilliCream.Nitro.HotChocolate +dotnet add package ChilliCream.Nitro.OpenTelemetry dotnet add package OpenTelemetry.Extensions.Hosting dotnet add package OpenTelemetry.Instrumentation.AspNetCore ``` @@ -52,19 +54,21 @@ Below is a sample implementation in C#: public void ConfigureServices(IServiceCollection services) { services - .AddGraphQL() - .AddQueryType() .AddNitro(x => { x.ApiKey = "<>"; x.ApiId = "QXBpCmc5NGYwZTIzNDZhZjQ0NjBmYTljNDNhZDA2ZmRkZDA2Ng=="; x.Stage = "dev"; }) + .AddOpenTelemetry(); + + services + .AddGraphQL() + .AddQueryType() .AddInstrumentation(); services .AddLogging(x => x - .AddNitroExporter() .AddOpenTelemetry(options => { options.IncludeFormattedMessage = true; @@ -85,14 +89,16 @@ public void ConfigureServices(IServiceCollection services) > public void ConfigureServices(IServiceCollection services) > { > services +> .AddNitro() +> .AddOpenTelemetry(); +> +> services > .AddGraphQL() > .AddQueryType() -> .AddNitro() > .AddInstrumentation(); // Enable the graphql telemetry > > services > .AddLogging(x => x -> .AddNitroExporter() > .AddOpenTelemetry(options => > { > options.IncludeFormattedMessage = true; diff --git a/website/src/docs/nitro/open-telemetry/operation-monitoring.md b/website/src/docs/nitro/open-telemetry/operation-monitoring.md index b6c993450b1..ccbaeb2b3b2 100644 --- a/website/src/docs/nitro/open-telemetry/operation-monitoring.md +++ b/website/src/docs/nitro/open-telemetry/operation-monitoring.md @@ -22,6 +22,8 @@ To install the Nitro services, run the following commands in your project's root ```bash dotnet add package ChilliCream.Nitro +dotnet add package ChilliCream.Nitro.HotChocolate +dotnet add package ChilliCream.Nitro.OpenTelemetry dotnet add package OpenTelemetry.Extensions.Hosting dotnet add package OpenTelemetry.Instrumentation.AspNetCore ``` @@ -32,14 +34,17 @@ After installing the package, you need to configure the services in your startup public void ConfigureServices(IServiceCollection services) { services - .AddGraphQL() - .AddQueryType() .AddNitro(x => { x.ApiKey = "<>"; x.ApiId = "QXBpCmc5NGYwZTIzNDZhZjQ0NjBmYTljNDNhZDA2ZmRkZDA2Ng=="; x.Stage = "dev"; }) + .AddOpenTelemetry(); + + services + .AddGraphQL() + .AddQueryType() .AddInstrumentation(); // Enable the graphql telemetry services @@ -47,7 +52,6 @@ public void ConfigureServices(IServiceCollection services) .WithTracing(x => { x.AddAspNetCoreInstrumentation(); - x.AddNitroExporter(); }); } ``` @@ -64,9 +68,12 @@ public void ConfigureServices(IServiceCollection services) > public void ConfigureServices(IServiceCollection services) > { > services +> .AddNitro() +> .AddOpenTelemetry(); +> +> services > .AddGraphQL() > .AddQueryType() -> .AddNitro() > .AddInstrumentation(); // Enable the graphql telemetry > > services @@ -74,7 +81,6 @@ public void ConfigureServices(IServiceCollection services) > .WithTracing(x => > { > x.AddAspNetCoreInstrumentation(); -> x.AddNitroExporter(); > }); > } > ``` diff --git a/website/src/docs/nitro/open-telemetry/service-monitoring.md b/website/src/docs/nitro/open-telemetry/service-monitoring.md index e81dfdb01a2..080742aa58f 100644 --- a/website/src/docs/nitro/open-telemetry/service-monitoring.md +++ b/website/src/docs/nitro/open-telemetry/service-monitoring.md @@ -9,7 +9,7 @@ Nitro’s OpenTelemetry support extends beyond GraphQL, allowing you to gather a ## Prerequisites 1. **.NET Application**: You’ll need a .NET project (e.g., ASP.NET Core, worker service, etc.) where you want to enable telemetry. -2. **ChilliCream.Nitro.Telemetry**: Make sure to reference version **15.0.0** or **14.1.0** of the `ChilliCream.Nitro.Telemetry` package. +2. **ChilliCream.Nitro.OpenTelemetry**: Make sure to reference the `ChilliCream.Nitro` meta-package and the `ChilliCream.Nitro.OpenTelemetry` package. 3. **OpenTelemetry**: Have the OpenTelemetry packages or extensions configured in your project. ## Quick Start @@ -19,23 +19,30 @@ Nitro’s OpenTelemetry support extends beyond GraphQL, allowing you to gather a In your .NET project, install the following NuGet packages if they are not already present: ```shell -dotnet add package ChilliCream.Nitro.Telemetry --version 15.0.0 +dotnet add package ChilliCream.Nitro +dotnet add package ChilliCream.Nitro.OpenTelemetry dotnet add package OpenTelemetry --version dotnet add package OpenTelemetry.Extensions.Hosting --version ``` -### 2. Configure OpenTelemetry Exporters +### 2. Register Nitro and OpenTelemetry Exporters -Configure your OpenTelemetry **tracer** and **logger** providers to export data to Nitro. For example, in your `Program.cs` or `Startup.cs`: +Register the Nitro connection and OpenTelemetry exporters. Call `AddNitro` with your API credentials, then chain `AddOpenTelemetry()` to register the OTLP exporters for tracing, metrics, and logging. For example, in your `Program.cs` or `Startup.cs`: ```csharp -services.ConfigureOpenTelemetryTracerProvider(x => x.AddNitroExporter()); -services.ConfigureOpenTelemetryLoggerProvider(x => x.AddNitroExporter()); +services + .AddNitro(options => + { + options.ApiId = apiId; // Replace with your Nitro API ID + options.ApiKey = apiKey; // Replace with your Nitro API Key + options.Stage = stage; // Replace with your environment or stage name + }) + .AddOpenTelemetry(); ``` -If you’re using ASP.NET Core, you might do this in the `ConfigureServices` method. +### 3. Add Additional Instrumentation -You can also add additional instrumentation as needed, such as for HTTP requests or background jobs. +You can continue configuring OpenTelemetry providers for non-Nitro instrumentation as needed, such as for ASP.NET Core or HTTP requests. ```shell dotnet add package OpenTelemetry.Extensions.Hosting @@ -46,25 +53,9 @@ dotnet add package OpenTelemetry.Instrumentation.AspNetCore services.ConfigureOpenTelemetryTracerProvider(x => { x.AddAspNetCoreInstrumentation(); - x.AddNitroExporter(); }); ``` -### 3. Register Nitro Telemetry - -Next, register Nitro telemetry with the appropriate **API credentials** in the same method: - -```csharp -services.AddNitroTelemetry(options => -{ - options.ApiId = apiId; // Replace with your Nitro API ID - options.ApiKey = apiKey; // Replace with your Nitro API Key - options.Stage = stage; // Replace with your environment or stage name -}); -``` - -These options tell Nitro where to send the collected telemetry. - ### 4. View Your Traces Once your service is running, head over to the **Nitro dashboard**.