Commit 83c1f584 authored by Liuhaoyang's avatar Liuhaoyang

Init TracingContext

parent 3fc84f15
...@@ -27,16 +27,34 @@ namespace SkyWalking.Context.Trace ...@@ -27,16 +27,34 @@ namespace SkyWalking.Context.Trace
{ {
public class ExitSpan : StackBasedTracingSpan, IWithPeerInfo public class ExitSpan : StackBasedTracingSpan, IWithPeerInfo
{ {
private string _peer; private readonly string _peer;
private int _peerId; private readonly int _peerId;
protected ExitSpan(int spanId, int parentSpanId, string operationName,string peer) : base(spanId, parentSpanId, operationName) public ExitSpan(int spanId, int parentSpanId, String operationName, String peer)
: base(spanId, parentSpanId, operationName)
{ {
_peer = peer; _peer = peer;
_peerId = DictionaryUtil.NullValue;
} }
protected ExitSpan(int spanId, int parentSpanId, int operationId,int peerId) : base(spanId, parentSpanId, operationId) public ExitSpan(int spanId, int parentSpanId, int operationId, int peerId)
: base(spanId, parentSpanId, operationId)
{ {
_peer = null;
_peerId = peerId;
}
public ExitSpan(int spanId, int parentSpanId, int operationId, String peer)
: base(spanId, parentSpanId, operationId)
{
_peer = peer;
_peerId = DictionaryUtil.NullValue;
}
public ExitSpan(int spanId, int parentSpanId, String operationName, int peerId)
: base(spanId, parentSpanId, operationName)
{
_peer = null;
_peerId = peerId; _peerId = peerId;
} }
...@@ -54,6 +72,7 @@ namespace SkyWalking.Context.Trace ...@@ -54,6 +72,7 @@ namespace SkyWalking.Context.Trace
{ {
base.Start(); base.Start();
} }
return base.Start(); return base.Start();
} }
...@@ -63,6 +82,7 @@ namespace SkyWalking.Context.Trace ...@@ -63,6 +82,7 @@ namespace SkyWalking.Context.Trace
{ {
base.Tag(key, value); base.Tag(key, value);
} }
return this; return this;
} }
...@@ -72,6 +92,7 @@ namespace SkyWalking.Context.Trace ...@@ -72,6 +92,7 @@ namespace SkyWalking.Context.Trace
{ {
return base.SetLayer(layer); return base.SetLayer(layer);
} }
return this; return this;
} }
...@@ -81,6 +102,7 @@ namespace SkyWalking.Context.Trace ...@@ -81,6 +102,7 @@ namespace SkyWalking.Context.Trace
{ {
return base.SetComponent(component); return base.SetComponent(component);
} }
return this; return this;
} }
...@@ -90,15 +112,13 @@ namespace SkyWalking.Context.Trace ...@@ -90,15 +112,13 @@ namespace SkyWalking.Context.Trace
{ {
return base.SetComponent(componentName); return base.SetComponent(componentName);
} }
return this; return this;
} }
public override string OperationName public override string OperationName
{ {
get get { return base.OperationName; }
{
return base.OperationName;
}
set set
{ {
if (_stackDepth == 1) if (_stackDepth == 1)
...@@ -110,10 +130,7 @@ namespace SkyWalking.Context.Trace ...@@ -110,10 +130,7 @@ namespace SkyWalking.Context.Trace
public override int OperationId public override int OperationId
{ {
get get { return base.OperationId; }
{
return base.OperationId;
}
set set
{ {
if (_stackDepth == 1) if (_stackDepth == 1)
...@@ -125,7 +142,7 @@ namespace SkyWalking.Context.Trace ...@@ -125,7 +142,7 @@ namespace SkyWalking.Context.Trace
public override SpanObject Transform() public override SpanObject Transform()
{ {
var spanObject= base.Transform(); var spanObject = base.Transform();
if (_peerId != DictionaryUtil.NullValue) if (_peerId != DictionaryUtil.NullValue)
{ {
......
...@@ -21,11 +21,11 @@ namespace SkyWalking.Context.Trace ...@@ -21,11 +21,11 @@ namespace SkyWalking.Context.Trace
{ {
public class LocalSpan : StackBasedTracingSpan public class LocalSpan : StackBasedTracingSpan
{ {
protected LocalSpan(int spanId, int parentSpanId, string operationName) : base(spanId, parentSpanId, operationName) public LocalSpan(int spanId, int parentSpanId, string operationName) : base(spanId, parentSpanId, operationName)
{ {
} }
protected LocalSpan(int spanId, int parentSpanId, int operationId) : base(spanId, parentSpanId, operationId) public LocalSpan(int spanId, int parentSpanId, int operationId) : base(spanId, parentSpanId, operationId)
{ {
} }
......
...@@ -16,19 +16,26 @@ ...@@ -16,19 +16,26 @@
* *
*/ */
using System;
using System.Collections; using System.Collections;
using System.Collections.Generic; using System.Collections.Generic;
using System.Linq;
using System.Linq.Expressions;
using System.Runtime.InteropServices;
using SkyWalking.Context.Trace; using SkyWalking.Context.Trace;
using SkyWalking.Dictionary;
using SkyWalking.Dictionarys;
using SkyWalking.Sampling; using SkyWalking.Sampling;
using SkyWalking.Utils;
namespace SkyWalking.Context namespace SkyWalking.Context
{ {
public class TracingContext: ITracerContext public class TracingContext : ITracerContext
{ {
private long _lastWarningTimestamp = 0; private long _lastWarningTimestamp = 0;
private ISampler _sampler; private readonly ISampler _sampler;
private ITraceSegment _segment; private readonly ITraceSegment _segment;
private Stack<ISpan> _activeSpanStacks; private readonly Stack<ISpan> _activeSpanStacks;
private int _spanIdGenerator; private int _spanIdGenerator;
public TracingContext() public TracingContext()
...@@ -38,48 +45,343 @@ namespace SkyWalking.Context ...@@ -38,48 +45,343 @@ namespace SkyWalking.Context
_activeSpanStacks = new Stack<ISpan>(); _activeSpanStacks = new Stack<ISpan>();
} }
/// <summary>
/// Inject the context into the given carrier, only when the active span is an exit one.
/// </summary>
public void Inject(IContextCarrier carrier) public void Inject(IContextCarrier carrier)
{ {
throw new System.NotImplementedException(); var span = InternalActiveSpan();
if (!span.IsExit)
{
throw new InvalidOperationException("Inject can be done only in Exit Span");
}
var spanWithPeer = span as IWithPeerInfo;
var peer = spanWithPeer.Peer;
var peerId = spanWithPeer.PeerId;
carrier.TraceSegmentId = _segment.TraceSegmentId;
carrier.SpanId = span.SpanId;
carrier.ParentApplicationInstanceId = _segment.ApplicationInstanceId;
if (DictionaryUtil.IsNull(peerId))
{
carrier.PeerHost = peer;
}
else
{
carrier.PeerId = peerId;
}
var refs = _segment.Refs;
var firstSpan = _activeSpanStacks.First();
var metaValue = GetMetaValue(refs);
carrier.EntryApplicationInstanceId = metaValue.entryApplicationInstanceId;
if (DictionaryUtil.IsNull(metaValue.operationId))
{
carrier.EntryOperationName = metaValue.operationName;
}
else
{
carrier.EntryOperationId = metaValue.operationId;
} }
var parentOperationId = firstSpan.OperationId;
if (DictionaryUtil.IsNull(parentOperationId))
{
carrier.ParentOperationName = firstSpan.OperationName;
}
else
{
carrier.ParentOperationId = parentOperationId;
}
carrier.SetDistributedTraceIds(_segment.RelatedGlobalTraces);
}
/// <summary>
/// Extract the carrier to build the reference for the pre segment.
/// </summary>
public void Extract(IContextCarrier carrier) public void Extract(IContextCarrier carrier)
{ {
throw new System.NotImplementedException(); var traceSegmentRef = new TraceSegmentRef(carrier);
_segment.Ref(traceSegmentRef);
_segment.RelatedGlobalTrace(carrier.DistributedTraceId);
var span = InternalActiveSpan();
if (span is EntrySpan)
{
span.Ref(traceSegmentRef);
}
} }
public IContextSnapshot Capture { get; } /// <summary>
/// Capture the snapshot of current context.
/// </summary>
public IContextSnapshot Capture => InternalCapture();
public ISpan ActiveSpan { get; } public ISpan ActiveSpan => InternalActiveSpan();
public void Continued(IContextSnapshot snapshot) public void Continued(IContextSnapshot snapshot)
{ {
throw new System.NotImplementedException(); var segmentRef = new TraceSegmentRef(snapshot);
_segment.Ref(segmentRef);
ActiveSpan.Ref(segmentRef);
_segment.RelatedGlobalTrace(snapshot.DistributedTraceId);
} }
public string GetReadableGlobalTraceId() public string GetReadableGlobalTraceId()
{ {
throw new System.NotImplementedException(); return _segment.RelatedGlobalTraces.First()?.ToString();
} }
/// <summary>
/// Create an entry span
/// </summary>
public ISpan CreateEntrySpan(string operationName) public ISpan CreateEntrySpan(string operationName)
{ {
throw new System.NotImplementedException(); if (!EnsureLimitMechanismWorking(out var noopSpan))
{
return noopSpan;
} }
_activeSpanStacks.TryPeek(out var parentSpan);
var parentSpanId = parentSpan?.SpanId ?? -1;
if (parentSpan != null && parentSpan.IsEntry)
{
var entrySpan = (ISpan) DictionaryManager.OperationName.FindOnly(_segment.ApplicationId, operationName)
.InCondition(id =>
{
parentSpan.OperationId = id;
return parentSpan;
}, () =>
{
parentSpan.OperationName = operationName;
return parentSpan;
});
return entrySpan.Start();
}
else
{
var entrySpan = (ISpan) DictionaryManager.OperationName.FindOnly(_segment.ApplicationId, operationName)
.InCondition(id => new EntrySpan(_spanIdGenerator++, parentSpanId, id),
() => new EntrySpan(_spanIdGenerator++, parentSpanId, operationName));
entrySpan.Start();
_activeSpanStacks.Push(entrySpan);
return entrySpan;
}
}
/// <summary>
/// Create a local span
/// </summary>
public ISpan CreateLocalSpan(string operationName) public ISpan CreateLocalSpan(string operationName)
{ {
throw new System.NotImplementedException(); if (!EnsureLimitMechanismWorking(out var noopSpan))
{
return noopSpan;
}
_activeSpanStacks.TryPeek(out var parentSpan);
var parentSpanId = parentSpan?.SpanId ?? -1;
var span = (ISpan) DictionaryManager.OperationName
.FindOrPrepareForRegister(_segment.ApplicationId, operationName, false, false)
.InCondition(id => new LocalSpan(_spanIdGenerator++, parentSpanId, operationName),
() => new LocalSpan(_spanIdGenerator++, parentSpanId, operationName));
span.Start();
_activeSpanStacks.Push(span);
return span;
} }
/// <summary>
/// Create an exit span
/// </summary>
public ISpan CreateExitSpan(string operationName, string remotePeer) public ISpan CreateExitSpan(string operationName, string remotePeer)
{ {
throw new System.NotImplementedException(); _activeSpanStacks.TryPeek(out var parentSpan);
if (parentSpan != null && parentSpan.IsExit)
{
return parentSpan.Start();
}
else
{
var parentSpanId = parentSpan?.SpanId ?? -1;
var exitSpan = (ISpan) DictionaryManager.NetworkAddress.Find(remotePeer)
.InCondition(peerId =>
{
if (IsLimitMechanismWorking())
{
return new NoopExitSpan(peerId);
} }
return DictionaryManager.OperationName.FindOnly(_segment.ApplicationId, operationName)
.InCondition(id => new ExitSpan(_spanIdGenerator++, parentSpanId, id, peerId),
() => new ExitSpan(_spanIdGenerator++, parentSpanId, operationName, peerId));
},
() =>
{
if (IsLimitMechanismWorking())
{
return new NoopExitSpan(remotePeer);
}
return DictionaryManager.OperationName.FindOnly(_segment.ApplicationId, operationName)
.InCondition(id => new ExitSpan(_spanIdGenerator++, parentSpanId, id, remotePeer),
() => new ExitSpan(_spanIdGenerator++, parentSpanId, operationName,
remotePeer));
});
_activeSpanStacks.Push(exitSpan);
return exitSpan.Start();
}
}
/// <summary>
/// Stop the given span, if and only if this one is the top element of {@link #activeSpanStack}. Because the tracing
/// core must make sure the span must match in a stack module, like any program did.
/// </summary>
public void StopSpan(ISpan span) public void StopSpan(ISpan span)
{ {
throw new System.NotImplementedException(); _activeSpanStacks.TryPeek(out var lastSpan);
if (lastSpan == span)
{
if (lastSpan is AbstractTracingSpan tracingSpan)
{
if (tracingSpan.Finish(_segment))
{
_activeSpanStacks.Pop();
}
}
else
{
_activeSpanStacks.Pop();
}
}
else
{
throw new InvalidOperationException("Stopping the unexpected span = " + span);
}
if (_activeSpanStacks.Count == 0)
{
Finish();
}
}
private void Finish()
{
var finishedSegment = _segment.Finish(IsLimitMechanismWorking());
if (!_segment.HasRef && _segment.IsSingleSpanSegment)
{
if (!_sampler.TrySampling())
{
finishedSegment.IsIgnore = true;
}
}
ListenerManager.NotifyFinish(finishedSegment);
}
private ISpan InternalActiveSpan()
{
if (!_activeSpanStacks.TryPeek(out var span))
{
throw new InvalidOperationException("No active span.");
}
return span;
}
private IContextSnapshot InternalCapture()
{
var refs = _segment.Refs;
var snapshot =
new ContextSnapshot(_segment.TraceSegmentId, ActiveSpan.SpanId, _segment.RelatedGlobalTraces);
var metaValue = GetMetaValue(refs);
snapshot.EntryApplicationInstanceId = metaValue.entryApplicationInstanceId;
if (DictionaryUtil.IsNull(metaValue.operationId))
{
snapshot.EntryOperationName = metaValue.operationName;
}
else
{
snapshot.EntryOperationId = metaValue.operationId;
}
var parentSpan = _activeSpanStacks.First();
if (DictionaryUtil.IsNull(parentSpan.OperationId))
{
snapshot.ParentOperationName = parentSpan.OperationName;
}
else
{
snapshot.ParentOperationId = parentSpan.OperationId;
}
return snapshot;
}
private (string operationName, int operationId, int entryApplicationInstanceId) GetMetaValue(
IEnumerable<ITraceSegmentRef> refs)
{
if (refs != null && refs.Any())
{
var segmentRef = refs.First();
return (segmentRef.EntryOperationName, segmentRef.EntryOperationId,
segmentRef.EntryApplicationInstanceId);
}
else
{
var span = _activeSpanStacks.First();
return (span.OperationName, span.OperationId, _segment.ApplicationInstanceId);
}
}
private bool IsLimitMechanismWorking()
{
if (_spanIdGenerator < Config.AgentConfig.SpanLimitPerSegment)
{
return false;
}
var currentTimeMillis = DateTime.UtcNow.GetTimeMillis();
if (currentTimeMillis - _lastWarningTimestamp > 30 * 1000)
{
//todo log warning
_lastWarningTimestamp = currentTimeMillis;
}
return true;
}
private bool EnsureLimitMechanismWorking(out ISpan noopSpan)
{
if (IsLimitMechanismWorking())
{
var span = new NoopSpan();
_activeSpanStacks.Push(span);
noopSpan = span;
return false;
}
noopSpan = null;
return true;
} }
} }
} }
\ No newline at end of file
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment