Skip to content

Commit

Permalink
Merge pull request #151 from serilog-contrib/dev
Browse files Browse the repository at this point in the history
update with latest
  • Loading branch information
pwelter34 authored May 10, 2024
2 parents 539d490 + ad0c3f2 commit 7ceda92
Show file tree
Hide file tree
Showing 12 changed files with 1,034 additions and 657 deletions.
4 changes: 2 additions & 2 deletions .github/workflows/build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -53,11 +53,11 @@ jobs:
run: 'dotnet build --no-restore --configuration Release'

- name: Test Project
run: 'dotnet test --no-build --no-restore --configuration Release'
run: 'dotnet test --no-build --configuration Release'

- name: Create Packages
if: success() && github.event_name != 'pull_request'
run: 'dotnet pack --configuration Release --include-symbols --include-source --no-build --no-restore --output "${{env.BUILD_PATH}}"'
run: 'dotnet pack --configuration Release --no-build --output "${{env.BUILD_PATH}}"'

- name: Upload Packages
if: success() && github.event_name != 'pull_request'
Expand Down
4 changes: 2 additions & 2 deletions samples/SampleWebApplication/Pages/Logs.cshtml
Original file line number Diff line number Diff line change
Expand Up @@ -182,7 +182,7 @@
asp-page="/Logs"
asp-route-z="@Model.PageSize"
asp-route-l="@Model.Level"
asp-route-d="@Model.Date.Date"
asp-route-d="@Model.Date"
asp-route-t="">First</a>
</li>
}
Expand All @@ -199,7 +199,7 @@
asp-page="/Logs"
asp-route-z="@Model.PageSize"
asp-route-l="@Model.Level"
asp-route-d="@Model.Date.Date"
asp-route-d="@Model.Date"
asp-route-t="@Model.NextToken">Next</a>
</li>
}
Expand Down
10 changes: 3 additions & 7 deletions samples/SampleWebApplication/Pages/Logs.cshtml.cs
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@

using SampleWebApplication.Models;

using Serilog.Sinks.AzureTableStorage.Extensions;
using Serilog.Sinks.AzureTableStorage;

namespace SampleWebApplication.Pages;

Expand All @@ -25,7 +25,7 @@ public LogsModel(TableServiceClient tableServiceClient)
public string? Level { get; set; } = string.Empty;

[BindProperty(Name = "d", SupportsGet = true)]
public DateTime Date { get; set; } = DateTime.Today;
public DateOnly Date { get; set; } = DateOnly.FromDateTime(DateTime.Today);

