From 082c712ac367367eacf404891f56e2f8b61d50c7 Mon Sep 17 00:00:00 2001 From: Johannes Tax Date: Fri, 26 Jan 2024 17:04:52 +0100 Subject: [PATCH] Add .NET 8 to the test matrix (#81) * Add .NET 8 to the test matrix --------- Co-authored-by: Matthew Hensley --- CHANGELOG.md | 7 ++ GrafanaOpenTelemetry.sln | 10 +++ .../docker-compose.net8.oats.yml | 25 +++++++ .../http/oats-template.yml | 5 ++ .../oats-template.yml | 5 ++ .../Controllers/HttpClientController.cs | 46 +++++++++++++ .../aspnetcore/Controllers/MsSqlController.cs | 68 +++++++++++++++++++ .../aspnetcore/Controllers/RedisController.cs | 51 ++++++++++++++ .../Controllers/WeatherForecastController.cs | 44 ++++++++++++ examples/net8.0/aspnetcore/Dockerfile | 25 +++++++ examples/net8.0/aspnetcore/Program.cs | 40 +++++++++++ .../aspnetcore/Properties/launchSettings.json | 40 +++++++++++ .../aspnetcore/appsettings.Development.json | 8 +++ examples/net8.0/aspnetcore/appsettings.json | 9 +++ examples/net8.0/aspnetcore/aspnetcore.csproj | 24 +++++++ 15 files changed, 407 insertions(+) create mode 100644 docker/docker-compose-aspnetcore/docker-compose.net8.oats.yml create mode 100644 examples/net8.0/aspnetcore/Controllers/HttpClientController.cs create mode 100644 examples/net8.0/aspnetcore/Controllers/MsSqlController.cs create mode 100644 examples/net8.0/aspnetcore/Controllers/RedisController.cs create mode 100644 examples/net8.0/aspnetcore/Controllers/WeatherForecastController.cs create mode 100644 examples/net8.0/aspnetcore/Dockerfile create mode 100644 examples/net8.0/aspnetcore/Program.cs create mode 100644 examples/net8.0/aspnetcore/Properties/launchSettings.json create mode 100644 examples/net8.0/aspnetcore/appsettings.Development.json create mode 100644 examples/net8.0/aspnetcore/appsettings.json create mode 100644 examples/net8.0/aspnetcore/aspnetcore.csproj diff --git a/CHANGELOG.md b/CHANGELOG.md index cad5c68..3aa270d 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,12 @@ # Changelog +## Unreleased + +### New features + +* [#81](https://github.com/grafana/grafana-opentelemetry-dotnet/pull/81) + Adds a .NET 8 test project and integrates it into the OATS test matrix. + ## 0.7.0-beta.3 ### Bug fixes diff --git a/GrafanaOpenTelemetry.sln b/GrafanaOpenTelemetry.sln index 3543ddb..2efbd31 100644 --- a/GrafanaOpenTelemetry.sln +++ b/GrafanaOpenTelemetry.sln @@ -23,6 +23,10 @@ Project("{E53339B2-1760-4266-BCC7-CA923CBCF16C}") = "docker-compose-aspnetcore", EndProject Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "docker", "docker", "{E63943FA-D9F6-4DC4-91EE-D0BD0BF8E324}" EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "net8.0", "net8.0", "{74BA358B-6EDB-463F-8AB2-313FAA4DE564}" +EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "aspnetcore", "examples\net8.0\aspnetcore\aspnetcore.csproj", "{BD1FB154-C711-4E37-947D-063F5DC4BF9E}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU @@ -49,6 +53,10 @@ Global {A4C41298-ED4F-4A4C-9B18-014986186C71}.Debug|Any CPU.Build.0 = Debug|Any CPU {A4C41298-ED4F-4A4C-9B18-014986186C71}.Release|Any CPU.ActiveCfg = Release|Any CPU {A4C41298-ED4F-4A4C-9B18-014986186C71}.Release|Any CPU.Build.0 = Release|Any CPU + {BD1FB154-C711-4E37-947D-063F5DC4BF9E}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {BD1FB154-C711-4E37-947D-063F5DC4BF9E}.Debug|Any CPU.Build.0 = Debug|Any CPU + {BD1FB154-C711-4E37-947D-063F5DC4BF9E}.Release|Any CPU.ActiveCfg = Release|Any CPU + {BD1FB154-C711-4E37-947D-063F5DC4BF9E}.Release|Any CPU.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE @@ -60,5 +68,7 @@ Global {A9FD1876-1DC6-49A8-9E81-A8DD3BBD03F9} = {2DC924CF-282A-446D-B94B-D2931E5C6130} {13045789-1D27-4694-BE88-B20534DD28EC} = {A9FD1876-1DC6-49A8-9E81-A8DD3BBD03F9} {A4C41298-ED4F-4A4C-9B18-014986186C71} = {E63943FA-D9F6-4DC4-91EE-D0BD0BF8E324} + {74BA358B-6EDB-463F-8AB2-313FAA4DE564} = {2DC924CF-282A-446D-B94B-D2931E5C6130} + {BD1FB154-C711-4E37-947D-063F5DC4BF9E} = {74BA358B-6EDB-463F-8AB2-313FAA4DE564} EndGlobalSection EndGlobal diff --git a/docker/docker-compose-aspnetcore/docker-compose.net8.oats.yml b/docker/docker-compose-aspnetcore/docker-compose.net8.oats.yml new file mode 100644 index 0000000..7a77224 --- /dev/null +++ b/docker/docker-compose-aspnetcore/docker-compose.net8.oats.yml @@ -0,0 +1,25 @@ +version: '3.4' + +services: + aspnetcore: + image: ${DOCKER_REGISTRY-}aspnetcore + build: + context: ../.. + dockerfile: examples/net8.0/aspnetcore/Dockerfile + environment: + - OTEL_EXPORTER_OTLP_ENDPOINT=http://collector:4317 + ports: + - "5000:8080" + - "8080:8080" # for OATs + depends_on: + - redis + - mssql + redis: + image: redis:7.2 + ports: + - "6379:6379" + mssql: + image: mcr.microsoft.com/mssql/server:2022-latest + environment: + - ACCEPT_EULA=Y + - MSSQL_SA_PASSWORD=Password12345%% diff --git a/docker/docker-compose-aspnetcore/http/oats-template.yml b/docker/docker-compose-aspnetcore/http/oats-template.yml index 4c2b2a7..0f98b44 100644 --- a/docker/docker-compose-aspnetcore/http/oats-template.yml +++ b/docker/docker-compose-aspnetcore/http/oats-template.yml @@ -9,4 +9,9 @@ matrix: generator: lgtm files: - ../docker-compose.self-contained.oats.yml + - name: net8 + docker-compose: + generator: lgtm + files: + - ../docker-compose.net8.oats.yml interval: 500ms diff --git a/docker/docker-compose-aspnetcore/oats-template.yml b/docker/docker-compose-aspnetcore/oats-template.yml index e0733ac..4502dd0 100644 --- a/docker/docker-compose-aspnetcore/oats-template.yml +++ b/docker/docker-compose-aspnetcore/oats-template.yml @@ -9,4 +9,9 @@ matrix: generator: lgtm files: - ./docker-compose.self-contained.oats.yml + - name: net8 + docker-compose: + generator: lgtm + files: + - ./docker-compose.net8.oats.yml interval: 500ms diff --git a/examples/net8.0/aspnetcore/Controllers/HttpClientController.cs b/examples/net8.0/aspnetcore/Controllers/HttpClientController.cs new file mode 100644 index 0000000..a7baa3b --- /dev/null +++ b/examples/net8.0/aspnetcore/Controllers/HttpClientController.cs @@ -0,0 +1,46 @@ +// +// Copyright Grafana Labs +// SPDX-License-Identifier: Apache-2.0 +// + +using Microsoft.AspNetCore.Mvc; + +namespace aspnetcore.Controllers; +[Route("api/[controller]/[action]")] +[ApiController] +public class HttpClientController : ControllerBase +{ + private readonly ILogger _logger; + + public HttpClientController(ILogger logger) + { + _logger = logger; + } + + [HttpGet] + public async Task>> Get() + { + var client = new HttpClient(); + var response = await client.GetAsync("https://postman-echo.com/get?hello=world"); + var content = await response.Content.ReadAsStringAsync(); + return Ok(content); + } + + [HttpGet] + public async Task>> GetError() + { + var client = new HttpClient(); + var response = await client.GetAsync("http://postman-echo.com/status/500"); + var content = await response.Content.ReadAsStringAsync(); + return Ok(content); + } + + [HttpPost] + public async Task> Post() + { + var client = new HttpClient(); + var response = await client.PostAsync("https://postman-echo.com/post", new StringContent("Hello World")); + var content = await response.Content.ReadAsStringAsync(); + return Ok(content); + } +} diff --git a/examples/net8.0/aspnetcore/Controllers/MsSqlController.cs b/examples/net8.0/aspnetcore/Controllers/MsSqlController.cs new file mode 100644 index 0000000..cc8ac97 --- /dev/null +++ b/examples/net8.0/aspnetcore/Controllers/MsSqlController.cs @@ -0,0 +1,68 @@ +// +// Copyright Grafana Labs +// SPDX-License-Identifier: Apache-2.0 +// + +using System.Data; +using Microsoft.AspNetCore.Mvc; +using Microsoft.Data.SqlClient; + +namespace aspnetcore.Controllers; +[Route("api/[controller]/[action]")] +[ApiController] +public class MsSqlController : ControllerBase +{ + private readonly ILogger _logger; + private readonly SqlConnection _db; + + public MsSqlController(ILogger logger, SqlConnection db) + { + _logger = logger; + _db = db; + } + + [HttpGet] + public async Task>> Tables() + { + this._db.Open(); + + using (var command = _db.CreateCommand()) + { + command.CommandText = "SELECT TABLE_NAME FROM INFORMATION_SCHEMA.TABLES"; + var tables = new List(); + + using (var reader = await command.ExecuteReaderAsync()) + { + while (await reader.ReadAsync()) + { + tables.Add(reader.GetString(0)); + } + } + return Ok(tables); + } + } + + [HttpGet] + public async Task>> ServerInfo() + { + this._db.Open(); + + using (var command = _db.CreateCommand()) + { + command.CommandText = "sp_server_info"; + command.CommandType = CommandType.StoredProcedure; + + var serverInfo = new List(); + + using (var reader = await command.ExecuteReaderAsync()) + { + while (await reader.ReadAsync()) + { + serverInfo.Add($"ID={reader.GetInt32(0)} , NAME={reader.GetString(1)} , VALUE={reader.GetString(2)}"); + } + } + + return Ok(serverInfo); + } + } +} diff --git a/examples/net8.0/aspnetcore/Controllers/RedisController.cs b/examples/net8.0/aspnetcore/Controllers/RedisController.cs new file mode 100644 index 0000000..0daabc1 --- /dev/null +++ b/examples/net8.0/aspnetcore/Controllers/RedisController.cs @@ -0,0 +1,51 @@ +// +// Copyright Grafana Labs +// SPDX-License-Identifier: Apache-2.0 +// + +using System.ComponentModel.DataAnnotations; +using Microsoft.AspNetCore.Mvc; +using StackExchange.Redis; + +namespace aspnetcore.Controllers; +[Route("api/[controller]/[action]")] +[ApiController] +public class RedisController : ControllerBase +{ + const string LIST_KEY = "list"; + private readonly ILogger _logger; + private IDatabase _redisDb; + + public RedisController(ILogger logger, IDatabase database) + { + _logger = logger; + _redisDb = database; + } + + [HttpPost] + public async Task> LeftPush([FromBody] LeftPushBody data) + { + if (!ModelState.IsValid) + { + return StatusCode(500); + } + + var length = await _redisDb.ListLeftPushAsync(LIST_KEY, data.Name); + _logger.LogInformation($"LeftPush: {data.Name} - {length}"); + return Ok(); + } + + [HttpPost] + public async Task> LeftPop() + { + var value = await _redisDb.ListLeftPopAsync(LIST_KEY); + _logger.LogInformation($"LeftPop: {value}"); + return Ok(value); + } + + public class LeftPushBody + { + [Required] + public string? Name { get; set; } + } +} diff --git a/examples/net8.0/aspnetcore/Controllers/WeatherForecastController.cs b/examples/net8.0/aspnetcore/Controllers/WeatherForecastController.cs new file mode 100644 index 0000000..70b896d --- /dev/null +++ b/examples/net8.0/aspnetcore/Controllers/WeatherForecastController.cs @@ -0,0 +1,44 @@ +// +// Copyright Grafana Labs +// SPDX-License-Identifier: Apache-2.0 +// + +using Microsoft.AspNetCore.Mvc; + +namespace aspnetcore.Controllers; +[ApiController] +[Route("[controller]")] +public class WeatherForecastController : ControllerBase +{ + private static readonly string[] Summaries = new[] + { + "Freezing", "Bracing", "Chilly", "Cool", "Mild", "Warm", "Balmy", "Hot", "Sweltering", "Scorching" + }; + + private readonly ILogger _logger; + + public WeatherForecastController(ILogger logger) + { + _logger = logger; + } + + [HttpGet(Name = "GetWeatherForecast")] + public IEnumerable Get() + { + return Enumerable.Range(1, 5).Select(index => new WeatherForecast + { + Date = DateTime.Now.AddDays(index), + TemperatureC = Random.Shared.Next(-20, 55), + Summary = Summaries[Random.Shared.Next(Summaries.Length)] + }) + .ToArray(); + } + + public class WeatherForecast + { + public DateTime Date { get; set; } + public int TemperatureC { get; set; } + public int TemperatureF => 32 + (int)(TemperatureC / 0.5556); + public string? Summary { get; set; } + } +} diff --git a/examples/net8.0/aspnetcore/Dockerfile b/examples/net8.0/aspnetcore/Dockerfile new file mode 100644 index 0000000..c0e9863 --- /dev/null +++ b/examples/net8.0/aspnetcore/Dockerfile @@ -0,0 +1,25 @@ +#See https://aka.ms/customizecontainer to learn how to customize your debug container and how Visual Studio uses this Dockerfile to build your images for faster debugging. + +FROM mcr.microsoft.com/dotnet/aspnet:8.0 AS base +WORKDIR /app +EXPOSE 80 + +FROM mcr.microsoft.com/dotnet/sdk:8.0 AS build + +ARG DOTNET_PUBLISH_ARGS="" + +WORKDIR /src +COPY ["examples/net8.0/aspnetcore/aspnetcore.csproj", "examples/net8.0/aspnetcore/"] +RUN dotnet restore "examples/net8.0/aspnetcore/aspnetcore.csproj" +COPY . . +WORKDIR "/src/examples/net8.0/aspnetcore" +RUN dotnet build "aspnetcore.csproj" -c Release -o /app/build + +FROM build AS publish +RUN dotnet publish "aspnetcore.csproj" -c Release -o /app/publish ${DOTNET_PUBLISH_ARGS} + +FROM base AS final +WORKDIR /app +COPY --from=publish /app/publish . +RUN apt-get update && apt-get install -y curl +ENTRYPOINT ["dotnet", "aspnetcore.dll"] diff --git a/examples/net8.0/aspnetcore/Program.cs b/examples/net8.0/aspnetcore/Program.cs new file mode 100644 index 0000000..9785ac9 --- /dev/null +++ b/examples/net8.0/aspnetcore/Program.cs @@ -0,0 +1,40 @@ +// +// Copyright Grafana Labs +// SPDX-License-Identifier: Apache-2.0 +// + +using Grafana.OpenTelemetry; +using Microsoft.Data.SqlClient; +using OpenTelemetry.Trace; +using StackExchange.Redis; + +var builder = WebApplication.CreateBuilder(args); +builder.Services.AddOpenTelemetry() + .WithMetrics(builder => builder.UseGrafana()) + .WithTracing(builder => builder.UseGrafana().AddConsoleExporter()); + +// Redis +builder.Services.AddSingleton( + sp => ConnectionMultiplexer.Connect("redis:6379")); +builder.Services.AddScoped( + sp => sp.GetRequiredService().GetDatabase()); + +// MSSQL +builder.Services.AddTransient(sp => +{ + var connectionString = "Server=mssql,1433;Database=master;User=sa;Password=Password12345%%;Encrypt=False;TrustServerCertificate=True"; + return new SqlConnection(connectionString); +}); + +builder.Services.AddControllers(); +// Learn more about configuring Swagger/OpenAPI at https://aka.ms/aspnetcore/swashbuckle +builder.Services.AddEndpointsApiExplorer(); +builder.Services.AddSwaggerGen(); + +var app = builder.Build(); +app.UseSwagger(); +app.UseSwaggerUI(); +app.UseAuthorization(); +app.MapControllers(); +app.MapGet("/", () => Results.Redirect("/swagger")); +app.Run(); diff --git a/examples/net8.0/aspnetcore/Properties/launchSettings.json b/examples/net8.0/aspnetcore/Properties/launchSettings.json new file mode 100644 index 0000000..ff0e31a --- /dev/null +++ b/examples/net8.0/aspnetcore/Properties/launchSettings.json @@ -0,0 +1,40 @@ +{ + "profiles": { + "aspnetcore": { + "commandName": "Project", + "launchBrowser": true, + "launchUrl": "swagger", + "environmentVariables": { + "ASPNETCORE_ENVIRONMENT": "Development" + }, + "dotnetRunMessages": true, + "applicationUrl": "http://localhost:5125" + }, + "IIS Express": { + "commandName": "IISExpress", + "launchBrowser": true, + "launchUrl": "swagger", + "environmentVariables": { + "ASPNETCORE_ENVIRONMENT": "Development" + } + }, + "Docker": { + "commandName": "Docker", + "launchBrowser": true, + "launchUrl": "{Scheme}://{ServiceHost}:{ServicePort}/swagger", + "environmentVariables": { + "ASPNETCORE_URLS": "http://+:80" + }, + "publishAllPorts": true + } + }, + "$schema": "https://json.schemastore.org/launchsettings.json", + "iisSettings": { + "windowsAuthentication": false, + "anonymousAuthentication": true, + "iisExpress": { + "applicationUrl": "http://localhost:11318", + "sslPort": 0 + } + } +} \ No newline at end of file diff --git a/examples/net8.0/aspnetcore/appsettings.Development.json b/examples/net8.0/aspnetcore/appsettings.Development.json new file mode 100644 index 0000000..0c208ae --- /dev/null +++ b/examples/net8.0/aspnetcore/appsettings.Development.json @@ -0,0 +1,8 @@ +{ + "Logging": { + "LogLevel": { + "Default": "Information", + "Microsoft.AspNetCore": "Warning" + } + } +} diff --git a/examples/net8.0/aspnetcore/appsettings.json b/examples/net8.0/aspnetcore/appsettings.json new file mode 100644 index 0000000..10f68b8 --- /dev/null +++ b/examples/net8.0/aspnetcore/appsettings.json @@ -0,0 +1,9 @@ +{ + "Logging": { + "LogLevel": { + "Default": "Information", + "Microsoft.AspNetCore": "Warning" + } + }, + "AllowedHosts": "*" +} diff --git a/examples/net8.0/aspnetcore/aspnetcore.csproj b/examples/net8.0/aspnetcore/aspnetcore.csproj new file mode 100644 index 0000000..f1cfe9d --- /dev/null +++ b/examples/net8.0/aspnetcore/aspnetcore.csproj @@ -0,0 +1,24 @@ + + + + net8.0 + enable + enable + Linux + ..\..\.. + ..\..\..\docker-compose-aspnetcore.dcproj + + + + + + + + + + + + + + +