超级管理员现在可在“组织与权限 → 运维与审计 → 系统性能”中直接查看:

请求量、5xx 比例、HTTP/数据库 P95
请求速率与延迟趋势
最慢接口排行
慢查询与数据库查询排行
Grafana 原始调用链入口
This commit is contained in:
2026-07-31 09:34:31 +08:00 Unverified
parent ca7148ab61
commit 551f1143b7
12 changed files with 1655 additions and 3 deletions
+36
View File
@@ -85,6 +85,9 @@ var operationsOptions = builder.Configuration
var observabilityOptions = builder.Configuration
.GetSection(ObservabilityOptions.SectionName)
.Get<ObservabilityOptions>() ?? new ObservabilityOptions();
var performanceReportingOptions = builder.Configuration
.GetSection(PerformanceReportingOptions.SectionName)
.Get<PerformanceReportingOptions>() ?? new PerformanceReportingOptions();
var rabbitMqOptions = builder.Configuration
.GetSection(RabbitMqOptions.SectionName)
.Get<RabbitMqOptions>() ?? new RabbitMqOptions();
@@ -126,6 +129,28 @@ if (string.IsNullOrWhiteSpace(observabilityOptions.ServiceName) ||
"Observability 服务名、慢查询阈值或 SQL 文本长度超出允许范围。");
}
if (performanceReportingOptions.CacheSeconds is < 5 or > 300 ||
performanceReportingOptions.TimeoutSeconds is < 1 or > 60 ||
performanceReportingOptions.BearerToken.Length > 8000 ||
!PerformanceReportingOptions.IsMetricOrLabelName(
performanceReportingOptions.ServiceLabel) ||
!PerformanceReportingOptions.IsMetricOrLabelName(
performanceReportingOptions.RequestDurationMetric) ||
!PerformanceReportingOptions.IsMetricOrLabelName(
performanceReportingOptions.DatabaseDurationMetric) ||
!PerformanceReportingOptions.IsMetricOrLabelName(
performanceReportingOptions.SlowDatabaseMetric) ||
!PerformanceReportingOptions.IsMetricOrLabelName(
performanceReportingOptions.FailedDatabaseMetric) ||
(performanceReportingOptions.Enabled &&
!IsHttpUrl(performanceReportingOptions.PrometheusBaseUrl)) ||
(!string.IsNullOrWhiteSpace(performanceReportingOptions.GrafanaBaseUrl) &&
!IsHttpUrl(performanceReportingOptions.GrafanaBaseUrl)))
{
throw new InvalidOperationException(
"PerformanceReporting 数据源、超时、缓存或指标名称配置无效。");
}
var otlpEndpoint = builder.Configuration["OTEL_EXPORTER_OTLP_ENDPOINT"];
if (!string.IsNullOrWhiteSpace(otlpEndpoint) &&
(!Uri.TryCreate(otlpEndpoint, UriKind.Absolute, out var parsedOtlpEndpoint) ||
@@ -219,8 +244,15 @@ builder.Services.AddSingleton(officialDocumentOptions);
builder.Services.AddSingleton(backgroundJobOptions);
builder.Services.AddSingleton(operationsOptions);
builder.Services.AddSingleton(observabilityOptions);
builder.Services.AddSingleton(performanceReportingOptions);
builder.Services.AddSingleton(rabbitMqOptions);
builder.Services.AddSingleton<DatabaseCommandTelemetryInterceptor>();
builder.Services.AddMemoryCache();
builder.Services.AddHttpClient<PerformanceReportService>((services, client) =>
{
var reporting = services.GetRequiredService<PerformanceReportingOptions>();
client.Timeout = TimeSpan.FromSeconds(reporting.TimeoutSeconds);
});
builder.Services.Configure<OfficialDocumentOptions>(
builder.Configuration.GetSection(OfficialDocumentOptions.SectionName));
builder.Services.AddDbContextPool<AppDbContext>((services, options) =>
@@ -668,4 +700,8 @@ static async Task<IResult> CheckMessagingHealthAsync(
}
}
static bool IsHttpUrl(string value) =>
Uri.TryCreate(value, UriKind.Absolute, out var uri) &&
uri.Scheme is "http" or "https";
public partial class Program;