[BindProperty(Name = "t", SupportsGet = true)]
public string ContinuationToken { get; set; } = string.Empty;
Expand All @@ -38,11 +38,7 @@ public async Task<IActionResult> OnGetAsync(CancellationToken cancellationToken)
{
var logTable = _tableServiceClient.GetTableClient("SampleLog");

var dateTime = Date.Date.ToUniversalTime();
var upper = dateTime.GeneratePartitionKey();
var lower = dateTime.AddDays(1).GeneratePartitionKey();

var filter = $"({nameof(ITableEntity.PartitionKey)} ge '{lower}') and ({nameof(ITableEntity.PartitionKey)} lt '{upper}')";
var filter = DefaultKeyGenerator.GeneratePartitionKeyQuery(Date);

if (!string.IsNullOrWhiteSpace(Level))
filter += $" and ({nameof(LogEventModel.Level)} eq '{Level}')";
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,11 +16,22 @@
<PackageLicenseExpression>Apache-2.0</PackageLicenseExpression>
<RepositoryUrl>https://github.com/serilog-contrib/serilog-sinks-azuretablestorage.git</RepositoryUrl>
<RepositoryType>git</RepositoryType>
<PublishRepositoryUrl>true</PublishRepositoryUrl>
<GenerateDocumentationFile>true</GenerateDocumentationFile>
<RootNamespace>Serilog</RootNamespace>
<LangVersion>latest</LangVersion>
<TreatWarningsAsErrors>true</TreatWarningsAsErrors>
<Copyright>Copyright © Serilog Contributors 2023</Copyright>
<Copyright>Copyright © Serilog Contributors 2024</Copyright>
</PropertyGroup>

<PropertyGroup Label="Debug">
<DebugType>embedded</DebugType>
<EmbedUntrackedSources>true</EmbedUntrackedSources>
<IncludeSymbols>false</IncludeSymbols>
</PropertyGroup>

<PropertyGroup Condition="'$(GITHUB_ACTIONS)' == 'true'">
<ContinuousIntegrationBuild>true</ContinuousIntegrationBuild>
</PropertyGroup>

<ItemGroup>
Expand All @@ -43,7 +54,7 @@
<ItemGroup>
<PackageReference Include="MinVer" Version="5.0.0" PrivateAssets="All" />
<PackageReference Include="Serilog" Version="3.1.1" />
<PackageReference Include="Serilog.Sinks.PeriodicBatching" Version="4.0.1" />
<PackageReference Include="Serilog.Sinks.PeriodicBatching" Version="4.1.0" />
<PackageReference Include="Azure.Data.Tables" Version="12.8.3" />
<PackageReference Include="ulid" Version="1.3.3" />
</ItemGroup>
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,9 @@
using System;
using System.Dynamic;
using System.Threading;

using Azure.Data.Tables;

using Serilog.Events;
using Serilog.Sinks.AzureTableStorage.Extensions;

Expand All @@ -9,8 +12,10 @@ namespace Serilog.Sinks.AzureTableStorage;
/// <summary>
/// Default document key generator
/// </summary>
/// <seealso cref="Serilog.Sinks.AzureTableStorage.IKeyGenerator" />
public class DefaultKeyGenerator : IKeyGenerator
{
private const string PartitionKeyName = nameof(ITableEntity.PartitionKey);

/// <summary>
/// Automatically generates the PartitionKey based on the logEvent timestamp
Expand All @@ -28,7 +33,7 @@ public virtual string GeneratePartitionKey(LogEvent logEvent, AzureTableStorageS
// batch insert is used to get around time based partition key performance issues
// values are created in reverse chronological order so newest are always first

var utcEventTime = logEvent.Timestamp.UtcDateTime;
var utcEventTime = logEvent.Timestamp;
var partitionKeyRounding = options?.PartitionKeyRounding;

return GeneratePartitionKey(utcEventTime, partitionKeyRounding);
Expand All @@ -47,45 +52,149 @@ public virtual string GenerateRowKey(LogEvent logEvent, AzureTableStorageSinkOpt

// row key created in reverse chronological order so newest are always first

var utcEventTime = logEvent.Timestamp.UtcDateTime;
var utcEventTime = logEvent.Timestamp;
return GenerateRowKey(utcEventTime);
}



/// <summary>
/// Generates the PartitionKey based on the logEvent timestamp
/// Generates the PartitionKey based on the specified <paramref name="eventTime"/> timestamp
/// </summary>
/// <param name="utcEventTime">The UTC event time.</param>
/// <param name="eventTime">The event time.</param>
/// <param name="roundSpan">The round span.</param>
/// <returns>
/// The Generated PartitionKey
/// </returns>
/// <remarks>
/// The partition key based on the Timestamp rounded to the nearest 5 min
/// </remarks>
public static string GeneratePartitionKey(DateTime utcEventTime, TimeSpan? roundSpan = null)
public static string GeneratePartitionKey(DateTimeOffset eventTime, TimeSpan? roundSpan = null)
{
var span = roundSpan ?? TimeSpan.FromMinutes(5);
var roundedEvent = utcEventTime.Round(span);
var dateTime = eventTime.ToUniversalTime();
var roundedEvent = dateTime.Round(span);

// create a 19 character String for reverse chronological ordering.
return $"{DateTime.MaxValue.Ticks - roundedEvent.Ticks:D19}";
return $"{DateTimeOffset.MaxValue.Ticks - roundedEvent.Ticks:D19}";
}

/// <summary>
/// Generates the RowKey using the timestamp
/// Generates the PartitionKey based on the specified <paramref name="eventTime"/> timestamp
/// </summary>
/// <param name="utcEventTime">The UTC event time.</param>
/// <param name="eventTime">The event time.</param>
/// <param name="roundSpan">The round span.</param>
/// <returns>
/// The Generated PartitionKey
/// </returns>
/// <remarks>
/// The partition key based on the Timestamp rounded to the nearest 5 min
/// </remarks>
public static string GeneratePartitionKey(DateTime eventTime, TimeSpan? roundSpan = null)
{
var dateTime = eventTime.ToUniversalTime();
var dateTimeOffset = new DateTimeOffset(dateTime, TimeSpan.Zero);

return GeneratePartitionKey(dateTimeOffset, roundSpan);
}


/// <summary>
/// Generates the RowKey using a reverse chronological ordering date, newest logs sorted first
/// </summary>
/// <param name="eventTime">The event time.</param>
/// <returns>
/// The generated RowKey
/// </returns>
public static string GenerateRowKey(DateTime utcEventTime)
public static string GenerateRowKey(DateTimeOffset eventTime)
{
var dateTime = eventTime.ToUniversalTime();

// create a reverse chronological ordering date, newest logs sorted first
var timestamp = utcEventTime.ToReverseChronological();
var timestamp = dateTime.ToReverseChronological();

// use Ulid for speed and efficiency
return Ulid.NewUlid(timestamp).ToString();
}

/// <summary>
/// Generates the RowKey using a reverse chronological ordering date, newest logs sorted first
/// </summary>
/// <param name="eventTime">The event time.</param>
/// <returns>
/// The generated RowKey
/// </returns>
public static string GenerateRowKey(DateTime eventTime)
{
var dateTime = eventTime.ToUniversalTime();
var dateTimeOffset = new DateTimeOffset(dateTime, TimeSpan.Zero);

return GenerateRowKey(dateTimeOffset);
}


#if NET6_0_OR_GREATER
/// <summary>
/// Generates the partition key query using the specified <paramref name="date"/>.
/// </summary>
/// <param name="date">The date to use for query.</param>
/// <param name="offset">The date's offset from Coordinated Universal Time (UTC).</param>
/// <returns>An Azure Table partiion key query.</returns>
public static string GeneratePartitionKeyQuery(DateOnly date, TimeSpan offset)
{
// date is assumed to be in local time, will be converted to UTC
var startTime = new DateTimeOffset(date.Year, date.Month, date.Day, 0, 0, 0, offset);
var endTime = startTime.AddDays(1);

return GeneratePartitionKeyQuery(startTime, endTime);
}

/// <summary>
/// Generates the partition key query using the specified <paramref name="date"/>.
/// </summary>
/// <param name="date">The date to use for query.</param>
/// <param name="zone">The time zone the date is in.</param>
/// <returns>An Azure Table partiion key query.</returns>
public static string GeneratePartitionKeyQuery(DateOnly date, TimeZoneInfo zone = null)
{
// date is assumed to be in local time, will be converted to UTC
var startTime = date.ToDateTimeOffset(zone);
var endTime = date.AddDays(1).ToDateTimeOffset(zone);

return GeneratePartitionKeyQuery(startTime, endTime);
}
#endif

/// <summary>
/// Generates the partition key query using the specified <paramref name="startDate"/> and <paramref name="endDate"/>.
/// </summary>
/// <param name="startDate">The start date to use for query.</param>
/// <param name="endDate">The end date to use for query.</param>
/// <returns>An Azure Table partiion key query.</returns>
public static string GeneratePartitionKeyQuery(DateTime startDate, DateTime endDate)
{
var startTime = startDate.ToUniversalTime();
var startTimeOffset = new DateTimeOffset(startTime, TimeSpan.Zero);

var endTime = endDate.ToUniversalTime();
var endTimeOffset = new DateTimeOffset(endTime, TimeSpan.Zero);

return GeneratePartitionKeyQuery(startTimeOffset, endTimeOffset);
}

/// <summary>
/// Generates the partition key query using the specified <paramref name="startDate"/> and <paramref name="endDate"/>.
/// </summary>
/// <param name="startDate">The start date to use for query.</param>
/// <param name="endDate">The end date to use for query.</param>
/// <returns>An Azure Table partiion key query.</returns>
public static string GeneratePartitionKeyQuery(DateTimeOffset startDate, DateTimeOffset endDate)
{
var startTime = startDate.ToUniversalTime();
var endTime = endDate.ToUniversalTime();

var upper = startTime.ToReverseChronological().Ticks.ToString("D19");
var lower = endTime.ToReverseChronological().Ticks.ToString("D19");

return $"({PartitionKeyName} ge '{lower}') and ({PartitionKeyName} lt '{upper}')";
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
using System;

namespace Serilog.Sinks.AzureTableStorage.Extensions;

#if NET6_0_OR_GREATER
/// <summary>
/// Extension methods for <see cref="DateOnly"/>
/// </summary>
public static class DateOnlyExtensions
{
/// <summary>
/// Converts the <see cref="DateOnly"/> to a <see cref="DateTimeOffset"/> in the specified timezone.
/// </summary>
/// <param name="dateOnly">The date to convert.</param>
/// <param name="zone">The time zone the date is in.</param>
/// <returns>The converted <see cref="DateTimeOffset"/></returns>
public static DateTimeOffset ToDateTimeOffset(this DateOnly dateOnly, TimeZoneInfo zone = null)
{
zone ??= TimeZoneInfo.Local;

var dateTime = dateOnly.ToDateTime(TimeOnly.MinValue);
var offset = zone.GetUtcOffset(dateTime);

return new DateTimeOffset(dateTime, offset);
}

/// <summary>
/// Converts the <see cref="DateTimeOffset"/> to a <see cref="DateOnly"/> in the specified timezone.
/// </summary>
/// <param name="dateTime">The <see cref="DateTimeOffset"/> to convert.</param>
/// <param name="zone">The time zone the date is in.</param>
/// <returns>The converted <see cref="DateOnly"/></returns>
public static DateOnly ToDateOnly(this DateTimeOffset dateTime, TimeZoneInfo zone = null)
{
zone ??= TimeZoneInfo.Local;

var targetZone = TimeZoneInfo.ConvertTime(dateTime, zone);
return DateOnly.FromDateTime(targetZone.Date);
}
}
#endif
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,6 @@ public static class DateTimeExtensions
/// <remarks>
/// The partition key based on the Timestamp rounded to the nearest 5 min
/// </remarks>
[Obsolete("Use DefaultKeyGenerator instead")]
public static string GeneratePartitionKey(this DateTime utcEventTime, TimeSpan? roundSpan = null)
{
return DefaultKeyGenerator.GeneratePartitionKey(utcEventTime, roundSpan);
Expand All @@ -31,7 +30,6 @@ public static string GeneratePartitionKey(this DateTime utcEventTime, TimeSpan?
/// <returns>
/// The generated RowKey
/// </returns>
[Obsolete("Use DefaultKeyGenerator instead")]
public static string GenerateRowKey(this DateTime utcEventTime)
{
return DefaultKeyGenerator.GenerateRowKey(utcEventTime);
Expand Down
Loading

0 comments on commit 7ceda92

Please sign in to comment.