source: TFP-WebServer/SpaceWizards.HttpListener/src/System/Net/Logging/NetEventSource.Common.cs

Last change on this file was 377, checked in by alloc, 3 years ago

Made SpaceWizards.HttpListener compilable against .NET 4.8 with preprocessor define UNITY_NETFRAMEWORK

File size: 30.4 KB
Line 
1// Licensed to the .NET Foundation under one or more agreements.
2// The .NET Foundation licenses this file to you under the MIT license.
3
4// ReSharper disable RedundantUsingDirective
5// ReSharper disable RedundantExtendsListEntry
6// ReSharper disable UnusedMember.Local
7// ReSharper disable InterpolatedStringExpressionIsNotIFormattable
8// ReSharper disable ConditionIsAlwaysTrueOrFalse
9// ReSharper disable PartialMethodWithSinglePart
10
11#if DEBUG
12// Uncomment to enable runtime checks to help validate that NetEventSource isn't being misused
13// in a way that will cause performance problems, e.g. unexpected boxing of value types.
14//#define DEBUG_NETEVENTSOURCE_MISUSE
15#endif
16
17#nullable enable
18using System.Collections;
19using System.Diagnostics;
20using System.Diagnostics.CodeAnalysis;
21using System.Diagnostics.Tracing;
22using System.Runtime.CompilerServices;
23using System.Runtime.InteropServices;
24#if NET46
25using System.Security;
26#endif
27
28#pragma warning disable CA1823 // not all IDs are used by all partial providers
29
30namespace System.Net
31{
32 // Implementation:
33 // This partial file is meant to be consumed into each System.Net.* assembly that needs to log. Each such assembly also provides
34 // its own NetEventSource partial class that adds an appropriate [EventSource] attribute, giving it a unique name for that assembly.
35 // Those partials can then also add additional events if needed, starting numbering from the NextAvailableEventId defined by this partial.
36
37 // Usage:
38 // - Operations that may allocate (e.g. boxing a value type, using string interpolation, etc.) or that may have computations
39 // at call sites should guard access like:
40 // if (NetEventSource.Log.IsEnabled()) NetEventSource.Info(null, $"Found certificate: {cert}"); // info logging with a formattable string
41 // - Operations that have zero allocations / measurable computations at call sites can use a simpler pattern, calling methods like:
42 // NetEventSource.Info(this, "literal string"); // arbitrary message with a literal string
43 // Debug.Asserts inside the logging methods will help to flag some misuse if the DEBUG_NETEVENTSOURCE_MISUSE compilation constant is defined.
44 // However, because it can be difficult by observation to understand all of the costs involved, guarding can be done everywhere.
45 // - Messages can be strings, formattable strings, or any other object. Objects (including those used in formattable strings) have special
46 // formatting applied, controlled by the Format method. Partial specializations can also override this formatting by implementing a partial
47 // method that takes an object and optionally provides a string representation of it, in case a particular library wants to customize further.
48
49 /// <summary>Provides logging facilities for System.Net libraries.</summary>
50#if NET46
51 [SecuritySafeCritical]
52#endif
53 internal sealed partial class NetEventSource : EventSource
54 {
55 /// <summary>The single event source instance to use for all logging.</summary>
56 public static readonly NetEventSource Log = new NetEventSource();
57
58 #region Metadata
59 public class Keywords
60 {
61 public const EventKeywords Default = (EventKeywords)0x0001;
62 public const EventKeywords Debug = (EventKeywords)0x0002;
63
64 // No longer used:
65 // EnterExit = (EventKeywords)0x0004;
66 }
67
68 private const string MissingMember = "(?)";
69 private const string NullInstance = "(null)";
70 private const string StaticMethodObject = "(static)";
71 private const string NoParameters = "";
72 private const int MaxDumpSize = 1024;
73
74 // No longer used:
75 // EnterEventId = 1;
76 // ExitEventId = 2;
77
78 private const int AssociateEventId = 3;
79 private const int InfoEventId = 4;
80 private const int ErrorEventId = 5;
81 private const int DumpArrayEventId = 7;
82
83 // These events are implemented in NetEventSource.Security.cs.
84 // Define the ids here so that projects that include NetEventSource.Security.cs will not have conflicts.
85 private const int EnumerateSecurityPackagesId = 8;
86 private const int SspiPackageNotFoundId = 9;
87 private const int AcquireDefaultCredentialId = 10;
88 private const int AcquireCredentialsHandleId = 11;
89 private const int InitializeSecurityContextId = 12;
90 private const int SecurityContextInputBufferId = 13;
91 private const int SecurityContextInputBuffersId = 14;
92 private const int AcceptSecuritContextId = 15;
93 private const int OperationReturnedSomethingId = 16;
94
95 private const int NextAvailableEventId = 17; // Update this value whenever new events are added. Derived types should base all events off of this to avoid conflicts.
96 #endregion
97
98 #region Events
99 #region Info
100 /// <summary>Logs an information message.</summary>
101 /// <param name="thisOrContextObject">`this`, or another object that serves to provide context for the operation.</param>
102 /// <param name="formattableString">The message to be logged.</param>
103 /// <param name="memberName">The calling member.</param>
104 [NonEvent]
105 public static void Info(object? thisOrContextObject, FormattableString? formattableString = null, [CallerMemberName] string? memberName = null)
106 {
107 DebugValidateArg(thisOrContextObject);
108 DebugValidateArg(formattableString);
109 if (IsEnabled) Log.Info(IdOf(thisOrContextObject), memberName, formattableString != null ? Format(formattableString) : NoParameters);
110 }
111
112 /// <summary>Logs an information message.</summary>
113 /// <param name="thisOrContextObject">`this`, or another object that serves to provide context for the operation.</param>
114 /// <param name="message">The message to be logged.</param>
115 /// <param name="memberName">The calling member.</param>
116 [NonEvent]
117 public static void Info(object? thisOrContextObject, object? message, [CallerMemberName] string? memberName = null)
118 {
119 DebugValidateArg(thisOrContextObject);
120 DebugValidateArg(message);
121 if (IsEnabled) Log.Info(IdOf(thisOrContextObject), memberName, Format(message).ToString());
122 }
123
124 [Event(InfoEventId, Level = EventLevel.Informational, Keywords = Keywords.Default)]
125 private void Info(string thisOrContextObject, string? memberName, string? message) =>
126 WriteEvent(InfoEventId, thisOrContextObject, memberName ?? MissingMember, message);
127 #endregion
128
129 #region Error
130 /// <summary>Logs an error message.</summary>
131 /// <param name="thisOrContextObject">`this`, or another object that serves to provide context for the operation.</param>
132 /// <param name="formattableString">The message to be logged.</param>
133 /// <param name="memberName">The calling member.</param>
134 [NonEvent]
135 public static void Error(object? thisOrContextObject, FormattableString formattableString, [CallerMemberName] string? memberName = null)
136 {
137 DebugValidateArg(thisOrContextObject);
138 DebugValidateArg(formattableString);
139 if (IsEnabled) Log.ErrorMessage(IdOf(thisOrContextObject), memberName, Format(formattableString));
140 }
141
142 /// <summary>Logs an error message.</summary>
143 /// <param name="thisOrContextObject">`this`, or another object that serves to provide context for the operation.</param>
144 /// <param name="message">The message to be logged.</param>
145 /// <param name="memberName">The calling member.</param>
146 [NonEvent]
147 public static void Error(object? thisOrContextObject, object message, [CallerMemberName] string? memberName = null)
148 {
149 DebugValidateArg(thisOrContextObject);
150 DebugValidateArg(message);
151 if (IsEnabled) Log.ErrorMessage(IdOf(thisOrContextObject), memberName, Format(message).ToString());
152 }
153
154 [Event(ErrorEventId, Level = EventLevel.Error, Keywords = Keywords.Default)]
155 private void ErrorMessage(string thisOrContextObject, string? memberName, string? message) =>
156 WriteEvent(ErrorEventId, thisOrContextObject, memberName ?? MissingMember, message);
157 #endregion
158
159 #region Verbose
160 /// <summary>Logs an info message at verbose mode.</summary>
161 /// <param name="thisOrContextObject">`this`, or another object that serves to provide context for the operation.</param>
162 /// <param name="formattableString">The message to be logged.</param>
163 /// <param name="memberName">The calling member.</param>
164 [NonEvent]
165 public static void Verbose(object? thisOrContextObject, FormattableString formattableString, [CallerMemberName] string? memberName = null)
166 {
167 DebugValidateArg(thisOrContextObject);
168 DebugValidateArg(formattableString);
169 if (IsEnabled) Log.ErrorMessage(IdOf(thisOrContextObject), memberName, Format(formattableString));
170 }
171
172 /// <summary>Logs an info at verbose mode.</summary>
173 /// <param name="thisOrContextObject">`this`, or another object that serves to provide context for the operation.</param>
174 /// <param name="message">The message to be logged.</param>
175 /// <param name="memberName">The calling member.</param>
176 [NonEvent]
177 public static void Verbose(object? thisOrContextObject, object message, [CallerMemberName] string? memberName = null)
178 {
179 DebugValidateArg(thisOrContextObject);
180 DebugValidateArg(message);
181 if (IsEnabled) Log.VerboseMessage(IdOf(thisOrContextObject), memberName, Format(message).ToString());
182 }
183
184 [Event(ErrorEventId, Level = EventLevel.Verbose, Keywords = Keywords.Default)]
185 private void VerboseMessage(string thisOrContextObject, string? memberName, string? message) =>
186 WriteEvent(ErrorEventId, thisOrContextObject, memberName ?? MissingMember, message);
187 #endregion
188
189 #region DumpBuffer
190 /// <summary>Logs the contents of a buffer.</summary>
191 /// <param name="thisOrContextObject">`this`, or another object that serves to provide context for the operation.</param>
192 /// <param name="buffer">The buffer to be logged.</param>
193 /// <param name="memberName">The calling member.</param>
194 [NonEvent]
195 public static void DumpBuffer(object? thisOrContextObject, byte[] buffer, [CallerMemberName] string? memberName = null)
196 {
197 DumpBuffer(thisOrContextObject, buffer, 0, buffer.Length, memberName);
198 }
199
200 /// <summary>Logs the contents of a buffer.</summary>
201 /// <param name="thisOrContextObject">`this`, or another object that serves to provide context for the operation.</param>
202 /// <param name="buffer">The buffer to be logged.</param>
203 /// <param name="offset">The starting offset from which to log.</param>
204 /// <param name="count">The number of bytes to log.</param>
205 /// <param name="memberName">The calling member.</param>
206 [NonEvent]
207 public static void DumpBuffer(object? thisOrContextObject, byte[] buffer, int offset, int count, [CallerMemberName] string? memberName = null)
208 {
209 if (IsEnabled && offset >= 0 && offset <= buffer.Length - count)
210 {
211 count = Math.Min(count, MaxDumpSize);
212
213 byte[] slice = buffer;
214 if (offset != 0 || count != buffer.Length)
215 {
216 slice = new byte[count];
217 Buffer.BlockCopy(buffer, offset, slice, 0, count);
218 }
219
220 Log.DumpBuffer(IdOf(thisOrContextObject), memberName, slice);
221 }
222 }
223
224 /// <summary>Logs the contents of a buffer.</summary>
225 /// <param name="thisOrContextObject">`this`, or another object that serves to provide context for the operation.</param>
226 /// <param name="bufferPtr">The starting location of the buffer to be logged.</param>
227 /// <param name="count">The number of bytes to log.</param>
228 /// <param name="memberName">The calling member.</param>
229 [NonEvent]
230 public static unsafe void DumpBuffer(object? thisOrContextObject, IntPtr bufferPtr, int count, [CallerMemberName] string? memberName = null)
231 {
232 Debug.Assert(bufferPtr != IntPtr.Zero);
233 Debug.Assert(count >= 0);
234
235 if (IsEnabled)
236 {
237 var buffer = new byte[Math.Min(count, MaxDumpSize)];
238 fixed (byte* targetPtr = buffer)
239 {
240 Buffer.MemoryCopy((byte*)bufferPtr, targetPtr, buffer.Length, buffer.Length);
241 }
242 Log.DumpBuffer(IdOf(thisOrContextObject), memberName, buffer);
243 }
244 }
245
246 [Event(DumpArrayEventId, Level = EventLevel.Verbose, Keywords = Keywords.Debug)]
247 private void DumpBuffer(string thisOrContextObject, string? memberName, byte[] buffer) =>
248 WriteEvent(DumpArrayEventId, thisOrContextObject, memberName ?? MissingMember, buffer);
249 #endregion
250
251 #region Associate
252 /// <summary>Logs a relationship between two objects.</summary>
253 /// <param name="first">The first object.</param>
254 /// <param name="second">The second object.</param>
255 /// <param name="memberName">The calling member.</param>
256 [NonEvent]
257 public static void Associate(object first, object second, [CallerMemberName] string? memberName = null)
258 {
259 DebugValidateArg(first);
260 DebugValidateArg(second);
261 if (IsEnabled) Log.Associate(IdOf(first), memberName, IdOf(first), IdOf(second));
262 }
263
264 /// <summary>Logs a relationship between two objects.</summary>
265 /// <param name="thisOrContextObject">`this`, or another object that serves to provide context for the operation.</param>
266 /// <param name="first">The first object.</param>
267 /// <param name="second">The second object.</param>
268 /// <param name="memberName">The calling member.</param>
269 [NonEvent]
270 public static void Associate(object? thisOrContextObject, object first, object second, [CallerMemberName] string? memberName = null)
271 {
272 DebugValidateArg(thisOrContextObject);
273 DebugValidateArg(first);
274 DebugValidateArg(second);
275 if (IsEnabled) Log.Associate(IdOf(thisOrContextObject), memberName, IdOf(first), IdOf(second));
276 }
277
278 [Event(AssociateEventId, Level = EventLevel.Informational, Keywords = Keywords.Default, Message = "[{2}]<-->[{3}]")]
279 private void Associate(string thisOrContextObject, string? memberName, string first, string second) =>
280 WriteEvent(AssociateEventId, thisOrContextObject, memberName ?? MissingMember, first, second);
281 #endregion
282 #endregion
283
284 #region Helpers
285 [Conditional("DEBUG_NETEVENTSOURCE_MISUSE")]
286 private static void DebugValidateArg(object? arg)
287 {
288 if (!IsEnabled)
289 {
290 Debug.Assert(!(arg is ValueType), $"Should not be passing value type {arg?.GetType()} to logging without IsEnabled check");
291 Debug.Assert(!(arg is FormattableString), $"Should not be formatting FormattableString \"{arg}\" if tracing isn't enabled");
292 }
293 }
294
295 [Conditional("DEBUG_NETEVENTSOURCE_MISUSE")]
296 private static void DebugValidateArg(FormattableString? arg)
297 {
298 Debug.Assert(IsEnabled || arg == null, $"Should not be formatting FormattableString \"{arg}\" if tracing isn't enabled");
299 }
300
301 public static new bool IsEnabled =>
302 Log.IsEnabled();
303
304 [NonEvent]
305 public static string IdOf(object? value) => value != null ? value.GetType().Name + "#" + GetHashCode(value) : NullInstance;
306
307 [NonEvent]
308 public static int GetHashCode(object? value) => value?.GetHashCode() ?? 0;
309
310 [NonEvent]
311 public static object Format(object? value)
312 {
313 // If it's null, return a known string for null values
314 if (value == null)
315 {
316 return NullInstance;
317 }
318
319 // Give another partial implementation a chance to provide its own string representation
320 string? result = null;
321 AdditionalCustomizedToString(value, ref result);
322 if (result != null)
323 {
324 return result;
325 }
326
327 // Format arrays with their element type name and length
328 if (value is Array arr)
329 {
330 return $"{arr.GetType().GetElementType()}[{((Array)value).Length}]";
331 }
332
333 // Format ICollections as the name and count
334 if (value is ICollection c)
335 {
336 return $"{c.GetType().Name}({c.Count})";
337 }
338
339 // Format SafeHandles as their type, hash code, and pointer value
340 if (value is SafeHandle handle)
341 {
342 return $"{handle.GetType().Name}:{handle.GetHashCode()}(0x{handle.DangerousGetHandle():X})";
343 }
344
345 // Format IntPtrs as hex
346 if (value is IntPtr)
347 {
348 return $"0x{value:X}";
349 }
350
351 // If the string representation of the instance would just be its type name,
352 // use its id instead.
353 string? toString = value.ToString();
354 if (toString == null || toString == value.GetType().FullName)
355 {
356 return IdOf(value);
357 }
358
359 // Otherwise, return the original object so that the caller does default formatting.
360 return value;
361 }
362
363 [NonEvent]
364 private static string Format(FormattableString s)
365 {
366 switch (s.ArgumentCount)
367 {
368 case 0: return s.Format;
369 case 1: return string.Format(s.Format, Format(s.GetArgument(0)));
370 case 2: return string.Format(s.Format, Format(s.GetArgument(0)), Format(s.GetArgument(1)));
371 case 3: return string.Format(s.Format, Format(s.GetArgument(0)), Format(s.GetArgument(1)), Format(s.GetArgument(2)));
372 default:
373 object?[] args = s.GetArguments();
374 object[] formattedArgs = new object[args.Length];
375 for (int i = 0; i < args.Length; i++)
376 {
377 formattedArgs[i] = Format(args[i]);
378 }
379 return string.Format(s.Format, formattedArgs);
380 }
381 }
382
383 static partial void AdditionalCustomizedToString<T>(T value, ref string? result);
384 #endregion
385
386 #region Custom WriteEvent overloads
387
388 [NonEvent]
389 private unsafe void WriteEvent(int eventId, string? arg1, string? arg2, string? arg3, string? arg4)
390 {
391 if (IsEnabled())
392 {
393 if (arg1 == null) arg1 = "";
394 if (arg2 == null) arg2 = "";
395 if (arg3 == null) arg3 = "";
396 if (arg4 == null) arg4 = "";
397
398 fixed (char* string1Bytes = arg1)
399 fixed (char* string2Bytes = arg2)
400 fixed (char* string3Bytes = arg3)
401 fixed (char* string4Bytes = arg4)
402 {
403 const int NumEventDatas = 4;
404 var descrs = stackalloc EventData[NumEventDatas];
405
406 descrs[0] = new EventData
407 {
408 DataPointer = (IntPtr)string1Bytes,
409 Size = ((arg1.Length + 1) * 2)
410 };
411 descrs[1] = new EventData
412 {
413 DataPointer = (IntPtr)string2Bytes,
414 Size = ((arg2.Length + 1) * 2)
415 };
416 descrs[2] = new EventData
417 {
418 DataPointer = (IntPtr)string3Bytes,
419 Size = ((arg3.Length + 1) * 2)
420 };
421 descrs[3] = new EventData
422 {
423 DataPointer = (IntPtr)string4Bytes,
424 Size = ((arg4.Length + 1) * 2)
425 };
426
427 WriteEventCore(eventId, NumEventDatas, descrs);
428 }
429 }
430 }
431
432 [NonEvent]
433 private unsafe void WriteEvent(int eventId, string? arg1, string? arg2, byte[]? arg3)
434 {
435 if (IsEnabled())
436 {
437 if (arg1 == null) arg1 = "";
438 if (arg2 == null) arg2 = "";
439 if (arg3 == null) arg3 = Array.Empty<byte>();
440
441 fixed (char* arg1Ptr = arg1)
442 fixed (char* arg2Ptr = arg2)
443 fixed (byte* arg3Ptr = arg3)
444 {
445 int bufferLength = arg3.Length;
446 const int NumEventDatas = 4;
447 var descrs = stackalloc EventData[NumEventDatas];
448
449 descrs[0] = new EventData
450 {
451 DataPointer = (IntPtr)arg1Ptr,
452 Size = (arg1.Length + 1) * sizeof(char)
453 };
454 descrs[1] = new EventData
455 {
456 DataPointer = (IntPtr)arg2Ptr,
457 Size = (arg2.Length + 1) * sizeof(char)
458 };
459 descrs[2] = new EventData
460 {
461 DataPointer = (IntPtr)(&bufferLength),
462 Size = 4
463 };
464 descrs[3] = new EventData
465 {
466 DataPointer = (IntPtr)arg3Ptr,
467 Size = bufferLength
468 };
469
470 WriteEventCore(eventId, NumEventDatas, descrs);
471 }
472 }
473 }
474
475 [NonEvent]
476 private unsafe void WriteEvent(int eventId, string? arg1, int arg2, int arg3, int arg4)
477 {
478 if (IsEnabled())
479 {
480 if (arg1 == null) arg1 = "";
481
482 fixed (char* arg1Ptr = arg1)
483 {
484 const int NumEventDatas = 4;
485 var descrs = stackalloc EventData[NumEventDatas];
486
487 descrs[0] = new EventData
488 {
489 DataPointer = (IntPtr)(arg1Ptr),
490 Size = (arg1.Length + 1) * sizeof(char)
491 };
492 descrs[1] = new EventData
493 {
494 DataPointer = (IntPtr)(&arg2),
495 Size = sizeof(int)
496 };
497 descrs[2] = new EventData
498 {
499 DataPointer = (IntPtr)(&arg3),
500 Size = sizeof(int)
501 };
502 descrs[3] = new EventData
503 {
504 DataPointer = (IntPtr)(&arg4),
505 Size = sizeof(int)
506 };
507
508 WriteEventCore(eventId, NumEventDatas, descrs);
509 }
510 }
511 }
512
513 [NonEvent]
514 private unsafe void WriteEvent(int eventId, string? arg1, int arg2, string? arg3)
515 {
516 if (IsEnabled())
517 {
518 if (arg1 == null) arg1 = "";
519 if (arg3 == null) arg3 = "";
520
521 fixed (char* arg1Ptr = arg1)
522 fixed (char* arg3Ptr = arg3)
523 {
524 const int NumEventDatas = 3;
525 var descrs = stackalloc EventData[NumEventDatas];
526
527 descrs[0] = new EventData
528 {
529 DataPointer = (IntPtr)(arg1Ptr),
530 Size = (arg1.Length + 1) * sizeof(char)
531 };
532 descrs[1] = new EventData
533 {
534 DataPointer = (IntPtr)(&arg2),
535 Size = sizeof(int)
536 };
537 descrs[2] = new EventData
538 {
539 DataPointer = (IntPtr)(arg3Ptr),
540 Size = (arg3.Length + 1) * sizeof(char)
541 };
542
543 WriteEventCore(eventId, NumEventDatas, descrs);
544 }
545 }
546 }
547
548 [NonEvent]
549 private unsafe void WriteEvent(int eventId, string? arg1, string? arg2, int arg3)
550 {
551 if (IsEnabled())
552 {
553 if (arg1 == null) arg1 = "";
554 if (arg2 == null) arg2 = "";
555
556 fixed (char* arg1Ptr = arg1)
557 fixed (char* arg2Ptr = arg2)
558 {
559 const int NumEventDatas = 3;
560 var descrs = stackalloc EventData[NumEventDatas];
561
562 descrs[0] = new EventData
563 {
564 DataPointer = (IntPtr)(arg1Ptr),
565 Size = (arg1.Length + 1) * sizeof(char)
566 };
567 descrs[1] = new EventData
568 {
569 DataPointer = (IntPtr)(arg2Ptr),
570 Size = (arg2.Length + 1) * sizeof(char)
571 };
572 descrs[2] = new EventData
573 {
574 DataPointer = (IntPtr)(&arg3),
575 Size = sizeof(int)
576 };
577
578 WriteEventCore(eventId, NumEventDatas, descrs);
579 }
580 }
581 }
582
583 [NonEvent]
584 private unsafe void WriteEvent(int eventId, string? arg1, string? arg2, string? arg3, int arg4)
585 {
586 if (IsEnabled())
587 {
588 if (arg1 == null) arg1 = "";
589 if (arg2 == null) arg2 = "";
590 if (arg3 == null) arg3 = "";
591
592 fixed (char* arg1Ptr = arg1)
593 fixed (char* arg2Ptr = arg2)
594 fixed (char* arg3Ptr = arg3)
595 {
596 const int NumEventDatas = 4;
597 var descrs = stackalloc EventData[NumEventDatas];
598
599 descrs[0] = new EventData
600 {
601 DataPointer = (IntPtr)(arg1Ptr),
602 Size = (arg1.Length + 1) * sizeof(char)
603 };
604 descrs[1] = new EventData
605 {
606 DataPointer = (IntPtr)(arg2Ptr),
607 Size = (arg2.Length + 1) * sizeof(char)
608 };
609 descrs[2] = new EventData
610 {
611 DataPointer = (IntPtr)(arg3Ptr),
612 Size = (arg3.Length + 1) * sizeof(char)
613 };
614 descrs[3] = new EventData
615 {
616 DataPointer = (IntPtr)(&arg4),
617 Size = sizeof(int)
618 };
619
620 WriteEventCore(eventId, NumEventDatas, descrs);
621 }
622 }
623 }
624
625 [NonEvent]
626 private unsafe void WriteEvent(int eventId, string arg1, int arg2, int arg3, int arg4, int arg5, int arg6, int arg7, int arg8)
627 {
628 if (IsEnabled())
629 {
630 if (arg1 == null) arg1 = "";
631
632 fixed (char* arg1Ptr = arg1)
633 {
634 const int NumEventDatas = 8;
635 var descrs = stackalloc EventData[NumEventDatas];
636
637 descrs[0] = new EventData
638 {
639 DataPointer = (IntPtr)(arg1Ptr),
640 Size = (arg1.Length + 1) * sizeof(char)
641 };
642 descrs[1] = new EventData
643 {
644 DataPointer = (IntPtr)(&arg2),
645 Size = sizeof(int)
646 };
647 descrs[2] = new EventData
648 {
649 DataPointer = (IntPtr)(&arg3),
650 Size = sizeof(int)
651 };
652 descrs[3] = new EventData
653 {
654 DataPointer = (IntPtr)(&arg4),
655 Size = sizeof(int)
656 };
657 descrs[4] = new EventData
658 {
659 DataPointer = (IntPtr)(&arg5),
660 Size = sizeof(int)
661 };
662 descrs[5] = new EventData
663 {
664 DataPointer = (IntPtr)(&arg6),
665 Size = sizeof(int)
666 };
667 descrs[6] = new EventData
668 {
669 DataPointer = (IntPtr)(&arg7),
670 Size = sizeof(int)
671 };
672 descrs[7] = new EventData
673 {
674 DataPointer = (IntPtr)(&arg8),
675 Size = sizeof(int)
676 };
677
678 WriteEventCore(eventId, NumEventDatas, descrs);
679 }
680 }
681 }
682
683 [NonEvent]
684 private unsafe void WriteEvent(int eventId, string arg1, string arg2, int arg3, int arg4, int arg5)
685 {
686 if (IsEnabled())
687 {
688 if (arg1 == null) arg1 = "";
689 if (arg2 == null) arg2 = "";
690
691 fixed (char* arg1Ptr = arg1)
692 fixed (char* arg2Ptr = arg2)
693 {
694 const int NumEventDatas = 5;
695 var descrs = stackalloc EventData[NumEventDatas];
696
697 descrs[0] = new EventData
698 {
699 DataPointer = (IntPtr)(arg1Ptr),
700 Size = (arg1.Length + 1) * sizeof(char)
701 };
702 descrs[1] = new EventData
703 {
704 DataPointer = (IntPtr)(arg2Ptr),
705 Size = (arg2.Length + 1) * sizeof(char)
706 };
707 descrs[2] = new EventData
708 {
709 DataPointer = (IntPtr)(&arg3),
710 Size = sizeof(int)
711 };
712 descrs[3] = new EventData
713 {
714 DataPointer = (IntPtr)(&arg4),
715 Size = sizeof(int)
716 };
717 descrs[4] = new EventData
718 {
719 DataPointer = (IntPtr)(&arg5),
720 Size = sizeof(int)
721 };
722
723 WriteEventCore(eventId, NumEventDatas, descrs);
724 }
725 }
726 }
727 #endregion
728 }
729}
Note: See TracBrowser for help on using the repository browser.