Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/mono/corefx.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLiudmila Molkova <lmolkova@microsoft.com>2017-01-31 21:23:04 +0300
committerLiudmila Molkova <lmolkova@microsoft.com>2017-02-08 03:24:26 +0300
commit038bbe9940b83853945547e839931a53529d0b03 (patch)
treea133ffdf99fa0509ad98758c68251bbdd375cf27
parentcb468ec555ce4ca2e22c690b3a39191593cd97be (diff)
review comments
-rw-r--r--src/System.Diagnostics.DiagnosticSource/src/System.Diagnostics.DiagnosticSource.csproj2
-rw-r--r--src/System.Diagnostics.DiagnosticSource/src/System/Diagnostics/Activity.cs55
-rw-r--r--src/System.Diagnostics.DiagnosticSource/tests/ActivityTests.cs76
-rw-r--r--src/System.Diagnostics.DiagnosticSource/tests/Configurations.props1
4 files changed, 94 insertions, 40 deletions
diff --git a/src/System.Diagnostics.DiagnosticSource/src/System.Diagnostics.DiagnosticSource.csproj b/src/System.Diagnostics.DiagnosticSource/src/System.Diagnostics.DiagnosticSource.csproj
index 655a17a8e8..7697d55182 100644
--- a/src/System.Diagnostics.DiagnosticSource/src/System.Diagnostics.DiagnosticSource.csproj
+++ b/src/System.Diagnostics.DiagnosticSource/src/System.Diagnostics.DiagnosticSource.csproj
@@ -52,7 +52,7 @@
<Reference Include="System.Diagnostics.Tracing" />
<Reference Include="System.Reflection" />
<Reference Include="System.Runtime" />
- <Reference Include="System.Runtime.Extensions" />
+ <Reference Include="System.Runtime.Extensions" />
<Reference Include="System.Threading" />
</ItemGroup>
<Import Project="$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory), dir.targets))\dir.targets" />
diff --git a/src/System.Diagnostics.DiagnosticSource/src/System/Diagnostics/Activity.cs b/src/System.Diagnostics.DiagnosticSource/src/System/Diagnostics/Activity.cs
index 33f008263e..55a8c583d3 100644
--- a/src/System.Diagnostics.DiagnosticSource/src/System/Diagnostics/Activity.cs
+++ b/src/System.Diagnostics.DiagnosticSource/src/System/Diagnostics/Activity.cs
@@ -66,15 +66,13 @@ namespace System.Diagnostics
{
get
{
- if (ParentId != null)
- yield return new KeyValuePair<string, string>("ParentId", ParentId);
for (var tags = _tags; tags != null; tags = tags.Next)
yield return tags.keyValue;
}
}
/// <summary>
- /// Tags are string-string key-value pairs that represent information that will
+ /// Baggage is string-string key-value pairs that represent information that will
/// be passed along to children of this activity. Baggage is serialized
/// when requests leave the process (along with the ID). Typically Baggage is
/// used to do fine-grained control over logging of the activty and any children.
@@ -112,6 +110,8 @@ namespace System.Diagnostics
/// <param name="operationName">Operations name <see cref="OperationName"/></param>
public Activity(string operationName)
{
+ if (string.IsNullOrEmpty(operationName))
+ throw new ArgumentException($"{nameof(operationName)} must not be null or empty");
OperationName = operationName;
}
@@ -151,6 +151,17 @@ namespace System.Diagnostics
/// </summary>
public Activity SetParentId(string parentId)
{
+ if (Parent != null)
+ throw new InvalidOperationException(
+ $"Trying to set {nameof(ParentId)} on activity which has {nameof(Parent)}");
+
+ if (ParentId != null)
+ throw new InvalidOperationException(
+ $"{nameof(ParentId)} is already set");
+
+ if (string.IsNullOrEmpty(parentId))
+ throw new ArgumentException($"{nameof(parentId)} must not be null or empty");
+
ParentId = parentId;
return this;
}
@@ -162,6 +173,8 @@ namespace System.Diagnostics
/// <returns>'this' for convinient chaining</returns>
public Activity SetStartTime(DateTime startTimeUtc)
{
+ if (startTimeUtc.Kind != DateTimeKind.Utc)
+ throw new InvalidOperationException($"{nameof(startTimeUtc)} is not UTC");
StartTimeUtc = startTimeUtc;
return this;
}
@@ -174,6 +187,9 @@ namespace System.Diagnostics
/// <returns>'this' for convinient chaining</returns>
public Activity SetEndTime(DateTime endTimeUtc)
{
+ if (endTimeUtc.Kind != DateTimeKind.Utc)
+ throw new InvalidOperationException($"{nameof(endTimeUtc)} is not UTC");
+
Duration = endTimeUtc - StartTimeUtc;
return this;
}
@@ -249,39 +265,19 @@ namespace System.Diagnostics
{
// Normal start within the process
Debug.Assert(!string.IsNullOrEmpty(Parent.Id));
-#if DEBUG
- ret = Parent.Id + "/" + OperationName + "_" + Interlocked.Increment(ref Parent._currentChildId);
-#else // To keep things short, we drop the operation name
- ret = Parent.Id + "/" + Interlocked.Increment(ref Parent._currentChildId);
-#endif
+ ret = $"{Parent.Id}.{Interlocked.Increment(ref Parent._currentChildId)}";
}
else if (ParentId != null)
{
// Start from outside the process (e.g. incoming HTTP)
Debug.Assert(ParentId.Length != 0);
-#if DEBUG
- ret = ParentId + "/" + OperationName + "_I_" + Interlocked.Increment(ref s_currentRootId);
-#else // To keep things short, we drop the operation name
- ret = ParentId + "/I_" + Interlocked.Increment(ref s_currentRootId);
-#endif
+ ret = $"{ParentId}.{Interlocked.Increment(ref s_currentRootId)}";
}
else
{
- // A Root Activity (no parent).
- if (s_uniqPrefix == null)
- {
- // Here we make an ID to represent the Process/AppDomain. Ideally we use process ID but
- // it is unclear if we have that ID handy. Currently we use low bits of high freq tick
- // as a unique random number (which is not bad, but loses randomness for startup scenarios).
- int uniqNum = (int)Stopwatch.GetTimestamp();
- string uniqPrefix = $"//{uniqNum:x}_";
- Interlocked.CompareExchange(ref s_uniqPrefix, uniqPrefix, null);
- }
-#if DEBUG
- ret = s_uniqPrefix + OperationName + "_" + Interlocked.Increment(ref s_currentRootId);
-#else // To keep things short, we drop the operation name
- ret = s_uniqPrefix + Interlocked.Increment(ref s_currentRootId);
-#endif
+ byte[] bytes = new byte[8];
+ s_random.Value.NextBytes(bytes);
+ ret = $"{BitConverter.ToUInt64(bytes, 0)}";
}
// Useful place to place a conditional breakpoint.
return ret;
@@ -290,8 +286,7 @@ namespace System.Diagnostics
// Used to generate an ID
long _currentChildId; // A unique number for all children of this activity.
static long s_currentRootId; // A unique number inside the appdomain.
- static string s_uniqPrefix; // A unique prefix that represents the machine/process/appdomain
-
+ private static readonly Lazy<Random> s_random = new Lazy<Random>();
/// <summary>
/// Having our own key-value linked list allows us to be more efficient
/// </summary>
diff --git a/src/System.Diagnostics.DiagnosticSource/tests/ActivityTests.cs b/src/System.Diagnostics.DiagnosticSource/tests/ActivityTests.cs
index ae740cee97..0f6a2c95a1 100644
--- a/src/System.Diagnostics.DiagnosticSource/tests/ActivityTests.cs
+++ b/src/System.Diagnostics.DiagnosticSource/tests/ActivityTests.cs
@@ -1,5 +1,6 @@
using System.Collections.Generic;
using System.Linq;
+using System.Threading.Tasks;
using Xunit;
namespace System.Diagnostics.Tests
@@ -53,10 +54,25 @@ namespace System.Diagnostics.Tests
Assert.Equal(1, tags.Count);
Assert.Equal(tags[0].Key, "some tag");
Assert.Equal(tags[0].Value, "value");
+ }
+
+ /// <summary>
+ /// Tests activity SetParentId
+ /// </summary>
+ [Fact]
+ public void SetParentId()
+ {
+ var parent = new Activity("parent");
+ Assert.Throws<ArgumentException>(() => parent.SetParentId(null));
+ Assert.Throws<ArgumentException>(() => parent.SetParentId(""));
+ parent.SetParentId("1");
+ Assert.Equal("1", parent.ParentId);
+ Assert.Throws<InvalidOperationException>(() => parent.SetParentId("2"));
- Assert.Equal(activity, activity.SetParentId("1"));
- Assert.Equal(2, activity.Tags.ToList().Count);
- Assert.Equal("1", activity.ParentId);
+ parent.Start();
+ var child = new Activity("child");
+ child.Start();
+ Assert.Throws<InvalidOperationException>(() => child.SetParentId("3"));
}
/// <summary>
@@ -79,18 +95,60 @@ namespace System.Diagnostics.Tests
}
/// <summary>
+ /// Tests Id generation
+ /// </summary>
+ [Fact]
+ public void IdGenerationInternalParent()
+ {
+ var parent = new Activity("parent");
+ parent.Start();
+ var child1 = new Activity("child1");
+ var child2 = new Activity("child2");
+ //start 2 children in different execution contexts
+ var t1 = Task.Run(() => child1.Start());
+ var t2 = Task.Run(() => child2.Start());
+ Task.WhenAll(t1, t2).Wait();
+ Assert.Equal(parent.Id + ".1", child1.Id);
+ Assert.Equal(parent.Id + ".2", child2.Id);
+ child1.Stop();
+ child2.Stop();
+ var child3 = new Activity("child3");
+ child3.Start();
+ Assert.Equal(parent.Id + ".3", child3.Id);
+ }
+
+ /// <summary>
+ /// Tests Id generation
+ /// </summary>
+ [Fact]
+ public void IdGenerationExternalParentId()
+ {
+ var child1 = new Activity("child1");
+ child1.SetParentId("123");
+ child1.Start();
+ child1.Stop();
+ var child2 = new Activity("child2");
+ child2.SetParentId("123");
+ child2.Start();
+ Assert.NotEqual(child2.Id, child1.Id);
+ }
+
+ /// <summary>
/// Tests Activity Start and Stop with timestamp
/// </summary>
[Fact]
public void StartStopWithTimestamp()
{
+ var activity = new Activity("activity");
+ Assert.Throws<InvalidOperationException>(() => activity.SetStartTime(DateTime.Now));
+
var startTime = DateTime.UtcNow.AddSeconds(-1);
- var activity = new Activity("activity")
- .SetStartTime(startTime);
+ activity.SetStartTime(startTime);
activity.Start();
Assert.Equal(startTime, activity.StartTimeUtc);
+ Assert.Throws<InvalidOperationException>(() => activity.SetEndTime(DateTime.Now));
var stopTime = DateTime.UtcNow;
activity.SetEndTime(stopTime);
Assert.Equal(stopTime - startTime, activity.Duration);
@@ -129,6 +187,7 @@ namespace System.Diagnostics.Tests
.AddTag("tag1", "tag from parent");
parent.Start();
+
Assert.Equal(parent, Activity.Current);
var child = new Activity("child");
@@ -141,8 +200,7 @@ namespace System.Diagnostics.Tests
//no tags from parent
var childTags = child.Tags.ToList();
- Assert.Equal(1, childTags.Count);
- Assert.Equal(child.ParentId, childTags[0].Value);
+ Assert.Equal(0, childTags.Count);
child.Stop();
Assert.Equal(parent, Activity.Current);
@@ -172,7 +230,7 @@ namespace System.Diagnostics.Tests
[Fact]
public void StartTwice()
{
- var activity = new Activity("");
+ var activity = new Activity("activity");
activity.Start();
Assert.Throws<InvalidOperationException>(() => activity.Start());
}
@@ -183,7 +241,7 @@ namespace System.Diagnostics.Tests
[Fact]
public void StopNotStarted()
{
- Assert.Throws<InvalidOperationException>(() => new Activity("").Stop());
+ Assert.Throws<InvalidOperationException>(() => new Activity("activity").Stop());
}
/// <summary>
diff --git a/src/System.Diagnostics.DiagnosticSource/tests/Configurations.props b/src/System.Diagnostics.DiagnosticSource/tests/Configurations.props
index c6602850c6..e239022946 100644
--- a/src/System.Diagnostics.DiagnosticSource/tests/Configurations.props
+++ b/src/System.Diagnostics.DiagnosticSource/tests/Configurations.props
@@ -5,6 +5,7 @@
net45-Windows_NT;
netstandard;
netstandard1.1;
+ netstandard1.3;
</BuildConfigurations>
</PropertyGroup>
</Project> \ No newline at end of file