diff --git a/.dockerignore b/.dockerignore new file mode 100644 index 0000000..cd967fc --- /dev/null +++ b/.dockerignore @@ -0,0 +1,25 @@ +**/.dockerignore +**/.env +**/.git +**/.gitignore +**/.project +**/.settings +**/.toolstarget +**/.vs +**/.vscode +**/.idea +**/*.*proj.user +**/*.dbmdl +**/*.jfm +**/azds.yaml +**/bin +**/charts +**/docker-compose* +**/Dockerfile* +**/node_modules +**/npm-debug.log +**/obj +**/secrets.dev.yaml +**/values.dev.yaml +LICENSE +README.md \ No newline at end of file diff --git a/Dockerfile b/Dockerfile new file mode 100644 index 0000000..c30179e --- /dev/null +++ b/Dockerfile @@ -0,0 +1,23 @@ +FROM mcr.microsoft.com/dotnet/aspnet:8.0 AS base +USER $APP_UID +WORKDIR /app +EXPOSE 8080 +EXPOSE 8081 + +FROM mcr.microsoft.com/dotnet/sdk:8.0 AS build +ARG BUILD_CONFIGURATION=Release +WORKDIR /src +COPY ["telemetry.csproj", "./"] +RUN dotnet restore "telemetry.csproj" +COPY . . +WORKDIR "/src/" +RUN dotnet build "./telemetry.csproj" -c $BUILD_CONFIGURATION -o /app/build + +FROM build AS publish +ARG BUILD_CONFIGURATION=Release +RUN dotnet publish "./telemetry.csproj" -c $BUILD_CONFIGURATION -o /app/publish /p:UseAppHost=false + +FROM base AS final +WORKDIR /app +COPY --from=publish /app/publish . +ENTRYPOINT ["dotnet", "telemetry.dll"] diff --git a/Pages/Index.cshtml.cs b/Pages/Index.cshtml.cs index 34a599f..87c705d 100644 --- a/Pages/Index.cshtml.cs +++ b/Pages/Index.cshtml.cs @@ -1,3 +1,5 @@ +using System.Diagnostics; +using System.Diagnostics.Metrics; using Microsoft.AspNetCore.Mvc; using Microsoft.AspNetCore.Mvc.RazorPages; @@ -6,14 +8,22 @@ namespace telemetry.Pages; public class IndexModel : PageModel { private readonly ILogger _logger; + private readonly Metrics _metrics; - public IndexModel(ILogger logger) + public IndexModel(ILogger logger, Metrics metrics) { _logger = logger; + _metrics = metrics; } public void OnGet() { - + var sw = Stopwatch.StartNew(); + for (var i = 0; i < new Random().Next(0, 100); i++) + { + Console.Write("1"); + } + sw.Stop(); + _metrics.RequestToIndex(sw.Elapsed); } } diff --git a/Program.cs b/Program.cs index bc275e4..75c3ee1 100644 --- a/Program.cs +++ b/Program.cs @@ -1,7 +1,33 @@ +using OpenTelemetry.Logs; +using OpenTelemetry.Metrics; +using OpenTelemetry.Resources; +using OpenTelemetry.Trace; +using telemetry; + var builder = WebApplication.CreateBuilder(args); // Add services to the container. builder.Services.AddRazorPages(); +builder.Services.AddSingleton(); + +builder.Logging.AddOpenTelemetry(options => +{ + options + .SetResourceBuilder( + ResourceBuilder.CreateDefault() + .AddService("TelemetryExample")) + .AddConsoleExporter(); +}); +builder.Services.AddOpenTelemetry() + .ConfigureResource(resource => resource.AddService("TelemetryExample")) + .WithTracing(tracing => tracing + .AddAspNetCoreInstrumentation() + .AddConsoleExporter()) + .WithMetrics(metrics => metrics + .AddPrometheusExporter() + .AddAspNetCoreInstrumentation() + .AddConsoleExporter() + .AddMeter(nameof(Metrics))); var app = builder.Build(); @@ -13,6 +39,7 @@ app.UseHsts(); } + app.UseHttpsRedirection(); app.UseStaticFiles(); @@ -22,4 +49,6 @@ app.MapRazorPages(); +app.UseOpenTelemetryPrometheusScrapingEndpoint(); + app.Run(); diff --git a/WeatherApp.sln b/WeatherApp.sln index fea1c6b..676a970 100644 --- a/WeatherApp.sln +++ b/WeatherApp.sln @@ -5,6 +5,11 @@ VisualStudioVersion = 17.0.31903.59 MinimumVisualStudioVersion = 10.0.40219.1 Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "telemetry", "telemetry.csproj", "{318D0823-22FB-4FE3-94F2-7391C3B7CEEB}" EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution Items", "{467A809B-62BF-469C-8DC3-72E75DC53870}" + ProjectSection(SolutionItems) = preProject + compose.yaml = compose.yaml + EndProjectSection +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU diff --git a/cl.cs b/cl.cs new file mode 100644 index 0000000..204d732 --- /dev/null +++ b/cl.cs @@ -0,0 +1,22 @@ +using System.Diagnostics.Metrics; + +namespace telemetry; + +public class Metrics +{ + private readonly Counter indexRequestsCount; + private readonly Histogram indexRequestsTime; + + public Metrics(IMeterFactory meterFactory) + { + var meter = meterFactory.Create(nameof(Metrics)); + indexRequestsCount = meter.CreateCounter("requests.index.count", "pcs", "Количество запросов"); + indexRequestsTime = meter.CreateHistogram("requests.index.time", "ms", "Время запроса к index"); + } + + public void RequestToIndex(TimeSpan elapsed) + { + indexRequestsCount.Add(1); + indexRequestsTime.Record(elapsed.TotalMilliseconds); + } +} \ No newline at end of file diff --git a/compose.yaml b/compose.yaml new file mode 100644 index 0000000..34b44cc --- /dev/null +++ b/compose.yaml @@ -0,0 +1,12 @@ +services: + prometheus: + image: "prom/prometheus" + ports: + - "9090:9090" + volumes: + - "./prometheus.yml:/etc/prometheus/prometheus.yml" + + grafana: + image: "grafana/grafana-oss" + ports: + - "3000:3000" \ No newline at end of file diff --git a/prometheus.yml b/prometheus.yml new file mode 100644 index 0000000..0660196 --- /dev/null +++ b/prometheus.yml @@ -0,0 +1,6 @@ +scrape_configs: + - job_name: "prometheus" + # Override the global default and scrape targets from this job every 5 seconds. + scrape_interval: 5s + static_configs: + - targets: ["host.docker.internal:5149"] \ No newline at end of file diff --git a/telemetry.csproj b/telemetry.csproj index 1b28a01..27e0ff0 100644 --- a/telemetry.csproj +++ b/telemetry.csproj @@ -4,6 +4,17 @@ net8.0 enable enable + Linux + + + + + + + + + +