You've already forked linux-packaging-mono
Imported Upstream version 4.6.0.125
Former-commit-id: a2155e9bd80020e49e72e86c44da02a8ac0e57a4
This commit is contained in:
parent
a569aebcfd
commit
e79aa3c0ed
@@ -0,0 +1,45 @@
|
||||
//------------------------------------------------------------------------------
|
||||
// <copyright file="AssertSection.cs" company="Microsoft Corporation">
|
||||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
// </copyright>
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
#if CONFIGURATION_DEP
|
||||
using System.Configuration;
|
||||
|
||||
namespace System.Diagnostics {
|
||||
internal class AssertSection : ConfigurationElement {
|
||||
private static readonly ConfigurationPropertyCollection _properties;
|
||||
private static readonly ConfigurationProperty _propAssertUIEnabled = new ConfigurationProperty("assertuienabled", typeof(bool), true, ConfigurationPropertyOptions.None);
|
||||
private static readonly ConfigurationProperty _propLogFile = new ConfigurationProperty("logfilename", typeof(string), String.Empty, ConfigurationPropertyOptions.None);
|
||||
|
||||
static AssertSection() {
|
||||
_properties = new ConfigurationPropertyCollection();
|
||||
_properties.Add(_propAssertUIEnabled);
|
||||
_properties.Add(_propLogFile);
|
||||
}
|
||||
|
||||
[ConfigurationProperty("assertuienabled", DefaultValue = true)]
|
||||
public bool AssertUIEnabled {
|
||||
get {
|
||||
return (bool) this[_propAssertUIEnabled];
|
||||
}
|
||||
}
|
||||
|
||||
[ConfigurationProperty("logfilename", DefaultValue = "")]
|
||||
public string LogFileName {
|
||||
get {
|
||||
return (string) this[_propLogFile];
|
||||
}
|
||||
}
|
||||
|
||||
protected override ConfigurationPropertyCollection Properties {
|
||||
get {
|
||||
return _properties;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,56 @@
|
||||
//------------------------------------------------------------------------------
|
||||
// <copyright file="BooleanSwitch.cs" company="Microsoft">
|
||||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
// </copyright>
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
/*
|
||||
*/
|
||||
|
||||
namespace System.Diagnostics {
|
||||
using System.Diagnostics;
|
||||
using System;
|
||||
using System.Security;
|
||||
using System.Security.Permissions;
|
||||
|
||||
/// <devdoc>
|
||||
/// <para>Provides a simple on/off switch that can be used to control debugging and tracing
|
||||
/// output.</para>
|
||||
/// </devdoc>
|
||||
[SwitchLevel(typeof(bool))]
|
||||
public class BooleanSwitch : Switch {
|
||||
/// <devdoc>
|
||||
/// <para>Initializes a new instance of the <see cref='System.Diagnostics.BooleanSwitch'/>
|
||||
/// class.</para>
|
||||
/// </devdoc>
|
||||
public BooleanSwitch(string displayName, string description)
|
||||
: base(displayName, description) {
|
||||
}
|
||||
|
||||
public BooleanSwitch(string displayName, string description, string defaultSwitchValue)
|
||||
: base(displayName, description, defaultSwitchValue) { }
|
||||
|
||||
/// <devdoc>
|
||||
/// <para>Specifies whether the switch is enabled
|
||||
/// (<see langword='true'/>) or disabled (<see langword='false'/>).</para>
|
||||
/// </devdoc>
|
||||
public bool Enabled {
|
||||
get {
|
||||
return (SwitchSetting == 0) ? false : true;
|
||||
}
|
||||
[SecurityPermission(SecurityAction.LinkDemand, Flags=SecurityPermissionFlag.UnmanagedCode)]
|
||||
set {
|
||||
SwitchSetting = value ? 1 : 0;
|
||||
}
|
||||
}
|
||||
|
||||
protected override void OnValueChanged() {
|
||||
bool b;
|
||||
if (Boolean.TryParse(Value, out b))
|
||||
SwitchSetting = ( b ? 1 : 0);
|
||||
else
|
||||
base.OnValueChanged();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,31 @@
|
||||
//------------------------------------------------------------------------------
|
||||
// <copyright file="TextWriterTraceListener.cs" company="Microsoft">
|
||||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
// </copyright>
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
/*
|
||||
*/
|
||||
namespace System.Diagnostics {
|
||||
using System;
|
||||
using System.IO;
|
||||
using System.Security.Permissions;
|
||||
using Microsoft.Win32;
|
||||
|
||||
[HostProtection(Synchronization=true)]
|
||||
public class ConsoleTraceListener : TextWriterTraceListener {
|
||||
|
||||
public ConsoleTraceListener() : base (Console.Out) {
|
||||
}
|
||||
|
||||
public ConsoleTraceListener(bool useErrorStream) : base (useErrorStream ? Console.Error : Console.Out) {
|
||||
}
|
||||
|
||||
public override void Close() {
|
||||
// No resources to clean up.
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -0,0 +1,68 @@
|
||||
//------------------------------------------------------------------------------
|
||||
// <copyright file="CorrelationManager.cs" company="Microsoft">
|
||||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
// </copyright>
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
using System;
|
||||
using System.Collections;
|
||||
using System.Collections.Specialized;
|
||||
using System.Threading;
|
||||
using System.Runtime.Remoting.Messaging;
|
||||
|
||||
|
||||
namespace System.Diagnostics {
|
||||
public class CorrelationManager {
|
||||
private const string transactionSlotName = "System.Diagnostics.Trace.CorrelationManagerSlot";
|
||||
private const string activityIdSlotName = "E2ETrace.ActivityID";
|
||||
|
||||
internal CorrelationManager() { }
|
||||
|
||||
public Guid ActivityId {
|
||||
get {
|
||||
Object id = CallContext.LogicalGetData(activityIdSlotName);
|
||||
if (id != null)
|
||||
return (Guid) id;
|
||||
else
|
||||
return Guid.Empty;
|
||||
}
|
||||
set {
|
||||
CallContext.LogicalSetData(activityIdSlotName, value);
|
||||
}
|
||||
}
|
||||
|
||||
public Stack LogicalOperationStack {
|
||||
get {
|
||||
return GetLogicalOperationStack();
|
||||
}
|
||||
}
|
||||
|
||||
public void StartLogicalOperation(object operationId) {
|
||||
if (operationId == null)
|
||||
throw new ArgumentNullException("operationId");
|
||||
|
||||
Stack idStack = GetLogicalOperationStack();
|
||||
idStack.Push(operationId);
|
||||
}
|
||||
|
||||
public void StartLogicalOperation() {
|
||||
StartLogicalOperation(Guid.NewGuid());
|
||||
}
|
||||
|
||||
public void StopLogicalOperation() {
|
||||
Stack idStack = GetLogicalOperationStack();
|
||||
idStack.Pop();
|
||||
}
|
||||
|
||||
private Stack GetLogicalOperationStack() {
|
||||
Stack idStack = CallContext.LogicalGetData(transactionSlotName) as Stack;
|
||||
if (idStack == null) {
|
||||
idStack = new Stack();
|
||||
CallContext.LogicalSetData(transactionSlotName, idStack);
|
||||
}
|
||||
|
||||
return idStack;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,231 @@
|
||||
//------------------------------------------------------------------------------
|
||||
// <copyright file="DefaultTraceListener.cs" company="Microsoft">
|
||||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
// </copyright>
|
||||
//------------------------------------------------------------------------------
|
||||
#define DEBUG
|
||||
#define TRACE
|
||||
namespace System.Diagnostics {
|
||||
using System;
|
||||
using System.IO;
|
||||
using System.Text;
|
||||
using System.Collections;
|
||||
using System.Reflection;
|
||||
using System.Runtime.InteropServices;
|
||||
using System.Security.Permissions;
|
||||
using System.Security;
|
||||
using Microsoft.Win32;
|
||||
using System.Globalization;
|
||||
using System.Runtime.Versioning;
|
||||
|
||||
/// <devdoc>
|
||||
/// <para>Provides
|
||||
/// the default output methods and behavior for tracing.</para>
|
||||
/// </devdoc>
|
||||
[HostProtection(Synchronization=true)]
|
||||
public class DefaultTraceListener : TraceListener {
|
||||
|
||||
bool assertUIEnabled;
|
||||
string logFileName;
|
||||
bool settingsInitialized;
|
||||
const int internalWriteSize = 16384;
|
||||
|
||||
|
||||
/// <devdoc>
|
||||
/// <para>Initializes a new instance of the <see cref='System.Diagnostics.DefaultTraceListener'/> class with
|
||||
/// Default as its <see cref='System.Diagnostics.TraceListener.Name'/>.</para>
|
||||
/// </devdoc>
|
||||
public DefaultTraceListener()
|
||||
: base("Default") {
|
||||
}
|
||||
|
||||
/// <devdoc>
|
||||
/// <para>[To be supplied.]</para>
|
||||
/// </devdoc>
|
||||
public bool AssertUiEnabled {
|
||||
get {
|
||||
if (!settingsInitialized) InitializeSettings();
|
||||
return assertUIEnabled;
|
||||
}
|
||||
set {
|
||||
if (!settingsInitialized) InitializeSettings();
|
||||
assertUIEnabled = value;
|
||||
}
|
||||
}
|
||||
|
||||
/// <devdoc>
|
||||
/// <para>[To be supplied.]</para>
|
||||
/// </devdoc>
|
||||
public string LogFileName {
|
||||
[ResourceExposure(ResourceScope.Machine)]
|
||||
[ResourceConsumption(ResourceScope.Machine)]
|
||||
get {
|
||||
if (!settingsInitialized) InitializeSettings();
|
||||
return logFileName;
|
||||
}
|
||||
[ResourceExposure(ResourceScope.Machine)]
|
||||
[ResourceConsumption(ResourceScope.Machine)]
|
||||
set {
|
||||
if (!settingsInitialized) InitializeSettings();
|
||||
logFileName = value;
|
||||
}
|
||||
}
|
||||
|
||||
/// <devdoc>
|
||||
/// <para>
|
||||
/// Emits or displays a message
|
||||
/// and a stack trace for an assertion that
|
||||
/// always fails.
|
||||
/// </para>
|
||||
/// </devdoc>
|
||||
public override void Fail(string message) {
|
||||
Fail(message, null);
|
||||
}
|
||||
|
||||
/// <devdoc>
|
||||
/// <para>
|
||||
/// Emits or displays messages and a stack trace for an assertion that
|
||||
/// always fails.
|
||||
/// </para>
|
||||
/// </devdoc>
|
||||
public override void Fail(string message, string detailMessage) {
|
||||
StackTrace stack = new StackTrace(true);
|
||||
int userStackFrameIndex = 0;
|
||||
string stackTrace;
|
||||
bool uiPermission = UiPermission;
|
||||
|
||||
try {
|
||||
stackTrace = stack.ToString();
|
||||
}
|
||||
catch {
|
||||
stackTrace = "";
|
||||
}
|
||||
|
||||
WriteAssert(stackTrace, message, detailMessage);
|
||||
if (AssertUiEnabled && uiPermission) {
|
||||
AssertWrapper.ShowAssert(stackTrace, stack.GetFrame(userStackFrameIndex), message, detailMessage);
|
||||
}
|
||||
}
|
||||
|
||||
[ResourceExposure(ResourceScope.None)]
|
||||
[ResourceConsumption(ResourceScope.Machine, ResourceScope.Machine)]
|
||||
private void InitializeSettings() {
|
||||
// don't use the property setters here to avoid infinite recursion.
|
||||
#if CONFIGURATION_DEP
|
||||
assertUIEnabled = DiagnosticsConfiguration.AssertUIEnabled;
|
||||
logFileName = DiagnosticsConfiguration.LogFileName;
|
||||
#endif
|
||||
settingsInitialized = true;
|
||||
}
|
||||
|
||||
private void WriteAssert(string stackTrace, string message, string detailMessage) {
|
||||
string assertMessage = SR.GetString(SR.DebugAssertBanner) + Environment.NewLine
|
||||
+ SR.GetString(SR.DebugAssertShortMessage) + Environment.NewLine
|
||||
+ message + Environment.NewLine
|
||||
+ SR.GetString(SR.DebugAssertLongMessage) + Environment.NewLine +
|
||||
detailMessage + Environment.NewLine
|
||||
+ stackTrace;
|
||||
WriteLine(assertMessage);
|
||||
}
|
||||
|
||||
[ResourceExposure(ResourceScope.None)]
|
||||
[ResourceConsumption(ResourceScope.Machine, ResourceScope.Machine)]
|
||||
private void WriteToLogFile(string message, bool useWriteLine) {
|
||||
try {
|
||||
FileInfo file = new FileInfo(LogFileName);
|
||||
using (Stream stream = file.Open(FileMode.OpenOrCreate)) {
|
||||
using (StreamWriter writer = new StreamWriter(stream)) {
|
||||
stream.Position = stream.Length;
|
||||
if (useWriteLine)
|
||||
writer.WriteLine(message);
|
||||
else
|
||||
writer.Write(message);
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (Exception e) {
|
||||
WriteLine(SR.GetString(SR.ExceptionOccurred, LogFileName, e.ToString()), false);
|
||||
}
|
||||
}
|
||||
|
||||
/// <devdoc>
|
||||
/// <para>
|
||||
/// Writes the output to the OutputDebugString
|
||||
/// API and
|
||||
/// to System.Diagnostics.Debugger.Log.
|
||||
/// </para>
|
||||
/// </devdoc>
|
||||
public override void Write(string message) {
|
||||
Write(message, true);
|
||||
}
|
||||
|
||||
[ResourceExposure(ResourceScope.None)]
|
||||
[ResourceConsumption(ResourceScope.Machine, ResourceScope.Machine)]
|
||||
private void Write(string message, bool useLogFile) {
|
||||
if (NeedIndent) WriteIndent();
|
||||
|
||||
// really huge messages mess up both VS and dbmon, so we chop it up into
|
||||
// reasonable chunks if it's too big
|
||||
if (message == null || message.Length <= internalWriteSize) {
|
||||
internalWrite(message);
|
||||
}
|
||||
else {
|
||||
int offset;
|
||||
for (offset = 0; offset < message.Length - internalWriteSize; offset += internalWriteSize) {
|
||||
internalWrite(message.Substring(offset, internalWriteSize));
|
||||
}
|
||||
internalWrite(message.Substring(offset));
|
||||
}
|
||||
|
||||
if (useLogFile && LogFileName.Length != 0)
|
||||
WriteToLogFile(message, false);
|
||||
}
|
||||
|
||||
void internalWrite(string message) {
|
||||
if (Debugger.IsLogging()) {
|
||||
Debugger.Log(0, null, message);
|
||||
} else {
|
||||
if (message == null)
|
||||
SafeNativeMethods.OutputDebugString(String.Empty);
|
||||
else
|
||||
SafeNativeMethods.OutputDebugString(message);
|
||||
}
|
||||
}
|
||||
|
||||
/// <devdoc>
|
||||
/// <para>
|
||||
/// Writes the output to the OutputDebugString
|
||||
/// API and to System.Diagnostics.Debugger.Log
|
||||
/// followed by a line terminator.
|
||||
/// </para>
|
||||
/// </devdoc>
|
||||
public override void WriteLine(string message) {
|
||||
WriteLine(message, true);
|
||||
}
|
||||
|
||||
private void WriteLine(string message, bool useLogFile) {
|
||||
if (NeedIndent) WriteIndent();
|
||||
// I do the concat here to make sure it goes as one call to the output.
|
||||
// we would save a stringbuilder operation by calling Write twice.
|
||||
Write(message + Environment.NewLine, useLogFile);
|
||||
NeedIndent = true;
|
||||
}
|
||||
|
||||
/// <devdoc>
|
||||
/// It returns true if the current permission set allows an assert dialog to be displayed.
|
||||
/// </devdoc>
|
||||
private static bool UiPermission {
|
||||
get {
|
||||
bool uiPermission = false;
|
||||
|
||||
try {
|
||||
new UIPermission(UIPermissionWindow.SafeSubWindows).Demand();
|
||||
uiPermission = true;
|
||||
}
|
||||
catch {
|
||||
}
|
||||
return uiPermission;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,240 @@
|
||||
//------------------------------------------------------------------------------
|
||||
// <copyright file="DelimitedListTraceListener.cs" company="Microsoft">
|
||||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
// </copyright>
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
|
||||
using System;
|
||||
using System.Text;
|
||||
using System.Globalization;
|
||||
using System.IO;
|
||||
using System.Collections;
|
||||
using System.Security.Permissions;
|
||||
using System.Runtime.Versioning;
|
||||
|
||||
namespace System.Diagnostics {
|
||||
[HostProtection(Synchronization=true)]
|
||||
public class DelimitedListTraceListener : TextWriterTraceListener {
|
||||
string delimiter = ";";
|
||||
string secondaryDelim = ",";
|
||||
bool initializedDelim = false;
|
||||
|
||||
public DelimitedListTraceListener(Stream stream) : base(stream) {
|
||||
}
|
||||
|
||||
public DelimitedListTraceListener(Stream stream, string name) : base(stream, name) {
|
||||
}
|
||||
|
||||
public DelimitedListTraceListener(TextWriter writer) : base(writer) {
|
||||
}
|
||||
|
||||
public DelimitedListTraceListener(TextWriter writer, string name) : base(writer, name) {
|
||||
}
|
||||
|
||||
[ResourceExposure(ResourceScope.Machine)]
|
||||
[ResourceConsumption(ResourceScope.Machine)]
|
||||
public DelimitedListTraceListener(string fileName) : base (fileName) {
|
||||
}
|
||||
|
||||
[ResourceExposure(ResourceScope.Machine)]
|
||||
[ResourceConsumption(ResourceScope.Machine)]
|
||||
public DelimitedListTraceListener(string fileName, string name) : base(fileName, name) {
|
||||
}
|
||||
|
||||
public string Delimiter {
|
||||
get {
|
||||
lock(this) { // Probably overkill
|
||||
if (!initializedDelim) {
|
||||
|
||||
if (Attributes.ContainsKey("delimiter"))
|
||||
delimiter = Attributes["delimiter"];
|
||||
|
||||
initializedDelim = true;
|
||||
}
|
||||
}
|
||||
return delimiter;
|
||||
}
|
||||
set {
|
||||
if (value == null)
|
||||
throw new ArgumentNullException("Delimiter");
|
||||
|
||||
if (value.Length == 0)
|
||||
throw new ArgumentException(SR.GetString("Generic_ArgCantBeEmptyString", "Delimiter"));
|
||||
|
||||
lock(this) {
|
||||
delimiter = value;
|
||||
initializedDelim = true;
|
||||
}
|
||||
|
||||
if (delimiter == ",")
|
||||
secondaryDelim = ";";
|
||||
else
|
||||
secondaryDelim = ",";
|
||||
}
|
||||
}
|
||||
|
||||
protected override internal string[] GetSupportedAttributes() {
|
||||
return new String[]{"delimiter"};
|
||||
}
|
||||
|
||||
|
||||
public override void TraceEvent(TraceEventCache eventCache, String source, TraceEventType eventType, int id, string format, params object[] args) {
|
||||
if (Filter != null && !Filter.ShouldTrace(eventCache, source, eventType, id, format, args))
|
||||
return;
|
||||
|
||||
WriteHeader(source, eventType, id);
|
||||
|
||||
if (args != null)
|
||||
WriteEscaped(String.Format(CultureInfo.InvariantCulture, format, args));
|
||||
else
|
||||
WriteEscaped(format);
|
||||
Write(Delimiter); // Use get_Delimiter
|
||||
|
||||
// one more delimiter for the data object
|
||||
Write(Delimiter); // Use get_Delimiter
|
||||
|
||||
WriteFooter(eventCache);
|
||||
}
|
||||
|
||||
public override void TraceEvent(TraceEventCache eventCache, String source, TraceEventType eventType, int id, string message) {
|
||||
if (Filter != null && !Filter.ShouldTrace(eventCache, source, eventType, id, message))
|
||||
return;
|
||||
|
||||
WriteHeader(source, eventType, id);
|
||||
|
||||
WriteEscaped(message);
|
||||
Write(Delimiter); // Use get_Delimiter
|
||||
|
||||
// one more delimiter for the data object
|
||||
Write(Delimiter); // Use get_Delimiter
|
||||
|
||||
WriteFooter(eventCache);
|
||||
}
|
||||
|
||||
public override void TraceData(TraceEventCache eventCache, String source, TraceEventType eventType, int id, object data) {
|
||||
if (Filter != null && !Filter.ShouldTrace(eventCache, source, eventType, id, null, null, data))
|
||||
return;
|
||||
|
||||
WriteHeader(source, eventType, id);
|
||||
|
||||
// first a delimiter for the message
|
||||
Write(Delimiter); // Use get_Delimiter
|
||||
|
||||
WriteEscaped(data.ToString());
|
||||
Write(Delimiter); // Use get_Delimiter
|
||||
|
||||
WriteFooter(eventCache);
|
||||
}
|
||||
|
||||
public override void TraceData(TraceEventCache eventCache, String source, TraceEventType eventType, int id, params object[] data) {
|
||||
if (Filter != null && !Filter.ShouldTrace(eventCache, source, eventType, id, null, null, null, data))
|
||||
return;
|
||||
|
||||
WriteHeader(source, eventType, id);
|
||||
|
||||
// first a delimiter for the message
|
||||
Write(Delimiter); // Use get_Delimiter
|
||||
|
||||
if (data != null) {
|
||||
for (int i=0; i<data.Length; i++) {
|
||||
if (i != 0)
|
||||
Write(secondaryDelim);
|
||||
WriteEscaped(data[i].ToString());
|
||||
}
|
||||
}
|
||||
Write(Delimiter); // Use get_Delimiter
|
||||
|
||||
WriteFooter(eventCache);
|
||||
}
|
||||
|
||||
private void WriteHeader(String source, TraceEventType eventType, int id) {
|
||||
WriteEscaped(source);
|
||||
Write(Delimiter); // Use get_Delimiter
|
||||
|
||||
Write(eventType.ToString());
|
||||
Write(Delimiter); // Use get_Delimiter
|
||||
|
||||
Write(id.ToString(CultureInfo.InvariantCulture));
|
||||
Write(Delimiter); // Use get_Delimiter
|
||||
}
|
||||
|
||||
[ResourceExposure(ResourceScope.None)]
|
||||
[ResourceConsumption(ResourceScope.Process, ResourceScope.Process)]
|
||||
private void WriteFooter(TraceEventCache eventCache) {
|
||||
if (eventCache != null) {
|
||||
if (IsEnabled(TraceOptions.ProcessId))
|
||||
Write(eventCache.ProcessId.ToString(CultureInfo.InvariantCulture));
|
||||
Write(Delimiter); // Use get_Delimiter
|
||||
|
||||
if (IsEnabled(TraceOptions.LogicalOperationStack))
|
||||
WriteStackEscaped(eventCache.LogicalOperationStack);
|
||||
Write(Delimiter); // Use get_Delimiter
|
||||
|
||||
if (IsEnabled(TraceOptions.ThreadId))
|
||||
WriteEscaped(eventCache.ThreadId.ToString(CultureInfo.InvariantCulture));
|
||||
Write(Delimiter); // Use get_Delimiter
|
||||
|
||||
if (IsEnabled(TraceOptions.DateTime))
|
||||
WriteEscaped(eventCache.DateTime.ToString("o", CultureInfo.InvariantCulture));
|
||||
Write(Delimiter); // Use get_Delimiter
|
||||
|
||||
if (IsEnabled(TraceOptions.Timestamp))
|
||||
Write(eventCache.Timestamp.ToString(CultureInfo.InvariantCulture));
|
||||
Write(Delimiter); // Use get_Delimiter
|
||||
|
||||
if (IsEnabled(TraceOptions.Callstack))
|
||||
WriteEscaped(eventCache.Callstack);
|
||||
}
|
||||
else {
|
||||
for (int i=0; i<5; i++)
|
||||
Write(Delimiter); // Use get_Delimiter
|
||||
}
|
||||
|
||||
WriteLine("");
|
||||
}
|
||||
|
||||
private void WriteEscaped(string message) {
|
||||
if (!String.IsNullOrEmpty(message)) {
|
||||
StringBuilder sb = new StringBuilder("\"");
|
||||
int index;
|
||||
int lastindex = 0;
|
||||
while((index = message.IndexOf('"', lastindex)) != -1) {
|
||||
sb.Append(message, lastindex, index - lastindex);
|
||||
sb.Append("\"\"");
|
||||
lastindex = index + 1;
|
||||
}
|
||||
|
||||
sb.Append(message, lastindex, message.Length - lastindex);
|
||||
sb.Append("\"");
|
||||
Write(sb.ToString());
|
||||
}
|
||||
}
|
||||
|
||||
private void WriteStackEscaped(Stack stack) {
|
||||
StringBuilder sb = new StringBuilder("\"");
|
||||
bool first = true;
|
||||
foreach (Object obj in stack) {
|
||||
if (!first)
|
||||
sb.Append(", ");
|
||||
else
|
||||
first = false;
|
||||
|
||||
string operation = obj.ToString();
|
||||
|
||||
int index;
|
||||
int lastindex = 0;
|
||||
while((index = operation.IndexOf('"', lastindex)) != -1) {
|
||||
sb.Append(operation, lastindex, index - lastindex);
|
||||
sb.Append("\"\"");
|
||||
lastindex = index + 1;
|
||||
}
|
||||
|
||||
sb.Append(operation, lastindex, operation.Length - lastindex);
|
||||
}
|
||||
sb.Append("\"");
|
||||
Write(sb.ToString());
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,259 @@
|
||||
//------------------------------------------------------------------------------
|
||||
// <copyright file="DiagnosticsConfiguration.cs" company="Microsoft">
|
||||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
// </copyright>
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
#if CONFIGURATION_DEP
|
||||
namespace System.Diagnostics {
|
||||
using System;
|
||||
using System.Reflection;
|
||||
using System.Collections;
|
||||
using System.Configuration;
|
||||
using System.Threading;
|
||||
using System.Runtime.Versioning;
|
||||
|
||||
internal enum InitState {
|
||||
NotInitialized,
|
||||
Initializing,
|
||||
Initialized
|
||||
}
|
||||
|
||||
internal static class DiagnosticsConfiguration {
|
||||
private static volatile SystemDiagnosticsSection configSection;
|
||||
private static volatile InitState initState = InitState.NotInitialized;
|
||||
|
||||
// setting for Switch.switchSetting
|
||||
internal static SwitchElementsCollection SwitchSettings {
|
||||
get {
|
||||
Initialize();
|
||||
SystemDiagnosticsSection configSectionSav = configSection;
|
||||
if (configSectionSav != null)
|
||||
return configSectionSav.Switches;
|
||||
else
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
// setting for DefaultTraceListener.AssertUIEnabled
|
||||
internal static bool AssertUIEnabled {
|
||||
get {
|
||||
Initialize();
|
||||
SystemDiagnosticsSection configSectionSav = configSection;
|
||||
if (configSectionSav != null && configSectionSav.Assert != null)
|
||||
return configSectionSav.Assert.AssertUIEnabled;
|
||||
else
|
||||
return true; // the default
|
||||
}
|
||||
}
|
||||
|
||||
internal static string ConfigFilePath {
|
||||
[ResourceExposure(ResourceScope.Machine)]
|
||||
[ResourceConsumption(ResourceScope.Machine)]
|
||||
get {
|
||||
Initialize();
|
||||
SystemDiagnosticsSection configSectionSav = configSection;
|
||||
if (configSectionSav != null)
|
||||
return configSectionSav.ElementInformation.Source;
|
||||
else
|
||||
return string.Empty; // the default
|
||||
}
|
||||
}
|
||||
|
||||
// setting for DefaultTraceListener.LogFileName
|
||||
internal static string LogFileName {
|
||||
[ResourceExposure(ResourceScope.Machine)]
|
||||
[ResourceConsumption(ResourceScope.Machine)]
|
||||
get {
|
||||
Initialize();
|
||||
SystemDiagnosticsSection configSectionSav = configSection;
|
||||
if (configSectionSav != null && configSectionSav.Assert != null)
|
||||
return configSectionSav.Assert.LogFileName;
|
||||
else
|
||||
return string.Empty; // the default
|
||||
}
|
||||
}
|
||||
|
||||
// setting for TraceInternal.AutoFlush
|
||||
internal static bool AutoFlush {
|
||||
get {
|
||||
Initialize();
|
||||
SystemDiagnosticsSection configSectionSav = configSection;
|
||||
if (configSectionSav != null && configSectionSav.Trace != null)
|
||||
return configSectionSav.Trace.AutoFlush;
|
||||
else
|
||||
return false; // the default
|
||||
}
|
||||
}
|
||||
|
||||
// setting for TraceInternal.UseGlobalLock
|
||||
internal static bool UseGlobalLock {
|
||||
get {
|
||||
Initialize();
|
||||
SystemDiagnosticsSection configSectionSav = configSection;
|
||||
if (configSectionSav != null && configSectionSav.Trace != null)
|
||||
return configSectionSav.Trace.UseGlobalLock;
|
||||
else
|
||||
return true; // the default
|
||||
}
|
||||
}
|
||||
|
||||
// setting for TraceInternal.IndentSize
|
||||
internal static int IndentSize {
|
||||
get {
|
||||
Initialize();
|
||||
SystemDiagnosticsSection configSectionSav = configSection;
|
||||
if (configSectionSav != null && configSectionSav.Trace != null)
|
||||
return configSectionSav.Trace.IndentSize;
|
||||
else
|
||||
return 4; // the default
|
||||
}
|
||||
}
|
||||
|
||||
#if !FEATURE_PAL // perfcounter
|
||||
internal static int PerfomanceCountersFileMappingSize {
|
||||
get {
|
||||
for (int retryCount = 0; !CanInitialize() && retryCount <= 5; ++retryCount) {
|
||||
if (retryCount == 5)
|
||||
return SharedPerformanceCounter.DefaultCountersFileMappingSize;
|
||||
|
||||
System.Threading.Thread.Sleep(200);
|
||||
}
|
||||
|
||||
Initialize();
|
||||
SystemDiagnosticsSection configSectionSav = configSection;
|
||||
if (configSectionSav != null && configSectionSav.PerfCounters != null) {
|
||||
int size = configSectionSav.PerfCounters.FileMappingSize;
|
||||
if (size < SharedPerformanceCounter.MinCountersFileMappingSize)
|
||||
size = SharedPerformanceCounter.MinCountersFileMappingSize;
|
||||
|
||||
if (size > SharedPerformanceCounter.MaxCountersFileMappingSize)
|
||||
size = SharedPerformanceCounter.MaxCountersFileMappingSize;
|
||||
|
||||
return size;
|
||||
}
|
||||
else
|
||||
return SharedPerformanceCounter.DefaultCountersFileMappingSize;
|
||||
}
|
||||
}
|
||||
#endif // !FEATURE_PAL
|
||||
|
||||
internal static ListenerElementsCollection SharedListeners {
|
||||
get {
|
||||
Initialize();
|
||||
SystemDiagnosticsSection configSectionSav = configSection;
|
||||
if (configSectionSav != null)
|
||||
return configSectionSav.SharedListeners;
|
||||
else
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
internal static SourceElementsCollection Sources {
|
||||
get {
|
||||
Initialize();
|
||||
SystemDiagnosticsSection configSectionSav = configSection;
|
||||
if (configSectionSav != null && configSectionSav.Sources != null)
|
||||
return configSectionSav.Sources;
|
||||
else
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
internal static SystemDiagnosticsSection SystemDiagnosticsSection {
|
||||
get {
|
||||
Initialize();
|
||||
return configSection;
|
||||
}
|
||||
}
|
||||
|
||||
private static SystemDiagnosticsSection GetConfigSection() {
|
||||
SystemDiagnosticsSection configSection = (SystemDiagnosticsSection) PrivilegedConfigurationManager.GetSection("system.diagnostics");
|
||||
return configSection;
|
||||
}
|
||||
|
||||
internal static bool IsInitializing() {
|
||||
return initState == InitState.Initializing;
|
||||
}
|
||||
|
||||
internal static bool IsInitialized() {
|
||||
return initState == InitState.Initialized;
|
||||
}
|
||||
|
||||
|
||||
internal static bool CanInitialize() {
|
||||
return (initState != InitState.Initializing) &&
|
||||
!ConfigurationManagerInternalFactory.Instance.SetConfigurationSystemInProgress;
|
||||
}
|
||||
|
||||
internal static void Initialize() {
|
||||
// Initialize() is also called by other components outside of Trace (such as PerformanceCounter)
|
||||
// as a result using one lock for this critical section and another for Trace API critical sections
|
||||
// (such as Trace.WriteLine) could potentially lead to deadlock between 2 threads that are
|
||||
// executing these critical sections (and consequently obtaining the 2 locks) in the reverse order.
|
||||
// Using the same lock for DiagnosticsConfiguration as well as TraceInternal avoids this issue.
|
||||
// Sequential locks on TraceInternal.critSec by the same thread is a non issue for this critical section.
|
||||
lock (TraceInternal.critSec) {
|
||||
|
||||
// because some of the code used to load config also uses diagnostics
|
||||
// we can't block them while we initialize from config. Therefore we just
|
||||
// return immediately and they just use the default values.
|
||||
if ( initState != InitState.NotInitialized ||
|
||||
ConfigurationManagerInternalFactory.Instance.SetConfigurationSystemInProgress) {
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
initState = InitState.Initializing; // used for preventing recursion
|
||||
try {
|
||||
configSection = GetConfigSection();
|
||||
}
|
||||
finally {
|
||||
initState = InitState.Initialized;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
internal static void Refresh() {
|
||||
ConfigurationManager.RefreshSection("system.diagnostics");
|
||||
|
||||
// There might still be some persistant state left behind for
|
||||
// ConfigPropertyCollection (for ex, swtichelements), probably for perf.
|
||||
// We need to explicitly cleanup any unrecognized attributes that we
|
||||
// have added during last deserialization, so that they are re-added
|
||||
// during the next Config.GetSection properly and we get a chance to
|
||||
// populate the Attributes collection for re-deserialization.
|
||||
// Another alternative could be to expose the properties collection
|
||||
// directly as Attributes collection (currently we keep a local
|
||||
// hashtable which we explicitly need to keep in sycn and hence the
|
||||
// cleanup logic below) but the down side of that would be we need to
|
||||
// explicitly compute what is recognized Vs unrecognized from that
|
||||
// collection when we expose the unrecognized Attributes publically
|
||||
SystemDiagnosticsSection configSectionSav = configSection;
|
||||
if (configSectionSav != null) {
|
||||
|
||||
if (configSectionSav.Switches != null) {
|
||||
foreach (SwitchElement swelem in configSectionSav.Switches)
|
||||
swelem.ResetProperties();
|
||||
}
|
||||
|
||||
if (configSectionSav.SharedListeners != null) {
|
||||
foreach (ListenerElement lnelem in configSectionSav.SharedListeners)
|
||||
lnelem.ResetProperties();
|
||||
}
|
||||
|
||||
if (configSectionSav.Sources != null) {
|
||||
foreach (SourceElement srelem in configSectionSav.Sources)
|
||||
srelem.ResetProperties();
|
||||
}
|
||||
}
|
||||
|
||||
configSection = null;
|
||||
|
||||
initState = InitState.NotInitialized;
|
||||
Initialize();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,33 @@
|
||||
//------------------------------------------------------------------------------
|
||||
// <copyright file="FilterElement.cs" company="Microsoft Corporation">
|
||||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
// </copyright>
|
||||
//------------------------------------------------------------------------------
|
||||
#if CONFIGURATION_DEP
|
||||
using System.Configuration;
|
||||
using System;
|
||||
|
||||
namespace System.Diagnostics {
|
||||
internal class FilterElement : TypedElement {
|
||||
public FilterElement() : base(typeof(TraceFilter)) {}
|
||||
|
||||
public TraceFilter GetRuntimeObject() {
|
||||
TraceFilter newFilter = (TraceFilter) BaseGetRuntimeObject();
|
||||
newFilter.initializeData = InitData;
|
||||
return newFilter;
|
||||
}
|
||||
|
||||
internal TraceFilter RefreshRuntimeObject(TraceFilter filter) {
|
||||
if (Type.GetType(TypeName) != filter.GetType() || InitData != filter.initializeData) {
|
||||
// type or initdata changed
|
||||
_runtimeObject = null;
|
||||
return GetRuntimeObject();
|
||||
}
|
||||
else {
|
||||
return filter;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,376 @@
|
||||
//------------------------------------------------------------------------------
|
||||
// <copyright file="ListenerElementsCollection.cs" company="Microsoft Corporation">
|
||||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
// </copyright>
|
||||
//------------------------------------------------------------------------------
|
||||
#if CONFIGURATION_DEP
|
||||
using System.Configuration;
|
||||
using System;
|
||||
using System.Reflection;
|
||||
using System.Globalization;
|
||||
using System.Xml;
|
||||
using System.Collections.Specialized;
|
||||
using System.Collections;
|
||||
using System.Security;
|
||||
using System.Security.Permissions;
|
||||
|
||||
namespace System.Diagnostics {
|
||||
[ConfigurationCollection(typeof(ListenerElement))]
|
||||
internal class ListenerElementsCollection : ConfigurationElementCollection {
|
||||
|
||||
new public ListenerElement this[string name] {
|
||||
get {
|
||||
return (ListenerElement) BaseGet(name);
|
||||
}
|
||||
}
|
||||
|
||||
public override ConfigurationElementCollectionType CollectionType {
|
||||
get {
|
||||
return ConfigurationElementCollectionType.AddRemoveClearMap;
|
||||
}
|
||||
}
|
||||
|
||||
protected override ConfigurationElement CreateNewElement() {
|
||||
return new ListenerElement(true);
|
||||
}
|
||||
|
||||
protected override Object GetElementKey(ConfigurationElement element) {
|
||||
return ((ListenerElement) element).Name;
|
||||
}
|
||||
|
||||
public TraceListenerCollection GetRuntimeObject() {
|
||||
TraceListenerCollection listeners = new TraceListenerCollection();
|
||||
bool _isDemanded = false;
|
||||
|
||||
foreach(ListenerElement element in this) {
|
||||
|
||||
// At some point, we need to pull out adding/removing the 'default' DefaultTraceListener
|
||||
// code from here in favor of adding/not-adding after we load the config (in TraceSource
|
||||
// and in static Trace)
|
||||
|
||||
if (!_isDemanded && !element._isAddedByDefault) {
|
||||
// Do a full damand; This will disable partially trusted code from hooking up listeners
|
||||
new SecurityPermission(SecurityPermissionFlag.UnmanagedCode).Demand();
|
||||
_isDemanded = true;
|
||||
}
|
||||
|
||||
|
||||
|
||||
listeners.Add(element.GetRuntimeObject());
|
||||
}
|
||||
|
||||
return listeners;
|
||||
}
|
||||
|
||||
protected override void InitializeDefault() {
|
||||
InitializeDefaultInternal();
|
||||
}
|
||||
|
||||
internal void InitializeDefaultInternal() {
|
||||
ListenerElement defaultListener = new ListenerElement(false);
|
||||
defaultListener.Name = "Default";
|
||||
defaultListener.TypeName = typeof(DefaultTraceListener).FullName;
|
||||
defaultListener._isAddedByDefault = true;
|
||||
|
||||
this.BaseAdd(defaultListener);
|
||||
}
|
||||
|
||||
protected override void BaseAdd(ConfigurationElement element) {
|
||||
ListenerElement listenerElement = element as ListenerElement;
|
||||
|
||||
Debug.Assert((listenerElement != null), "adding elements other than ListenerElement to ListenerElementsCollection?");
|
||||
|
||||
if (listenerElement.Name.Equals("Default") && listenerElement.TypeName.Equals(typeof(DefaultTraceListener).FullName))
|
||||
BaseAdd(listenerElement, false);
|
||||
else
|
||||
BaseAdd(listenerElement, ThrowOnDuplicate);
|
||||
}
|
||||
}
|
||||
|
||||
// This is the collection used by the sharedListener section. It is only slightly different from ListenerElementsCollection.
|
||||
// The differences are that it does not allow remove and clear, and that the ListenerElements it creates do not allow
|
||||
// references.
|
||||
[ConfigurationCollection(typeof(ListenerElement), AddItemName = "add",
|
||||
CollectionType = ConfigurationElementCollectionType.BasicMap)]
|
||||
internal class SharedListenerElementsCollection : ListenerElementsCollection {
|
||||
|
||||
public override ConfigurationElementCollectionType CollectionType {
|
||||
get {
|
||||
return ConfigurationElementCollectionType.BasicMap;
|
||||
}
|
||||
}
|
||||
|
||||
protected override ConfigurationElement CreateNewElement() {
|
||||
return new ListenerElement(false);
|
||||
}
|
||||
|
||||
protected override string ElementName {
|
||||
get {
|
||||
return "add";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
internal class ListenerElement : TypedElement {
|
||||
private static readonly ConfigurationProperty _propFilter = new ConfigurationProperty("filter", typeof(FilterElement), null, ConfigurationPropertyOptions.None);
|
||||
private static readonly ConfigurationProperty _propName = new ConfigurationProperty("name", typeof(string), null, ConfigurationPropertyOptions.IsRequired | ConfigurationPropertyOptions.IsKey);
|
||||
private static readonly ConfigurationProperty _propOutputOpts = new ConfigurationProperty("traceOutputOptions", typeof(TraceOptions), TraceOptions.None, ConfigurationPropertyOptions.None);
|
||||
|
||||
private ConfigurationProperty _propListenerTypeName;
|
||||
private bool _allowReferences;
|
||||
private Hashtable _attributes;
|
||||
internal bool _isAddedByDefault;
|
||||
|
||||
static ListenerElement() {
|
||||
}
|
||||
|
||||
public ListenerElement(bool allowReferences) : base(typeof(TraceListener)) {
|
||||
_allowReferences = allowReferences;
|
||||
|
||||
ConfigurationPropertyOptions flags = ConfigurationPropertyOptions.None;
|
||||
if (!_allowReferences)
|
||||
flags |= ConfigurationPropertyOptions.IsRequired;
|
||||
|
||||
_propListenerTypeName = new ConfigurationProperty("type", typeof(string), null, flags);
|
||||
|
||||
_properties.Remove("type");
|
||||
_properties.Add(_propListenerTypeName);
|
||||
_properties.Add(_propFilter);
|
||||
_properties.Add(_propName);
|
||||
_properties.Add(_propOutputOpts);
|
||||
}
|
||||
|
||||
public Hashtable Attributes {
|
||||
get {
|
||||
if (_attributes == null)
|
||||
_attributes = new Hashtable(StringComparer.OrdinalIgnoreCase);
|
||||
return _attributes;
|
||||
}
|
||||
}
|
||||
|
||||
[ConfigurationProperty("filter")]
|
||||
public FilterElement Filter {
|
||||
get {
|
||||
return (FilterElement) this[_propFilter];
|
||||
}
|
||||
}
|
||||
|
||||
[ConfigurationProperty("name", IsRequired = true, IsKey = true)]
|
||||
public string Name {
|
||||
get {
|
||||
return (string) this[_propName];
|
||||
}
|
||||
set {
|
||||
this[_propName] = value;
|
||||
}
|
||||
}
|
||||
|
||||
[ConfigurationProperty("traceOutputOptions", DefaultValue = (TraceOptions) TraceOptions.None)]
|
||||
public TraceOptions TraceOutputOptions {
|
||||
get {
|
||||
return (TraceOptions) this[_propOutputOpts];
|
||||
}
|
||||
// This is useful when the OM becomes public. In the meantime, this can be utilized via reflection
|
||||
set {
|
||||
this[_propOutputOpts] = value;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
[ConfigurationProperty("type")]
|
||||
public override string TypeName {
|
||||
get {
|
||||
return (string) this[_propListenerTypeName];
|
||||
}
|
||||
set {
|
||||
this[_propListenerTypeName] = value;
|
||||
}
|
||||
}
|
||||
|
||||
public override bool Equals(object compareTo) {
|
||||
if (this.Name.Equals("Default") && this.TypeName.Equals(typeof(DefaultTraceListener).FullName)) {
|
||||
// This is a workaround to treat all DefaultTraceListener named 'Default' the same.
|
||||
// This is needed for the Config.Save to work properly as otherwise config base layers
|
||||
// above us would run into duplicate 'Default' listener element and perceive it as
|
||||
// error.
|
||||
ListenerElement compareToElem = compareTo as ListenerElement;
|
||||
return (compareToElem != null) && compareToElem.Name.Equals("Default")
|
||||
&& compareToElem.TypeName.Equals(typeof(DefaultTraceListener).FullName);
|
||||
}
|
||||
else
|
||||
return base.Equals(compareTo);
|
||||
}
|
||||
|
||||
public override int GetHashCode() {
|
||||
return base.GetHashCode();
|
||||
}
|
||||
|
||||
public TraceListener GetRuntimeObject() {
|
||||
if (_runtimeObject != null)
|
||||
return (TraceListener) _runtimeObject;
|
||||
|
||||
try {
|
||||
string className = TypeName;
|
||||
if (String.IsNullOrEmpty(className)) {
|
||||
// Look it up in SharedListeners
|
||||
Debug.Assert(_allowReferences, "_allowReferences must be true if type name is null");
|
||||
|
||||
if (_attributes != null || ElementInformation.Properties[_propFilter.Name].ValueOrigin == PropertyValueOrigin.SetHere || TraceOutputOptions != TraceOptions.None || !String.IsNullOrEmpty(InitData))
|
||||
throw new ConfigurationErrorsException(SR.GetString(SR.Reference_listener_cant_have_properties, Name));
|
||||
|
||||
if (DiagnosticsConfiguration.SharedListeners == null)
|
||||
throw new ConfigurationErrorsException(SR.GetString(SR.Reference_to_nonexistent_listener, Name));
|
||||
|
||||
ListenerElement sharedListener = DiagnosticsConfiguration.SharedListeners[Name];
|
||||
if (sharedListener == null)
|
||||
throw new ConfigurationErrorsException(SR.GetString(SR.Reference_to_nonexistent_listener, Name));
|
||||
else {
|
||||
_runtimeObject = sharedListener.GetRuntimeObject();
|
||||
return (TraceListener) _runtimeObject;
|
||||
}
|
||||
}
|
||||
else {
|
||||
// create a new one
|
||||
TraceListener newListener = (TraceListener) BaseGetRuntimeObject();
|
||||
newListener.initializeData = InitData;
|
||||
newListener.Name = Name;
|
||||
newListener.SetAttributes(Attributes);
|
||||
newListener.TraceOutputOptions = TraceOutputOptions;
|
||||
|
||||
if ((Filter != null) && (Filter.TypeName != null) && (Filter.TypeName.Length != 0)) {
|
||||
newListener.Filter = Filter.GetRuntimeObject();
|
||||
XmlWriterTraceListener listerAsXmlWriter = newListener as XmlWriterTraceListener;
|
||||
if (listerAsXmlWriter != null) {
|
||||
// This filter was added via configuration, which means we want the listener
|
||||
// to respect it for TraceTransfer events.
|
||||
listerAsXmlWriter.shouldRespectFilterOnTraceTransfer = true;
|
||||
}
|
||||
}
|
||||
|
||||
_runtimeObject = newListener;
|
||||
return newListener;
|
||||
}
|
||||
}
|
||||
catch (ArgumentException e) {
|
||||
throw new ConfigurationErrorsException(SR.GetString(SR.Could_not_create_listener, Name), e);
|
||||
}
|
||||
}
|
||||
|
||||
// Our optional attributes implementation is little convoluted as there is
|
||||
// no such firsclass mechanism from the config system. We basically cache
|
||||
// any "unrecognized" attribute here and serialize it out later.
|
||||
protected override bool OnDeserializeUnrecognizedAttribute(String name, String value) {
|
||||
Attributes.Add(name, value);
|
||||
return true;
|
||||
}
|
||||
|
||||
// We need to serialize optional attributes here, a better place would have
|
||||
// been inside SerializeElement but the base class implementation from
|
||||
// ConfigurationElement doesn't take into account for derived class doing
|
||||
// extended serialization, it basically writes out child element that
|
||||
// forces the element closing syntax, so any attribute serialization needs
|
||||
// to happen before normal element serialization from ConfigurationElement.
|
||||
// This means we would write out custom attributes ahead of normal ones.
|
||||
// The other alternative would be to re-implement the entire routine here
|
||||
// which is an overkill and a maintenance issue.
|
||||
protected override void PreSerialize(XmlWriter writer) {
|
||||
if (_attributes != null) {
|
||||
IDictionaryEnumerator e = _attributes.GetEnumerator();
|
||||
while (e.MoveNext()) {
|
||||
string xmlValue = (string)e.Value;
|
||||
string xmlName = (string)e.Key;
|
||||
|
||||
if ((xmlValue != null) && (writer != null)) {
|
||||
writer.WriteAttributeString(xmlName, xmlValue);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Account for optional attributes from custom listeners.
|
||||
protected override bool SerializeElement(XmlWriter writer, bool serializeCollectionKey) {
|
||||
bool DataToWrite = base.SerializeElement(writer, serializeCollectionKey);
|
||||
DataToWrite = DataToWrite || ((_attributes != null) && (_attributes.Count > 0));
|
||||
return DataToWrite;
|
||||
}
|
||||
|
||||
protected override void Unmerge(ConfigurationElement sourceElement,
|
||||
ConfigurationElement parentElement,
|
||||
ConfigurationSaveMode saveMode) {
|
||||
base.Unmerge(sourceElement, parentElement, saveMode);
|
||||
|
||||
// Unmerge the optional attributes cache as well
|
||||
ListenerElement le = sourceElement as ListenerElement;
|
||||
if ((le != null) && (le._attributes != null))
|
||||
this._attributes = le._attributes;
|
||||
}
|
||||
|
||||
internal void ResetProperties()
|
||||
{
|
||||
// blow away any UnrecognizedAttributes that we have deserialized earlier
|
||||
if (_attributes != null) {
|
||||
_attributes.Clear();
|
||||
_properties.Clear();
|
||||
_properties.Add(_propListenerTypeName);
|
||||
_properties.Add(_propFilter);
|
||||
_properties.Add(_propName);
|
||||
_properties.Add(_propOutputOpts);
|
||||
}
|
||||
}
|
||||
|
||||
internal TraceListener RefreshRuntimeObject(TraceListener listener) {
|
||||
_runtimeObject = null;
|
||||
try {
|
||||
string className = TypeName;
|
||||
if (String.IsNullOrEmpty(className)) {
|
||||
// Look it up in SharedListeners and ask the sharedListener to refresh.
|
||||
Debug.Assert(_allowReferences, "_allowReferences must be true if type name is null");
|
||||
|
||||
if (_attributes != null || ElementInformation.Properties[_propFilter.Name].ValueOrigin == PropertyValueOrigin.SetHere || TraceOutputOptions != TraceOptions.None || !String.IsNullOrEmpty(InitData))
|
||||
throw new ConfigurationErrorsException(SR.GetString(SR.Reference_listener_cant_have_properties, Name));
|
||||
|
||||
if (DiagnosticsConfiguration.SharedListeners == null)
|
||||
throw new ConfigurationErrorsException(SR.GetString(SR.Reference_to_nonexistent_listener, Name));
|
||||
|
||||
ListenerElement sharedListener = DiagnosticsConfiguration.SharedListeners[Name];
|
||||
if (sharedListener == null)
|
||||
throw new ConfigurationErrorsException(SR.GetString(SR.Reference_to_nonexistent_listener, Name));
|
||||
else {
|
||||
_runtimeObject = sharedListener.RefreshRuntimeObject(listener);
|
||||
return (TraceListener) _runtimeObject;
|
||||
}
|
||||
}
|
||||
else {
|
||||
// We're the element with the type and initializeData info. First see if those two are the same as they were.
|
||||
// If not, create a whole new object, otherwise, just update the other properties.
|
||||
if (Type.GetType(className) != listener.GetType() || InitData != listener.initializeData) {
|
||||
// type or initdata changed
|
||||
return GetRuntimeObject();
|
||||
}
|
||||
else {
|
||||
listener.SetAttributes(Attributes);
|
||||
listener.TraceOutputOptions = TraceOutputOptions;
|
||||
|
||||
if (listener.Filter != null ) {
|
||||
if (ElementInformation.Properties[_propFilter.Name].ValueOrigin == PropertyValueOrigin.SetHere ||
|
||||
ElementInformation.Properties[_propFilter.Name].ValueOrigin == PropertyValueOrigin.Inherited)
|
||||
listener.Filter = Filter.RefreshRuntimeObject(listener.Filter);
|
||||
else
|
||||
listener.Filter = null;
|
||||
}
|
||||
|
||||
_runtimeObject = listener;
|
||||
return listener;
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (ArgumentException e) {
|
||||
throw new ConfigurationErrorsException(SR.GetString(SR.Could_not_create_listener, Name), e);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,35 @@
|
||||
//------------------------------------------------------------------------------
|
||||
// <copyright file="PerfCounterSection.cs" company="Microsoft Corporation">
|
||||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
// </copyright>
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
#if CONFIGURATION_DEP
|
||||
using System.Configuration;
|
||||
|
||||
namespace System.Diagnostics {
|
||||
internal class PerfCounterSection : ConfigurationElement {
|
||||
private static readonly ConfigurationPropertyCollection _properties;
|
||||
private static readonly ConfigurationProperty _propFileMappingSize = new ConfigurationProperty("filemappingsize", typeof(int), 524288, ConfigurationPropertyOptions.None);
|
||||
|
||||
static PerfCounterSection(){
|
||||
_properties = new ConfigurationPropertyCollection();
|
||||
_properties.Add(_propFileMappingSize);
|
||||
}
|
||||
|
||||
[ConfigurationProperty("filemappingsize", DefaultValue = 524288)]
|
||||
public int FileMappingSize {
|
||||
get {
|
||||
return (int) this[_propFileMappingSize];
|
||||
}
|
||||
}
|
||||
|
||||
protected override ConfigurationPropertyCollection Properties {
|
||||
get {
|
||||
return _properties;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,32 @@
|
||||
//------------------------------------------------------------------------------
|
||||
// <copyright file="SeverityFilter.cs" company="Microsoft">
|
||||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
// </copyright>
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
using System;
|
||||
|
||||
namespace System.Diagnostics {
|
||||
public class EventTypeFilter : TraceFilter {
|
||||
private SourceLevels level;
|
||||
|
||||
public EventTypeFilter(SourceLevels level) {
|
||||
this.level = level;
|
||||
}
|
||||
|
||||
public override bool ShouldTrace(TraceEventCache cache, string source, TraceEventType eventType, int id, string formatOrMessage,
|
||||
object[] args, object data1, object[] data) {
|
||||
|
||||
return ((int) eventType & (int) level) != 0;
|
||||
}
|
||||
|
||||
public SourceLevels EventType {
|
||||
get {
|
||||
return level;
|
||||
}
|
||||
set {
|
||||
level = value;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,190 @@
|
||||
//------------------------------------------------------------------------------
|
||||
// <copyright file="SourceElementsCollection .cs" company="Microsoft Corporation">
|
||||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
// </copyright>
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
#if CONFIGURATION_DEP
|
||||
using System.Configuration;
|
||||
using System.Collections;
|
||||
using System.Collections.Specialized;
|
||||
using System.Xml;
|
||||
|
||||
namespace System.Diagnostics {
|
||||
[ConfigurationCollection(typeof(SourceElement), AddItemName = "source",
|
||||
CollectionType = ConfigurationElementCollectionType.BasicMap)]
|
||||
internal class SourceElementsCollection : ConfigurationElementCollection {
|
||||
|
||||
new public SourceElement this[string name] {
|
||||
get {
|
||||
return (SourceElement) BaseGet(name);
|
||||
}
|
||||
}
|
||||
|
||||
protected override string ElementName {
|
||||
get {
|
||||
return "source";
|
||||
}
|
||||
}
|
||||
|
||||
public override ConfigurationElementCollectionType CollectionType {
|
||||
get {
|
||||
return ConfigurationElementCollectionType.BasicMap;
|
||||
}
|
||||
}
|
||||
|
||||
protected override ConfigurationElement CreateNewElement() {
|
||||
SourceElement se = new SourceElement();
|
||||
se.Listeners.InitializeDefaultInternal();
|
||||
return se;
|
||||
}
|
||||
|
||||
protected override Object GetElementKey(ConfigurationElement element) {
|
||||
return ((SourceElement) element).Name;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
internal class SourceElement : ConfigurationElement {
|
||||
private static readonly ConfigurationPropertyCollection _properties;
|
||||
private static readonly ConfigurationProperty _propName = new ConfigurationProperty("name", typeof(string), "", ConfigurationPropertyOptions.IsRequired);
|
||||
private static readonly ConfigurationProperty _propSwitchName = new ConfigurationProperty("switchName", typeof(string), null, ConfigurationPropertyOptions.None);
|
||||
private static readonly ConfigurationProperty _propSwitchValue = new ConfigurationProperty("switchValue", typeof(string), null, ConfigurationPropertyOptions.None);
|
||||
private static readonly ConfigurationProperty _propSwitchType = new ConfigurationProperty("switchType", typeof(string), null, ConfigurationPropertyOptions.None);
|
||||
private static readonly ConfigurationProperty _propListeners = new ConfigurationProperty("listeners", typeof(ListenerElementsCollection), new ListenerElementsCollection(), ConfigurationPropertyOptions.None);
|
||||
|
||||
private Hashtable _attributes;
|
||||
|
||||
static SourceElement() {
|
||||
_properties = new ConfigurationPropertyCollection();
|
||||
_properties.Add(_propName);
|
||||
_properties.Add(_propSwitchName);
|
||||
_properties.Add(_propSwitchValue);
|
||||
_properties.Add(_propSwitchType);
|
||||
_properties.Add(_propListeners);
|
||||
}
|
||||
|
||||
public Hashtable Attributes {
|
||||
get {
|
||||
if (_attributes == null)
|
||||
_attributes = new Hashtable(StringComparer.OrdinalIgnoreCase);
|
||||
return _attributes;
|
||||
}
|
||||
}
|
||||
|
||||
[ConfigurationProperty("listeners")]
|
||||
public ListenerElementsCollection Listeners {
|
||||
get {
|
||||
return (ListenerElementsCollection) this[_propListeners];
|
||||
}
|
||||
}
|
||||
|
||||
[ConfigurationProperty("name", IsRequired=true, DefaultValue="")]
|
||||
public string Name {
|
||||
get {
|
||||
return (string) this[_propName];
|
||||
}
|
||||
}
|
||||
|
||||
protected override ConfigurationPropertyCollection Properties {
|
||||
get {
|
||||
return _properties;
|
||||
}
|
||||
}
|
||||
|
||||
[ConfigurationProperty("switchName")]
|
||||
public string SwitchName {
|
||||
get {
|
||||
return (string) this[_propSwitchName];
|
||||
}
|
||||
}
|
||||
|
||||
[ConfigurationProperty("switchValue")]
|
||||
public string SwitchValue {
|
||||
get {
|
||||
return (string) this[_propSwitchValue];
|
||||
}
|
||||
}
|
||||
|
||||
[ConfigurationProperty("switchType")]
|
||||
public string SwitchType {
|
||||
get {
|
||||
return (string) this[_propSwitchType];
|
||||
}
|
||||
}
|
||||
|
||||
protected override void DeserializeElement(XmlReader reader, bool serializeCollectionKey)
|
||||
{
|
||||
base.DeserializeElement(reader, serializeCollectionKey);
|
||||
|
||||
if (!String.IsNullOrEmpty(SwitchName) && !String.IsNullOrEmpty(SwitchValue))
|
||||
throw new ConfigurationErrorsException(SR.GetString(SR.Only_specify_one, Name));
|
||||
}
|
||||
|
||||
// Our optional attributes implementation is little convoluted as there is
|
||||
// no such firsclass mechanism from the config system. We basically cache
|
||||
// any "unrecognized" attribute here and serialize it out later.
|
||||
protected override bool OnDeserializeUnrecognizedAttribute(String name, String value) {
|
||||
Attributes.Add(name, value);
|
||||
return true;
|
||||
}
|
||||
|
||||
// We need to serialize optional attributes here, a better place would have
|
||||
// been inside SerializeElement but the base class implementation from
|
||||
// ConfigurationElement doesn't take into account for derived class doing
|
||||
// extended serialization, it basically writes out child element that
|
||||
// forces the element closing syntax, so any attribute serialization needs
|
||||
// to happen before normal element serialization from ConfigurationElement.
|
||||
// This means we would write out custom attributes ahead of normal ones.
|
||||
// The other alternative would be to re-implement the entire routine here
|
||||
// which is an overkill and a maintenance issue.
|
||||
protected override void PreSerialize(XmlWriter writer) {
|
||||
if (_attributes != null) {
|
||||
IDictionaryEnumerator e = _attributes.GetEnumerator();
|
||||
while (e.MoveNext()) {
|
||||
string xmlValue = (string)e.Value;
|
||||
string xmlName = (string)e.Key;
|
||||
|
||||
if ((xmlValue != null) && (writer != null)) {
|
||||
writer.WriteAttributeString(xmlName, xmlValue);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Account for optional attributes from custom listeners.
|
||||
protected override bool SerializeElement(XmlWriter writer, bool serializeCollectionKey) {
|
||||
bool DataToWrite = base.SerializeElement(writer, serializeCollectionKey);
|
||||
DataToWrite = DataToWrite || ((_attributes != null) && (_attributes.Count > 0));
|
||||
return DataToWrite;
|
||||
}
|
||||
|
||||
protected override void Unmerge(ConfigurationElement sourceElement,
|
||||
ConfigurationElement parentElement,
|
||||
ConfigurationSaveMode saveMode) {
|
||||
base.Unmerge(sourceElement, parentElement, saveMode);
|
||||
|
||||
// Unmerge the optional attributes cache as well
|
||||
SourceElement le = sourceElement as SourceElement;
|
||||
if ((le != null) && (le._attributes != null))
|
||||
this._attributes = le._attributes;
|
||||
}
|
||||
|
||||
internal void ResetProperties()
|
||||
{
|
||||
// blow away any UnrecognizedAttributes that we have deserialized earlier
|
||||
if (_attributes != null) {
|
||||
_attributes.Clear();
|
||||
_properties.Clear();
|
||||
_properties.Add(_propName);
|
||||
_properties.Add(_propSwitchName);
|
||||
_properties.Add(_propSwitchValue);
|
||||
_properties.Add(_propSwitchType);
|
||||
_properties.Add(_propListeners);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,38 @@
|
||||
//------------------------------------------------------------------------------
|
||||
// <copyright file="SourceFilter.cs" company="Microsoft">
|
||||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
// </copyright>
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
using System;
|
||||
using System.Collections;
|
||||
|
||||
namespace System.Diagnostics {
|
||||
public class SourceFilter : TraceFilter {
|
||||
private string src;
|
||||
|
||||
public SourceFilter(string source) {
|
||||
Source = source;
|
||||
}
|
||||
|
||||
public override bool ShouldTrace(TraceEventCache cache, string source, TraceEventType eventType, int id, string formatOrMessage,
|
||||
object[] args, object data1, object[] data) {
|
||||
if (source == null)
|
||||
throw new ArgumentNullException("source");
|
||||
|
||||
return String.Equals(src, source);
|
||||
}
|
||||
|
||||
public String Source {
|
||||
get {
|
||||
return src;
|
||||
}
|
||||
set {
|
||||
if (value == null)
|
||||
throw new ArgumentNullException("source");
|
||||
src = value;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,26 @@
|
||||
//------------------------------------------------------------------------------
|
||||
// <copyright file="SourceLevels.cs" company="Microsoft">
|
||||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
// </copyright>
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
using System;
|
||||
using System.ComponentModel;
|
||||
|
||||
namespace System.Diagnostics {
|
||||
|
||||
[Flags]
|
||||
public enum SourceLevels {
|
||||
Off = 0,
|
||||
Critical = 0x01,
|
||||
Error = 0x03,
|
||||
Warning = 0x07,
|
||||
Information = 0x0F,
|
||||
Verbose = 0x1F,
|
||||
|
||||
[EditorBrowsable(EditorBrowsableState.Advanced)]
|
||||
ActivityTracing = 0xFF00,
|
||||
All = unchecked ((int) 0xFFFFFFFF),
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,39 @@
|
||||
//------------------------------------------------------------------------------
|
||||
// <copyright file="SourceSwitch.cs" company="Microsoft">
|
||||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
// </copyright>
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
using System;
|
||||
using System.Collections;
|
||||
using System.Collections.Specialized;
|
||||
using System.Threading;
|
||||
using System.Security;
|
||||
using System.Security.Permissions;
|
||||
|
||||
namespace System.Diagnostics {
|
||||
public class SourceSwitch : Switch {
|
||||
public SourceSwitch(string name) : base(name, String.Empty) {}
|
||||
|
||||
public SourceSwitch(string displayName, string defaultSwitchValue)
|
||||
: base(displayName, String.Empty, defaultSwitchValue) { }
|
||||
|
||||
public SourceLevels Level {
|
||||
get {
|
||||
return (SourceLevels) SwitchSetting;
|
||||
}
|
||||
[SecurityPermission(SecurityAction.LinkDemand, Flags=SecurityPermissionFlag.UnmanagedCode)]
|
||||
set {
|
||||
SwitchSetting = (int) value;
|
||||
}
|
||||
}
|
||||
|
||||
public bool ShouldTrace(TraceEventType eventType) {
|
||||
return (SwitchSetting & (int) eventType) != 0;
|
||||
}
|
||||
|
||||
protected override void OnValueChanged() {
|
||||
SwitchSetting = (int) Enum.Parse(typeof(SourceLevels), Value, true);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,317 @@
|
||||
//------------------------------------------------------------------------------
|
||||
// <copyright file="Switch.cs" company="Microsoft">
|
||||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
// </copyright>
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
/*
|
||||
*/
|
||||
#if !CONFIGURATION_DEP
|
||||
using SwitchElementsCollection = System.Object;
|
||||
#endif
|
||||
|
||||
namespace System.Diagnostics {
|
||||
using System;
|
||||
using System.Security;
|
||||
using System.Security.Permissions;
|
||||
using System.Threading;
|
||||
using System.Runtime.InteropServices;
|
||||
using Microsoft.Win32;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using System.Collections.Specialized;
|
||||
using System.Globalization;
|
||||
using System.Configuration;
|
||||
#if XML_DEP
|
||||
using System.Xml.Serialization;
|
||||
#endif
|
||||
using System.Diagnostics.CodeAnalysis;
|
||||
|
||||
/// <devdoc>
|
||||
/// <para>Provides an <see langword='abstract '/>base class to
|
||||
/// create new debugging and tracing switches.</para>
|
||||
/// </devdoc>
|
||||
public abstract class Switch {
|
||||
private SwitchElementsCollection switchSettings;
|
||||
private readonly string description;
|
||||
private readonly string displayName;
|
||||
private int switchSetting = 0;
|
||||
private volatile bool initialized = false;
|
||||
private bool initializing = false;
|
||||
private volatile string switchValueString = String.Empty;
|
||||
private StringDictionary attributes;
|
||||
private string defaultValue;
|
||||
private object m_intializedLock;
|
||||
|
||||
private static List<WeakReference> switches = new List<WeakReference>();
|
||||
private static int s_LastCollectionCount;
|
||||
|
||||
private object IntializedLock {
|
||||
[SuppressMessage("Microsoft.Concurrency", "CA8001", Justification = "Reviewed for thread-safety")]
|
||||
get {
|
||||
if (m_intializedLock == null) {
|
||||
Object o = new Object();
|
||||
Interlocked.CompareExchange<Object>(ref m_intializedLock, o, null);
|
||||
}
|
||||
|
||||
return m_intializedLock;
|
||||
}
|
||||
}
|
||||
|
||||
/// <devdoc>
|
||||
/// <para>Initializes a new instance of the <see cref='System.Diagnostics.Switch'/>
|
||||
/// class.</para>
|
||||
/// </devdoc>
|
||||
protected Switch(string displayName, string description) : this(displayName, description, "0") {
|
||||
}
|
||||
|
||||
protected Switch(string displayName, string description, string defaultSwitchValue) {
|
||||
// displayName is used as a hashtable key, so it can never
|
||||
// be null.
|
||||
if (displayName == null) displayName = string.Empty;
|
||||
|
||||
this.displayName = displayName;
|
||||
this.description = description;
|
||||
|
||||
// Add a weakreference to this switch and cleanup invalid references
|
||||
lock (switches) {
|
||||
_pruneCachedSwitches();
|
||||
switches.Add(new WeakReference(this));
|
||||
}
|
||||
|
||||
defaultValue = defaultSwitchValue;
|
||||
}
|
||||
|
||||
private static void _pruneCachedSwitches() {
|
||||
lock (switches) {
|
||||
if (s_LastCollectionCount != GC.CollectionCount(2)) {
|
||||
List<WeakReference> buffer = new List<WeakReference>(switches.Count);
|
||||
for (int i = 0; i < switches.Count; i++) {
|
||||
Switch s = ((Switch)switches[i].Target);
|
||||
if (s != null) {
|
||||
buffer.Add(switches[i]);
|
||||
}
|
||||
}
|
||||
if (buffer.Count < switches.Count) {
|
||||
switches.Clear();
|
||||
switches.AddRange(buffer);
|
||||
switches.TrimExcess();
|
||||
}
|
||||
s_LastCollectionCount = GC.CollectionCount(2);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#if XML_DEP
|
||||
[XmlIgnore]
|
||||
#endif
|
||||
public StringDictionary Attributes {
|
||||
get {
|
||||
Initialize();
|
||||
if (attributes == null)
|
||||
attributes = new StringDictionary();
|
||||
return attributes;
|
||||
}
|
||||
}
|
||||
|
||||
/// <devdoc>
|
||||
/// <para>Gets a name used to identify the switch.</para>
|
||||
/// </devdoc>
|
||||
public string DisplayName {
|
||||
get {
|
||||
return displayName;
|
||||
}
|
||||
}
|
||||
|
||||
/// <devdoc>
|
||||
/// <para>Gets a description of the switch.</para>
|
||||
/// </devdoc>
|
||||
public string Description {
|
||||
get {
|
||||
return (description == null) ? string.Empty : description;
|
||||
}
|
||||
}
|
||||
|
||||
/// <devdoc>
|
||||
/// <para>
|
||||
/// Indicates the current setting for this switch.
|
||||
/// </para>
|
||||
/// </devdoc>
|
||||
protected int SwitchSetting {
|
||||
[SuppressMessage("Microsoft.Concurrency", "CA8001", Justification = "reviewed for thread-safety")]
|
||||
get {
|
||||
if (!initialized) {
|
||||
if (InitializeWithStatus())
|
||||
OnSwitchSettingChanged();
|
||||
}
|
||||
return switchSetting;
|
||||
}
|
||||
[SuppressMessage("Microsoft.Concurrency", "CA8001", Justification = "reviewed for thread-safety")]
|
||||
set {
|
||||
bool didUpdate = false;
|
||||
lock (IntializedLock) {
|
||||
initialized = true;
|
||||
if (switchSetting != value) {
|
||||
switchSetting = value;
|
||||
didUpdate = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (didUpdate) {
|
||||
OnSwitchSettingChanged();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
protected string Value {
|
||||
get {
|
||||
Initialize();
|
||||
return switchValueString;
|
||||
}
|
||||
set {
|
||||
Initialize();
|
||||
switchValueString = value;
|
||||
#if CONFIGURATION_DEP
|
||||
try {
|
||||
OnValueChanged();
|
||||
}
|
||||
catch (ArgumentException e) {
|
||||
throw new ConfigurationErrorsException(SR.GetString(SR.BadConfigSwitchValue, DisplayName), e);
|
||||
}
|
||||
catch (FormatException e) {
|
||||
throw new ConfigurationErrorsException(SR.GetString(SR.BadConfigSwitchValue, DisplayName), e);
|
||||
}
|
||||
catch (OverflowException e) {
|
||||
throw new ConfigurationErrorsException(SR.GetString(SR.BadConfigSwitchValue, DisplayName), e);
|
||||
}
|
||||
#else
|
||||
OnValueChanged();
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
private void Initialize() {
|
||||
InitializeWithStatus();
|
||||
}
|
||||
|
||||
private bool InitializeWithStatus() {
|
||||
if (!initialized) {
|
||||
|
||||
lock (IntializedLock) {
|
||||
|
||||
if (initialized || initializing) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// This method is re-entrent during intitialization, since calls to OnValueChanged() in subclasses could end up having InitializeWithStatus()
|
||||
// called again, we don't want to get caught in an infinite loop.
|
||||
initializing = true;
|
||||
|
||||
if (switchSettings == null) {
|
||||
if (!InitializeConfigSettings()) {
|
||||
initialized = true;
|
||||
initializing = false;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
#if CONFIGURATION_DEP
|
||||
if (switchSettings != null) {
|
||||
SwitchElement mySettings = switchSettings[displayName];
|
||||
if (mySettings != null) {
|
||||
string value = mySettings.Value;
|
||||
if (value != null) {
|
||||
this.Value = value;
|
||||
} else
|
||||
this.Value = defaultValue;
|
||||
|
||||
try {
|
||||
TraceUtils.VerifyAttributes(mySettings.Attributes, GetSupportedAttributes(), this);
|
||||
} catch (ConfigurationException) {
|
||||
// if VerifyAttributes throws, clean up a little bit so we're not in a bad state.
|
||||
initialized = false;
|
||||
initializing = false;
|
||||
throw;
|
||||
}
|
||||
|
||||
attributes = new StringDictionary();
|
||||
attributes.ReplaceHashtable(mySettings.Attributes);
|
||||
} else {
|
||||
// We don't use the property here because we don't want to catch exceptions
|
||||
// and rethrow them as ConfigurationException. In this case there's no config.
|
||||
switchValueString = defaultValue;
|
||||
OnValueChanged();
|
||||
}
|
||||
} else {
|
||||
#endif
|
||||
// We don't use the property here because we don't want to catch exceptions
|
||||
// and rethrow them as ConfigurationException. In this case there's no config.
|
||||
switchValueString = defaultValue;
|
||||
OnValueChanged();
|
||||
#if CONFIGURATION_DEP
|
||||
}
|
||||
#endif
|
||||
|
||||
initialized = true;
|
||||
initializing = false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
private bool InitializeConfigSettings() {
|
||||
if (switchSettings != null)
|
||||
return true;
|
||||
|
||||
#if CONFIGURATION_DEP
|
||||
if (!DiagnosticsConfiguration.CanInitialize())
|
||||
return false;
|
||||
|
||||
// This hashtable is case-insensitive.
|
||||
switchSettings = DiagnosticsConfiguration.SwitchSettings;
|
||||
#endif
|
||||
return true;
|
||||
}
|
||||
|
||||
virtual protected internal string[] GetSupportedAttributes() {
|
||||
return null;
|
||||
}
|
||||
|
||||
/// <devdoc>
|
||||
/// This method is invoked when a switch setting has been changed. It will
|
||||
/// be invoked the first time a switch reads its value from the registry
|
||||
/// or environment, and then it will be invoked each time the switch's
|
||||
/// value is changed.
|
||||
/// </devdoc>
|
||||
protected virtual void OnSwitchSettingChanged() {
|
||||
}
|
||||
|
||||
protected virtual void OnValueChanged() {
|
||||
SwitchSetting = Int32.Parse(Value, CultureInfo.InvariantCulture);
|
||||
}
|
||||
|
||||
internal static void RefreshAll() {
|
||||
|
||||
lock (switches) {
|
||||
_pruneCachedSwitches();
|
||||
for (int i=0; i<switches.Count; i++) {
|
||||
Switch swtch = ((Switch) switches[i].Target);
|
||||
if (swtch != null) {
|
||||
swtch.Refresh();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
internal void Refresh() {
|
||||
lock (IntializedLock) {
|
||||
initialized = false;
|
||||
switchSettings = null;
|
||||
Initialize();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,90 @@
|
||||
//------------------------------------------------------------------------------
|
||||
// <copyright file="SwitchAttribute.cs" company="Microsoft">
|
||||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
// </copyright>
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
using System;
|
||||
using System.Reflection;
|
||||
using System.Collections;
|
||||
|
||||
namespace System.Diagnostics {
|
||||
|
||||
[AttributeUsage(AttributeTargets.Assembly | AttributeTargets.Class | AttributeTargets.Constructor |
|
||||
AttributeTargets.Event | AttributeTargets.Method | AttributeTargets.Property)]
|
||||
public sealed class SwitchAttribute : Attribute {
|
||||
private Type type;
|
||||
private string name;
|
||||
private string description;
|
||||
|
||||
public SwitchAttribute (string switchName, Type switchType) {
|
||||
SwitchName = switchName;
|
||||
SwitchType = switchType;
|
||||
}
|
||||
|
||||
public string SwitchName {
|
||||
get { return name; }
|
||||
set {
|
||||
if (value == null)
|
||||
throw new ArgumentNullException("value");
|
||||
if (value.Length == 0)
|
||||
throw new ArgumentException(SR.GetString(SR.InvalidNullEmptyArgument, "value"), "value");
|
||||
|
||||
name = value;
|
||||
}
|
||||
}
|
||||
|
||||
public Type SwitchType {
|
||||
get { return type; }
|
||||
set {
|
||||
if (value == null)
|
||||
throw new ArgumentNullException("value");
|
||||
type = value;
|
||||
}
|
||||
}
|
||||
|
||||
public string SwitchDescription {
|
||||
get { return description; }
|
||||
set { description = value;}
|
||||
}
|
||||
|
||||
public static SwitchAttribute[] GetAll(Assembly assembly) {
|
||||
if (assembly == null)
|
||||
throw new ArgumentNullException("assembly");
|
||||
|
||||
ArrayList switchAttribs = new ArrayList ();
|
||||
|
||||
object[] attribs = assembly.GetCustomAttributes(typeof(SwitchAttribute), false);
|
||||
switchAttribs.AddRange(attribs);
|
||||
|
||||
Type[] types = assembly.GetTypes();
|
||||
for (int i=0; i<types.Length; i++)
|
||||
GetAllRecursive(types[i], switchAttribs);
|
||||
|
||||
SwitchAttribute[] ret = new SwitchAttribute[switchAttribs.Count];
|
||||
switchAttribs.CopyTo(ret, 0);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void GetAllRecursive(Type type, ArrayList switchAttribs) {
|
||||
GetAllRecursive((MemberInfo) type, switchAttribs);
|
||||
MemberInfo[] members = type.GetMembers(BindingFlags.Public | BindingFlags.NonPublic |
|
||||
BindingFlags.DeclaredOnly | BindingFlags.Instance |
|
||||
BindingFlags.Static);
|
||||
for (int i=0; i<members.Length; i++) {
|
||||
// ignore Types here. They will get covered by the top level assembly.GetTypes
|
||||
if (!(members[i] is Type))
|
||||
GetAllRecursive(members[i], switchAttribs);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
static void GetAllRecursive(MemberInfo member, ArrayList switchAttribs) {
|
||||
object[] attribs = member.GetCustomAttributes(typeof(SwitchAttribute), false);
|
||||
switchAttribs.AddRange(attribs);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,141 @@
|
||||
//------------------------------------------------------------------------------
|
||||
// <copyright file="SwitchElementsCollection.cs" company="Microsoft Corporation">
|
||||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
// </copyright>
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
#if CONFIGURATION_DEP
|
||||
using System.Configuration;
|
||||
using System.Collections;
|
||||
using System.Collections.Specialized;
|
||||
using System.Xml;
|
||||
|
||||
namespace System.Diagnostics {
|
||||
[ConfigurationCollection(typeof(SwitchElement))]
|
||||
internal class SwitchElementsCollection : ConfigurationElementCollection {
|
||||
|
||||
new public SwitchElement this[string name] {
|
||||
get {
|
||||
return (SwitchElement) BaseGet(name);
|
||||
}
|
||||
}
|
||||
|
||||
public override ConfigurationElementCollectionType CollectionType {
|
||||
get {
|
||||
return ConfigurationElementCollectionType.AddRemoveClearMap;
|
||||
}
|
||||
}
|
||||
|
||||
protected override ConfigurationElement CreateNewElement() {
|
||||
return new SwitchElement();
|
||||
}
|
||||
|
||||
protected override Object GetElementKey(ConfigurationElement element) {
|
||||
return ((SwitchElement) element).Name;
|
||||
}
|
||||
}
|
||||
|
||||
internal class SwitchElement : ConfigurationElement {
|
||||
private static readonly ConfigurationPropertyCollection _properties;
|
||||
private static readonly ConfigurationProperty _propName = new ConfigurationProperty("name", typeof(string), "", ConfigurationPropertyOptions.IsRequired | ConfigurationPropertyOptions.IsKey);
|
||||
private static readonly ConfigurationProperty _propValue = new ConfigurationProperty("value", typeof(string), null, ConfigurationPropertyOptions.IsRequired);
|
||||
|
||||
private Hashtable _attributes;
|
||||
|
||||
static SwitchElement(){
|
||||
_properties = new ConfigurationPropertyCollection();
|
||||
_properties.Add(_propName);
|
||||
_properties.Add(_propValue);
|
||||
}
|
||||
|
||||
public Hashtable Attributes {
|
||||
get {
|
||||
if (_attributes == null)
|
||||
_attributes = new Hashtable(StringComparer.OrdinalIgnoreCase);
|
||||
return _attributes;
|
||||
}
|
||||
}
|
||||
|
||||
[ConfigurationProperty("name", DefaultValue = "", IsRequired = true, IsKey = true)]
|
||||
public string Name {
|
||||
get {
|
||||
return (string) this[_propName];
|
||||
}
|
||||
}
|
||||
|
||||
protected override ConfigurationPropertyCollection Properties {
|
||||
get {
|
||||
return _properties;
|
||||
}
|
||||
}
|
||||
|
||||
[ConfigurationProperty("value", IsRequired = true)]
|
||||
public string Value {
|
||||
get {
|
||||
return (string) this[_propValue];
|
||||
}
|
||||
}
|
||||
|
||||
// Our optional attributes implementation is little convoluted as there is
|
||||
// no such firsclass mechanism from the config system. We basically cache
|
||||
// any "unrecognized" attribute here and serialize it out later.
|
||||
protected override bool OnDeserializeUnrecognizedAttribute(String name, String value) {
|
||||
Attributes.Add(name, value);
|
||||
return true;
|
||||
}
|
||||
|
||||
// We need to serialize optional attributes here, a better place would have
|
||||
// been inside SerializeElement but the base class implementation from
|
||||
// ConfigurationElement doesn't take into account for derived class doing
|
||||
// extended serialization, it basically writes out child element that
|
||||
// forces the element closing syntax, so any attribute serialization needs
|
||||
// to happen before normal element serialization from ConfigurationElement.
|
||||
// This means we would write out custom attributes ahead of normal ones.
|
||||
// The other alternative would be to re-implement the entire routine here
|
||||
// which is an overkill and a maintenance issue.
|
||||
protected override void PreSerialize(XmlWriter writer) {
|
||||
if (_attributes != null) {
|
||||
IDictionaryEnumerator e = _attributes.GetEnumerator();
|
||||
while (e.MoveNext()) {
|
||||
string xmlValue = (string)e.Value;
|
||||
string xmlName = (string)e.Key;
|
||||
|
||||
if ((xmlValue != null) && (writer != null)) {
|
||||
writer.WriteAttributeString(xmlName, xmlValue);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Account for optional attributes from custom listeners.
|
||||
protected override bool SerializeElement(XmlWriter writer, bool serializeCollectionKey) {
|
||||
bool DataToWrite = base.SerializeElement(writer, serializeCollectionKey);
|
||||
DataToWrite = DataToWrite || ((_attributes != null) && (_attributes.Count > 0));
|
||||
return DataToWrite;
|
||||
}
|
||||
|
||||
protected override void Unmerge(ConfigurationElement sourceElement,
|
||||
ConfigurationElement parentElement,
|
||||
ConfigurationSaveMode saveMode) {
|
||||
base.Unmerge(sourceElement, parentElement, saveMode);
|
||||
|
||||
// Unmerge the optional attributes cache as well
|
||||
SwitchElement le = sourceElement as SwitchElement;
|
||||
if ((le != null) && (le._attributes != null))
|
||||
this._attributes = le._attributes;
|
||||
}
|
||||
|
||||
internal void ResetProperties()
|
||||
{
|
||||
// blow away any UnrecognizedAttributes that we have deserialized earlier
|
||||
if (_attributes != null) {
|
||||
_attributes.Clear();
|
||||
_properties.Clear();
|
||||
_properties.Add(_propName);
|
||||
_properties.Add(_propValue);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,31 @@
|
||||
//------------------------------------------------------------------------------
|
||||
// <copyright file="SwitchLevelAttribute .cs" company="Microsoft">
|
||||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
// </copyright>
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
using System;
|
||||
using System.Reflection;
|
||||
using System.Collections;
|
||||
|
||||
namespace System.Diagnostics {
|
||||
|
||||
[AttributeUsage(AttributeTargets.Class)]
|
||||
public sealed class SwitchLevelAttribute : Attribute {
|
||||
private Type type;
|
||||
|
||||
public SwitchLevelAttribute (Type switchLevelType) {
|
||||
SwitchLevelType = switchLevelType;
|
||||
}
|
||||
|
||||
public Type SwitchLevelType {
|
||||
get { return type;}
|
||||
set {
|
||||
if (value == null)
|
||||
throw new ArgumentNullException("value");
|
||||
|
||||
type = value;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user