11using System ;
22using System . Collections . Generic ;
33using System . Linq ;
4- using System . Text ;
54using NLog . Config ;
5+ using NLog . LayoutRenderers ;
66using NLog . Layouts ;
77
88namespace NLog . Extensions . Logging
@@ -17,12 +17,14 @@ public class MicrosoftConsoleJsonLayout : JsonLayout
1717 {
1818 private static readonly string [ ] EventIdMapper = Enumerable . Range ( 0 , 50 ) . Select ( id => id . ToString ( System . Globalization . CultureInfo . InvariantCulture ) ) . ToArray ( ) ;
1919
20+ private readonly SimpleLayout _timestampLayout = new SimpleLayout ( "${date:format=o:universalTime=true}" ) ;
21+
2022 /// <summary>
2123 /// Initializes a new instance of the <see cref="MicrosoftConsoleJsonLayout" /> class.
2224 /// </summary>
2325 public MicrosoftConsoleJsonLayout ( )
2426 {
25- Attributes . Add ( new JsonAttribute ( "Timestamp" , new TimestampLayout ( ) ) ) ;
27+ Attributes . Add ( new JsonAttribute ( "Timestamp" , _timestampLayout ) ) ;
2628 Attributes . Add ( new JsonAttribute ( "EventId" , Layout . FromMethod ( evt => LookupEventId ( evt ) , LayoutRenderOptions . ThreadAgnostic ) ) { Encode = false } ) ;
2729 Attributes . Add ( new JsonAttribute ( "LogLevel" , Layout . FromMethod ( evt => ConvertLogLevel ( evt . Level ) , LayoutRenderOptions . ThreadAgnostic ) ) ) ;
2830 Attributes . Add ( new JsonAttribute ( "Category" , "${logger}" ) ) ;
@@ -77,7 +79,7 @@ public string TimestampFormat
7779 get
7880 {
7981 var index = LookupNamedAttributeIndex ( "Timestamp" ) ;
80- return index >= 0 ? ( Attributes [ index ] . Layout as TimestampLayout ) ? . TimestampFormat : null ;
82+ return index >= 0 ? ( ( Attributes [ index ] . Layout as SimpleLayout ) ? . LayoutRenderers ? . FirstOrDefault ( ) as DateLayoutRenderer ) ? . Format : null ;
8183 }
8284 set
8385 {
@@ -89,7 +91,9 @@ public string TimestampFormat
8991
9092 if ( ! string . IsNullOrEmpty ( value ) )
9193 {
92- Attributes . Insert ( 0 , new JsonAttribute ( "Timestamp" , new TimestampLayout ( ) { TimestampFormat = value } ) ) ;
94+ var dateLayoutRenderer = _timestampLayout . LayoutRenderers . First ( ) as DateLayoutRenderer ;
95+ dateLayoutRenderer . Format = value ;
96+ Attributes . Insert ( 0 , new JsonAttribute ( "Timestamp" , _timestampLayout ) ) ;
9397 }
9498 }
9599 }
@@ -152,86 +156,5 @@ private static string ConvertLogLevel(LogLevel logLevel)
152156 else
153157 return nameof ( Microsoft . Extensions . Logging . LogLevel . Critical ) ;
154158 }
155-
156- [ ThreadAgnostic ]
157- private sealed class TimestampLayout : Layout
158- {
159- public string TimestampFormat
160- {
161- get => _timestampFormat ;
162- set
163- {
164- if ( "o" . Equals ( value ) )
165- value = "O" ;
166- _timestampFormat = value ;
167- _timestampFormatString = string . IsNullOrEmpty ( value ) ? null : $ "{{0:{ value } }}";
168- }
169- }
170- private string _timestampFormat ;
171- private string _timestampFormatString ;
172-
173- public TimestampLayout ( )
174- {
175- TimestampFormat = "O" ; // Round-trip - ISO8601 - yyyy-MM-ddTHH:mm:ss.fffffffZ
176- }
177-
178- protected override string GetFormattedMessage ( LogEventInfo logEvent )
179- {
180- return _timestampFormatString != null ? logEvent . TimeStamp . ToUniversalTime ( ) . ToString ( TimestampFormat , System . Globalization . CultureInfo . InvariantCulture ) : String . Empty ;
181- }
182-
183- protected override void RenderFormattedMessage ( LogEventInfo logEvent , StringBuilder target )
184- {
185- var utcTimestamp = logEvent . TimeStamp . ToUniversalTime ( ) ;
186- if ( "O" . Equals ( TimestampFormat ) )
187- {
188- // yyyy-MM-ddTHH:mm:ss.fffffffZ
189- Append4DigitsZeroPadded ( target , utcTimestamp . Year ) ;
190- target . Append ( '-' ) ;
191- Append2DigitsZeroPadded ( target , utcTimestamp . Month ) ;
192- target . Append ( '-' ) ;
193- Append2DigitsZeroPadded ( target , utcTimestamp . Day ) ;
194- target . Append ( 'T' ) ;
195- Append2DigitsZeroPadded ( target , utcTimestamp . Hour ) ;
196- target . Append ( ':' ) ;
197- Append2DigitsZeroPadded ( target , utcTimestamp . Minute ) ;
198- target . Append ( ':' ) ;
199- Append2DigitsZeroPadded ( target , utcTimestamp . Second ) ;
200- target . Append ( '.' ) ;
201- var ticks = ( int ) ( utcTimestamp . Ticks % 10000000 ) ;
202- Append7DigitsZeroPadded ( target , ticks ) ;
203- target . Append ( 'Z' ) ;
204- }
205- else if ( _timestampFormatString != null )
206- {
207- target . AppendFormat ( System . Globalization . CultureInfo . InvariantCulture , _timestampFormatString , utcTimestamp ) ;
208- }
209- }
210-
211- internal static void Append2DigitsZeroPadded ( StringBuilder builder , int number )
212- {
213- builder . Append ( ( char ) ( ( number / 10 ) + '0' ) ) ;
214- builder . Append ( ( char ) ( ( number % 10 ) + '0' ) ) ;
215- }
216-
217- internal static void Append4DigitsZeroPadded ( StringBuilder builder , int number )
218- {
219- builder . Append ( ( char ) ( ( ( number / 1000 ) % 10 ) + '0' ) ) ;
220- builder . Append ( ( char ) ( ( ( number / 100 ) % 10 ) + '0' ) ) ;
221- builder . Append ( ( char ) ( ( ( number / 10 ) % 10 ) + '0' ) ) ;
222- builder . Append ( ( char ) ( ( number % 10 ) + '0' ) ) ;
223- }
224-
225- internal static void Append7DigitsZeroPadded ( StringBuilder builder , int number )
226- {
227- builder . Append ( ( char ) ( ( ( number / 1000000 ) % 10 ) + '0' ) ) ;
228- builder . Append ( ( char ) ( ( ( number / 100000 ) % 10 ) + '0' ) ) ;
229- builder . Append ( ( char ) ( ( ( number / 10000 ) % 10 ) + '0' ) ) ;
230- builder . Append ( ( char ) ( ( ( number / 1000 ) % 10 ) + '0' ) ) ;
231- builder . Append ( ( char ) ( ( ( number / 100 ) % 10 ) + '0' ) ) ;
232- builder . Append ( ( char ) ( ( ( number / 10 ) % 10 ) + '0' ) ) ;
233- builder . Append ( ( char ) ( ( number % 10 ) + '0' ) ) ;
234- }
235- }
236159 }
237160}
0 commit comments