Kyroon.Events 1.0.0

dotnet add package Kyroon.Events --version 1.0.0
                    
NuGet\Install-Package Kyroon.Events -Version 1.0.0
                    
This command is intended to be used within the Package Manager Console in Visual Studio, as it uses the NuGet module's version of Install-Package.
<PackageReference Include="Kyroon.Events" Version="1.0.0" />
                    
For projects that support PackageReference, copy this XML node into the project file to reference the package.
<PackageVersion Include="Kyroon.Events" Version="1.0.0" />
                    
Directory.Packages.props
<PackageReference Include="Kyroon.Events" />
                    
Project file
For projects that support Central Package Management (CPM), copy this XML node into the solution Directory.Packages.props file to version the package.
paket add Kyroon.Events --version 1.0.0
                    
#r "nuget: Kyroon.Events, 1.0.0"
                    
#r directive can be used in F# Interactive and Polyglot Notebooks. Copy this into the interactive tool or source code of the script to reference the package.
#:package Kyroon.Events@1.0.0
                    
#:package directive can be used in C# file-based apps starting in .NET 10 preview 4. Copy this into a .cs file before any lines of code to reference the package.
#addin nuget:?package=Kyroon.Events&version=1.0.0
                    
Install as a Cake Addin
#tool nuget:?package=Kyroon.Events&version=1.0.0
                    
Install as a Cake Tool

Kyroon.Events

