11using System ;
2+ using System . Threading ;
23
34using Serilog . Events ;
45using Serilog . Sinks . AzureTableStorage . Extensions ;
@@ -10,6 +11,7 @@ namespace Serilog.Sinks.AzureTableStorage;
1011/// </summary>
1112public class DefaultKeyGenerator : IKeyGenerator
1213{
14+
1315 /// <summary>
1416 /// Automatically generates the PartitionKey based on the logEvent timestamp
1517 /// </summary>
@@ -33,7 +35,7 @@ public virtual string GeneratePartitionKey(LogEvent logEvent, AzureTableStorageS
3335 }
3436
3537 /// <summary>
36- /// Automatically generates the RowKey using the timestamp
38+ /// Automatically generates the RowKey using the timestamp
3739 /// </summary>
3840 /// <param name="logEvent">the log event</param>
3941 /// <param name="options">The table storage options.</param>
@@ -48,4 +50,69 @@ public virtual string GenerateRowKey(LogEvent logEvent, AzureTableStorageSinkOpt
4850 var utcEventTime = logEvent . Timestamp . UtcDateTime ;
4951 return utcEventTime . GenerateRowKey ( ) ;
5052 }
53+
54+
55+
56+ /// <summary>
57+ /// Generates the PartitionKey based on the logEvent timestamp
58+ /// </summary>
59+ /// <param name="utcEventTime">The UTC event time.</param>
60+ /// <param name="roundSpan">The round span.</param>
61+ /// <returns>
62+ /// The Generated PartitionKey
63+ /// </returns>
64+ /// <remarks>
65+ /// The partition key based on the Timestamp rounded to the nearest 5 min
66+ /// </remarks>
67+ public static string GeneratePartitionKey ( DateTime utcEventTime , TimeSpan ? roundSpan = null )
68+ {
69+ var span = roundSpan ?? TimeSpan . FromMinutes ( 5 ) ;
70+ var roundedEvent = Round ( utcEventTime , span ) ;
71+
72+ // create a 19 character String for reverse chronological ordering.
73+ return $ "{ DateTime . MaxValue . Ticks - roundedEvent . Ticks : D19} ";
74+ }
75+
76+ /// <summary>
77+ /// Generates the RowKey using the timestamp
78+ /// </summary>
79+ /// <param name="utcEventTime">The UTC event time.</param>
80+ /// <returns>
81+ /// The generated RowKey
82+ /// </returns>
83+ public static string GenerateRowKey ( DateTime utcEventTime )
84+ {
85+ // create a reverse chronological ordering date
86+ var targetTicks = DateTime . MaxValue . Ticks - utcEventTime . Ticks ;
87+
88+ // add incrementing value to ensure unique
89+ int padding = Next ( ) ;
90+
91+ return $ "{ targetTicks : D19} { padding : D4} ";
92+ }
93+
94+ /// <summary>
95+ /// Rounds the specified date.
96+ /// </summary>
97+ /// <param name="date">The date to round.</param>
98+ /// <param name="span">The span.</param>
99+ /// <returns>The rounded date</returns>
100+ public static DateTime Round ( DateTime date , TimeSpan span )
101+ {
102+ long ticks = ( date . Ticks + ( span . Ticks / 2 ) + 1 ) / span . Ticks ;
103+ return new DateTime ( ticks * span . Ticks ) ;
104+ }
105+
106+
107+ private static int _counter = new Random ( ) . Next ( _minCounter , _maxCounter ) ;
108+
109+ private const int _minCounter = 1 ;
110+ private const int _maxCounter = 9999 ;
111+
112+ private static int Next ( )
113+ {
114+ Interlocked . Increment ( ref _counter ) ;
115+ return Interlocked . CompareExchange ( ref _counter , _minCounter , _maxCounter ) ;
116+ }
117+
51118}
0 commit comments