-
Notifications
You must be signed in to change notification settings - Fork 325
Expand file tree
/
Copy pathLogHelper.cs
More file actions
850 lines (784 loc) · 36.5 KB
/
LogHelper.cs
File metadata and controls
850 lines (784 loc) · 36.5 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
// ----------------------------------------------------------------------------------
// Copyright Microsoft Corporation
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
// http://www.apache.org/licenses/LICENSE-2.0
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
// ----------------------------------------------------------------------------------
#nullable enable
namespace DurableTask.Core.Logging
{
using DurableTask.Core.Command;
using DurableTask.Core.Common;
using DurableTask.Core.Entities.EventFormat;
using DurableTask.Core.Entities.OperationFormat;
using DurableTask.Core.History;
using Microsoft.Extensions.Logging;
using System;
using System.Collections.Generic;
using System.Text;
class LogHelper
{
readonly ILogger? log;
public LogHelper(ILogger? log)
{
// null is okay
this.log = log;
}
bool IsStructuredLoggingEnabled => this.log != null;
#region TaskHubWorker
/// <summary>
/// Logs that a <see cref="TaskHubWorker"/> is starting.
/// </summary>
internal void TaskHubWorkerStarting()
{
if (this.IsStructuredLoggingEnabled)
{
this.WriteStructuredLog(new LogEvents.TaskHubWorkerStarting());
}
}
/// <summary>
/// Logs that a <see cref="TaskHubWorker"/> started successfully.
/// </summary>
/// <param name="latency">The amount of time it took to start the <see cref="TaskHubWorker"/>.</param>
internal void TaskHubWorkerStarted(TimeSpan latency)
{
if (this.IsStructuredLoggingEnabled)
{
this.WriteStructuredLog(new LogEvents.TaskHubWorkerStarted(latency));
}
}
/// <summary>
/// Logs that a <see cref="TaskHubWorker"/> is stopping.
/// </summary>
internal void TaskHubWorkerStopping(bool isForced)
{
if (this.IsStructuredLoggingEnabled)
{
this.WriteStructuredLog(new LogEvents.TaskHubWorkerStopping(isForced));
}
}
/// <summary>
/// Logs that a <see cref="TaskHubWorker"/> stopped successfully.
/// </summary>
/// <param name="latency">The amount of time it took to stop the <see cref="TaskHubWorker"/>.</param>
internal void TaskHubWorkerStopped(TimeSpan latency)
{
if (this.IsStructuredLoggingEnabled)
{
this.WriteStructuredLog(new LogEvents.TaskHubWorkerStopped(latency));
}
}
#endregion
#region WorkItemDispatcher traces
/// <summary>
/// Indicates that the work item dispatcher is starting.
/// </summary>
/// <param name="context">The context of the starting dispatcher.</param>
internal void DispatcherStarting(WorkItemDispatcherContext context)
{
if (this.IsStructuredLoggingEnabled)
{
this.WriteStructuredLog(new LogEvents.DispatcherStarting(context));
}
}
/// <summary>
/// Logs that a work item dispatcher has stopped running.
/// </summary>
/// <param name="context">The context of the starting dispatcher.</param>
internal void DispatcherStopped(WorkItemDispatcherContext context)
{
if (this.IsStructuredLoggingEnabled)
{
this.WriteStructuredLog(new LogEvents.DispatcherStopped(context));
}
}
/// <summary>
/// Logs that a work item dispatch loop encountered an unhandled exception.
/// </summary>
/// <param name="context">The context of the dispatcher that failed.</param>
/// <param name="exception">The unhandled exception.</param>
internal void DispatcherLoopFailed(WorkItemDispatcherContext context, Exception exception)
{
if (this.IsStructuredLoggingEnabled)
{
this.WriteStructuredLog(
new LogEvents.DispatcherLoopFailed(context, exception),
exception);
}
}
/// <summary>
/// Logs that the work item dispatcher is watching for individual dispatch loops to finish stopping.
/// </summary>
/// <param name="name">The name of the dispatcher - e.g. "TaskOrchestrationDispatcher"</param>
/// <param name="id">The unique ID of the dispatcher.</param>
/// <param name="concurrentWorkItemCount">The number of active work items.</param>
/// <param name="activeFetchers">The number of active fetchers.</param>
internal void DispatchersStopping(string name, string id, int concurrentWorkItemCount, int activeFetchers)
{
if (this.IsStructuredLoggingEnabled)
{
this.WriteStructuredLog(new LogEvents.DispatchersStopping(name, id, concurrentWorkItemCount, activeFetchers));
}
}
/// <summary>
/// Logs that we're starting to fetch a new work item.
/// </summary>
/// <param name="context">The dispatcher context.</param>
/// <param name="timeout">The fetch timeout.</param>
/// <param name="concurrentWorkItemCount">The current number of concurrent work items.</param>
/// <param name="maxConcurrentWorkItems">The maximum number of concurrent work items.</param>
internal void FetchWorkItemStarting(
WorkItemDispatcherContext context,
TimeSpan timeout,
int concurrentWorkItemCount,
int maxConcurrentWorkItems)
{
if (this.IsStructuredLoggingEnabled)
{
this.WriteStructuredLog(
new LogEvents.FetchWorkItemStarting(
context,
timeout,
concurrentWorkItemCount,
maxConcurrentWorkItems));
}
}
/// <summary>
/// Logs that a work-item was fetched successfully.
/// This event does not have enough context to understand the details of the work item.
/// </summary>
/// <param name="context">The dispatcher context.</param>
/// <param name="workItemId">The ID of the fetched work item.</param>
/// <param name="latency">The latency of the fetch operation.</param>
/// <param name="concurrentWorkItemCount">The current number of concurrent work items.</param>
/// <param name="maxConcurrentWorkItems">The maximum number of concurrent work items.</param>
internal void FetchWorkItemCompleted(
WorkItemDispatcherContext context,
string workItemId,
TimeSpan latency,
int concurrentWorkItemCount,
int maxConcurrentWorkItems)
{
if (this.IsStructuredLoggingEnabled)
{
this.WriteStructuredLog(
new LogEvents.FetchWorkItemCompleted(
context,
workItemId,
latency,
concurrentWorkItemCount,
maxConcurrentWorkItems));
}
}
/// <summary>
/// Logs that a work-item fetched failed with an unhandled exception.
/// </summary>
/// <param name="context">The dispatcher context.</param>
/// <param name="exception">The exception associted with the failure.</param>
internal void FetchWorkItemFailure(WorkItemDispatcherContext context, Exception exception)
{
if (this.IsStructuredLoggingEnabled)
{
this.WriteStructuredLog(
new LogEvents.FetchWorkItemFailure(context, exception),
exception);
}
}
/// <summary>
/// Logs that work-item fetching has been throttled due to concurrency constraints.
/// </summary>
/// <param name="context">The dispatcher context.</param>
/// <param name="concurrentWorkItemCount">The current number of concurrent work items.</param>
/// <param name="maxConcurrentWorkItems">The maximum number of concurrent work items.</param>
internal void FetchingThrottled(
WorkItemDispatcherContext context,
int concurrentWorkItemCount,
int maxConcurrentWorkItems)
{
if (this.IsStructuredLoggingEnabled)
{
this.WriteStructuredLog(
new LogEvents.FetchingThrottled(
context,
concurrentWorkItemCount,
maxConcurrentWorkItems));
}
}
/// <summary>
/// Logs that a work item is about to be processed.
/// This event does not have enough context to understand the details of the work item.
/// </summary>
/// <param name="context">The dispatcher context.</param>
/// <param name="workItemId">The ID of the work item.</param>
internal void ProcessWorkItemStarting(WorkItemDispatcherContext context, string workItemId)
{
if (this.IsStructuredLoggingEnabled)
{
this.WriteStructuredLog(
new LogEvents.ProcessWorkItemStarting(context, workItemId));
}
}
/// <summary>
/// Logs that a work item was processed successfully.
/// This event does not have enough context to understand the details of the work item.
/// </summary>
/// <param name="context">The dispatcher context.</param>
/// <param name="workItemId">The ID of the work item.</param>
internal void ProcessWorkItemCompleted(WorkItemDispatcherContext context, string workItemId)
{
if (this.IsStructuredLoggingEnabled)
{
this.WriteStructuredLog(
new LogEvents.ProcessWorkItemCompleted(context, workItemId));
}
}
/// <summary>
/// Logs that a work item was processed successfully.
/// This event does not have enough context to understand the details of the work item.
/// </summary>
/// <param name="context">The dispatcher context.</param>
/// <param name="workItemId">The ID of the work item.</param>
/// <param name="additionalInfo">Additional information associated with the failure.</param>
/// <param name="exception">The exception associated with the failure.</param>
internal void ProcessWorkItemFailed(
WorkItemDispatcherContext context,
string workItemId,
string additionalInfo,
Exception exception)
{
if (this.IsStructuredLoggingEnabled)
{
this.WriteStructuredLog(
new LogEvents.ProcessWorkItemFailed(context, workItemId, additionalInfo, exception),
exception);
}
}
#endregion
#region TaskHubClient traces
/// <summary>
/// Logs that a new orchestration instance has been scheduled.
/// </summary>
/// <param name="startedEvent">The start event for the new orchestration.</param>
internal void SchedulingOrchestration(ExecutionStartedEvent startedEvent)
{
// Note that this log event is also used when orchestrations send events
if (this.IsStructuredLoggingEnabled)
{
this.WriteStructuredLog(new LogEvents.SchedulingOrchestration(startedEvent));
}
}
/// <summary>
/// Logs that an event is being raised to an orchestration.
/// </summary>
/// <param name="target">The target orchestration instance.</param>
/// <param name="raisedEvent">The event-raised event.</param>
internal void RaisingEvent(OrchestrationInstance target, EventRaisedEvent raisedEvent)
{
if (this.IsStructuredLoggingEnabled)
{
this.WriteStructuredLog(new LogEvents.RaisingEvent(target, raisedEvent));
}
}
/// <summary>
/// Logs that an event is being raised by an orchestration.
/// </summary>
/// <param name="source">The sending orchestration instance.</param>
/// <param name="raisedEvent">The event-sent event.</param>
internal void RaisingEvent(OrchestrationInstance source, EventSentEvent raisedEvent)
{
if (this.IsStructuredLoggingEnabled)
{
this.WriteStructuredLog(new LogEvents.RaisingEvent(source, raisedEvent));
}
}
/// <summary>
/// Logs that an instance is being scheduled to be terminated.
/// </summary>
/// <param name="instance">The instance to be terminated.</param>
/// <param name="reason">The user-specified reason for the termination.</param>
internal void TerminatingInstance(OrchestrationInstance instance, string reason)
{
if (this.IsStructuredLoggingEnabled)
{
this.WriteStructuredLog(new LogEvents.TerminatingInstance(instance, reason));
}
}
/// <summary>
/// Logs that an instance is being scheduled to be suspended.
/// </summary>
/// <param name="instance">The instance to be suspended.</param>
/// <param name="reason">The user-specified reason for the suspension.</param>
internal void SuspendingInstance(OrchestrationInstance instance, string reason)
{
if (this.IsStructuredLoggingEnabled)
{
this.WriteStructuredLog(new LogEvents.SuspendingInstance(instance, reason));
}
}
/// <summary>
/// Logs that an instance is being scheduled to be resumed.
/// </summary>
/// <param name="instance">The instance to be resumed.</param>
/// <param name="reason">The user-specified reason for the resumption.</param>
internal void ResumingInstance(OrchestrationInstance instance, string reason)
{
if (this.IsStructuredLoggingEnabled)
{
this.WriteStructuredLog(new LogEvents.ResumingInstance(instance, reason));
}
}
/// <summary>
/// Logs that the client is waiting for an instance to reach a terminal state.
/// </summary>
/// <param name="instance">The instance being awaited.</param>
/// <param name="timeout">The maximum timeout the client will wait.</param>
internal void WaitingForInstance(OrchestrationInstance instance, TimeSpan timeout)
{
if (this.IsStructuredLoggingEnabled)
{
this.WriteStructuredLog(new LogEvents.WaitingForInstance(instance, timeout));
}
}
/// <summary>
/// Logs that the client is attempting to fetch the state of an orchestration instance.
/// </summary>
/// <param name="instanceId">The ID of the instance.</param>
/// <param name="executionId">The execution ID of the instance, if applicable.</param>
internal void FetchingInstanceState(string instanceId, string? executionId = null)
{
if (this.IsStructuredLoggingEnabled)
{
this.WriteStructuredLog(new LogEvents.FetchingInstanceState(instanceId, executionId));
}
}
/// <summary>
/// Logs that the client is attempting to fetch the history of an orchestration instance.
/// </summary>
/// <param name="instance">The instance to fetch the history of.</param>
internal void FetchingInstanceHistory(OrchestrationInstance instance)
{
if (this.IsStructuredLoggingEnabled)
{
this.WriteStructuredLog(new LogEvents.FetchingInstanceHistory(instance));
}
}
#endregion
#region Orchestration dispatcher
/// <summary>
/// Logs that an orchestration work item message is being processed.
/// </summary>
/// <param name="workItem">The orchestration work item.</param>
/// <param name="message">The message being processed.</param>
internal void ProcessingOrchestrationMessage(TaskOrchestrationWorkItem workItem, TaskMessage message)
{
if (this.IsStructuredLoggingEnabled)
{
this.WriteStructuredLog(new LogEvents.ProcessingOrchestrationMessage(workItem, message));
}
}
/// <summary>
/// Logs that an orchestration is about to start executing.
/// </summary>
/// <param name="instance">The orchestration instance that is about to start.</param>
/// <param name="name">The name of the orchestration.</param>
internal void OrchestrationExecuting(OrchestrationInstance instance, string name)
{
if (this.IsStructuredLoggingEnabled)
{
this.WriteStructuredLog(new LogEvents.OrchestrationExecuting(instance, name));
}
}
/// <summary>
/// Logs that an orchestration successfully executed an episode.
/// </summary>
/// <param name="instance">The orchestration instance that was executed.</param>
/// <param name="name">The name of the orchestration.</param>
/// <param name="actions">The actions taken by the orchestration</param>
internal void OrchestrationExecuted(
OrchestrationInstance instance,
string name,
IReadOnlyList<OrchestratorAction> actions)
{
if (this.IsStructuredLoggingEnabled)
{
this.WriteStructuredLog(new LogEvents.OrchestrationExecuted(instance, name, actions.Count));
}
}
/// <summary>
/// Logs that an orchestration is scheduling a task activity for execution.
/// </summary>
/// <param name="instance">The orchestration instance scheduling the task activity.</param>
/// <param name="scheduledEvent">The task scheduled event.</param>
internal void SchedulingActivity(OrchestrationInstance instance, TaskScheduledEvent scheduledEvent)
{
if (this.IsStructuredLoggingEnabled)
{
this.WriteStructuredLog(new LogEvents.SchedulingActivity(instance, scheduledEvent));
}
}
/// <summary>
/// Logs that an orchestration is creating a durable timer.
/// </summary>
/// <param name="instance">The orchestration instance scheduling the task activity.</param>
/// <param name="timerEvent">The timer creation event.</param>
/// <param name="isInternal"><c>true</c> if the timer was created internally by the framework; <c>false</c> if it was created by user code.</param>
internal void CreatingTimer(OrchestrationInstance instance, TimerCreatedEvent timerEvent, bool isInternal)
{
if (this.IsStructuredLoggingEnabled)
{
this.WriteStructuredLog(new LogEvents.CreatingTimer(instance, timerEvent, isInternal));
}
}
/// <summary>
/// Logs that an orchestration is sending an event to another orchestration instance.
/// </summary>
/// <param name="source">The orchestration instance sending the event.</param>
/// <param name="eventSentEvent">The event being sent.</param>
internal void SendingEvent(OrchestrationInstance source, EventSentEvent eventSentEvent)
{
if (this.IsStructuredLoggingEnabled)
{
// We re-use the existing RaisingEvent log event for this
this.WriteStructuredLog(new LogEvents.RaisingEvent(source, eventSentEvent));
}
}
/// <summary>
/// Logs that an orchestration instance has completed.
/// </summary>
/// <param name="runtimeState">The final runtime state of the completed orchestration.</param>
/// <param name="action">The orchestration instance's completion actions.</param>
internal void OrchestrationCompleted(
OrchestrationRuntimeState runtimeState,
OrchestrationCompleteOrchestratorAction action)
{
if (this.IsStructuredLoggingEnabled)
{
this.WriteStructuredLog(new LogEvents.OrchestrationCompleted(runtimeState, action));
}
}
/// <summary>
/// Logs a warning associated with an orchestration completing.
/// </summary>
/// <param name="instance">The orchestration instance of the orchestration.</param>
/// <param name="orchestrationStatus">The status of the completed orchestration.</param>
/// <param name="warningMessage">The warning message to log.</param>
internal void OrchestrationCompletedWithWarning(
OrchestrationInstance instance,
OrchestrationStatus orchestrationStatus,
string warningMessage)
{
if (this.IsStructuredLoggingEnabled)
{
this.WriteStructuredLog(new LogEvents.OrchestrationCompletedWithWarning(instance, orchestrationStatus.ToString(), warningMessage));
}
}
/// <summary>
/// Logs that an orchestration execution was aborted.
/// </summary>
/// <param name="instance">The orchestration instance that aborted execution.</param>
/// <param name="reason">The reason for aborting the orchestration execution.</param>
internal void OrchestrationAborted(OrchestrationInstance instance, string reason)
{
if (this.IsStructuredLoggingEnabled)
{
this.WriteStructuredLog(new LogEvents.OrchestrationAborted(instance, reason));
}
}
/// <summary>
/// Helper method for logging the dropping of all messages associated with the specified work item.
/// </summary>
/// <param name="workItem">The work item being dropped.</param>
/// <param name="reason">The reason for dropping this work item.</param>
internal void DroppingOrchestrationWorkItem(TaskOrchestrationWorkItem workItem, string reason)
{
foreach (TaskMessage message in workItem.NewMessages)
{
this.DroppingOrchestrationMessage(workItem, message, reason);
}
}
/// <summary>
/// Logs that a work item message is being dropped and includes a reason.
/// </summary>
/// <param name="workItem">The work item that this message belonged to.</param>
/// <param name="message">The message being dropped.</param>
/// <param name="reason">The reason for dropping the message.</param>
internal void DroppingOrchestrationMessage(TaskOrchestrationWorkItem workItem, TaskMessage message, string reason)
{
if (this.IsStructuredLoggingEnabled)
{
this.WriteStructuredLog(new LogEvents.DiscardingMessage(workItem, message, reason));
}
}
/// <summary>
/// Logs that an orchestration work item renewal operation is starting.
/// </summary>
/// <param name="workItem">The work item to be renewed.</param>
internal void RenewOrchestrationWorkItemStarting(TaskOrchestrationWorkItem workItem)
{
if (this.IsStructuredLoggingEnabled)
{
this.WriteStructuredLog(new LogEvents.RenewOrchestrationWorkItemStarting(workItem));
}
}
/// <summary>
/// Logs that an orchestration work item renewal operation succeeded.
/// </summary>
/// <param name="workItem">The work item that was renewed.</param>
internal void RenewOrchestrationWorkItemCompleted(TaskOrchestrationWorkItem workItem)
{
if (this.IsStructuredLoggingEnabled)
{
this.WriteStructuredLog(new LogEvents.RenewOrchestrationWorkItemCompleted(workItem));
}
}
/// <summary>
/// Logs that an orchestration work item renewal operation failed.
/// </summary>
/// <param name="workItem">The work item that was to be renewed.</param>
/// <param name="exception">The renew failure exception.</param>
internal void RenewOrchestrationWorkItemFailed(TaskOrchestrationWorkItem workItem, Exception exception)
{
if (this.IsStructuredLoggingEnabled)
{
this.WriteStructuredLog(new LogEvents.RenewOrchestrationWorkItemFailed(workItem, exception), exception);
}
}
/// <summary>
/// Logs that an entity operation batch is about to start executing.
/// </summary>
/// <param name="request">The batch request.</param>
internal void EntityBatchExecuting(EntityBatchRequest request)
{
if (this.IsStructuredLoggingEnabled)
{
this.WriteStructuredLog(new LogEvents.EntityBatchExecuting(request));
}
}
/// <summary>
/// Logs that an entity operation batch completed its execution.
/// </summary>
/// <param name="request">The batch request.</param>
/// <param name="result">The batch result.</param>
internal void EntityBatchExecuted(EntityBatchRequest request, EntityBatchResult result)
{
if (this.IsStructuredLoggingEnabled)
{
this.WriteStructuredLog(new LogEvents.EntityBatchExecuted(request, result));
}
}
/// <summary>
/// Logs that an entity processed a lock acquire message.
/// </summary>
/// <param name="entityId">The entity id.</param>
/// <param name="message">The message.</param>
internal void EntityLockAcquired(string entityId, Core.Entities.EventFormat.RequestMessage message)
{
if (this.IsStructuredLoggingEnabled)
{
this.WriteStructuredLog(new LogEvents.EntityLockAcquired(entityId, message));
}
}
/// <summary>
/// Logs that an entity processed a lock release message.
/// </summary>
/// <param name="entityId">The entity id.</param>
/// <param name="message">The message.</param>
internal void EntityLockReleased(string entityId, Core.Entities.EventFormat.ReleaseMessage message)
{
if (this.IsStructuredLoggingEnabled)
{
this.WriteStructuredLog(new LogEvents.EntityLockReleased(entityId, message));
}
}
#endregion
#region Activity dispatcher
/// <summary>
/// Logs that a task activity is about to begin execution.
/// </summary>
/// <param name="instance">The orchestration instance that scheduled this task activity.</param>
/// <param name="taskEvent">The history event associated with this activity execution.</param>
internal void TaskActivityStarting(OrchestrationInstance instance, TaskScheduledEvent taskEvent)
{
if (this.IsStructuredLoggingEnabled)
{
this.WriteStructuredLog(new LogEvents.TaskActivityStarting(instance, taskEvent));
}
}
/// <summary>
/// Logs that a task activity completed successfully.
/// </summary>
/// <param name="instance">The orchestration instance that scheduled this task activity.</param>
/// <param name="name">The name of the task activity.</param>
/// <param name="taskEvent">The history event associated with this activity completion.</param>
internal void TaskActivityCompleted(OrchestrationInstance instance, string name, TaskCompletedEvent taskEvent)
{
if (this.IsStructuredLoggingEnabled)
{
this.WriteStructuredLog(new LogEvents.TaskActivityCompleted(instance, name, taskEvent));
}
}
/// <summary>
/// Logs that an activity failed with an unhandled exception.
/// </summary>
/// <param name="instance">The orchestration instance that scheduled this task activity.</param>
/// <param name="name">The name of the task activity.</param>
/// <param name="failedEvent">The history event associated with this activity failure.</param>
/// <param name="exception">The unhandled exception.</param>
internal void TaskActivityFailure(
OrchestrationInstance instance,
string name,
TaskFailedEvent failedEvent,
Exception exception)
{
if (this.IsStructuredLoggingEnabled)
{
this.WriteStructuredLog(
new LogEvents.TaskActivityFailure(instance, name, failedEvent, exception),
exception);
}
}
/// <summary>
/// Logs a warning indicating that the activity execution was aborted.
/// </summary>
/// <param name="instance">The orchestration instance that scheduled this task activity.</param>
/// <param name="taskEvent">The history event associated with this activity execution.</param>
/// <param name="details">More information about why the execution was aborted.</param>
internal void TaskActivityAborted(OrchestrationInstance instance, TaskScheduledEvent taskEvent, string details)
{
if (this.IsStructuredLoggingEnabled)
{
this.WriteStructuredLog(new LogEvents.TaskActivityAborted(instance, taskEvent, details));
}
}
/// <summary>
/// Logs that an error occurred when attempting to dispatch an activity work item.
/// </summary>
/// <param name="workItem">The work item that caused the failure.</param>
/// <param name="details">The details of the failure.</param>
internal void TaskActivityDispatcherError(TaskActivityWorkItem workItem, string details)
{
if (this.IsStructuredLoggingEnabled)
{
this.WriteStructuredLog(new LogEvents.TaskActivityDispatcherError(workItem, details));
}
}
/// <summary>
/// Logs that an activity message renewal operation is starting.
/// </summary>
/// <param name="workItem">The work item associated with the message to be renewed.</param>
internal void RenewActivityMessageStarting(TaskActivityWorkItem workItem)
{
if (this.IsStructuredLoggingEnabled)
{
this.WriteStructuredLog(new LogEvents.RenewActivityMessageStarting(workItem));
}
}
/// <summary>
/// Logs that an activity message renewal operation succeeded.
/// </summary>
/// <param name="workItem">The work item associated with the renewed message.</param>
/// <param name="renewAt">The next scheduled renewal message time.</param>
internal void RenewActivityMessageCompleted(TaskActivityWorkItem workItem, DateTime renewAt)
{
if (this.IsStructuredLoggingEnabled)
{
this.WriteStructuredLog(new LogEvents.RenewActivityMessageCompleted(workItem, renewAt));
}
}
/// <summary>
/// Logs that an activity message renewal operation failed.
/// </summary>
/// <param name="workItem">The work item associated with the message to be renewed.</param>
/// <param name="exception">The renew failure exception.</param>
internal void RenewActivityMessageFailed(TaskActivityWorkItem workItem, Exception exception)
{
if (this.IsStructuredLoggingEnabled)
{
this.WriteStructuredLog(new LogEvents.RenewActivityMessageFailed(workItem, exception), exception);
}
}
/// <summary>
/// Logs that a "poison message" has been detected and is being dropped.
/// </summary>
/// <param name="orchestrationInstance">The orchestration instance this event was sent to.</param>
/// <param name="historyEvent">The "poisoned" event.</param>
/// <param name="details">Extra details related to the processing of this poison message.</param>
internal void PoisonMessageDetected(OrchestrationInstance? orchestrationInstance, HistoryEvent historyEvent, string details)
{
if (this.IsStructuredLoggingEnabled)
{
this.WriteStructuredLog(new LogEvents.PoisonMessageDetected(
orchestrationInstance,
historyEvent.EventType.ToString(),
Utils.GetTaskEventId(historyEvent),
details));
}
}
/// <summary>
/// Logs that a "poison" entity request message has been detected and is being dropped.
/// </summary>
/// <param name="orchestrationInstance">The orchestration instance this event was sent to.</param>
/// <param name="requestMessage">The "poisoned" request message.</param>
/// <param name="details">Extra details related to the processing of this poison message.</param>
internal void PoisonMessageDetected(OrchestrationInstance orchestrationInstance, RequestMessage requestMessage, string details)
{
if (this.IsStructuredLoggingEnabled)
{
this.WriteStructuredLog(new LogEvents.PoisonMessageDetected(
orchestrationInstance,
requestMessage.IsLockRequest ? "LockRequest" : "OperationRequest",
taskEventId: -1,
details));
}
}
#endregion
internal void OrchestrationDebugTrace(string instanceId, string executionId, string details)
{
if (this.IsStructuredLoggingEnabled)
{
this.WriteStructuredLog(new LogEvents.OrchestrationDebugTrace(instanceId, executionId, details));
}
}
void WriteStructuredLog(ILogEvent logEvent, Exception? exception = null)
{
this.log?.LogDurableEvent(logEvent, exception);
}
internal static string GetRedactedExceptionDetails(Exception? exception)
{
if (exception == null)
{
return string.Empty;
}
// Redact the exception message since its possible to contain sensitive information (PII, secrets, etc.)
// Exception.ToString() code: https://referencesource.microsoft.com/#mscorlib/system/exception.cs,e2e19f4ed8da81aa
// Example output for a method chain of Foo() --> Bar() --> Baz() --> (exception):
// System.ApplicationException: [Redacted]
// ---> System.Exception: [Redacted]
// ---> System.InvalidOperationException: [Redacted]
// at UserQuery.<Main>g__Baz|4_3() in C:\Users\xxx\AppData\Local\Temp\LINQPad7\_wrmpjfpn\hjvskp\LINQPadQuery:line 68
// at UserQuery.<Main>g__Bar|4_2() in C:\Users\xxx\AppData\Local\Temp\LINQPad7\_wrmpjfpn\hjvskp\LINQPadQuery:line 58
// --- End of inner exception stack trace ---
// at UserQuery.<Main>g__Bar|4_2() in C:\Users\xxx\AppData\Local\Temp\LINQPad7\_wrmpjfpn\hjvskp\LINQPadQuery:line 62
// at UserQuery.<Main>g__Foo|4_1() in C:\Users\xxx\AppData\Local\Temp\LINQPad7\_wrmpjfpn\hjvskp\LINQPadQuery:line 46
// --- End of inner exception stack trace ---
// at UserQuery.<Main>g__Foo|4_1() in C:\Users\xxx\AppData\Local\Temp\LINQPad7\_wrmpjfpn\hjvskp\LINQPadQuery:line 50
// at UserQuery.Main() in C:\Users\xxx\AppData\Local\Temp\LINQPad7\_wrmpjfpn\hjvskp\LINQPadQuery:line 4
var sb = new StringBuilder(capacity: 1024);
sb.Append(exception.GetType().FullName).Append(": ").Append("[Redacted]");
if (exception.InnerException != null)
{
// Recursive
sb.AppendLine().Append(" ---> ").AppendLine(GetRedactedExceptionDetails(exception.InnerException));
sb.Append(" --- End of inner exception stack trace ---");
}
sb.AppendLine().Append(exception.StackTrace);
return sb.ToString();
}
}
}