跳到正文
cccskills
免费在 GitHub 公开

aspire-service-defaults

Create a shared ServiceDefaults project for Aspire applications. Centralizes OpenTelemetry, health checks, resilience, and service discovery configuration across all services.

中文简介正在准备中。当前显示原文说明。

集成工具PostgreSQL

实测评分 未实测

查看安装方法

包含的文件(1)

  • SKILL.md10.2 KB

SKILL.md(原文)

安装前可以查看交给 AI 代理的指令内容。

Aspire Service Defaults

When to Use This Skill

Use this skill when:

  • Building Aspire-based distributed applications
  • Need consistent observability (logging, tracing, metrics) across services
  • Want shared health check configuration
  • Configuring HttpClient resilience and service discovery

What is ServiceDefaults?

ServiceDefaults is a shared project that provides common configuration for all services in an Aspire application:

  • OpenTelemetry - Logging, tracing, and metrics
  • Health Checks - Readiness and liveness endpoints
  • Service Discovery - Automatic service resolution
  • HTTP Resilience - Retry and circuit breaker policies

Every service references this project and calls AddServiceDefaults().


Project Structure

src/
  MyApp.ServiceDefaults/
    Extensions.cs
    MyApp.ServiceDefaults.csproj
  MyApp.Api/
    Program.cs  # Calls AddServiceDefaults()
  MyApp.Worker/
    Program.cs  # Calls AddServiceDefaults()
  MyApp.AppHost/
    Program.cs

ServiceDefaults Project

Project File

<Project Sdk="Microsoft.NET.Sdk">
  <PropertyGroup>
    <TargetFramework>net9.0</TargetFramework>
    <IsAspireSharedProject>true</IsAspireSharedProject>
  </PropertyGroup>

  <ItemGroup>
    <FrameworkReference Include="Microsoft.AspNetCore.App" />
    <PackageReference Include="Microsoft.Extensions.Http.Resilience" />
    <PackageReference Include="Microsoft.Extensions.ServiceDiscovery" />
    <PackageReference Include="OpenTelemetry.Exporter.OpenTelemetryProtocol" />
    <PackageReference Include="OpenTelemetry.Extensions.Hosting" />
    <PackageReference Include="OpenTelemetry.Instrumentation.AspNetCore" />
    <PackageReference Include="OpenTelemetry.Instrumentation.Http" />
    <PackageReference Include="OpenTelemetry.Instrumentation.Runtime" />
  </ItemGroup>
</Project>

Extensions.cs

using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Diagnostics.HealthChecks;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Diagnostics.HealthChecks;
using Microsoft.Extensions.Logging;
using OpenTelemetry;
using OpenTelemetry.Metrics;
using OpenTelemetry.Trace;

namespace Microsoft.Extensions.Hosting;

public static class Extensions
{
    private const string HealthEndpointPath = "/health";
    private const string AlivenessEndpointPath = "/alive";

    /// <summary>
    /// Adds common Aspire services: OpenTelemetry, health checks,
    /// service discovery, and HTTP resilience.
    /// </summary>
    public static TBuilder AddServiceDefaults<TBuilder>(this TBuilder builder)
        where TBuilder : IHostApplicationBuilder
    {
        builder.ConfigureOpenTelemetry();
        builder.AddDefaultHealthChecks();

        builder.Services.AddServiceDiscovery();

        builder.Services.ConfigureHttpClientDefaults(http =>
        {
            // Resilience: retries, circuit breaker, timeouts
            http.AddStandardResilienceHandler();

            // Service discovery: resolve service names to addresses
            http.AddServiceDiscovery();
        });

        return builder;
    }

