ironservices-dotnet/TelemetryApi.cs

216 lines
7.3 KiB
C#

namespace IronServices.Client;
/// <summary>
/// API client for IronTelemetry operations.
/// Access via IronServicesClient.Telemetry
/// </summary>
public class TelemetryApi
{
private readonly IronServicesClient _client;
private readonly string _baseUrl;
internal TelemetryApi(IronServicesClient client, string baseUrl)
{
_client = client;
_baseUrl = baseUrl;
}
private string Url(string endpoint) => IronServicesClient.BuildUrl(_baseUrl, endpoint);
#region Dashboard & Stats
/// <summary>
/// Get issue statistics (serves as dashboard stats).
/// </summary>
public async Task<TelemetryDashboardStats> GetDashboardStatsAsync(Guid? projectId = null, CancellationToken ct = default)
{
var query = projectId.HasValue ? $"?projectId={projectId}" : "";
return await _client.GetAsync<TelemetryDashboardStats>(Url($"api/v1/issues/stats{query}"), ct)
?? new TelemetryDashboardStats();
}
#endregion
#region Issues
/// <summary>
/// Get issues with optional filtering.
/// </summary>
public async Task<List<IssueDto>> GetIssuesAsync(Guid? projectId = null, string? status = null, int page = 1, int pageSize = 20, CancellationToken ct = default)
{
var query = new List<string> { $"page={page}", $"pageSize={pageSize}" };
if (projectId.HasValue) query.Add($"projectId={projectId}");
if (!string.IsNullOrEmpty(status)) query.Add($"status={status}");
var queryString = "?" + string.Join("&", query);
var result = await _client.GetAsync<IssuesListResponse>(Url($"api/v1/issues{queryString}"), ct);
return result?.Items ?? [];
}
/// <summary>
/// Get a specific issue by ID.
/// </summary>
public async Task<IssueDto?> GetIssueAsync(Guid issueId, CancellationToken ct = default)
{
return await _client.GetAsync<IssueDto>(Url($"api/v1/issues/{issueId}"), ct);
}
/// <summary>
/// Acknowledge an issue.
/// </summary>
public async Task<IssueDto?> AcknowledgeIssueAsync(Guid issueId, CancellationToken ct = default)
{
return await _client.PostAsync<object, IssueDto>(Url($"api/v1/issues/{issueId}/acknowledge"), new { }, ct);
}
/// <summary>
/// Resolve an issue.
/// </summary>
public async Task<IssueDto?> ResolveIssueAsync(Guid issueId, CancellationToken ct = default)
{
return await _client.PostAsync<object, IssueDto>(Url($"api/v1/issues/{issueId}/resolve"), new { }, ct);
}
/// <summary>
/// Ignore an issue.
/// </summary>
public async Task<IssueDto?> IgnoreIssueAsync(Guid issueId, CancellationToken ct = default)
{
return await _client.PostAsync<object, IssueDto>(Url($"api/v1/issues/{issueId}/ignore"), new { }, ct);
}
/// <summary>
/// Update an issue's status and other properties.
/// </summary>
public async Task<IssueDto?> UpdateIssueAsync(Guid issueId, UpdateIssueRequest request, CancellationToken ct = default)
{
return await _client.PutAsync<UpdateIssueRequest, IssueDto>(Url($"api/v1/issues/{issueId}"), request, ct);
}
#endregion
#region Signals
/// <summary>
/// Get signals (telemetry notifications).
/// </summary>
public async Task<List<SignalDto>> GetSignalsAsync(Guid? projectId = null, int page = 1, int pageSize = 50, CancellationToken ct = default)
{
var query = new List<string> { $"page={page}", $"pageSize={pageSize}" };
if (projectId.HasValue) query.Add($"projectId={projectId}");
var queryString = "?" + string.Join("&", query);
var result = await _client.GetAsync<SignalListResponse>(Url($"api/v1/signals{queryString}"), ct);
return result?.Signals ?? [];
}
/// <summary>
/// Get signal statistics.
/// </summary>
public async Task<SignalStatsResponse?> GetSignalStatsAsync(Guid? projectId = null, CancellationToken ct = default)
{
var query = projectId.HasValue ? $"?projectId={projectId}" : "";
return await _client.GetAsync<SignalStatsResponse>(Url($"api/v1/signals/stats{query}"), ct);
}
/// <summary>
/// Dismiss a signal.
/// </summary>
public async Task<SignalDto?> DismissSignalAsync(Guid signalId, CancellationToken ct = default)
{
return await _client.PostAsync<object, SignalDto>(Url($"api/v1/signals/{signalId}/dismiss"), new { }, ct);
}
#endregion
#region Projects
/// <summary>
/// Get all projects.
/// </summary>
public async Task<List<TelemetryProjectDto>> GetProjectsAsync(CancellationToken ct = default)
{
return await _client.GetAsync<List<TelemetryProjectDto>>(Url("api/v1/projects"), ct) ?? [];
}
/// <summary>
/// Get a specific project by ID.
/// </summary>
public async Task<TelemetryProjectDto?> GetProjectAsync(Guid projectId, CancellationToken ct = default)
{
return await _client.GetAsync<TelemetryProjectDto>(Url($"api/v1/projects/{projectId}"), ct);
}
/// <summary>
/// Create a new telemetry project.
/// </summary>
public async Task<TelemetryProjectDto?> CreateProjectAsync(string name, string platform = "DotNet", CancellationToken ct = default)
{
return await _client.PostAsync<object, TelemetryProjectDto>(Url("api/v1/projects"), new { name, platform }, ct);
}
/// <summary>
/// Update a project.
/// </summary>
public async Task<TelemetryProjectDto?> UpdateProjectAsync(Guid projectId, UpdateProjectRequest request, CancellationToken ct = default)
{
return await _client.PutAsync<UpdateProjectRequest, TelemetryProjectDto>(Url($"api/v1/projects/{projectId}"), request, ct);
}
/// <summary>
/// Regenerate project DSN.
/// </summary>
public async Task<TelemetryProjectDto?> RegenerateDsnAsync(Guid projectId, CancellationToken ct = default)
{
return await _client.PostAsync<object, TelemetryProjectDto>(Url($"api/v1/projects/{projectId}/regenerate-dsn"), new { }, ct);
}
#endregion
}
public class IssuesListResponse
{
public List<IssueDto> Items { get; set; } = [];
public int Total { get; set; }
public int Page { get; set; }
public int PageSize { get; set; }
}
public class SignalListResponse
{
public List<SignalDto> Signals { get; set; } = [];
public int Total { get; set; }
public int Page { get; set; }
public int PageSize { get; set; }
public int TotalPages { get; set; }
}
public class SignalStatsResponse
{
public int TotalSignals { get; set; }
public int SignalsLast24Hours { get; set; }
public int SignalsLast7Days { get; set; }
public int SentToNotify { get; set; }
public int PendingSignals { get; set; }
}
public class UpdateIssueRequest
{
public string? Status { get; set; }
public string? Severity { get; set; }
public Guid? AssignedToUserId { get; set; }
public bool? NotifyOnRegression { get; set; }
public bool? NotifyOnNewOccurrence { get; set; }
}
public class UpdateProjectRequest
{
public string? Name { get; set; }
public string? Platform { get; set; }
public bool? IsActive { get; set; }
public bool? StackTraceGroupingEnabled { get; set; }
public bool? JourneyTrackingEnabled { get; set; }
public bool? SourceMapEnabled { get; set; }
public int? SampleRate { get; set; }
}