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 // See the LICENSE file in the project root for more information.
6 using System
.Collections
.Generic
;
7 using Interlocked
= System
.Threading
.Interlocked
;
9 #if !ES_BUILD_AGAINST_DOTNET_V35
10 using Contract
= System
.Diagnostics
.Contracts
.Contract
;
12 using Contract
= Microsoft
.Diagnostics
.Contracts
.Internal
.Contract
;
15 #if ES_BUILD_STANDALONE
16 namespace Microsoft
.Diagnostics
.Tracing
18 namespace System
.Diagnostics
.Tracing
22 /// TraceLogging: Used when calling EventSource.WriteMultiMerge.
23 /// Stores the type information to use when writing the event fields.
25 public class TraceLoggingEventTypes
27 internal readonly TraceLoggingTypeInfo
[] typeInfos
;
28 #if FEATURE_PERFTRACING
29 internal readonly string[]? paramNames
;
31 internal readonly string name
;
32 internal readonly EventTags tags
;
33 internal readonly byte level
;
34 internal readonly byte opcode
;
35 internal readonly EventKeywords keywords
;
36 internal readonly byte[] typeMetadata
;
37 internal readonly int scratchSize
;
38 internal readonly int dataCount
;
39 internal readonly int pinCount
;
40 private ConcurrentSet
<KeyValuePair
<string, EventTags
>, NameInfo
> nameInfos
;
43 /// Initializes a new instance of TraceLoggingEventTypes corresponding
44 /// to the name, flags, and types provided. Always uses the default
45 /// TypeInfo for each Type.
47 /// <param name="name">
48 /// The name to use when the name parameter passed to
49 /// EventSource.Write is null. This value must not be null.
51 /// <param name="tags">
52 /// Tags to add to the event if the tags are not set via options.
54 /// <param name="types">
55 /// The types of the fields in the event. This value must not be null.
57 internal TraceLoggingEventTypes(
61 : this(tags
, name
, MakeArray(types
))
66 /// Returns a new instance of TraceLoggingEventInfo corresponding to the name,
67 /// flags, and typeInfos provided.
69 /// <param name="name">
70 /// The name to use when the name parameter passed to
71 /// EventSource.Write is null. This value must not be null.
73 /// <param name="tags">
74 /// Tags to add to the event if the tags are not set via options.
76 /// <param name="typeInfos">
77 /// The types of the fields in the event. This value must not be null.
80 /// An instance of TraceLoggingEventInfo with DefaultName set to the specified name
81 /// and with the specified typeInfos.
83 internal TraceLoggingEventTypes(
86 params TraceLoggingTypeInfo
[] typeInfos
)
87 : this(tags
, name
, MakeArray(typeInfos
))
91 internal TraceLoggingEventTypes(
94 System
.Reflection
.ParameterInfo
[] paramInfos
)
98 throw new ArgumentNullException(nameof(name
));
101 this.typeInfos
= MakeArray(paramInfos
);
102 #if FEATURE_PERFTRACING
103 this.paramNames
= MakeParamNameArray(paramInfos
);
107 this.level
= Statics
.DefaultLevel
;
109 var collector
= new TraceLoggingMetadataCollector();
110 for (int i
= 0; i
< typeInfos
.Length
; ++i
)
112 TraceLoggingTypeInfo typeInfo
= typeInfos
[i
];
113 this.level
= Statics
.Combine((int)typeInfo
.Level
, this.level
);
114 this.opcode
= Statics
.Combine((int)typeInfo
.Opcode
, this.opcode
);
115 this.keywords
|= typeInfo
.Keywords
;
116 string? paramName
= paramInfos
[i
].Name
;
117 if (Statics
.ShouldOverrideFieldName(paramName
!))
119 paramName
= typeInfo
.Name
;
121 typeInfo
.WriteMetadata(collector
, paramName
, EventFieldFormat
.Default
);
124 this.typeMetadata
= collector
.GetMetadata();
125 this.scratchSize
= collector
.ScratchSize
;
126 this.dataCount
= collector
.DataCount
;
127 this.pinCount
= collector
.PinCount
;
130 private TraceLoggingEventTypes(
133 TraceLoggingTypeInfo
[] typeInfos
)
135 if (defaultName
== null)
137 throw new ArgumentNullException(nameof(defaultName
));
140 this.typeInfos
= typeInfos
;
141 this.name
= defaultName
;
143 this.level
= Statics
.DefaultLevel
;
145 var collector
= new TraceLoggingMetadataCollector();
146 foreach (TraceLoggingTypeInfo typeInfo
in typeInfos
)
148 this.level
= Statics
.Combine((int)typeInfo
.Level
, this.level
);
149 this.opcode
= Statics
.Combine((int)typeInfo
.Opcode
, this.opcode
);
150 this.keywords
|= typeInfo
.Keywords
;
151 typeInfo
.WriteMetadata(collector
, null, EventFieldFormat
.Default
);
154 this.typeMetadata
= collector
.GetMetadata();
155 this.scratchSize
= collector
.ScratchSize
;
156 this.dataCount
= collector
.DataCount
;
157 this.pinCount
= collector
.PinCount
;
161 /// Gets the default name that will be used for events with this descriptor.
163 internal string Name
=> this.name
;
166 /// Gets the default level that will be used for events with this descriptor.
168 internal EventLevel Level
=> (EventLevel
)this.level
;
171 /// Gets the default opcode that will be used for events with this descriptor.
173 internal EventOpcode Opcode
=> (EventOpcode
)this.opcode
;
176 /// Gets the default set of keywords that will added to events with this descriptor.
178 internal EventKeywords Keywords
=> (EventKeywords
)this.keywords
;
181 /// Gets the default tags that will be added events with this descriptor.
183 internal EventTags Tags
=> this.tags
;
185 internal NameInfo
GetNameInfo(string name
, EventTags tags
)
187 NameInfo
? ret
= this.nameInfos
.TryGet(new KeyValuePair
<string, EventTags
>(name
, tags
));
190 ret
= this.nameInfos
.GetOrAdd(new NameInfo(name
, tags
, this.typeMetadata
.Length
));
196 private TraceLoggingTypeInfo
[] MakeArray(System
.Reflection
.ParameterInfo
[] paramInfos
)
198 if (paramInfos
== null)
200 throw new ArgumentNullException(nameof(paramInfos
));
203 var recursionCheck
= new List
<Type
>(paramInfos
.Length
);
204 var result
= new TraceLoggingTypeInfo
[paramInfos
.Length
];
205 for (int i
= 0; i
< paramInfos
.Length
; ++i
)
207 result
[i
] = TraceLoggingTypeInfo
.GetInstance(paramInfos
[i
].ParameterType
, recursionCheck
);
213 private static TraceLoggingTypeInfo
[] MakeArray(Type
[] types
)
217 throw new ArgumentNullException(nameof(types
));
220 var recursionCheck
= new List
<Type
>(types
.Length
);
221 var result
= new TraceLoggingTypeInfo
[types
.Length
];
222 for (int i
= 0; i
< types
.Length
; i
++)
224 result
[i
] = TraceLoggingTypeInfo
.GetInstance(types
[i
], recursionCheck
);
230 private static TraceLoggingTypeInfo
[] MakeArray(
231 TraceLoggingTypeInfo
[] typeInfos
)
233 if (typeInfos
== null)
235 throw new ArgumentNullException(nameof(typeInfos
));
238 return (TraceLoggingTypeInfo
[])typeInfos
.Clone(); ;
241 #if FEATURE_PERFTRACING
242 private static string[] MakeParamNameArray(
243 System
.Reflection
.ParameterInfo
[] paramInfos
)
245 string[] paramNames
= new string[paramInfos
.Length
];
246 for (int i
= 0; i
< paramNames
.Length
; i
++)
248 paramNames
[i
] = paramInfos
[i
].Name
!;