@@ -29,13 +29,16 @@ namespace OpenTelemetry.Logs
2929 /// </summary>
3030 public sealed class LogRecord
3131 {
32+ internal LogRecordData Data ;
33+
3234 private static readonly Action < object ? , List < object ? > > AddScopeToBufferedList = ( object ? scope , List < object ? > state ) =>
3335 {
3436 state . Add ( scope ) ;
3537 } ;
3638
3739 private List < object ? > ? bufferedScopes ;
3840
41+ // Note: Some users are calling this with reflection. Try not to change the signature to be nice.
3942 internal LogRecord (
4043 IExternalScopeProvider ? scopeProvider ,
4144 DateTime timestamp ,
@@ -47,71 +50,107 @@ internal LogRecord(
4750 Exception ? exception ,
4851 IReadOnlyList < KeyValuePair < string , object ? > > ? stateValues )
4952 {
50- this . ScopeProvider = scopeProvider ;
51-
52- var activity = Activity . Current ;
53- if ( activity != null )
53+ this . Data = new ( Activity . Current )
5454 {
55- this . TraceId = activity . TraceId ;
56- this . SpanId = activity . SpanId ;
57- this . TraceState = activity . TraceStateString ;
58- this . TraceFlags = activity . ActivityTraceFlags ;
59- }
55+ TimestampBacking = timestamp ,
6056
61- this . Timestamp = timestamp ;
62- this . CategoryName = categoryName ;
63- this . LogLevel = logLevel ;
64- this . EventId = eventId ;
65- this . FormattedMessage = formattedMessage ;
66- this . State = state ;
57+ CategoryName = categoryName ,
58+ LogLevel = logLevel ,
59+ EventId = eventId ,
60+ Message = formattedMessage ,
61+ Exception = exception ,
62+ } ;
63+
64+ this . ScopeProvider = scopeProvider ;
6765 this . StateValues = stateValues ;
68- this . Exception = exception ;
66+ this . State = state ;
6967 }
7068
7169 /// <summary>
72- /// Gets the log timestamp.
70+ /// Gets or sets the log timestamp.
7371 /// </summary>
74- public DateTime Timestamp { get ; }
72+ /// <remarks>
73+ /// Note: If <see cref="Timestamp"/> is set to a value with <see
74+ /// cref="DateTimeKind.Local"/> it will be automatically converted to
75+ /// UTC using <see cref="DateTime.ToUniversalTime"/>.
76+ /// </remarks>
77+ public DateTime Timestamp
78+ {
79+ get => this . Data . Timestamp ;
80+ set => this . Data . Timestamp = value ;
81+ }
7582
7683 /// <summary>
77- /// Gets the log <see cref="ActivityTraceId"/>.
84+ /// Gets or sets the log <see cref="ActivityTraceId"/>.
7885 /// </summary>
79- public ActivityTraceId TraceId { get ; }
86+ public ActivityTraceId TraceId
87+ {
88+ get => this . Data . TraceId ;
89+ set => this . Data . TraceId = value ;
90+ }
8091
8192 /// <summary>
82- /// Gets the log <see cref="ActivitySpanId"/>.
93+ /// Gets or sets the log <see cref="ActivitySpanId"/>.
8394 /// </summary>
84- public ActivitySpanId SpanId { get ; }
95+ public ActivitySpanId SpanId
96+ {
97+ get => this . Data . SpanId ;
98+ set => this . Data . SpanId = value ;
99+ }
85100
86101 /// <summary>
87- /// Gets the log <see cref="ActivityTraceFlags"/>.
102+ /// Gets or sets the log <see cref="ActivityTraceFlags"/>.
88103 /// </summary>
89- public ActivityTraceFlags TraceFlags { get ; }
104+ public ActivityTraceFlags TraceFlags
105+ {
106+ get => this . Data . TraceFlags ;
107+ set => this . Data . TraceFlags = value ;
108+ }
90109
91110 /// <summary>
92- /// Gets the log trace state.
111+ /// Gets or sets the log trace state.
93112 /// </summary>
94- public string ? TraceState { get ; }
113+ public string ? TraceState
114+ {
115+ get => this . Data . TraceState ;
116+ set => this . Data . TraceState = value ;
117+ }
95118
96119 /// <summary>
97- /// Gets the log category name.
120+ /// Gets or sets the log category name.
98121 /// </summary>
99- public string ? CategoryName { get ; }
122+ public string ? CategoryName
123+ {
124+ get => this . Data . CategoryName ;
125+ set => this . Data . CategoryName = value ;
126+ }
100127
101128 /// <summary>
102- /// Gets the log <see cref="Microsoft.Extensions.Logging.LogLevel"/>.
129+ /// Gets or sets the log <see cref="Microsoft.Extensions.Logging.LogLevel"/>.
103130 /// </summary>
104- public LogLevel LogLevel { get ; }
131+ public LogLevel LogLevel
132+ {
133+ get => this . Data . LogLevel ;
134+ set => this . Data . LogLevel = value ;
135+ }
105136
106137 /// <summary>
107- /// Gets the log <see cref="EventId"/>.
138+ /// Gets or sets the log <see cref="Microsoft.Extensions.Logging. EventId"/>.
108139 /// </summary>
109- public EventId EventId { get ; }
140+ public EventId EventId
141+ {
142+ get => this . Data . EventId ;
143+ set => this . Data . EventId = value ;
144+ }
110145
111146 /// <summary>
112147 /// Gets or sets the log formatted message.
113148 /// </summary>
114- public string ? FormattedMessage { get ; set ; }
149+ public string ? FormattedMessage
150+ {
151+ get => this . Data . Message ;
152+ set => this . Data . Message = value ;
153+ }
115154
116155 /// <summary>
117156 /// Gets or sets the raw state attached to the log. Set to <see
@@ -128,9 +167,13 @@ internal LogRecord(
128167 public IReadOnlyList < KeyValuePair < string , object ? > > ? StateValues { get ; set ; }
129168
130169 /// <summary>
131- /// Gets the log <see cref="System.Exception"/>.
170+ /// Gets or sets the log <see cref="System.Exception"/>.
132171 /// </summary>
133- public Exception ? Exception { get ; }
172+ public Exception ? Exception
173+ {
174+ get => this . Data . Exception ;
175+ set => this . Data . Exception = value ;
176+ }
134177
135178 internal IExternalScopeProvider ? ScopeProvider { get ; set ; }
136179
@@ -139,13 +182,6 @@ internal LogRecord(
139182 /// of creation. All callbacks are guaranteed to be called inline from
140183 /// this method.
141184 /// </summary>
142- /// <remarks>
143- /// Note: Scopes are only available during the lifecycle of the log
144- /// message being written. If you need to capture scopes to be used
145- /// later (for example in batching scenarios), call <see
146- /// cref="BufferLogScopes"/> to safely capture the values (incurs
147- /// allocation).
148- /// </remarks>
149185 /// <typeparam name="TState">State.</typeparam>
150186 /// <param name="callback">The callback to be executed for every scope object.</param>
151187 /// <param name="state">The state object to be passed into the callback.</param>
@@ -168,6 +204,15 @@ public void ForEachScope<TState>(Action<LogRecordScope, TState> callback, TState
168204 }
169205 }
170206
207+ /// <summary>
208+ /// Gets a reference to the <see cref="LogRecordData"/> for the log message.
209+ /// </summary>
210+ /// <returns><see cref="LogRecordData"/>.</returns>
211+ internal ref LogRecordData GetDataRef ( )
212+ {
213+ return ref this . Data ;
214+ }
215+
171216 /// <summary>
172217 /// Buffers the scopes attached to the log into a list so that they can
173218 /// be safely processed after the log message lifecycle has ended.
0 commit comments