11using System ;
2+ using System . Dynamic ;
23using System . Threading ;
34
5+ using Azure . Data . Tables ;
6+
47using Serilog . Events ;
58using Serilog . Sinks . AzureTableStorage . Extensions ;
69
@@ -9,8 +12,10 @@ namespace Serilog.Sinks.AzureTableStorage;
912/// <summary>
1013/// Default document key generator
1114/// </summary>
15+ /// <seealso cref="Serilog.Sinks.AzureTableStorage.IKeyGenerator" />
1216public class DefaultKeyGenerator : IKeyGenerator
1317{
18+ private const string PartitionKeyName = nameof ( ITableEntity . PartitionKey ) ;
1419
1520 /// <summary>
1621 /// Automatically generates the PartitionKey based on the logEvent timestamp
@@ -28,7 +33,7 @@ public virtual string GeneratePartitionKey(LogEvent logEvent, AzureTableStorageS
2833 // batch insert is used to get around time based partition key performance issues
2934 // values are created in reverse chronological order so newest are always first
3035
31- var utcEventTime = logEvent . Timestamp . UtcDateTime ;
36+ var utcEventTime = logEvent . Timestamp ;
3237 var partitionKeyRounding = options ? . PartitionKeyRounding ;
3338
3439 return GeneratePartitionKey ( utcEventTime , partitionKeyRounding ) ;
@@ -47,45 +52,149 @@ public virtual string GenerateRowKey(LogEvent logEvent, AzureTableStorageSinkOpt
4752
4853 // row key created in reverse chronological order so newest are always first
4954
50- var utcEventTime = logEvent . Timestamp . UtcDateTime ;
55+ var utcEventTime = logEvent . Timestamp ;
5156 return GenerateRowKey ( utcEventTime ) ;
5257 }
5358
5459
55-
5660 /// <summary>
57- /// Generates the PartitionKey based on the logEvent timestamp
61+ /// Generates the PartitionKey based on the specified <paramref name="eventTime"/> timestamp
5862 /// </summary>
59- /// <param name="utcEventTime ">The UTC event time.</param>
63+ /// <param name="eventTime ">The event time.</param>
6064 /// <param name="roundSpan">The round span.</param>
6165 /// <returns>
6266 /// The Generated PartitionKey
6367 /// </returns>
6468 /// <remarks>
6569 /// The partition key based on the Timestamp rounded to the nearest 5 min
6670 /// </remarks>
67- public static string GeneratePartitionKey ( DateTime utcEventTime , TimeSpan ? roundSpan = null )
71+ public static string GeneratePartitionKey ( DateTimeOffset eventTime , TimeSpan ? roundSpan = null )
6872 {
6973 var span = roundSpan ?? TimeSpan . FromMinutes ( 5 ) ;
70- var roundedEvent = utcEventTime . Round ( span ) ;
74+ var dateTime = eventTime . ToUniversalTime ( ) ;
75+ var roundedEvent = dateTime . Round ( span ) ;
7176
7277 // create a 19 character String for reverse chronological ordering.
73- return $ "{ DateTime . MaxValue . Ticks - roundedEvent . Ticks : D19} ";
78+ return $ "{ DateTimeOffset . MaxValue . Ticks - roundedEvent . Ticks : D19} ";
7479 }
7580
7681 /// <summary>
77- /// Generates the RowKey using the timestamp
82+ /// Generates the PartitionKey based on the specified <paramref name="eventTime"/> timestamp
7883 /// </summary>
79- /// <param name="utcEventTime">The UTC event time.</param>
84+ /// <param name="eventTime">The event time.</param>
85+ /// <param name="roundSpan">The round span.</param>
86+ /// <returns>
87+ /// The Generated PartitionKey
88+ /// </returns>
89+ /// <remarks>
90+ /// The partition key based on the Timestamp rounded to the nearest 5 min
91+ /// </remarks>
92+ public static string GeneratePartitionKey ( DateTime eventTime , TimeSpan ? roundSpan = null )
93+ {
94+ var dateTime = eventTime . ToUniversalTime ( ) ;
95+ var dateTimeOffset = new DateTimeOffset ( dateTime , TimeSpan . Zero ) ;
96+
97+ return GeneratePartitionKey ( dateTimeOffset , roundSpan ) ;
98+ }
99+
100+
101+ /// <summary>
102+ /// Generates the RowKey using a reverse chronological ordering date, newest logs sorted first
103+ /// </summary>
104+ /// <param name="eventTime">The event time.</param>
80105 /// <returns>
81106 /// The generated RowKey
82107 /// </returns>
83- public static string GenerateRowKey ( DateTime utcEventTime )
108+ public static string GenerateRowKey ( DateTimeOffset eventTime )
84109 {
110+ var dateTime = eventTime . ToUniversalTime ( ) ;
111+
85112 // create a reverse chronological ordering date, newest logs sorted first
86- var timestamp = utcEventTime . ToReverseChronological ( ) ;
113+ var timestamp = dateTime . ToReverseChronological ( ) ;
87114
88115 // use Ulid for speed and efficiency
89116 return Ulid . NewUlid ( timestamp ) . ToString ( ) ;
90117 }
118+
119+ /// <summary>
120+ /// Generates the RowKey using a reverse chronological ordering date, newest logs sorted first
121+ /// </summary>
122+ /// <param name="eventTime">The event time.</param>
123+ /// <returns>
124+ /// The generated RowKey
125+ /// </returns>
126+ public static string GenerateRowKey ( DateTime eventTime )
127+ {
128+ var dateTime = eventTime . ToUniversalTime ( ) ;
129+ var dateTimeOffset = new DateTimeOffset ( dateTime , TimeSpan . Zero ) ;
130+
131+ return GenerateRowKey ( dateTimeOffset ) ;
132+ }
133+
134+
135+ #if NET6_0_OR_GREATER
136+ /// <summary>
137+ /// Generates the partition key query using the specified <paramref name="date"/>.
138+ /// </summary>
139+ /// <param name="date">The date to use for query.</param>
140+ /// <param name="offset">The date's offset from Coordinated Universal Time (UTC).</param>
141+ /// <returns>An Azure Table partiion key query.</returns>
142+ public static string GeneratePartitionKeyQuery ( DateOnly date , TimeSpan offset )
143+ {
144+ // date is assumed to be in local time, will be converted to UTC
145+ var startTime = new DateTimeOffset ( date . Year , date . Month , date . Day , 0 , 0 , 0 , offset ) ;
146+ var endTime = startTime . AddDays ( 1 ) ;
147+
148+ return GeneratePartitionKeyQuery ( startTime , endTime ) ;
149+ }
150+
151+ /// <summary>
152+ /// Generates the partition key query using the specified <paramref name="date"/>.
153+ /// </summary>
154+ /// <param name="date">The date to use for query.</param>
155+ /// <param name="zone">The time zone the date is in.</param>
156+ /// <returns>An Azure Table partiion key query.</returns>
157+ public static string GeneratePartitionKeyQuery ( DateOnly date , TimeZoneInfo zone = null )
158+ {
159+ // date is assumed to be in local time, will be converted to UTC
160+ var startTime = date . ToDateTimeOffset ( zone ) ;
161+ var endTime = date . AddDays ( 1 ) . ToDateTimeOffset ( zone ) ;
162+
163+ return GeneratePartitionKeyQuery ( startTime , endTime ) ;
164+ }
165+ #endif
166+
167+ /// <summary>
168+ /// Generates the partition key query using the specified <paramref name="startDate"/> and <paramref name="endDate"/>.
169+ /// </summary>
170+ /// <param name="startDate">The start date to use for query.</param>
171+ /// <param name="endDate">The end date to use for query.</param>
172+ /// <returns>An Azure Table partiion key query.</returns>
173+ public static string GeneratePartitionKeyQuery ( DateTime startDate , DateTime endDate )
174+ {
175+ var startTime = startDate . ToUniversalTime ( ) ;
176+ var startTimeOffset = new DateTimeOffset ( startTime , TimeSpan . Zero ) ;
177+
178+ var endTime = endDate . ToUniversalTime ( ) ;
179+ var endTimeOffset = new DateTimeOffset ( endTime , TimeSpan . Zero ) ;
180+
181+ return GeneratePartitionKeyQuery ( startTimeOffset , endTimeOffset ) ;
182+ }
183+
184+ /// <summary>
185+ /// Generates the partition key query using the specified <paramref name="startDate"/> and <paramref name="endDate"/>.
186+ /// </summary>
187+ /// <param name="startDate">The start date to use for query.</param>
188+ /// <param name="endDate">The end date to use for query.</param>
189+ /// <returns>An Azure Table partiion key query.</returns>
190+ public static string GeneratePartitionKeyQuery ( DateTimeOffset startDate , DateTimeOffset endDate )
191+ {
192+ var startTime = startDate . ToUniversalTime ( ) ;
193+ var endTime = endDate . ToUniversalTime ( ) ;
194+
195+ var upper = startTime . ToReverseChronological ( ) . Ticks . ToString ( "D19" ) ;
196+ var lower = endTime . ToReverseChronological ( ) . Ticks . ToString ( "D19" ) ;
197+
198+ return $ "({ PartitionKeyName } ge '{ lower } ') and ({ PartitionKeyName } lt '{ upper } ')";
199+ }
91200}
0 commit comments