Skip to content
Back to skills

Maple Csharp Style

ASecurity

.NET / C# OpenTelemetry style for Maple: OpenTelemetry.Extensions.Hosting + OTLP HTTP exporter, ActivitySource for spans, ILogger bridging via WithLogging, inline endpoint + ingest key.

  • 1,799 stars
  • 0 votes
  • 0 copies
  • 0 views
  • Added October 1, 2026
devopsc#bashgitapi

Works with

  • cli
  • api

Security analysis

A100/100

Scanned October 1, 2026

npx -y skills add MapleTechLabs/maple --skill maple-csharp-style --agent claude-code

Installs into .claude/skills of the current project.

Are you the author of Maple Csharp Style?

Add the live security badge to your README. It updates with every re-scan.

Security grade badge for Maple Csharp Style
[![Security: A — Skills Directory](https://www.skillsdirectory.com/api/skills/mapletechlabs-maple-csharp-style/badge)](https://www.skillsdirectory.com/skills/mapletechlabs-maple-csharp-style)

More formats (shields.io, HTML) on the badges page. Keep it an A: scan every change in CI with Pro.

Download with Pro
SKILL.md
---
name: maple-csharp-style
description: ".NET / C# OpenTelemetry style for Maple: OpenTelemetry.Extensions.Hosting + OTLP HTTP exporter, ActivitySource for spans, ILogger bridging via WithLogging, inline endpoint + ingest key."
---

# Maple .NET / C# style

Use the official `OpenTelemetry` packages and wire them through the .NET hosting model. One `AddOpenTelemetry()` call on `IServiceCollection` configures traces, metrics, and `ILogger` export with a shared resource (`WithLogging` needs `OpenTelemetry.Extensions.Hosting` 1.9 or later).

## Install

```bash
dotnet add package OpenTelemetry.Extensions.Hosting
dotnet add package OpenTelemetry.Exporter.OpenTelemetryProtocol
dotnet add package OpenTelemetry.Instrumentation.AspNetCore
dotnet add package OpenTelemetry.Instrumentation.Http
```

## Bootstrap (ASP.NET Core)

Inline the endpoint and ingest key. The key is a project-scoped, write-only token (shaped like a Sentry DSN). No env-var indirection. With `HttpProtobuf`, an `Endpoint` set in code is used as-is, so include the `/v1/<signal>` path.

```csharp
using OpenTelemetry;
using OpenTelemetry.Exporter;
using OpenTelemetry.Logs;
using OpenTelemetry.Metrics;
using OpenTelemetry.Resources;
using OpenTelemetry.Trace;

const string MapleEndpoint = "https://ingest.maple.dev"; // EU: https://ingest.eu.maple.dev
const string MapleKey = "MAPLE_TEST"; // public ingest key (maple_pk_…), or MAPLE_TEST until the user has one

var builder = WebApplication.CreateBuilder(args);

void ConfigureOtlp(OtlpExporterOptions options, string path)
{
    options.Endpoint = new Uri($"{MapleEndpoint}/v1/{path}");
    options.Protocol = OtlpExportProtocol.HttpProtobuf;
    options.Headers = $"authorization=Bearer {MapleKey}";
}

builder.Services.AddOpenTelemetry()
    .ConfigureResource(r => r
        .AddService("orders-api")
        .AddAttributes(new Dictionary<string, object>
        {
            ["deployment.environment.name"] = builder.Environment.EnvironmentName,
            ["vcs.repository.url.full"] = "https://github.com/acme/orders-api",
            ["vcs.ref.head.revision"] = Environment.GetEnvironmentVariable("GITHUB_SHA") ?? "",
        }))
    .WithTracing(tracing => tracing
        .AddSource("orders.api") // every custom ActivitySource name, or its spans are dropped
        .AddAspNetCoreInstrumentation()
        .AddHttpClientInstrumentation()
        .AddOtlpExporter(o => ConfigureOtlp(o, "traces")))
    .WithMetrics(metrics => metrics
        .AddAspNetCoreInstrumentation()
        .AddHttpClientInstrumentation()
        .AddOtlpExporter(o => ConfigureOtlp(o, "metrics")))
    .WithLogging(
        logging => logging.AddOtlpExporter(o => ConfigureOtlp(o, "logs")),
        options =>
        {
            options.IncludeFormattedMessage = true;
            options.IncludeScopes = true;
        });

var app = builder.Build();
```

## Bounded business spans

Use a static `ActivitySource` per module and register its name with `.AddSource(...)`. Unregistered sources produce no spans: `StartActivity` returns `null`. ASP.NET Core and HttpClient instrumentation cover request spans. Use `ActivitySource.StartActivity` for business operations.

```csharp
public static class Tracing
{
    public static readonly ActivitySource Source = new("orders.api");
}

public sealed class OrderService
{
    public async Task SubmitAsync(string orderId, string tenantId)
    {
        using var activity = Tracing.Source.StartActivity("order.submit");
        activity?.SetTag("tenant.id", tenantId);
        activity?.SetTag("order.id", orderId);
        try
        {
            await ChargeAsync(orderId);
        }
        catch (Exception ex)
        {
            activity?.RecordException(ex);
            activity?.SetStatus(ActivityStatusCode.Error, ex.Message);
            throw;
        }
    }
}
```

`ActivitySource` and `ActivityStatusCode` live in `System.Diagnostics`. `RecordException(Exception)` is an extension method in `OpenTelemetry.Trace`, so add `using OpenTelemetry.Trace;`.

## Logs

Once `WithLogging` is wired, `ILogger<T>` records carry the active `Activity`'s `TraceId` / `SpanId`. Do not replace the user's existing logger or providers; OTLP export runs alongside them.

## Coexistence

If the project already exports to Application Insights, Datadog, or Honeycomb, keep those. `WithTracing(...)` accepts multiple exporters: chain `.AddOtlpExporter(...)` for Maple next to the existing one.

Attribution

Is this your skill, or is something wrong with this listing? Request removal or report an issue. Author removals are honored within 72 hours.

Comments

Loading comments…