Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
22 changes: 22 additions & 0 deletions .github/workflows/pullrequest.yml
Original file line number Diff line number Diff line change
Expand Up @@ -76,3 +76,25 @@ jobs:

- name: Run Health Monitoring unit tests
run: dotnet test HealthMonitoring/HealthMonitoring.Tests/HealthMonitoring.Tests.csproj --configuration Release --no-restore --filter "FullyQualifiedName!~ConfigurationTests"

central-logging-tests:
name: "Run Central Logging Tests"
runs-on: ubuntu-latest
permissions:
contents: read
steps:
- uses: actions/checkout@v4

- name: Install NET 10
uses: actions/setup-dotnet@v4.0.1
with:
dotnet-version: '10.0.x'

- name: Restore Central Logging solution
run: dotnet restore CentralLogging.sln --source https://api.nuget.org/v3/index.json

- name: Build Central Logging solution
run: dotnet build CentralLogging.sln --configuration Release --no-restore

- name: Test Central Logging solution
run: dotnet test CentralLogging.sln --configuration Release --no-build --no-restore
16 changes: 16 additions & 0 deletions CentralLogging.Api/CentralLogging.Api.csproj
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
<Project Sdk="Microsoft.NET.Sdk.Web">
<PropertyGroup>
<TargetFramework>net10.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
</PropertyGroup>

<ItemGroup>
<PackageReference Include="Microsoft.EntityFrameworkCore.Design" Version="10.0.13">
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
</PackageReference>
<PackageReference Include="Microsoft.EntityFrameworkCore.SqlServer" Version="10.0.13" />
<PackageReference Include="System.Security.Cryptography.Pkcs" Version="10.0.13" />
</ItemGroup>
</Project>
59 changes: 59 additions & 0 deletions CentralLogging.Api/Data/CentralLogsDbContext.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
using CentralLogging.Api.Models;
using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.ChangeTracking;
using Microsoft.EntityFrameworkCore.Metadata.Builders;

namespace CentralLogging.Api.Data;

public sealed class CentralLogsDbContext(DbContextOptions<CentralLogsDbContext> options) : DbContext(options)
{
private const String MaxNvarcharColumnType = "nvarchar(max)";

public DbSet<CentralLogEvent> LogEvents => this.Set<CentralLogEvent>();
public DbSet<ServiceStructuredField> ServiceStructuredFields => this.Set<ServiceStructuredField>();

protected override void OnModelCreating(ModelBuilder modelBuilder)
{
EntityTypeBuilder<CentralLogEvent> entity = modelBuilder.Entity<CentralLogEvent>();
entity.ToTable("LogEvents", "dbo", table =>
table.HasCheckConstraint("CK_LogEvents_PropertiesJson_IsJson", "ISJSON([PropertiesJson]) = 1"));
entity.HasKey(log => log.EventId);
entity.Property(log => log.TimestampUtc).HasColumnType("datetimeoffset(7)").IsRequired();
entity.Property(log => log.LogDateUtc)
.HasColumnType("date")
.HasComputedColumnSql("CONVERT(date, [TimestampUtc])", stored: true);
entity.Property(log => log.Severity).HasMaxLength(16).IsRequired();
entity.Property(log => log.ServiceName).HasMaxLength(200).IsRequired();
entity.Property(log => log.TraceId).HasMaxLength(32);
entity.Property(log => log.SpanId).HasMaxLength(16);
entity.Property(log => log.RequestId).HasMaxLength(200);
entity.Property(log => log.Message).HasColumnType(MaxNvarcharColumnType).IsRequired();
entity.Property(log => log.MessageTemplate).HasColumnType(MaxNvarcharColumnType);
entity.Property(log => log.Exception).HasColumnType(MaxNvarcharColumnType);
entity.Property(log => log.PropertiesJson).HasColumnType(MaxNvarcharColumnType).IsRequired();
entity.HasIndex(log => log.TimestampUtc).IsDescending();
entity.HasIndex(log => new { log.LogDateUtc, log.TimestampUtc })
.IsDescending(false, true)
.HasDatabaseName("IX_LogEvents_LogDateUtc_TimestampUtc");
entity.HasIndex(log => new { log.TenantId, log.TimestampUtc }).IsDescending(false, true);
entity.HasIndex(log => new { log.ServiceName, log.TimestampUtc }).IsDescending(false, true);
entity.HasIndex(log => log.CorrelationId).HasFilter("[CorrelationId] IS NOT NULL");

EntityTypeBuilder<ServiceStructuredField> structuredField = modelBuilder.Entity<ServiceStructuredField>();
structuredField.ToTable("ServiceStructuredFields", "dbo");
structuredField.HasKey(field => new { field.ServiceName, field.FieldName, field.JsonType });
structuredField.Property(field => field.ServiceName)
.HasMaxLength(200)
.UseCollation("Latin1_General_100_BIN2")
.IsRequired()
.Metadata.SetValueComparer(new ValueComparer<String>(
(left, right) => StringComparer.Ordinal.Equals(left, right),
value => StringComparer.Ordinal.GetHashCode(value),
value => value));
structuredField.Property(field => field.FieldName).HasMaxLength(200).UseCollation("Latin1_General_100_BIN2").IsRequired();
structuredField.Property(field => field.JsonType).HasMaxLength(16).IsRequired();
structuredField.Property(field => field.FirstSeenUtc).HasColumnType("datetimeoffset(7)").IsRequired();
structuredField.Property(field => field.LastSeenUtc).HasColumnType("datetimeoffset(7)").IsRequired();
structuredField.Property(field => field.EventCount).IsRequired();
}
}
26 changes: 26 additions & 0 deletions CentralLogging.Api/Data/CentralLogsDbContextFactory.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Design;
using Microsoft.Extensions.Configuration;

namespace CentralLogging.Api.Data;

public sealed class CentralLogsDbContextFactory : IDesignTimeDbContextFactory<CentralLogsDbContext>
{
public CentralLogsDbContext CreateDbContext(String[] args)
{
IConfiguration configuration = new ConfigurationBuilder()
.SetBasePath(Path.GetDirectoryName(typeof(CentralLogsDbContextFactory).Assembly.Location)!)
.AddJsonFile("appsettings.json", optional: false)
.AddEnvironmentVariables()
.Build();

String connectionString = configuration.GetConnectionString("CentralLogs")
?? throw new InvalidOperationException("Configure ConnectionStrings:CentralLogs for EF Core tooling.");

DbContextOptions<CentralLogsDbContext> options = new DbContextOptionsBuilder<CentralLogsDbContext>()
.UseSqlServer(connectionString)
.Options;

return new CentralLogsDbContext(options);
}
}
Loading
Loading