Files
Moonlight/Moonlight.ApiServer/Implementations/Startup/CoreStartup.cs

168 lines
5.3 KiB
C#

using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Routing;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
using Microsoft.Extensions.Logging;
using Microsoft.OpenApi.Models;
using Moonlight.ApiServer.Configuration;
using Moonlight.ApiServer.Database;
using Moonlight.ApiServer.Implementations.Diagnose;
using Moonlight.ApiServer.Implementations.Metrics;
using Moonlight.ApiServer.Interfaces;
using Moonlight.ApiServer.Models;
using Moonlight.ApiServer.Plugins;
using Moonlight.ApiServer.Services;
using OpenTelemetry.Logs;
using OpenTelemetry.Metrics;
using OpenTelemetry.Resources;
using OpenTelemetry.Trace;
namespace Moonlight.ApiServer.Implementations.Startup;
public class CoreStartup : IPluginStartup
{
public Task BuildApplicationAsync(IServiceProvider serviceProvider, IHostApplicationBuilder builder)
{
var configuration = serviceProvider.GetRequiredService<AppConfiguration>();
#region Api Docs
if (configuration.Development.EnableApiDocs)
{
builder.Services.AddEndpointsApiExplorer();
// Configure swagger api specification generator and set the document title for the api docs to use
builder.Services.AddSwaggerGen(options =>
{
options.SwaggerDoc("main", new OpenApiInfo()
{
Title = "Moonlight API"
});
options.CustomSchemaIds(x => x.FullName);
options.AddSecurityDefinition("Bearer", new OpenApiSecurityScheme
{
Name = "Authorization",
In = ParameterLocation.Header,
Type = SecuritySchemeType.ApiKey,
Scheme = "Bearer"
});
});
}
#endregion
#region Database
builder.Services.AddDbContext<CoreDataContext>();
#endregion
#region Diagnose
builder.Services.AddSingleton<IDiagnoseProvider, CoreConfigDiagnoseProvider>();
builder.Services.AddSingleton<IDiagnoseProvider, LogsDiagnoseProvider>();
#endregion
#region Prometheus
if (configuration.OpenTelemetry.Enable)
{
var openTel = builder.Services.AddOpenTelemetry();
var openTelConfig = configuration.OpenTelemetry;
var resourceBuilder = ResourceBuilder.CreateDefault();
resourceBuilder.AddService(serviceName: "moonlight");
openTel.ConfigureResource(x => x.AddService(serviceName: "moonlight"));
if (openTelConfig.Metrics.Enable)
{
builder.Services.AddSingleton<MetricsBackgroundService>();
builder.Services.AddHostedService(sp => sp.GetRequiredService<MetricsBackgroundService>());
builder.Services.AddSingleton<IMetric, ApplicationMetric>();
builder.Services.AddSingleton<IMetric, UsersMetric>();
openTel.WithMetrics(providerBuilder =>
{
providerBuilder.AddAspNetCoreInstrumentation();
providerBuilder.AddOtlpExporter();
if (openTelConfig.Metrics.EnablePrometheus)
providerBuilder.AddPrometheusExporter();
providerBuilder.AddMeter("moonlight");
});
}
if (openTelConfig.Logs.Enable)
{
openTel.WithLogging();
builder.Logging.AddOpenTelemetry(options =>
{
options.SetResourceBuilder(resourceBuilder);
options.AddOtlpExporter();
});
}
if (openTelConfig.Traces.Enable)
{
openTel.WithTracing(providerBuilder =>
{
providerBuilder.AddAspNetCoreInstrumentation();
providerBuilder.AddOtlpExporter();
});
}
}
#endregion
#region Client / Frontend
if (configuration.Frontend.EnableHosting)
{
builder.Services.AddSingleton(new FrontendConfigurationOption()
{
Scripts =
[
"/_content/Moonlight.Client/js/moonlight.js", "/_content/MoonCore.Blazor.FlyonUi/moonCore.js",
"/_content/MoonCore.Blazor.FlyonUi/ace/ace.js"
],
Styles = ["/css/style.min.css"]
});
}
#endregion
return Task.CompletedTask;
}
public Task ConfigureApplicationAsync(IServiceProvider serviceProvider, IApplicationBuilder app)
{
var configuration = serviceProvider.GetRequiredService<AppConfiguration>();
#region Prometheus
if (configuration.OpenTelemetry is { Enable: true, Metrics.EnablePrometheus: true })
app.UseOpenTelemetryPrometheusScrapingEndpoint();
#endregion
return Task.CompletedTask;
}
public Task ConfigureEndpointsAsync(IServiceProvider serviceProvider, IEndpointRouteBuilder routeBuilder)
{
var configuration = serviceProvider.GetRequiredService<AppConfiguration>();
if (configuration.Development.EnableApiDocs)
routeBuilder.MapSwagger("/api/swagger/{documentName}");
return Task.CompletedTask;
}
}