    public static TBuilder ConfigureOpenTelemetry<TBuilder>(this TBuilder builder)
        where TBuilder : IHostApplicationBuilder
    {
        // Logging
        builder.Logging.AddOpenTelemetry(logging =>
        {
            logging.IncludeFormattedMessage = true;
            logging.IncludeScopes = true;
        });

        builder.Services.AddOpenTelemetry()
            // Metrics
            .WithMetrics(metrics =>
            {
                metrics
                    .AddAspNetCoreInstrumentation()
                    .AddHttpClientInstrumentation()
                    .AddRuntimeInstrumentation();
            })
            // Tracing
            .WithTracing(tracing =>
            {
                tracing
                    .AddSource(builder.Environment.ApplicationName)
                    .AddAspNetCoreInstrumentation(options =>
                        // Exclude health checks from traces
                        options.Filter = context =>
                            !context.Request.Path.StartsWithSegments(HealthEndpointPath) &&
                            !context.Request.Path.StartsWithSegments(AlivenessEndpointPath))
                    .AddHttpClientInstrumentation();
            });

        builder.AddOpenTelemetryExporters();

        return builder;
    }

    private static TBuilder AddOpenTelemetryExporters<TBuilder>(this TBuilder builder)
        where TBuilder : IHostApplicationBuilder
    {
        // Use OTLP exporter if endpoint is configured (Aspire Dashboard, Jaeger, etc.)
        var useOtlp = !string.IsNullOrWhiteSpace(
            builder.Configuration["OTEL_EXPORTER_OTLP_ENDPOINT"]);

        if (useOtlp)
        {
            builder.Services.AddOpenTelemetry().UseOtlpExporter();
        }

        return builder;
    }

    public static TBuilder AddDefaultHealthChecks<TBuilder>(this TBuilder builder)
        where TBuilder : IHostApplicationBuilder
    {
        builder.Services.AddHealthChecks()
            .AddCheck("self", () => HealthCheckResult.Healthy(), ["live"]);

        return builder;
    }

    /// <summary>
    /// Maps health check endpoints. Call after UseRouting().
    /// </summary>
    public static WebApplication MapDefaultEndpoints(this WebApplication app)
    {
        // Only expose in development - see security note below
        if (app.Environment.IsDevelopment())
        {
            // Readiness: all health checks must pass
            app.MapHealthChecks(HealthEndpointPath);

            // Liveness: only "live" tagged checks
            app.MapHealthChecks(AlivenessEndpointPath, new HealthCheckOptions
            {
                Predicate = r => r.Tags.Contains("live")
            });
        }

        return app;
    }
}

Usage in Services

API Service

var builder = WebApplication.CreateBuilder(args);

// Add all service defaults
builder.AddServiceDefaults();

// Add your services
builder.Services.AddControllers();

var app = builder.Build();

// Map health endpoints
app.MapDefaultEndpoints();

app.MapControllers();
app.Run();

Worker Service

var builder = Host.CreateApplicationBuilder(args);

// Works for non-web hosts too
builder.AddServiceDefaults();

builder.Services.AddHostedService<MyWorker>();

var host = builder.Build();
host.Run();

Adding Custom Health Checks

public static TBuilder AddDefaultHealthChecks<TBuilder>(this TBuilder builder)
    where TBuilder : IHostApplicationBuilder
{
    builder.Services.AddHealthChecks()
        // Basic liveness
        .AddCheck("self", () => HealthCheckResult.Healthy(), ["live"])

        // Database readiness
        .AddNpgSql(
            builder.Configuration.GetConnectionString("postgres")!,
            name: "postgres",
            tags: ["ready"])

        // Redis readiness
        .AddRedis(
            builder.Configuration.GetConnectionString("redis")!,
            name: "redis",
            tags: ["ready"])

        // Custom check
        .AddCheck<MyCustomHealthCheck>("custom", tags: ["ready"]);

    return builder;
}

Adding Custom Trace Sources

For Akka.NET or custom ActivitySources:

public static TBuilder ConfigureOpenTelemetry<TBuilder>(this TBuilder builder)
    where TBuilder : IHostApplicationBuilder
{
    builder.Services.AddOpenTelemetry()
        .WithTracing(tracing =>
        {
            tracing
                .AddSource(builder.Environment.ApplicationName)
                // Akka.NET tracing
                .AddSource("Akka.NET")
                // Custom sources
                .AddSource("MyApp.Orders")
                .AddSource("MyApp.Payments")
                .AddAspNetCoreInstrumentation()
                .AddHttpClientInstrumentation();
        });

    return builder;
}

