CachingProxy/src/Program.cs (68 lines of code) (raw):
using System;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
using Microsoft.Extensions.Logging;
using Microsoft.Extensions.Options;
using OpenTelemetry.Metrics;
using OpenTelemetry.Resources;
using Polly;
namespace JetBrains.CachingProxy;
public static class Program
{
public static Task Main(string[] args)
{
var builder = WebApplication.CreateBuilder(args);
builder.WebHost.UseSentry();
if (builder.Environment.IsDevelopment())
{
builder.Logging.AddSimpleConsole();
}
else
{
builder.Logging.AddJsonConsole();
builder.Logging.AddSentry();
}
// Bind CachingProxyConfig from configuration
builder.Services.Configure<CachingProxyConfig>(builder.Configuration);
ConfigureOurServices(builder.Services);
builder.Services
.AddOpenTelemetry()
.ConfigureResource(resource => resource.AddService(builder.Environment.ApplicationName))
.WithMetrics(metrics => metrics
.AddAspNetCoreInstrumentation()
.AddRuntimeInstrumentation()
.AddMeter(CachingProxyMetrics.MeterName)
.AddPrometheusExporter()
.AddOtlpExporter()
);
var app = builder.Build();
if (app.Environment.IsDevelopment())
{
app.UseDeveloperExceptionPage();
}
app.UseOpenTelemetryPrometheusScrapingEndpoint();
app.UseMiddleware<CachingProxy>();
return app.RunAsync();
}
public static void ConfigureOurServices(IServiceCollection services)
{
services
.AddMemoryCache()
.AddSingleton<CachingProxyMetrics>()
.AddSingleton<ResponseCache>()
.AddHttpClient<ProxyHttpClient>((provider, client) =>
{
var config = provider.GetRequiredService<IOptions<CachingProxyConfig>>().Value;
client.Timeout = TimeSpan.FromSeconds(config.RequestTimeoutSec);
})
.UseSocketsHttpHandler((handler, _) =>
{
// force reconnection (and DNS re-resolve) every two minutes
handler.PooledConnectionLifetime = TimeSpan.FromMinutes(2);
handler.UseCookies = false;
})
.AddTransientHttpErrorPolicy(policyBuilder => policyBuilder.WaitAndRetryAsync(
4, retryAttempt => TimeSpan.FromSeconds(Math.Pow(2, retryAttempt - 1))));
}
}