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