SDK cliente oficial para enviar eventos ao Kyroon (https://api.kyroon.ai).

Sua aplicação captura um erro → chama uma linha → o incidente aparece no módulo de Incidentes do Kyroon, agrupável, filtrável e com expiração automática.

catch (Exception ex)
{
    await _kyroon.ReportExceptionAsync(ex, path: "POST /v1/orders");
    throw;
}

Instalação

dotnet add package Kyroon.Events
Install-Package Kyroon.Events

Compatibilidade

Alvo Cobertura
net10.0, net9.0, net8.0 .NET 8, 9 e 10
netstandard2.0 .NET Core 2.0+, .NET 5/6/7, Mono, Xamarin, Unity
net471, net472, net48 .NET Framework 4.7.1, 4.7.2 e 4.8

.NET Framework 4.6.1 a 4.7 também funcionam, via netstandard2.0.

Dependências: nos alvos .NET Framework o pacote traz apenas System.Text.Json. Nos demais, adiciona Microsoft.Extensions.DependencyInjection.Abstractions e Microsoft.Extensions.Http para a integração com DI. Sem Polly, sem Newtonsoft.


Pré-requisitos no Kyroon

  1. Abra o projeto no app do Kyroon.
  2. Ligue Incidentes.
  3. Copie a Access Key (50 caracteres).

Sem o passo 2 a API responde 403 — e é definitivo, o SDK não reenvia.

A Access Key é um segredo de escrita: quem a tem grava incidentes no seu projeto. Guarde em variável de ambiente ou secret store, nunca no código.


Uso — .NET 8 / 9 / 10

// Program.cs
builder.Services.AddKyroonEvents(o =>
{
    o.AccessKey     = builder.Configuration["Kyroon:AccessKey"];
    o.DefaultOrigin = "checkout-api";
});
public class OrderService(IKyroonEventsClient kyroon)
{
    public async Task PlaceAsync(Order order)
    {
        try
        {
            await _repository.SaveAsync(order);
        }
        catch (Exception ex)
        {
            await kyroon.ReportExceptionAsync(ex, path: "POST /v1/orders");
            throw;
        }
    }
}

AddKyroonEvents registra IKyroonEventsClient como singleton e usa IHttpClientFactory por baixo. A Access Key é validada no startup — chave errada quebra o boot, não a primeira exceção em produção.

Capturar tudo de uma vez (ASP.NET Core)

app.UseExceptionHandler(branch => branch.Run(async context =>
{
    var feature = context.Features.Get<IExceptionHandlerFeature>();
    if (feature?.Error is { } ex)
    {
        var kyroon = context.RequestServices.GetRequiredService<IKyroonEventsClient>();

        await kyroon.ReportAsync(IncidentEvent.FromException(
            ex,
            path: $"{context.Request.Method} {context.Request.Path}",
            ip:   context.Connection.RemoteIpAddress?.ToString()));
    }

    context.Response.StatusCode = StatusCodes.Status500InternalServerError;
}));

Uso — .NET Framework 4.7.1 / 4.7.2 / 4.8

Sem DI. Configure uma vez no startup:

// Global.asax.cs
protected void Application_Start()
{
    KyroonEvents.Configure(o =>
    {
        o.AccessKey     = ConfigurationManager.AppSettings["Kyroon:AccessKey"];
        o.DefaultOrigin = "portal-legado";
    });
}

protected void Application_Error()
{
    var ex = Server.GetLastError();
    if (ex != null)
        KyroonEvents.ReportException(ex, path: Request?.Path);
}

ReportException é síncrono e não trava: internamente despacha para o thread pool antes de esperar, evitando o deadlock clássico de sync-over-async sob SynchronizationContext (ASP.NET clássico, WinForms, WPF). Ainda assim, prefira ReportExceptionAsync onde der.

TLS 1.2

O SDK não mexe em ServicePointManager.SecurityProtocol — alterar estado global a partir de uma biblioteca quebraria outras chamadas HTTP do seu processo.

Em .NET Framework 4.7+ o default é SystemDefault, e o Windows atualizado já negocia TLS 1.2. Se o seu ambiente for antigo e as chamadas falharem no handshake, habilite no startup da aplicação:

ServicePointManager.SecurityProtocol |= SecurityProtocolType.Tls12;

Modos de entrega

Modo Endpoint Resposta Quando usar
Queued (default) POST /api/Incidents/queue 202 Quase sempre. Menor latência; um worker persiste depois.
Direct POST /api/Incidents 201 + id Quando você precisa do id de volta ou da confirmação de gravação.
// por chamada
await kyroon.ReportAsync(incident, EventDeliveryMode.Direct);

// ou como default
o.DeliveryMode = EventDeliveryMode.Direct;

IncidentId só vem preenchido no modo Direct — no Queued o incidente ainda não existe quando o servidor responde.


O SDK não derruba a sua aplicação

Regra de projeto: este SDK é chamado de dentro de blocos catch. Uma falha de telemetria não pode virar uma falha da aplicação — e, pior, mascarar a exceção original.

Por isso, por padrão nada é lançado:

var result = await kyroon.ReportExceptionAsync(ex);

if (!result.Success)
    _logger.LogWarning("Kyroon: {Result}", result);  // status, tentativas, retryable

Para observar falhas em um lugar só:

o.OnError = r => _logger.LogWarning("Falha ao reportar ao Kyroon: {Result}", r);

Se quiser o comportamento oposto (testes, ou entrega crítica): o.ThrowOnFailure = true → lança KyroonEventsException.


Retry

O SDK reenvia sozinho o que é transitório, com backoff exponencial e jitter.

Situação Retenta?
Timeout, DNS, socket, TLS ✅
408, 5xx ✅
429 ✅ — respeita o header Retry-After
503 (fila indisponível) ✅
400 payload inválido ❌
401 Access Key inválida ❌
403 incidentes desabilitados ❌ — definitivo por contrato
413 payload grande demais ❌
o.MaxRetryAttempts  = 3;                        // 0 desliga
o.InitialRetryDelay = TimeSpan.FromMilliseconds(200);
o.MaxRetryDelay     = TimeSpan.FromSeconds(10);
o.Timeout           = TimeSpan.FromSeconds(10); // por tentativa

Um Retry-After maior que MaxRetryDelay vence o teto: voltar antes da hora só geraria outro 429.


Campos do evento

var incident = new IncidentEvent
{
    Error   = "Falha ao debitar o cartão",   // obrigatório
    Origin  = "checkout-api",                 // ≤ 200  · default: options ou nome do assembly
    Ip      = "203.0.113.10",                 // ≤ 45   · default: options ou IP local
    Path    = "POST /v1/payments",            // ≤ 2000 · default: options ou "unknown"
    Request = sanitizedBody,                  // opcional
    Stack   = ex.ToString(),                  // opcional
};

await kyroon.ReportAsync(incident);

Origin, Ip e Path são obrigatórios no servidor, mas o SDK preenche cada um quando você os deixa nulos — você nunca toma 400 por esquecimento. Valores acima do limite são truncados localmente.

⚠️ Request e Stack são gravados como texto. Não coloque senha, token, cartão ou dado pessoal — sanitize antes. Acima de 64 KB o servidor trunca o campo e marca [truncated]; o incidente nunca é descartado por tamanho.

Retenção

// (1) não atribuir  → o servidor aplica 30 dias
// (2) data          → expira naquela data
incident.ExpiresAt = DateTime.UtcNow.AddDays(90);
// (3) null explícito → nunca expira
incident.ExpiresAt = null;
// voltar ao caso (1)
incident.ClearExpiration();

A diferença entre não atribuir e atribuir null é real e proposital: o SDK omite a propriedade no primeiro caso e envia "expiredAt": null no segundo.


Desligar em desenvolvimento

o.Enabled = builder.Environment.IsProduction();

Com Enabled = false nada vai para a rede; o resultado volta com Skipped = true.


Referência rápida de configuração

Propriedade Default O que faz
AccessKey — Obrigatória. 50 caracteres.
BaseUrl https://api.kyroon.ai Endpoint da API.
DeliveryMode Queued Queued ou Direct.
Enabled true false pula o envio.
ThrowOnFailure false true lança KyroonEventsException.
OnError — Callback nas falhas definitivas.
Timeout 10 s Por tentativa.
MaxRetryAttempts 3 Retentativas após a primeira falha.
InitialRetryDelay 200 ms Base do backoff.
MaxRetryDelay 10 s Teto do backoff.
DefaultOrigin nome do assembly origin padrão.
DefaultIp IP local ip padrão.
DefaultPath "unknown" path padrão.
UserAgent Kyroon.Events/<versão> User-Agent das requisições.

Licença

MIT — Copyright (c) Kyroon.

Product Compatible and additional computed target framework versions.
.NET net5.0 was computed.  net5.0-windows was computed.  net6.0 was computed.  net6.0-android was computed.  net6.0-ios was computed.  net6.0-maccatalyst was computed.  net6.0-macos was computed.  net6.0-tvos was computed.  net6.0-windows was computed.  net7.0 was computed.  net7.0-android was computed.  net7.0-ios was computed.  net7.0-maccatalyst was computed.  net7.0-macos was computed.  net7.0-tvos was computed.  net7.0-windows was computed.  net8.0 is compatible.  net8.0-android was computed.  net8.0-browser was computed.  net8.0-ios was computed.  net8.0-maccatalyst was computed.  net8.0-macos was computed.  net8.0-tvos was computed.  net8.0-windows was computed.  net9.0 is compatible.  net9.0-android was computed.  net9.0-browser was computed.  net9.0-ios was computed.  net9.0-maccatalyst was computed.  net9.0-macos was computed.  net9.0-tvos was computed.  net9.0-windows was computed.  net10.0 is compatible.  net10.0-android was computed.  net10.0-browser was computed.  net10.0-ios was computed.  net10.0-maccatalyst was computed.  net10.0-macos was computed.  net10.0-tvos was computed.  net10.0-windows was computed. 
.NET Core netcoreapp2.0 was computed.  netcoreapp2.1 was computed.  netcoreapp2.2 was computed.  netcoreapp3.0 was computed.  netcoreapp3.1 was computed. 
.NET Standard netstandard2.0 is compatible.  netstandard2.1 was computed. 
.NET Framework net461 was computed.  net462 was computed.  net463 was computed.  net47 was computed.  net471 is compatible.  net472 is compatible.  net48 is compatible.  net481 was computed. 
MonoAndroid monoandroid was computed. 
MonoMac monomac was computed. 
MonoTouch monotouch was computed. 
Tizen tizen40 was computed.  tizen60 was computed. 
Xamarin.iOS xamarinios was computed. 
Xamarin.Mac xamarinmac was computed. 
Xamarin.TVOS xamarintvos was computed. 
Xamarin.WatchOS xamarinwatchos was computed. 
Compatible target framework(s)
Included target framework(s) (in package)
Learn more about Target Frameworks and .NET Standard.

NuGet packages

This package is not used by any NuGet packages.

GitHub repositories

This package is not used by any popular GitHub repositories.

Version Downloads Last Updated
1.0.0 400 8/7/2026