Production Health Checks

For production, protect health endpoints or use different paths:

public static WebApplication MapDefaultEndpoints(this WebApplication app)
{
    // Always map for Kubernetes probes, but consider:
    // - Using internal-only ports
    // - Adding authorization
    // - Rate limiting

    app.MapHealthChecks("/health", new HealthCheckOptions
    {
        // Only return status, not details
        ResponseWriter = (context, report) =>
        {
            context.Response.ContentType = "text/plain";
            return context.Response.WriteAsync(report.Status.ToString());
        }
    });

    app.MapHealthChecks("/alive", new HealthCheckOptions
    {
        Predicate = r => r.Tags.Contains("live"),
        ResponseWriter = (context, report) =>
        {
            context.Response.ContentType = "text/plain";
            return context.Response.WriteAsync(report.Status.ToString());
        }
    });

    return app;
}

Integration with AppHost

The AppHost automatically configures OTLP endpoints:

// AppHost/Program.cs
var builder = DistributedApplication.CreateBuilder(args);

var postgres = builder.AddPostgres("postgres");
var redis = builder.AddRedis("redis");

var api = builder.AddProject<Projects.MyApp_Api>("api")
    .WithReference(postgres)
    .WithReference(redis);

builder.Build().Run();

Services receive OTEL_EXPORTER_OTLP_ENDPOINT automatically, sending telemetry to the Aspire Dashboard.


Best Practices

PracticeReason
One ServiceDefaults projectConsistent config across all services
Filter health checks from tracesReduces noise in observability data
Tag health checksSeparate liveness from readiness
Use StandardResilienceHandlerBuilt-in retry, circuit breaker, timeout
Add custom trace sourcesCapture domain-specific spans

Resources

评价

还没有评价。欢迎分享你的使用感受。

评论

无需登录即可发表。欢迎分享使用感受、提问,或说明在哪些环境下无法运行。

还没有评论。来写第一条吧。

提交后会立即公开。请勿填写邮箱、电话等个人信息。URL 最多 2 个。

0 / 1000 字

此表单受 reCAPTCHA 保护,适用 Google 的隐私权政策和服务条款。

同一仓库的技能

When the user wants to plan, design, or implement an A/B test or experiment. Also use when the user mentions "A/B test," "split test," "experiment," "test this change," "variant copy," "multivariate test," or "hypothesis." For tracking implementation, see analytics-tracking.

中文简介正在准备中。当前显示原文说明。

ComeOnOliver/skillshub642026年6月24日 更新

Audit and improve web accessibility following WCAG 2.1 guidelines. Use when asked to "improve accessibility", "a11y audit", "WCAG compliance", "screen reader support", "keyboard navigation", or "make accessible".

中文简介正在准备中。当前显示原文说明。

ComeOnOliver/skillshub642026年6月24日 更新

Audit and improve web accessibility following WCAG 2.2 guidelines. Use when asked to "improve accessibility", "a11y audit", "WCAG compliance", "screen reader support", "keyboard navigation", or "make accessible".

中文简介正在准备中。当前显示原文说明。

ComeOnOliver/skillshub642026年6月24日 更新

This skill should be used when the user asks to "create an agent", "add an agent", "write a subagent", "agent frontmatter", "when to use description", "agent examples", "agent tools", "agent colors", "autonomous agent", or needs guidance on agent structure, system prompts, triggering conditions, or agent development best practices for Claude Code plugins.

中文简介正在准备中。当前显示原文说明。

ComeOnOliver/skillshub642026年6月24日 更新

Head-to-head comparison of coding agents (Claude Code, Aider, Codex, etc.) on custom tasks with pass rate, cost, time, and consistency metrics

中文简介正在准备中。当前显示原文说明。

ComeOnOliver/skillshub642026年6月24日 更新

Design and optimize AI agent action spaces, tool definitions, and observation formatting for higher completion rates.

中文简介正在准备中。当前显示原文说明。

ComeOnOliver/skillshub642026年6月24日 更新

查看 ComeOnOliver 的全部技能

报告此技能的问题