Unverified Commit 2f240672 authored by Lemon's avatar Lemon Committed by GitHub

Refactor tracing context (#139)

* Delete `ISkyWalkingClient` interface

* Use segment protocol V2

* Forget the old api. All context apis will be overwritten.

* Add segments define

* Add some apis

* Add carrierParser

* Add SegmentContextAccessor API

* Add SampledDelegate interface

* Add thread-safe  SamplerChainBuilder

* Add SegmentContextFactory

* Add ITracingContext Interface

* Refactoring the core API for tracing context

* remove utils package

* Resolve issue #57 : Provide percentage-based sampling

* Refactor HttpClient Tracing

* Fix header carrier

* Add async exitSpan sample

* Add Task.WhenAll sample

* Refactor EntityFrameworkCore tracing

* Refactor SqlClient & CAP Tracing

* Refactor Asp.Net tracing

* Remove outdated APIs
parent 91ab544c
{ {
"SkyWalking": { "SkyWalking": {
"ApplicationCode": "SkyWalking.Sample.AspNet", "ServiceName": "aspnet-sample",
"SpanLimitPerSegment": 300,
"Sampling": {
"SamplePer3Secs": -1
},
"Logging": { "Logging": {
"Level": "Information", "Level": "Debug",
"FilePath": "logs\\SkyWalking-{Date}.log" "FilePath": "/tmp/logs/SkyWalking-{Date}.log"
}, },
"Transport": { "Transport": {
"Interval": 3000, "Interval": 3000,
"PendingSegmentLimit": 30000,
"PendingSegmentTimeout": 1000,
"gRPC": { "gRPC": {
"Servers": "localhost:11800", "Servers": "localhost:11800",
"Timeout": 2000, "Timeout": 10000,
"ConnectTimeout": 10000 "ConnectTimeout": 10000
} }
} }
......
using System.Threading.Tasks;
using Microsoft.AspNetCore.Mvc;
namespace SkyWalking.Sample.Backend.Controllers
{
[Route("api/[controller]")]
public class DelayController : Controller
{
// GET
[HttpGet("{delay}")]
public async Task<string> Get(int delay)
{
await Task.Delay(delay);
return $"delay {delay}ms";
}
}
}
\ No newline at end of file
using SkyWalking.Tracing;
namespace SkyWalking.Sample.Backend.Sampling
{
public class CustomSamplingInterceptor : ISamplingInterceptor
{
public int Priority { get; } = 0;
public bool Invoke(SamplingContext samplingContext, Sampler next)
{
return next(samplingContext);
}
}
}
\ No newline at end of file
...@@ -5,6 +5,8 @@ using Microsoft.EntityFrameworkCore; ...@@ -5,6 +5,8 @@ using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.Configuration; using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.DependencyInjection;
using SkyWalking.Sample.Backend.Models; using SkyWalking.Sample.Backend.Models;
using SkyWalking.Sample.Backend.Sampling;
using SkyWalking.Tracing;
namespace SkyWalking.Sample.Backend namespace SkyWalking.Sample.Backend
{ {
...@@ -26,6 +28,8 @@ namespace SkyWalking.Sample.Backend ...@@ -26,6 +28,8 @@ namespace SkyWalking.Sample.Backend
sqliteConnection.Open(); sqliteConnection.Open();
services.AddEntityFrameworkSqlite().AddDbContext<SampleDbContext>(c => c.UseSqlite(sqliteConnection)); services.AddEntityFrameworkSqlite().AddDbContext<SampleDbContext>(c => c.UseSqlite(sqliteConnection));
services.AddSingleton<ISamplingInterceptor, CustomSamplingInterceptor>();
} }
// This method gets called by the runtime. Use this method to configure the HTTP request pipeline. // This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
......
...@@ -9,11 +9,21 @@ namespace SkyWalking.Sample.Frontend.Controllers ...@@ -9,11 +9,21 @@ namespace SkyWalking.Sample.Frontend.Controllers
public class ValuesController : Controller public class ValuesController : Controller
{ {
// GET api/values // GET api/values
[HttpGet("/values")] [HttpGet]
public async Task<IEnumerable<string>> Get() public async Task<IEnumerable<string>> Get()
{ {
await new HttpClient().GetAsync("http://localhost:5002/api/values"); await new HttpClient().GetAsync("http://localhost:5002/api/values");
return new string[] { "value1", "value2" }; return new string[] {"value1", "value2"};
} }
[HttpGet("{id}")]
public async Task<string> Get(int id)
{
var client = new HttpClient();
Task.WhenAll(client.GetAsync("http://localhost:5002/api/delay/2000"),
client.GetAsync("http://localhost:5002/api/values"),
client.GetAsync("http://localhost:5002/api/delay/200"));
return await client.GetStringAsync("http://localhost:5002/api/delay/100");
}
} }
} }
\ No newline at end of file
...@@ -13,7 +13,7 @@ ...@@ -13,7 +13,7 @@
} }
}, },
"SkyWalking": { "SkyWalking": {
"ApplicationCode": "asp-net-core-frontend" "ServiceName": "asp-net-core-frontend"
} }
} }
/* /*
* Licensed to the OpenSkywalking under one or more * Licensed to the OpenSkywalking under one or more
* contributor license agreements. See the NOTICE file distributed with * contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership. * this work for additional information regarding copyright ownership.
...@@ -16,44 +16,26 @@ ...@@ -16,44 +16,26 @@
* *
*/ */
using System.Collections.Generic; namespace SkyWalking.Common
using SkyWalking.Context.Ids;
namespace SkyWalking.Context
{ {
public interface IContextCarrier public static class Components
{ {
public static readonly StringOrIntValue ASPNETCORE= new StringOrIntValue("AspNetCore");
DistributedTraceId DistributedTraceId { get; } public static readonly StringOrIntValue HTTPCLIENT = new StringOrIntValue("HttpClient");
int EntryApplicationInstanceId { get; set; }
string EntryOperationName { get; set; }
int EntryOperationId { get; set; } public static readonly StringOrIntValue ENTITYFRAMEWORKCORE = new StringOrIntValue("EntityFrameworkCore");
int ParentApplicationInstanceId { get; set; }
string ParentOperationName { get; set; }
int ParentOperationId { get; set; } public static readonly StringOrIntValue SQLCLIENT = new StringOrIntValue("SqlClient");
string PeerHost { get; set; }
int PeerId { get; set; } public static readonly StringOrIntValue CAP = new StringOrIntValue("CAP");
int SpanId { get; set; } public static readonly StringOrIntValue ENTITYFRAMEWORKCORE_SQLITE = new StringOrIntValue("EntityFrameworkCore.Sqlite");
ID TraceSegmentId { get; set; } public static readonly StringOrIntValue POMELO_ENTITYFRAMEWORKCORE_MYSQL = new StringOrIntValue("Pomelo.EntityFrameworkCore.MySql");
bool IsValid { get; } public static readonly StringOrIntValue NPGSQL_ENTITYFRAMEWORKCORE_POSTGRESQL = new StringOrIntValue("Npgsql.EntityFrameworkCore.PostgreSQL");
IContextCarrier Deserialize(string text); public static readonly StringOrIntValue ASPNET = new StringOrIntValue("AspNet");
string Serialize();
CarrierItem Items { get; }
void SetDistributedTraceIds(IEnumerable<DistributedTraceId> distributedTraceIds);
} }
} }
\ No newline at end of file
...@@ -16,7 +16,7 @@ ...@@ -16,7 +16,7 @@
* *
*/ */
namespace SkyWalking namespace SkyWalking.Common
{ {
public struct NullableValue public struct NullableValue
{ {
......
...@@ -16,7 +16,7 @@ ...@@ -16,7 +16,7 @@
* *
*/ */
namespace SkyWalking namespace SkyWalking.Common
{ {
public struct StringOrIntValue public struct StringOrIntValue
{ {
...@@ -29,6 +29,8 @@ namespace SkyWalking ...@@ -29,6 +29,8 @@ namespace SkyWalking
_stringValue = null; _stringValue = null;
} }
public bool HasValue => HasIntValue || HasStringValue;
public bool HasIntValue => _intValue != 0; public bool HasIntValue => _intValue != 0;
public bool HasStringValue => _stringValue != null; public bool HasStringValue => _stringValue != null;
...@@ -53,5 +55,11 @@ namespace SkyWalking ...@@ -53,5 +55,11 @@ namespace SkyWalking
{ {
return (_stringValue, _intValue); return (_stringValue, _intValue);
} }
public override string ToString()
{
if (HasIntValue) return _intValue.ToString();
return _stringValue;
}
} }
} }
\ No newline at end of file
/* /*
* Licensed to the OpenSkywalking under one or more * Licensed to the OpenSkywalking under one or more
* contributor license agreements. See the NOTICE file distributed with * contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership. * this work for additional information regarding copyright ownership.
...@@ -16,30 +16,27 @@ ...@@ -16,30 +16,27 @@
* *
*/ */
using SkyWalking.Context.Ids; namespace SkyWalking.Common
namespace SkyWalking.Context
{ {
public interface IContextSnapshot public static class Tags
{ {
string EntryOperationName { get; set; } public static readonly string URL = "url";
string ParentOperationName { get; set; } public static readonly string PATH = "path";
DistributedTraceId DistributedTraceId { get; }
int EntryApplicationInstanceId { get; set; }
int SpanId { get; }
bool IsFromCurrent { get; } public static readonly string HTTP_METHOD = "http.method";
bool IsValid { get; } public static readonly string STATUS_CODE = "status_code";
ID TraceSegmentId { get; } public static readonly string DB_TYPE = "db.type";
int EntryOperationId { set; } public static readonly string DB_INSTANCE = "db.instance";
public static readonly string DB_STATEMENT = "db.statement";
int ParentOperationId { set; } public static readonly string DB_BIND_VARIABLES = "db.bind_vars";
public static readonly string MQ_TOPIC = "mq.topic";
} }
} }
\ No newline at end of file
/*
* Licensed to the OpenSkywalking under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The OpenSkywalking licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
*/
using System.Collections.Generic;
namespace SkyWalking.Components
{
public class ComponentsDefine
{
public static readonly IComponent HttpClient = new OfficialComponent(2, "HttpClient");
public static readonly IComponent AspNetCore = new OfficialComponent(3001, "AspNetCore");
public static readonly IComponent EntityFrameworkCore = new OfficialComponent(3002, "EntityFrameworkCore");
public static readonly IComponent SqlClient = new OfficialComponent(3003, "SqlClient");
public static readonly IComponent CAP = new OfficialComponent(3004, "CAP");
public static readonly IComponent StackExchange_Redis = new OfficialComponent(3005, "StackExchange.Redis");
public static readonly IComponent SqlServer = new OfficialComponent(3006, "SqlServer");
public static readonly IComponent Npgsql = new OfficialComponent(3007, "Npgsql");
public static readonly IComponent MySqlConnector = new OfficialComponent(3008, "MySqlConnector");
public static readonly IComponent EntityFrameworkCore_InMemory = new OfficialComponent(3009, "EntityFrameworkCore.InMemory");
public static readonly IComponent EntityFrameworkCore_SqlServer = new OfficialComponent(3010, "EntityFrameworkCore.SqlServer");
public static readonly IComponent EntityFrameworkCore_Sqlite = new OfficialComponent(3011, "EntityFrameworkCore.Sqlite");
public static readonly IComponent Pomelo_EntityFrameworkCore_MySql = new OfficialComponent(3012, "Pomelo.EntityFrameworkCore.MySql");
public static readonly IComponent Npgsql_EntityFrameworkCore_PostgreSQL = new OfficialComponent(3013, "Npgsql.EntityFrameworkCore.PostgreSQL");
public static readonly IComponent InMemoryDatabase = new OfficialComponent(3014, "InMemoryDatabase");
public static readonly IComponent AspNet = new OfficialComponent(3015, "AspNet");
public static readonly IComponent MySqlData = new OfficialComponent(3016, "MySql.Data");
}
}
...@@ -21,7 +21,7 @@ using System; ...@@ -21,7 +21,7 @@ using System;
namespace SkyWalking.Config namespace SkyWalking.Config
{ {
[Config("SkyWalking")] [Config("SkyWalking")]
public class InstrumentationConfig public class InstrumentConfig
{ {
public string Namespace { get; set; } public string Namespace { get; set; }
...@@ -29,7 +29,14 @@ namespace SkyWalking.Config ...@@ -29,7 +29,14 @@ namespace SkyWalking.Config
public string ApplicationCode { get; set; } public string ApplicationCode { get; set; }
public string ServiceName { get; set; } public string ServiceName { get; set; }
public string[] HeaderVersions { get; set; }
}
public int SpanLimitPerSegment { get; set; } = 300; public static class HeaderVersions
{
public static string SW3 { get; } = "sw3";
public static string SW6 { get; } = "sw6";
} }
} }
\ No newline at end of file
...@@ -22,5 +22,7 @@ namespace SkyWalking.Config ...@@ -22,5 +22,7 @@ namespace SkyWalking.Config
public class SamplingConfig public class SamplingConfig
{ {
public int SamplePer3Secs { get; set; } = -1; public int SamplePer3Secs { get; set; } = -1;
public double Percentage { get; set; } = -1d;
} }
} }
\ No newline at end of file
...@@ -21,7 +21,7 @@ namespace SkyWalking.Config ...@@ -21,7 +21,7 @@ namespace SkyWalking.Config
[Config("SkyWalking", "Transport")] [Config("SkyWalking", "Transport")]
public class TransportConfig public class TransportConfig
{ {
public int PendingSegmentLimit { get; set; } = 30000; public int QueueSize { get; set; } = 30000;
/// <summary> /// <summary>
/// Flush Interval Millisecond /// Flush Interval Millisecond
...@@ -31,7 +31,7 @@ namespace SkyWalking.Config ...@@ -31,7 +31,7 @@ namespace SkyWalking.Config
/// <summary> /// <summary>
/// Data queued beyond this time will be discarded. /// Data queued beyond this time will be discarded.
/// </summary> /// </summary>
public int PendingSegmentTimeout { get; set; } = 1000; public int BatchSize { get; set; } = 3000;
public string ProtocolVersion { get; set; } = ProtocolVersions.V6; public string ProtocolVersion { get; set; } = ProtocolVersions.V6;
} }
......
/*
* Licensed to the OpenSkywalking under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The OpenSkywalking licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
*/
using System;
namespace SkyWalking.Context
{
public interface IInjectable
{
IContextCarrier GetCarrier();
/// <summary>
/// @return peer, represent ipv4, ipv6, hostname, or cluster addresses list.
/// </summary>
/// <returns></returns>
String GetPeer();
}
}
/*
* Licensed to the OpenSkywalking under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The OpenSkywalking licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
*/
using System;
using SkyWalking.Transport;
namespace SkyWalking.Context.Ids
{
/// <inheritdoc />
/// <summary>
/// The <code>DistributedTraceId</code> presents a distributed call chain.
/// This call chain has an unique (service) entrance,
/// such as: Service : http://www.skywalking.com/cust/query, all the remote, called behind this service, rest remote,
/// db executions, are using the same <code>DistributedTraceId</code> even in different CLR process.
/// The <code>DistributedTraceId</code> contains only one string, and can NOT be reset, creating a new instance is the only option.
/// </summary>
public abstract class DistributedTraceId : IEquatable<DistributedTraceId>
{
private readonly ID _id;
protected DistributedTraceId(ID id)
{
_id = id;
}
protected DistributedTraceId(string id)
{
_id = new ID(id);
}
public string Encode => _id?.Encode;
public UniqueIdRequest ToUniqueId() => _id?.Transform();
public bool Equals(DistributedTraceId other)
{
if (other == null)
return false;
return _id?.Equals(other._id) ?? other._id == null;
}
public override bool Equals(object obj)
{
var id = obj as DistributedTraceId;
return Equals(id);
}
public override int GetHashCode() => _id != null ? _id.GetHashCode() : 0;
public override string ToString() => _id?.ToString();
}
}
/*
* Licensed to the OpenSkywalking under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The OpenSkywalking licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
*/
using System;
using SkyWalking.Transport;
namespace SkyWalking.Context.Ids
{
public class ID : IEquatable<ID>
{
private readonly long _part1;
private readonly long _part2;
private readonly long _part3;
private string _encoding;
public bool IsValid { get; }
public string Encode => _encoding ?? (_encoding = ToString());
public ID(long part1, long part2, long part3)
{
_part1 = part1;
_part2 = part2;
_part3 = part3;
IsValid = true;
}
public ID(string encodingString)
{
if (encodingString == null)
{
throw new ArgumentNullException(nameof(encodingString));
}
string[] idParts = encodingString.Split("\\.".ToCharArray(), 3);
for (int part = 0; part < 3; part++)
{
if (part == 0)
{
IsValid = long.TryParse(idParts[part], out _part1);
}
else if (part == 1)
{
IsValid = long.TryParse(idParts[part], out _part2);
}
else
{
IsValid = long.TryParse(idParts[part], out _part3);
}
if (!IsValid)
{
break;
}
}
}
public override string ToString()
{
return $"{_part1}.{_part2}.{_part3}";
}
public override int GetHashCode()
{
var result = (int)(_part1 ^ (_part1 >> 32));
result = 31 * result + (int)(_part2 ^ (_part2 >> 32));
result = 31 * result + (int)(_part3 ^ (_part3 >> 32));
return result;
}
public override bool Equals(object obj)
{
var id = obj as ID;
return Equals(id);
}
public bool Equals(ID other)
{
if (other == null)
return false;
if (this == other)
return true;
if (_part1 != other._part1)
return false;
if (_part2 != other._part2)
return false;
return _part3 == other._part3;
}
public UniqueIdRequest Transform()
{
var uniqueId = new UniqueIdRequest {Part1 = _part1, Part2 = _part2, Part3 = _part3};
return uniqueId;
}
}
}
/*
* Licensed to the OpenSkywalking under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The OpenSkywalking licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
*/
using System;
using System.Collections.Generic;
using SkyWalking.Transport;
using SkyWalking.Components;
namespace SkyWalking.Context.Trace
{
/// <summary>
/// The <code>AbstractTracingSpan</code> represents a group of {@link ISpan} implementations, which belongs a real distributed trace.
/// </summary>
public abstract class AbstractTracingSpan : ISpan
{
protected readonly int _spanId;
protected readonly int _parnetSpanId;
protected Dictionary<string, string> _tags;
protected string _operationName;
protected int _operationId;
protected SpanLayer? _layer;
/// <summary>
/// The start time of this Span.
/// </summary>
protected long _startTime;
/// <summary>
/// The end time of this Span.
/// </summary>
protected long _endTime;
protected bool _errorOccurred = false;
protected int _componentId = 0;
protected string _componentName;
/// <summary>
/// Log is a concept from OpenTracing spec. <p> {@see https://github.com/opentracing/specification/blob/master/specification.md#log-structured-data}
/// </summary>
protected ICollection<LogDataEntity> _logs;
/// <summary>
/// The refs of parent trace segments, except the primary one. For most RPC call, {@link #refs} contains only one
/// element, but if this segment is a start span of batch process, the segment faces multi parents, at this moment,
/// we use this {@link #refs} to link them.
/// </summary>
protected ICollection<ITraceSegmentRef> _refs;
protected AbstractTracingSpan(int spanId, int parentSpanId, string operationName)
{
_operationName = operationName;
_spanId = spanId;
_parnetSpanId = parentSpanId;
}
protected AbstractTracingSpan(int spanId, int parentSpanId, int operationId)
{
_operationName = null;
_operationId = operationId;
_spanId = spanId;
_parnetSpanId = parentSpanId;
}
public abstract bool IsEntry { get; }
public abstract bool IsExit { get; }
public virtual int SpanId => _spanId;
public virtual string OperationName
{
get => _operationName;
set
{
_operationName = value;
_operationId = 0;
}
}
public virtual int OperationId
{
get => _operationId;
set
{
_operationId = value;
_operationName = null;
}
}
public virtual ISpan SetComponent(IComponent component)
{
_componentId = component.Id;
return this;
}
public virtual ISpan SetComponent(string componentName)
{
_componentName = componentName;
return this;
}
public virtual ISpan Tag(string key, string value)
{
if (_tags == null)
{
_tags = new Dictionary<string, string>();
}
_tags.Add(key, value);
return this;
}
public virtual ISpan SetLayer(SpanLayer layer)
{
_layer = layer;
return this;
}
/// <summary>
/// Record an exception event of the current walltime timestamp.
/// </summary>
public virtual ISpan Log(Exception exception)
{
EnsureLogs();
_logs.Add(new LogDataEntity.Builder()
.Add("event", "error")
.Add("error.kind", exception.GetType().FullName)
.Add("message", exception.Message)
.Add("stack", exception.StackTrace)
.Build(DateTimeOffset.UtcNow.ToUnixTimeMilliseconds()));
return this;
}
public virtual ISpan ErrorOccurred()
{
_errorOccurred = true;
return this;
}
public virtual ISpan Log(long timestamp, IDictionary<string, object> events)
{
EnsureLogs();
var builder = new LogDataEntity.Builder();
foreach (var @event in events)
{
builder.Add(@event.Key, @event.Value.ToString());
}
_logs.Add(builder.Build(timestamp));
return this;
}
public virtual ISpan Start()
{
_startTime = DateTimeOffset.UtcNow.ToUnixTimeMilliseconds();
return this;
}
public virtual ISpan Start(long timestamp)
{
_startTime = timestamp;
return this;
}
public virtual void Ref(ITraceSegmentRef traceSegmentRef)
{
if (_refs == null)
{
_refs = new List<ITraceSegmentRef>();
}
if (!_refs.Contains(traceSegmentRef))
{
_refs.Add(traceSegmentRef);
}
}
/// <summary>
/// Finish the active Span. When it is finished, it will be archived by the given {@link TraceSegment}, which owners it
/// </summary>
/// <param name="owner"></param>
/// <returns></returns>
public virtual bool Finish(ITraceSegment owner)
{
_endTime = DateTimeOffset.UtcNow.ToUnixTimeMilliseconds();
owner.Archive(this);
return true;
}
public virtual SpanRequest Transform()
{
var spanRequest = new SpanRequest
{
SpanId = _spanId,
ParentSpanId = _parnetSpanId,
StartTime = _startTime,
EndTime = _endTime,
OperationName = new StringOrIntValue(_operationId, _operationName),
Component = new StringOrIntValue(_componentId, _componentName),
IsError = _errorOccurred
};
if (IsEntry)
{
spanRequest.SpanType = 0;
}
else if (IsExit)
{
spanRequest.SpanType = 1;
}
else
{
spanRequest.SpanType = 2;
}
if (_layer.HasValue)
{
spanRequest.SpanLayer = (int) _layer.Value;
}
foreach (var tag in _tags)
{
spanRequest.Tags.Add(new KeyValuePair<string, string>(tag.Key, tag.Value));
}
if (_logs != null)
{
foreach (var logDataEntity in _logs)
{
spanRequest.Logs.Add(logDataEntity.Transform());
}
}
if (_refs == null) return spanRequest;
foreach (var traceSegmentRef in _refs)
{
spanRequest.References.Add(traceSegmentRef.Transform());
}
return spanRequest;
}
private void EnsureLogs()
{
if (_logs == null)
{
_logs = new LinkedList<LogDataEntity>();
}
}
}
}
\ No newline at end of file
/*
* Licensed to the OpenSkywalking under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The OpenSkywalking licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
*/
using System;
using System.Collections.Generic;
using SkyWalking.Components;
namespace SkyWalking.Context.Trace
{
/// <summary>
/// The <code>AbstractSpan</code> represents the span's skeleton, which contains all open methods.
/// </summary>
public interface ISpan
{
/// <summary>
/// Set the component id, which defines in ComponentsDefine
/// </summary>
/// <param name="component"></param>
/// <returns></returns>
ISpan SetComponent(IComponent component);
/// <summary>
/// Only use this method in explicit skyWalking, like opentracing-skywalking-bridge. It it higher recommend
/// don't use this for performance consideration.
/// </summary>
/// <param name="componentName"></param>
/// <returns></returns>
ISpan SetComponent(string componentName);
/// <summary>
/// Set a key:value tag on the Span.
/// </summary>
/// <param name="key"></param>
/// <param name="value"></param>
/// <returns></returns>
ISpan Tag(string key, string value);
ISpan SetLayer(SpanLayer layer);
/// <summary>
/// Record an exception event of the current walltime timestamp.
/// </summary>
/// <param name="exception"></param>
/// <returns></returns>
ISpan Log(Exception exception);
ISpan ErrorOccurred();
bool IsEntry { get; }
bool IsExit { get; }
ISpan Log(long timestamp, IDictionary<string, object> @event);
ISpan Start();
int SpanId { get; }
string OperationName { get; set; }
int OperationId { get; set; }
ISpan Start(long timestamp);
void Ref(ITraceSegmentRef traceSegmentRef);
}
}
/*
* Licensed to the OpenSkywalking under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The OpenSkywalking licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
*/
using System.Collections.Generic;
using SkyWalking.Transport;
using SkyWalking.Context.Ids;
namespace SkyWalking.Context.Trace
{
public interface ITraceSegment
{
void Archive(AbstractTracingSpan finishedSpan);
ITraceSegment Finish(bool isSizeLimited);
int ApplicationId { get; }
int ApplicationInstanceId { get; }
IEnumerable<ITraceSegmentRef> Refs { get; }
IEnumerable<DistributedTraceId> RelatedGlobalTraces { get; }
ID TraceSegmentId { get; }
bool HasRef { get; }
bool IsIgnore { get; set; }
bool IsSingleSpanSegment { get; }
void Ref(ITraceSegmentRef refSegment);
void RelatedGlobalTrace(DistributedTraceId distributedTraceId);
SegmentRequest Transform();
}
}
/*
* Licensed to the OpenSkywalking under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The OpenSkywalking licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
*/
using System.Collections.Generic;
using System.Collections.ObjectModel;
using SkyWalking.Transport;
namespace SkyWalking.Context.Trace
{
public class LogDataEntity
{
private readonly long _timestamp;
private readonly Dictionary<string, string> _logs;
private LogDataEntity(long timestamp, Dictionary<string, string> logs)
{
_timestamp = timestamp;
_logs = logs;
}
public IReadOnlyDictionary<string, string> Logs => new ReadOnlyDictionary<string, string>(_logs);
public class Builder
{
private readonly Dictionary<string, string> _logs;
public Builder()
{
_logs = new Dictionary<string, string>();
}
public Builder Add(IDictionary<string, string> fields)
{
foreach (var field in fields)
_logs.Add(field.Key, field.Value);
return this;
}
public Builder Add(string key, string value)
{
_logs.Add(key, value);
return this;
}
public LogDataEntity Build(long timestamp)
{
return new LogDataEntity(timestamp, _logs);
}
}
public LogDataRequest Transform()
{
var logMessage = new LogDataRequest();
logMessage.Timestamp = _timestamp;
foreach (var log in _logs)
{
logMessage.Data.Add(new KeyValuePair<string, string>(log.Key, log.Value));
}
return logMessage;
}
}
}
\ No newline at end of file
/*
* Licensed to the OpenSkywalking under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The OpenSkywalking licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
*/
using System;
using System.Collections.Generic;
using System.Text;
namespace SkyWalking.Context.Trace
{
public enum SpanLayer
{
DB = 1,
RPC_FRAMEWORK = 2,
HTTP = 3,
MQ = 4,
CACHE = 5
}
}
/*
* Licensed to the OpenSkywalking under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The OpenSkywalking licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
*/
namespace SkyWalking.Context.Trace
{
public abstract class StackBasedTracingSpan : AbstractTracingSpan
{
protected int _stackDepth;
protected StackBasedTracingSpan(int spanId, int parentSpanId, string operationName)
: base(spanId, parentSpanId, operationName)
{
_stackDepth = 0;
}
protected StackBasedTracingSpan(int spanId, int parentSpanId, int operationId)
: base(spanId, parentSpanId, operationId)
{
_stackDepth = 0;
}
}
}
/* /*
* Licensed to the OpenSkywalking under one or more * Licensed to the OpenSkywalking under one or more
* contributor license agreements. See the NOTICE file distributed with * contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership. * this work for additional information regarding copyright ownership.
...@@ -16,12 +16,12 @@ ...@@ -16,12 +16,12 @@
* *
*/ */
namespace SkyWalking.Context.Trace namespace SkyWalking
{ {
public interface IWithPeerInfo public interface IBase64Formatter
{ {
int PeerId { get; } string Decode(string value);
string Peer { get; } string Encode(string value);
} }
} }
\ No newline at end of file
...@@ -21,7 +21,7 @@ using System.Threading.Tasks; ...@@ -21,7 +21,7 @@ using System.Threading.Tasks;
namespace SkyWalking namespace SkyWalking
{ {
public interface ISkyWalkingAgentStartup public interface IInstrumentStartup
{ {
Task StartAsync(CancellationToken cancellationToken = default(CancellationToken)); Task StartAsync(CancellationToken cancellationToken = default(CancellationToken));
......
...@@ -17,6 +17,7 @@ ...@@ -17,6 +17,7 @@
*/ */
using System; using System;
using SkyWalking.Common;
namespace SkyWalking namespace SkyWalking
{ {
......
/* /*
* Licensed to the OpenSkywalking under one or more * Licensed to the OpenSkywalking under one or more
* contributor license agreements. See the NOTICE file distributed with * contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership. * this work for additional information regarding copyright ownership.
...@@ -17,28 +17,27 @@ ...@@ -17,28 +17,27 @@
*/ */
using System; using System;
using SkyWalking.Tracing.Segments;
namespace SkyWalking.Context.Trace namespace SkyWalking.Tracing
{ {
public class NoopExitSpan : NoopSpan, IWithPeerInfo public static class SegmentSpanExtensions
{ {
public int PeerId => peerId; public static void ErrorOccurred(this SegmentSpan span, Exception exception = null)
public string Peer => peer;
private String peer;
private int peerId;
public NoopExitSpan(int peerId)
{ {
this.peerId = peerId; if (span == null)
} {
return;
}
public NoopExitSpan(String peer) span.IsError = true;
{ if (exception != null)
this.peer = peer; {
span.AddLog(LogEvent.Event("error"),
LogEvent.ErrorKind(exception.GetType().FullName),
LogEvent.Message(exception.Message),
LogEvent.ErrorStack(exception.StackTrace));
}
} }
public override bool IsExit { get; } = true;
} }
} }
\ No newline at end of file
/* /*
* Licensed to the OpenSkywalking under one or more * Licensed to the OpenSkywalking under one or more
* contributor license agreements. See the NOTICE file distributed with * contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership. * this work for additional information regarding copyright ownership.
...@@ -16,19 +16,30 @@ ...@@ -16,19 +16,30 @@
* *
*/ */
using System; using SkyWalking.Common;
using SkyWalking.Transport;
namespace SkyWalking.Context.Trace namespace SkyWalking.Tracing
{ {
public interface ITraceSegmentRef : IEquatable<ITraceSegmentRef> public interface ICarrier
{ {
string EntryOperationName { get; } bool HasValue { get; }
int EntryOperationId { get; } bool? Sampled { get; }
int EntryApplicationInstanceId { get; } UniqueId TraceId { get; }
UniqueId ParentSegmentId { get; }
int ParentSpanId { get; }
SegmentReferenceRequest Transform(); int ParentServiceInstanceId { get; }
int EntryServiceInstanceId { get; }
StringOrIntValue NetworkAddress { get; }
StringOrIntValue EntryEndpoint { get; }
StringOrIntValue ParentEndpoint { get; }
} }
} }
\ No newline at end of file
/*
* Licensed to the OpenSkywalking under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The OpenSkywalking licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
*/
using SkyWalking.Tracing.Segments;
namespace SkyWalking.Tracing
{
public interface ICarrierFormatter
{
string Key { get; }
bool Enable { get; }
ICarrier Decode(string content);
string Encode(ICarrier carrier);
}
}
\ No newline at end of file
using System.Collections.Generic;
namespace SkyWalking.Tracing
{
public interface ICarrierHeaderCollection : IEnumerable<KeyValuePair<string, string>>
{
void Add(string key, string value);
}
}
\ No newline at end of file
/* /*
* Licensed to the OpenSkywalking under one or more * Licensed to the OpenSkywalking under one or more
* contributor license agreements. See the NOTICE file distributed with * contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership. * this work for additional information regarding copyright ownership.
...@@ -16,14 +16,14 @@ ...@@ -16,14 +16,14 @@
* *
*/ */
using System.Collections.Generic; using SkyWalking.Tracing.Segments;
namespace SkyWalking.Context.Ids namespace SkyWalking.Tracing
{ {
public interface IDistributedTraceIdCollection public interface ICarrierPropagator
{ {
IReadOnlyList<DistributedTraceId> GetRelatedGlobalTraces(); void Inject(SegmentContext segmentContext, ICarrierHeaderCollection carrier);
void Append(DistributedTraceId distributedTraceId); ICarrier Extract(ICarrierHeaderCollection carrier);
} }
} }
\ No newline at end of file
/*
* Licensed to the OpenSkywalking under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The OpenSkywalking licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
*/
using SkyWalking.Tracing.Segments;
namespace SkyWalking.Tracing
{
public interface IEntrySegmentContextAccessor
{
SegmentContext Context { get; set; }
}
}
\ No newline at end of file
/* /*
* Licensed to the OpenSkywalking under one or more * Licensed to the OpenSkywalking under one or more
* contributor license agreements. See the NOTICE file distributed with * contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership. * this work for additional information regarding copyright ownership.
...@@ -16,10 +16,12 @@ ...@@ -16,10 +16,12 @@
* *
*/ */
namespace SkyWalking.Context using SkyWalking.Tracing.Segments;
namespace SkyWalking.Tracing
{ {
public interface IIgnoreTracerContextListener public interface IExitSegmentContextAccessor
{ {
void AfterFinish(ITracerContext tracerContext); SegmentContext Context { get; set; }
} }
} }
\ No newline at end of file
/*
* Licensed to the OpenSkywalking under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The OpenSkywalking licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
*/
using SkyWalking.Tracing.Segments;
namespace SkyWalking.Tracing
{
public interface ILocalSegmentContextAccessor
{
SegmentContext Context { get; set; }
}
}
\ No newline at end of file
/* /*
* Licensed to the OpenSkywalking under one or more * Licensed to the OpenSkywalking under one or more
* contributor license agreements. See the NOTICE file distributed with * contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership. * this work for additional information regarding copyright ownership.
...@@ -16,12 +16,10 @@ ...@@ -16,12 +16,10 @@
* *
*/ */
namespace SkyWalking namespace SkyWalking.Tracing
{ {
public interface ISampler public interface ISamplerChainBuilder
{ {
bool Sampled(); Sampler Build();
void ForceSampled();
} }
} }
\ No newline at end of file
...@@ -16,12 +16,14 @@ ...@@ -16,12 +16,14 @@
* *
*/ */
namespace SkyWalking.Config using SkyWalking.Tracing.Segments;
namespace SkyWalking.Tracing
{ {
public class RuntimeConfig public interface ISamplingInterceptor
{ {
public NullableValue ApplicationId { get; set; } int Priority { get; }
public NullableValue ApplicationInstance { get; set; } bool Invoke(SamplingContext samplingContext, Sampler next);
} }
} }
\ No newline at end of file
/* /*
* Licensed to the OpenSkywalking under one or more * Licensed to the OpenSkywalking under one or more
* contributor license agreements. See the NOTICE file distributed with * contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership. * this work for additional information regarding copyright ownership.
* The OpenSkywalking licenses this file to You under the Apache License, Version 2.0 * The OpenSkywalking licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with * (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at * the License. You may obtain a copy of the License at
* *
* http://www.apache.org/licenses/LICENSE-2.0 * http://www.apache.org/licenses/LICENSE-2.0
* *
* Unless required by applicable law or agreed to in writing, software * Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, * distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and * See the License for the specific language governing permissions and
* limitations under the License. * limitations under the License.
* *
*/ */
namespace SkyWalking.Components using SkyWalking.Common;
{ using SkyWalking.Tracing.Segments;
/// <summary>
/// The <code>Component</code> represents component library , which has been supported by skywalking namespace SkyWalking.Tracing
/// </summary> {
public interface IComponent public interface ISegmentContextFactory
{ {
int Id { get; } SegmentContext CreateEntrySegment(string operationName, ICarrier carrier);
string Name { get; } SegmentContext CreateLocalSegment(string operationName);
}
SegmentContext CreateExitSegment(string operationName, StringOrIntValue networkAddress);
void Release(SegmentContext segmentContext);
}
} }
\ No newline at end of file
...@@ -16,22 +16,19 @@ ...@@ -16,22 +16,19 @@
* *
*/ */
using SkyWalking.Config; using SkyWalking.Tracing.Segments;
namespace SkyWalking.Context namespace SkyWalking.Tracing
{ {
public class ContextCarrierFactory : IContextCarrierFactory public interface ITracingContext
{ {
private readonly InstrumentationConfig _config; SegmentContext CreateEntrySegmentContext(string operationName, ICarrierHeaderCollection carrierHeader);
public ContextCarrierFactory(IConfigAccessor configAccessor) SegmentContext CreateLocalSegmentContext(string operationName);
{
_config = configAccessor.Get<InstrumentationConfig>();
}
public IContextCarrier Create() SegmentContext CreateExitSegmentContext(string operationName, string networkAddress,
{ ICarrierHeaderCollection carrierHeader = default(ICarrierHeaderCollection));
return new ContextCarrier(_config.Namespace);
} void Release(SegmentContext segmentContext);
} }
} }
\ No newline at end of file
/* /*
* Licensed to the OpenSkywalking under one or more * Licensed to the OpenSkywalking under one or more
* contributor license agreements. See the NOTICE file distributed with * contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership. * this work for additional information regarding copyright ownership.
...@@ -16,11 +16,10 @@ ...@@ -16,11 +16,10 @@
* *
*/ */
namespace SkyWalking.Context.Trace namespace SkyWalking.Tracing
{ {
public enum SegmentRefType public interface IUniqueIdGenerator
{ {
CrossProcess = 0, UniqueId Generate();
CrossThread = 1
} }
} }
\ No newline at end of file
/* /*
* Licensed to the OpenSkywalking under one or more * Licensed to the OpenSkywalking under one or more
* contributor license agreements. See the NOTICE file distributed with * contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership. * this work for additional information regarding copyright ownership.
* The OpenSkywalking licenses this file to You under the Apache License, Version 2.0 * The OpenSkywalking licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with * (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at * the License. You may obtain a copy of the License at
* *
* http://www.apache.org/licenses/LICENSE-2.0 * http://www.apache.org/licenses/LICENSE-2.0
* *
* Unless required by applicable law or agreed to in writing, software * Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, * distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and * See the License for the specific language governing permissions and
* limitations under the License. * limitations under the License.
* *
*/ */
namespace SkyWalking.Context namespace SkyWalking.Tracing
{ {
public interface IContextCarrierFactory public interface IUniqueIdParser
{ {
IContextCarrier Create(); bool TryParse(string text, out UniqueId uniqueId);
} }
} }
\ No newline at end of file
/*
* Licensed to the OpenSkywalking under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The OpenSkywalking licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
*/
using SkyWalking.Common;
using SkyWalking.Tracing.Segments;
namespace SkyWalking.Tracing
{
public delegate bool Sampler(SamplingContext samplingContext);
public class SamplingContext
{
public string OperationName { get; }
public StringOrIntValue Peer { get; }
public StringOrIntValue EntryEndpoint { get; }
public StringOrIntValue ParentEndpoint { get; }
public SamplingContext(string operationName, StringOrIntValue peer, StringOrIntValue entryEndpoint,
StringOrIntValue parentEndpoint)
{
OperationName = operationName;
Peer = peer;
EntryEndpoint = entryEndpoint;
ParentEndpoint = parentEndpoint;
}
}
}
\ No newline at end of file
/*
* Licensed to the OpenSkywalking under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The OpenSkywalking licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
*/
namespace SkyWalking.Tracing.Segments
{
public class SegmentContext
{
public UniqueId SegmentId { get; }
public UniqueId TraceId { get; }
public SegmentSpan Span { get; }
public int ServiceId { get; }
public int ServiceInstanceId { get; }
public bool Sampled { get; }
public bool IsSizeLimited { get; } = false;
public SegmentReferenceCollection References { get; } = new SegmentReferenceCollection();
public SegmentContext(UniqueId traceId, UniqueId segmentId, bool sampled, int serviceId, int serviceInstanceId,
string operationName, SpanType spanType)
{
TraceId = traceId;
Sampled = sampled;
SegmentId = segmentId;
ServiceId = serviceId;
ServiceInstanceId = serviceInstanceId;
Span = new SegmentSpan(operationName, spanType);
}
}
}
\ No newline at end of file
/* /*
* Licensed to the OpenSkywalking under one or more * Licensed to the OpenSkywalking under one or more
* contributor license agreements. See the NOTICE file distributed with * contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership. * this work for additional information regarding copyright ownership.
* The OpenSkywalking licenses this file to You under the Apache License, Version 2.0 * The OpenSkywalking licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with * (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at * the License. You may obtain a copy of the License at
* *
* http://www.apache.org/licenses/LICENSE-2.0 * http://www.apache.org/licenses/LICENSE-2.0
* *
* Unless required by applicable law or agreed to in writing, software * Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, * distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and * See the License for the specific language governing permissions and
* limitations under the License. * limitations under the License.
* *
*/ */
using System; using System.Collections;
using System.Collections.Generic; using System.Collections.Generic;
using SkyWalking.Components; using SkyWalking.Common;
namespace SkyWalking.Context.Trace namespace SkyWalking.Tracing.Segments
{ {
public class NoopSpan : ISpan public class SegmentReference
{ {
public int SpanId => 0; public Reference Reference { get; set; }
public string OperationName { get => string.Empty; set { } } public UniqueId ParentSegmentId { get; set; }
public int OperationId { get => 0; set { } } public int ParentSpanId { get; set; }
public ISpan ErrorOccurred() public int ParentServiceInstanceId { get; set; }
{
return this; public int EntryServiceInstanceId { get; set; }
}
public StringOrIntValue NetworkAddress { get; set; }
public ISpan Log(Exception exception)
{ public StringOrIntValue EntryEndpoint { get; set; }
return this;
} public StringOrIntValue ParentEndpoint { get; set; }
}
public ISpan Log(long timestamp, IDictionary<string, object> @event)
{ public enum Reference
return this; {
} CrossProcess = 0,
CrossThread = 1
public void Ref(ITraceSegmentRef traceSegmentRef) }
{
} public class SegmentReferenceCollection : IEnumerable<SegmentReference>
{
public ISpan SetComponent(IComponent component) private readonly HashSet<SegmentReference> _references = new HashSet<SegmentReference>();
{
return this; public bool Add(SegmentReference reference)
} {
return _references.Add(reference);
public ISpan SetComponent(string componentName) }
{
return this; public IEnumerator<SegmentReference> GetEnumerator()
} {
return _references.GetEnumerator();
public ISpan SetLayer(SpanLayer layer) }
{
return this; IEnumerator IEnumerable.GetEnumerator()
} {
return _references.GetEnumerator();
public ISpan Start() }
{
return this; public int Count => _references.Count;
} }
}
public ISpan Start(long timestamp) \ No newline at end of file
{
return this;
}
public ISpan Tag(string key, string value)
{
return this;
}
public virtual bool IsEntry => false;
public virtual bool IsExit => false;
}
}
/*
* Licensed to the OpenSkywalking under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The OpenSkywalking licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
*/
using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using SkyWalking.Common;
namespace SkyWalking.Tracing.Segments
{
public class SegmentSpan
{
public int SpanId { get; } = 0;
public int ParentSpanId { get; } = -1;
public long StartTime { get; } = DateTimeOffset.UtcNow.ToUnixTimeMilliseconds();
public long EndTime { get; private set; }
public StringOrIntValue OperationName { get; }
public StringOrIntValue Peer { get; set; }
public SpanType SpanType { get; }
public SpanLayer SpanLayer { get; set; }
public StringOrIntValue Component { get; set; }
public bool IsError { get; set; }
public TagCollection Tags { get; } = new TagCollection();
public LogCollection Logs { get; } = new LogCollection();
public SegmentSpan(string operationName, SpanType spanType)
{
OperationName = new StringOrIntValue(operationName);
SpanType = spanType;
}
public SegmentSpan AddTag(string key, string value)
{
Tags.AddTag(key, value);
return this;
}
public SegmentSpan AddTag(string key, long value)
{
Tags.AddTag(key, value.ToString());
return this;
}
public SegmentSpan AddTag(string key, bool value)
{
Tags.AddTag(key, value.ToString());
return this;
}
public void AddLog(params LogEvent[] events)
{
var log = new SpanLog(DateTimeOffset.UtcNow.ToUnixTimeMilliseconds(), events);
Logs.AddLog(log);
}
public void Finish()
{
EndTime = DateTimeOffset.UtcNow.ToUnixTimeMilliseconds();
}
}
public class TagCollection : IEnumerable<KeyValuePair<string, string>>
{
private readonly Dictionary<string, string> tags = new Dictionary<string, string>();
internal void AddTag(string key, string value)
{
tags[key] = value;
}
public IEnumerator<KeyValuePair<string, string>> GetEnumerator()
{
return tags.GetEnumerator();
}
IEnumerator IEnumerable.GetEnumerator()
{
return tags.GetEnumerator();
}
}
public enum SpanType
{
Entry = 0,
Exit = 1,
Local = 2
}
public enum SpanLayer
{
DB = 1,
RPC_FRAMEWORK = 2,
HTTP = 3,
MQ = 4,
CACHE = 5
}
public class LogCollection : IEnumerable<SpanLog>
{
private readonly List<SpanLog> _logs = new List<SpanLog>();
internal void AddLog(SpanLog log)
{
_logs.Add(log);
}
public IEnumerator<SpanLog> GetEnumerator()
{
return _logs.GetEnumerator();
}
IEnumerator IEnumerable.GetEnumerator()
{
return _logs.GetEnumerator();
}
}
public class SpanLog
{
private static readonly Dictionary<string, string> Empty = new Dictionary<string, string>();
public long Timestamp { get; }
public IReadOnlyDictionary<string, string> Data { get; }
public SpanLog(long timestamp, params LogEvent[] events)
{
Timestamp = timestamp;
Data = events?.ToDictionary(x => x.Key, x => x.Value) ?? Empty;
}
}
public class LogEvent
{
public string Key { get; }
public string Value { get; }
public LogEvent(string key, string value)
{
Key = key;
Value = value;
}
public static LogEvent Event(string value)
{
return new LogEvent("event", value);
}
public static LogEvent Message(string value)
{
return new LogEvent("message", value);
}
public static LogEvent ErrorKind(string value)
{
return new LogEvent("error.kind", value);
}
public static LogEvent ErrorStack(string value)
{
return new LogEvent("stack", value);
}
}
}
\ No newline at end of file
/*
* Licensed to the OpenSkywalking under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The OpenSkywalking licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
*/
using System;
namespace SkyWalking.Tracing
{
public class UniqueId : IEquatable<UniqueId>
{
public long Part1 { get; }
public long Part2 { get; }
public long Part3 { get; }
public UniqueId(long part1, long part2, long part3)
{
Part1 = part1;
Part2 = part2;
Part3 = part3;
}
public override string ToString() => $"{Part1}.{Part2}.{Part3}";
public bool Equals(UniqueId other)
{
if (ReferenceEquals(null, other)) return false;
if (ReferenceEquals(this, other)) return true;
if (Part1 != other.Part1) return false;
if (Part2 != other.Part2) return false;
return Part3 == other.Part3;
}
public override bool Equals(object obj)
{
if (ReferenceEquals(null, obj)) return false;
if (ReferenceEquals(this, obj)) return true;
if (!(obj is UniqueId id)) return false;
return Equals(id);
}
public override int GetHashCode()
{
throw new NotImplementedException();
}
}
}
\ No newline at end of file
/* /*
* Licensed to the OpenSkywalking under one or more * Licensed to the OpenSkywalking under one or more
* contributor license agreements. See the NOTICE file distributed with * contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership. * this work for additional information regarding copyright ownership.
...@@ -16,12 +16,12 @@ ...@@ -16,12 +16,12 @@
* *
*/ */
using SkyWalking.Context.Trace; using SkyWalking.Tracing.Segments;
namespace SkyWalking.Context namespace SkyWalking.Transport
{ {
public interface ITracingContextListener public interface ISegmentContextMapper
{ {
void AfterFinished(ITraceSegment traceSegment); SegmentRequest Map(SegmentContext segmentContext);
} }
} }
\ No newline at end of file
...@@ -18,12 +18,13 @@ ...@@ -18,12 +18,13 @@
using System.Threading; using System.Threading;
using System.Threading.Tasks; using System.Threading.Tasks;
using SkyWalking.Tracing.Segments;
namespace SkyWalking.Transport namespace SkyWalking.Transport
{ {
public interface ISegmentDispatcher public interface ISegmentDispatcher
{ {
bool Dispatch(SegmentRequest segment); bool Dispatch(SegmentContext segmentContext);
Task Flush(CancellationToken token = default(CancellationToken)); Task Flush(CancellationToken token = default(CancellationToken));
......
...@@ -19,6 +19,7 @@ ...@@ -19,6 +19,7 @@
using System.Collections.Generic; using System.Collections.Generic;
using System.Threading; using System.Threading;
using System.Threading.Tasks; using System.Threading.Tasks;
using SkyWalking.Common;
using SkyWalking.Transport; using SkyWalking.Transport;
namespace SkyWalking.Transport namespace SkyWalking.Transport
......
...@@ -17,6 +17,7 @@ ...@@ -17,6 +17,7 @@
*/ */
using System.Collections.Generic; using System.Collections.Generic;
using SkyWalking.Common;
namespace SkyWalking.Transport namespace SkyWalking.Transport
{ {
......
...@@ -19,6 +19,7 @@ ...@@ -19,6 +19,7 @@
using System; using System;
using System.Threading; using System.Threading;
using System.Threading.Tasks; using System.Threading.Tasks;
using SkyWalking.Common;
namespace SkyWalking.Transport namespace SkyWalking.Transport
{ {
...@@ -31,4 +32,4 @@ namespace SkyWalking.Transport ...@@ -31,4 +32,4 @@ namespace SkyWalking.Transport
Task HeartbeatAsync(int applicationInstance, long heartbeatTime, CancellationToken cancellationToken = default(CancellationToken)); Task HeartbeatAsync(int applicationInstance, long heartbeatTime, CancellationToken cancellationToken = default(CancellationToken));
} }
} }
\ No newline at end of file
...@@ -21,7 +21,6 @@ using Microsoft.Extensions.DependencyInjection; ...@@ -21,7 +21,6 @@ using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting; using Microsoft.Extensions.Hosting;
using SkyWalking.AspNetCore.Diagnostics; using SkyWalking.AspNetCore.Diagnostics;
using SkyWalking.Config; using SkyWalking.Config;
using SkyWalking.Context;
using SkyWalking.Diagnostics; using SkyWalking.Diagnostics;
using SkyWalking.Diagnostics.EntityFrameworkCore; using SkyWalking.Diagnostics.EntityFrameworkCore;
using SkyWalking.Diagnostics.HttpClient; using SkyWalking.Diagnostics.HttpClient;
...@@ -30,7 +29,9 @@ using SkyWalking.Utilities.Configuration; ...@@ -30,7 +29,9 @@ using SkyWalking.Utilities.Configuration;
using SkyWalking.Utilities.DependencyInjection; using SkyWalking.Utilities.DependencyInjection;
using SkyWalking.Utilities.Logging; using SkyWalking.Utilities.Logging;
using SkyWalking.Logging; using SkyWalking.Logging;
using SkyWalking.Sampling;
using SkyWalking.Service; using SkyWalking.Service;
using SkyWalking.Tracing;
using SkyWalking.Transport; using SkyWalking.Transport;
using SkyWalking.Transport.Grpc; using SkyWalking.Transport.Grpc;
using SkyWalking.Transport.Grpc.V5; using SkyWalking.Transport.Grpc.V5;
...@@ -46,27 +47,51 @@ namespace SkyWalking.Agent.AspNetCore ...@@ -46,27 +47,51 @@ namespace SkyWalking.Agent.AspNetCore
{ {
throw new ArgumentNullException(nameof(services)); throw new ArgumentNullException(nameof(services));
} }
services.AddSingleton<IContextCarrierFactory, ContextCarrierFactory>();
services.AddSingleton<ISegmentDispatcher, AsyncQueueSegmentDispatcher>(); services.AddSingleton<ISegmentDispatcher, AsyncQueueSegmentDispatcher>();
services.AddSingleton<IExecutionService, SegmentReportService>();
services.AddSingleton<IExecutionService, RegisterService>(); services.AddSingleton<IExecutionService, RegisterService>();
services.AddSingleton<IExecutionService, PingService>(); services.AddSingleton<IExecutionService, PingService>();
services.AddSingleton<IExecutionService, SamplingRefreshService>();
services.AddSingleton<IExecutionService, ServiceDiscoveryV5Service>(); services.AddSingleton<IExecutionService, ServiceDiscoveryV5Service>();
services.AddSingleton<ISkyWalkingAgentStartup, SkyWalkingAgentStartup>(); services.AddSingleton<IExecutionService, SegmentReportService>();
services.AddSingleton<ISampler>(DefaultSampler.Instance); services.AddSingleton<IInstrumentStartup, InstrumentStartup>();
services.AddSingleton<IRuntimeEnvironment>(RuntimeEnvironment.Instance); services.AddSingleton<IRuntimeEnvironment>(RuntimeEnvironment.Instance);
services.AddSingleton<TracingDiagnosticProcessorObserver>(); services.AddSingleton<TracingDiagnosticProcessorObserver>();
services.AddSingleton<IConfigAccessor, ConfigAccessor>(); services.AddSingleton<IConfigAccessor, ConfigAccessor>();
services.AddSingleton<IHostedService, InstrumentationHostedService>(); services.AddSingleton<IHostedService, InstrumentationHostedService>();
services.AddSingleton<IEnvironmentProvider, HostingEnvironmentProvider>(); services.AddSingleton<IEnvironmentProvider, HostingEnvironmentProvider>();
services.AddGrpcTransport().AddLogging(); services.AddTracing().AddSampling().AddGrpcTransport().AddLogging();
services.AddSkyWalkingExtensions().AddAspNetCoreHosting().AddHttpClient().AddSqlClient() services.AddSkyWalkingExtensions().AddAspNetCoreHosting().AddHttpClient().AddSqlClient()
.AddEntityFrameworkCore(c => c.AddPomeloMysql().AddNpgsql().AddSqlite()); .AddEntityFrameworkCore(c => c.AddPomeloMysql().AddNpgsql().AddSqlite());
return services; return services;
} }
private static IServiceCollection AddTracing(this IServiceCollection services)
{
services.AddSingleton<ITracingContext, Tracing.TracingContext>();
services.AddSingleton<ICarrierPropagator, CarrierPropagator>();
services.AddSingleton<ICarrierFormatter, Sw3CarrierFormatter>();
services.AddSingleton<ICarrierFormatter, Sw6CarrierFormatter>();
services.AddSingleton<ISegmentContextFactory, SegmentContextFactory>();
services.AddSingleton<IEntrySegmentContextAccessor, EntrySegmentContextAccessor>();
services.AddSingleton<ILocalSegmentContextAccessor, LocalSegmentContextAccessor>();
services.AddSingleton<IExitSegmentContextAccessor, ExitSegmentContextAccessor>();
services.AddSingleton<ISamplerChainBuilder, SamplerChainBuilder>();
services.AddSingleton<IUniqueIdGenerator, UniqueIdGenerator>();
services.AddSingleton<IUniqueIdParser, UniqueIdParser>();
services.AddSingleton<ISegmentContextMapper, SegmentContextMapper>();
services.AddSingleton<IBase64Formatter, Base64Formatter>();
return services;
}
private static IServiceCollection AddSampling(this IServiceCollection services)
{
services.AddSingleton<SimpleCountSamplingInterceptor>();
services.AddSingleton<ISamplingInterceptor>(p => p.GetService<SimpleCountSamplingInterceptor>());
services.AddSingleton<IExecutionService>(p => p.GetService<SimpleCountSamplingInterceptor>());
services.AddSingleton<ISamplingInterceptor, RandomSamplingInterceptor>();
return services;
}
private static IServiceCollection AddGrpcTransport(this IServiceCollection services) private static IServiceCollection AddGrpcTransport(this IServiceCollection services)
{ {
services.AddSingleton<ISkyWalkingClientV5, SkyWalkingClientV5>(); services.AddSingleton<ISkyWalkingClientV5, SkyWalkingClientV5>();
......
...@@ -24,9 +24,9 @@ namespace SkyWalking.Agent.AspNetCore ...@@ -24,9 +24,9 @@ namespace SkyWalking.Agent.AspNetCore
{ {
internal class InstrumentationHostedService : IHostedService internal class InstrumentationHostedService : IHostedService
{ {
private readonly ISkyWalkingAgentStartup _startup; private readonly IInstrumentStartup _startup;
public InstrumentationHostedService(ISkyWalkingAgentStartup startup) public InstrumentationHostedService(IInstrumentStartup startup)
{ {
_startup = startup; _startup = startup;
} }
......
...@@ -18,10 +18,11 @@ ...@@ -18,10 +18,11 @@
using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.DependencyInjection;
using SkyWalking.Config; using SkyWalking.Config;
using SkyWalking.Context;
using SkyWalking.Diagnostics; using SkyWalking.Diagnostics;
using SkyWalking.Logging; using SkyWalking.Logging;
using SkyWalking.Sampling;
using SkyWalking.Service; using SkyWalking.Service;
using SkyWalking.Tracing;
using SkyWalking.Transport; using SkyWalking.Transport;
using SkyWalking.Transport.Grpc; using SkyWalking.Transport.Grpc;
using SkyWalking.Transport.Grpc.V5; using SkyWalking.Transport.Grpc.V5;
...@@ -35,26 +36,45 @@ namespace SkyWalking.AspNet.Extensions ...@@ -35,26 +36,45 @@ namespace SkyWalking.AspNet.Extensions
{ {
public static IServiceCollection AddSkyWalkingCore(this IServiceCollection services) public static IServiceCollection AddSkyWalkingCore(this IServiceCollection services)
{ {
services.AddSingleton<IContextCarrierFactory, ContextCarrierFactory>();
services.AddSingleton<ISegmentDispatcher, AsyncQueueSegmentDispatcher>(); services.AddSingleton<ISegmentDispatcher, AsyncQueueSegmentDispatcher>();
services.AddSingleton<IExecutionService, SegmentReportService>();
services.AddSingleton<IExecutionService, RegisterService>(); services.AddSingleton<IExecutionService, RegisterService>();
services.AddSingleton<IExecutionService, PingService>(); services.AddSingleton<IExecutionService, PingService>();
services.AddSingleton<IExecutionService, SamplingRefreshService>();
services.AddSingleton<IExecutionService, ServiceDiscoveryV5Service>(); services.AddSingleton<IExecutionService, ServiceDiscoveryV5Service>();
services.AddSingleton<ISkyWalkingAgentStartup, SkyWalkingAgentStartup>(); services.AddSingleton<IExecutionService, SegmentReportService>();
services.AddSingleton<ISampler>(DefaultSampler.Instance); services.AddSingleton<IInstrumentStartup, InstrumentStartup>();
services.AddSingleton<IRuntimeEnvironment>(RuntimeEnvironment.Instance); services.AddSingleton<IRuntimeEnvironment>(RuntimeEnvironment.Instance);
services.AddSingleton<TracingDiagnosticProcessorObserver>(); services.AddSingleton<TracingDiagnosticProcessorObserver>();
services.AddSingleton<IConfigAccessor, ConfigAccessor>(); services.AddSingleton<IConfigAccessor, ConfigAccessor>();
services.AddSingleton<IEnvironmentProvider, HostingEnvironmentProvider>(); services.AddSingleton<IEnvironmentProvider, HostingEnvironmentProvider>();
services.AddSingleton<InstrumentRequestCallback>();
services.AddSingleton<ITracingContext, Tracing.TracingContext>();
services.AddSingleton<ICarrierPropagator, CarrierPropagator>();
services.AddSingleton<ICarrierFormatter, Sw3CarrierFormatter>();
services.AddSingleton<ICarrierFormatter, Sw6CarrierFormatter>();
services.AddSingleton<ISegmentContextFactory, SegmentContextFactory>();
services.AddSingleton<IEntrySegmentContextAccessor, EntrySegmentContextAccessor>();
services.AddSingleton<ILocalSegmentContextAccessor, LocalSegmentContextAccessor>();
services.AddSingleton<IExitSegmentContextAccessor, ExitSegmentContextAccessor>();
services.AddSingleton<ISamplerChainBuilder, SamplerChainBuilder>();
services.AddSingleton<IUniqueIdGenerator, UniqueIdGenerator>();
services.AddSingleton<IUniqueIdParser, UniqueIdParser>();
services.AddSingleton<ISegmentContextMapper, SegmentContextMapper>();
services.AddSingleton<IBase64Formatter, Base64Formatter>();
services.AddSingleton<SimpleCountSamplingInterceptor>();
services.AddSingleton<ISamplingInterceptor>(p => p.GetService<SimpleCountSamplingInterceptor>());
services.AddSingleton<IExecutionService>(p => p.GetService<SimpleCountSamplingInterceptor>());
services.AddSingleton<ISamplingInterceptor, RandomSamplingInterceptor>();
services.AddSingleton<ISkyWalkingClientV5, SkyWalkingClientV5>();
services.AddSingleton<ISegmentReporter, SegmentReporter>(); services.AddSingleton<ISegmentReporter, SegmentReporter>();
services.AddSingleton<ConnectionManager>(); services.AddSingleton<ConnectionManager>();
services.AddSingleton<IPingCaller, PingCaller>(); services.AddSingleton<IPingCaller, PingCaller>();
services.AddSingleton<IServiceRegister, ServiceRegister>(); services.AddSingleton<IServiceRegister, ServiceRegister>();
services.AddSingleton<IExecutionService, ConnectService>(); services.AddSingleton<IExecutionService, ConnectService>();
services.AddSingleton<ILoggerFactory, DefaultLoggerFactory>(); services.AddSingleton<ILoggerFactory, DefaultLoggerFactory>();
services.AddSingleton<ISkyWalkingClientV5, SkyWalkingClientV5>();
return services; return services;
} }
} }
......
/* /*
* Licensed to the OpenSkywalking under one or more * Licensed to the OpenSkywalking under one or more
* contributor license agreements. See the NOTICE file distributed with * contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership. * this work for additional information regarding copyright ownership.
...@@ -16,34 +16,39 @@ ...@@ -16,34 +16,39 @@
* *
*/ */
using System.Collections;
using System.Collections.Generic; using System.Collections.Generic;
using System.Web;
using SkyWalking.Tracing;
namespace SkyWalking.Context.Ids namespace SkyWalking.AspNet
{ {
public class DistributedTraceIdCollection : IDistributedTraceIdCollection public class HttpRequestCarrierHeaderCollection : ICarrierHeaderCollection
{ {
private readonly List<DistributedTraceId> _relatedGlobalTraces; private readonly Dictionary<string, string> _headers;
public DistributedTraceIdCollection() public HttpRequestCarrierHeaderCollection(HttpRequest httpRequest)
{ {
_relatedGlobalTraces = new List<DistributedTraceId>(); _headers = new Dictionary<string, string>();
foreach (var key in httpRequest.Headers.AllKeys)
{
_headers[key] = httpRequest.Headers[key];
}
} }
public IReadOnlyList<DistributedTraceId> GetRelatedGlobalTraces() public IEnumerator<KeyValuePair<string, string>> GetEnumerator()
{ {
return _relatedGlobalTraces.AsReadOnly(); return _headers.GetEnumerator();
} }
public void Append(DistributedTraceId distributedTraceId) IEnumerator IEnumerable.GetEnumerator()
{ {
if (_relatedGlobalTraces.Count > 0 && _relatedGlobalTraces[0] is NewDistributedTraceId) return _headers.GetEnumerator();
{ }
_relatedGlobalTraces.RemoveAt(0);
} public void Add(string key, string value)
if (!_relatedGlobalTraces.Contains(distributedTraceId)) {
{ throw new System.NotImplementedException();
_relatedGlobalTraces.Add(distributedTraceId);
}
} }
} }
} }
\ No newline at end of file
...@@ -17,74 +17,88 @@ ...@@ -17,74 +17,88 @@
*/ */
using System; using System;
using System.Collections;
using System.Collections.Generic; using System.Collections.Generic;
using System.Net.Http; using System.Net.Http;
using System.Net.Http.Headers;
using System.Threading; using System.Threading;
using System.Threading.Tasks; using System.Threading.Tasks;
using SkyWalking.Components; using CommonServiceLocator;
using SkyWalking.Context; using SkyWalking.Tracing;
using SkyWalking.Context.Tag; using SpanLayer = SkyWalking.Tracing.Segments.SpanLayer;
using SkyWalking.Context.Trace;
namespace SkyWalking.AspNet namespace SkyWalking.AspNet
{ {
public class HttpTracingHandler : DelegatingHandler public class HttpTracingHandler : DelegatingHandler
{ {
private readonly IContextCarrierFactory _contextCarrierFactory;
public HttpTracingHandler() public HttpTracingHandler()
: this(new HttpClientHandler()) : this(new HttpClientHandler())
{ {
} }
public HttpTracingHandler(HttpMessageHandler innerHandler) public HttpTracingHandler(HttpMessageHandler innerHandler)
: this(innerHandler, CommonServiceLocator.ServiceLocator.Current.GetInstance<IContextCarrierFactory>())
{
}
private HttpTracingHandler(HttpMessageHandler innerHandler, IContextCarrierFactory contextCarrierFactory)
{ {
InnerHandler = innerHandler; InnerHandler = innerHandler;
_contextCarrierFactory = contextCarrierFactory;
} }
protected override async Task<HttpResponseMessage> SendAsync(HttpRequestMessage request, protected override async Task<HttpResponseMessage> SendAsync(HttpRequestMessage request,
CancellationToken cancellationToken) CancellationToken cancellationToken)
{ {
var peer = $"{request.RequestUri.Host}:{request.RequestUri.Port}"; var tracingContext = ServiceLocator.Current.GetInstance<ITracingContext>();
var contextCarrier = _contextCarrierFactory.Create(); var operationName = request.RequestUri.ToString();
var span = ContextManager.CreateExitSpan(request.RequestUri.ToString(), contextCarrier, peer); var networkAddress = $"{request.RequestUri.Host}:{request.RequestUri.Port}";
var context = tracingContext.CreateExitSegmentContext(operationName, networkAddress,
new CarrierHeaderCollection(request.Headers));
try try
{ {
Tags.Url.Set(span, request.RequestUri.ToString()); context.Span.SpanLayer = SpanLayer.HTTP;
span.AsHttp(); context.Span.Component = Common.Components.HTTPCLIENT;
span.SetComponent(ComponentsDefine.HttpClient); context.Span.AddTag(Common.Tags.URL, request.RequestUri.ToString());
Tags.HTTP.Method.Set(span, request.Method.ToString()); context.Span.AddTag(Common.Tags.PATH, request.RequestUri.PathAndQuery);
foreach (var item in contextCarrier.Items) context.Span.AddTag(Common.Tags.HTTP_METHOD, request.Method.ToString());
request.Headers.Add(item.HeadKey, item.HeadValue); var response = await base.SendAsync(request, cancellationToken);
var statusCode = (int) response.StatusCode;
if (request.Method.Method != "GET") if (statusCode >= 400)
{ {
// record request body data context.Span.ErrorOccurred();
if (!request.Content.Headers.ContentType?.MediaType.ToLower().Contains("multipart/form-data")??false)
{
string bodyStr = await request.Content.ReadAsStringAsync();
span.Log(DateTimeOffset.UtcNow.ToUnixTimeMilliseconds(), new Dictionary<string, object> { { "Body", bodyStr } });
}
} }
var response = await base.SendAsync(request, cancellationToken); context.Span.AddTag(Common.Tags.STATUS_CODE, statusCode);
Tags.StatusCode.Set(span, response.StatusCode.ToString());
return response; return response;
} }
catch (Exception e) catch (Exception exception)
{ {
span.ErrorOccurred().Log(e); context.Span.ErrorOccurred(exception);
throw; throw;
} }
finally finally
{ {
ContextManager.StopSpan(span); tracingContext.Release(context);
}
}
private class CarrierHeaderCollection : ICarrierHeaderCollection
{
private readonly HttpRequestHeaders _headers;
public CarrierHeaderCollection(HttpRequestHeaders headers)
{
_headers = headers;
}
public void Add(string key, string value)
{
_headers.Add(key, value);
}
public IEnumerator<KeyValuePair<string, string>> GetEnumerator()
{
throw new NotImplementedException();
}
IEnumerator IEnumerable.GetEnumerator()
{
return GetEnumerator();
} }
} }
} }
......
...@@ -19,13 +19,14 @@ ...@@ -19,13 +19,14 @@
using CommonServiceLocator; using CommonServiceLocator;
using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.DependencyInjection;
using System.Web; using System.Web;
using Nito.AsyncEx;
using SkyWalking.AspNet.Extensions; using SkyWalking.AspNet.Extensions;
namespace SkyWalking.AspNet namespace SkyWalking.AspNet
{ {
public class SkyWalkingModule : IHttpModule public class InstrumentModule : IHttpModule
{ {
public SkyWalkingModule() public InstrumentModule()
{ {
var serviceProvider = new ServiceCollection().AddSkyWalkingCore().BuildServiceProvider(); var serviceProvider = new ServiceCollection().AddSkyWalkingCore().BuildServiceProvider();
var serviceLocatorProvider = new ServiceProviderLocator(serviceProvider); var serviceLocatorProvider = new ServiceProviderLocator(serviceProvider);
...@@ -34,15 +35,17 @@ namespace SkyWalking.AspNet ...@@ -34,15 +35,17 @@ namespace SkyWalking.AspNet
public void Init(HttpApplication application) public void Init(HttpApplication application)
{ {
var startup = ServiceLocator.Current.GetInstance<ISkyWalkingAgentStartup>(); var startup = ServiceLocator.Current.GetInstance<IInstrumentStartup>();
AsyncContext.Run(() => startup.StartAsync()); AsyncContext.Run(() => startup.StartAsync());
var requestCallback = ServiceLocator.Current.GetInstance<SkyWalkingApplicationRequestCallback>(); var requestCallback = ServiceLocator.Current.GetInstance<InstrumentRequestCallback>();
application.BeginRequest += requestCallback.ApplicationOnBeginRequest; application.BeginRequest += requestCallback.ApplicationOnBeginRequest;
application.EndRequest += requestCallback.ApplicationOnEndRequest; application.EndRequest += requestCallback.ApplicationOnEndRequest;
} }
public void Dispose() public void Dispose()
{ {
var startup = ServiceLocator.Current.GetInstance<IInstrumentStartup>();
AsyncContext.Run(() => startup.StopAsync());
} }
} }
} }
\ No newline at end of file
...@@ -20,15 +20,15 @@ using Microsoft.Web.Infrastructure.DynamicModuleHelper; ...@@ -20,15 +20,15 @@ using Microsoft.Web.Infrastructure.DynamicModuleHelper;
using System.Web; using System.Web;
using SkyWalking.AspNet; using SkyWalking.AspNet;
[assembly:PreApplicationStartMethod(typeof(SkyWalkingModuleRegister), "Register")] [assembly:PreApplicationStartMethod(typeof(InstrumentModuleFactory), nameof(InstrumentModuleFactory.Create))]
namespace SkyWalking.AspNet namespace SkyWalking.AspNet
{ {
public class SkyWalkingModuleRegister public class InstrumentModuleFactory
{ {
public static void Register() public static void Create()
{ {
DynamicModuleUtility.RegisterModule(typeof(SkyWalkingModule)); DynamicModuleUtility.RegisterModule(typeof(InstrumentModule));
} }
} }
} }
\ No newline at end of file
...@@ -17,26 +17,27 @@ ...@@ -17,26 +17,27 @@
*/ */
using System; using System;
using System.Collections.Generic;
using System.IO;
using System.Web; using System.Web;
using SkyWalking.Components; using SkyWalking.Common;
using SkyWalking.Config; using SkyWalking.Config;
using SkyWalking.Context; using SkyWalking.Tracing;
using SkyWalking.Context.Tag; using SkyWalking.Tracing.Segments;
using SkyWalking.Context.Trace; using SpanLayer = SkyWalking.Tracing.Segments.SpanLayer;
namespace SkyWalking.AspNet namespace SkyWalking.AspNet
{ {
internal class SkyWalkingApplicationRequestCallback internal class InstrumentRequestCallback
{ {
private readonly IContextCarrierFactory _contextCarrierFactory; private readonly InstrumentConfig _config;
private readonly InstrumentationConfig _config; private readonly ITracingContext _tracingContext;
private readonly IEntrySegmentContextAccessor _contextAccessor;
public SkyWalkingApplicationRequestCallback(IConfigAccessor configAccessor, IContextCarrierFactory carrierFactory) public InstrumentRequestCallback(IConfigAccessor configAccessor, ITracingContext tracingContext,
IEntrySegmentContextAccessor contextAccessor)
{ {
_config = configAccessor.Get<InstrumentationConfig>(); _config = configAccessor.Get<InstrumentConfig>();
_contextCarrierFactory = carrierFactory; _tracingContext = tracingContext;
_contextAccessor = contextAccessor;
} }
public void ApplicationOnBeginRequest(object sender, EventArgs e) public void ApplicationOnBeginRequest(object sender, EventArgs e)
...@@ -44,113 +45,57 @@ namespace SkyWalking.AspNet ...@@ -44,113 +45,57 @@ namespace SkyWalking.AspNet
var httpApplication = sender as HttpApplication; var httpApplication = sender as HttpApplication;
var httpContext = httpApplication.Context; var httpContext = httpApplication.Context;
if(httpContext.Request.HttpMethod == "OPTIONS") if (httpContext.Request.HttpMethod == "OPTIONS")
{ {
//asp.net Exclude OPTIONS request //asp.net Exclude OPTIONS request
return; return;
} }
var context = _tracingContext.CreateEntrySegmentContext(httpContext.Request.Path,
var carrier = _contextCarrierFactory.Create(); new HttpRequestCarrierHeaderCollection(httpContext.Request));
foreach (var item in carrier.Items) context.Span.SpanLayer = SpanLayer.HTTP;
item.HeadValue = httpContext.Request.Headers[item.HeadKey]; context.Span.Peer = new StringOrIntValue(httpContext.Request.UserHostAddress);
var httpRequestSpan = ContextManager.CreateEntrySpan($"{_config.ApplicationCode} {httpContext.Request.Path}", carrier); context.Span.Component = Common.Components.ASPNET;
httpRequestSpan.AsHttp(); context.Span.AddTag(Tags.URL, httpContext.Request.Url.OriginalString);
httpRequestSpan.SetComponent(ComponentsDefine.AspNet); context.Span.AddTag(Tags.PATH, httpContext.Request.Path);
Tags.Url.Set(httpRequestSpan, httpContext.Request.Path); context.Span.AddTag(Tags.HTTP_METHOD, httpContext.Request.HttpMethod);
Tags.HTTP.Method.Set(httpRequestSpan, httpContext.Request.HttpMethod); context.Span.AddLog(LogEvent.Event("AspNet BeginRequest"),
LogEvent.Message(
var dictLog = new Dictionary<string, object> $"Request starting {httpContext.Request.Url.Scheme} {httpContext.Request.HttpMethod} {httpContext.Request.Url.OriginalString}"));
{
{"event", "AspNet BeginRequest"},
{"message", $"Request starting {httpContext.Request.Url.Scheme} {httpContext.Request.HttpMethod} {httpContext.Request.Url.OriginalString}"}
};
// record request body data
SetBodyData(httpContext.Request, dictLog);
httpRequestSpan.Log(DateTimeOffset.UtcNow.ToUnixTimeMilliseconds(), dictLog);
httpContext.Items.Add("span_Context", ContextManager.ActiveContext);
} }
public void ApplicationOnEndRequest(object sender, EventArgs e) public void ApplicationOnEndRequest(object sender, EventArgs e)
{ {
var context = _contextAccessor.Context;
if (context == null)
{
return;
}
var httpApplication = sender as HttpApplication; var httpApplication = sender as HttpApplication;
var httpContext = httpApplication.Context; var httpContext = httpApplication.Context;
ITracerContext context=null;
if (httpContext.Request.HttpMethod == "OPTIONS") if (httpContext.Request.HttpMethod == "OPTIONS")
{ {
//asp.net Exclude OPTIONS request //asp.net Exclude OPTIONS request
return; return;
} }
var httpRequestSpan = ContextManager.ActiveSpan;
if (httpRequestSpan == null)
{
// ContextManager.ActiveSpan is null, from httpContext.Items
if(!httpContext.Items.Contains("span_Context"))
return;
context = httpContext.Items["span_Context"] as ITracerContext;
if (context == null)
return;
httpRequestSpan = context.ActiveSpan;
if (httpRequestSpan == null)
return;
}
var statusCode = httpContext.Response.StatusCode; var statusCode = httpContext.Response.StatusCode;
if (statusCode >= 400) if (statusCode >= 400)
{ {
httpRequestSpan.ErrorOccurred(); context.Span.ErrorOccurred();
} }
Tags.StatusCode.Set(httpRequestSpan, statusCode.ToString());
var exception = httpContext.Error; var exception = httpContext.Error;
if (exception != null) if (exception != null)
{ {
httpRequestSpan.ErrorOccurred().Log(exception); context.Span.ErrorOccurred(exception);
} }
httpRequestSpan.Log(DateTimeOffset.UtcNow.ToUnixTimeMilliseconds(), context.Span.AddLog(LogEvent.Event("AspNet EndRequest"),
new Dictionary<string, object> LogEvent.Message(
{ $"Request finished {httpContext.Response.StatusCode} {httpContext.Response.ContentType}"));
{"event", "AspNet EndRequest"},
{"message", $"Request finished {httpContext.Response.StatusCode} {httpContext.Response.ContentType}"}
});
ContextManager.StopSpan(httpRequestSpan, context); _tracingContext.Release(context);
}
/// <summary>
/// record request body data
/// </summary>
/// <param name="request"></param>
/// <param name="dict"></param>
private void SetBodyData(HttpRequest request, Dictionary<string, object> dict)
{
if (request.HttpMethod == "GET")
{
return;
}
if (dict == null)
dict = new Dictionary<string, object>();
if (request.ContentType?.ToLower().Contains("multipart/form-data")??false)
{
dict.Add("ContentLength", request.ContentLength);
return;
}
var stearm = request.GetBufferedInputStream();
using (StreamReader sr = new StreamReader(stearm))
{
var bodyStr = sr.ReadToEnd();
dict.Add("Body", bodyStr);
}
} }
} }
} }
\ No newline at end of file
...@@ -28,5 +28,6 @@ ...@@ -28,5 +28,6 @@
<PackageReference Include="Microsoft.Extensions.Configuration" Version="2.2.0" /> <PackageReference Include="Microsoft.Extensions.Configuration" Version="2.2.0" />
<PackageReference Include="Microsoft.Extensions.DependencyInjection" Version="2.2.0" /> <PackageReference Include="Microsoft.Extensions.DependencyInjection" Version="2.2.0" />
<PackageReference Include="Microsoft.Web.Infrastructure" Version="1.0.0" /> <PackageReference Include="Microsoft.Web.Infrastructure" Version="1.0.0" />
<PackageReference Include="Nito.AsyncEx.Context" Version="1.1.0" />
</ItemGroup> </ItemGroup>
</Project> </Project>
\ No newline at end of file
/* /*
* Licensed to the OpenSkywalking under one or more * Licensed to the OpenSkywalking under one or more
* contributor license agreements. See the NOTICE file distributed with * contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership. * this work for additional information regarding copyright ownership.
...@@ -16,19 +16,21 @@ ...@@ -16,19 +16,21 @@
* *
*/ */
using SkyWalking.Context.Trace; using System;
using System.Text;
namespace SkyWalking.Context.Tag namespace SkyWalking
{ {
public class StringTag : AbstractTag<string> public class Base64Formatter : IBase64Formatter
{ {
public StringTag(string tagKey) : base(tagKey) public string Decode(string value)
{ {
return value == null ? value : Encoding.UTF8.GetString(Convert.FromBase64String(value));
} }
public override void Set(ISpan span, string tagValue) public string Encode(string value)
{ {
span.Tag(Key, tagValue); return value == null ? value : Convert.ToBase64String(Encoding.UTF8.GetBytes(value));
} }
} }
} }
\ No newline at end of file
...@@ -2,7 +2,7 @@ ...@@ -2,7 +2,7 @@
* Licensed to the OpenSkywalking under one or more * Licensed to the OpenSkywalking under one or more
* contributor license agreements. See the NOTICE file distributed with * contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership. * this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0 * The OpenSkywalking licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with * (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at * the License. You may obtain a copy of the License at
* *
...@@ -18,7 +18,7 @@ ...@@ -18,7 +18,7 @@
using System.Threading; using System.Threading;
namespace SkyWalking.Utils namespace SkyWalking.Common
{ {
public class AtomicInteger public class AtomicInteger
{ {
......
...@@ -2,7 +2,7 @@ ...@@ -2,7 +2,7 @@
* Licensed to the OpenSkywalking under one or more * Licensed to the OpenSkywalking under one or more
* contributor license agreements. See the NOTICE file distributed with * contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership. * this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0 * The OpenSkywalking licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with * (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at * the License. You may obtain a copy of the License at
* *
...@@ -20,7 +20,7 @@ using System.Linq; ...@@ -20,7 +20,7 @@ using System.Linq;
using System.Net; using System.Net;
using System.Net.Sockets; using System.Net.Sockets;
namespace SkyWalking.Utils namespace SkyWalking.Common
{ {
public static class DnsHelpers public static class DnsHelpers
{ {
......
...@@ -2,7 +2,7 @@ ...@@ -2,7 +2,7 @@
* Licensed to the OpenSkywalking under one or more * Licensed to the OpenSkywalking under one or more
* contributor license agreements. See the NOTICE file distributed with * contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership. * this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0 * The OpenSkywalking licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with * (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at * the License. You may obtain a copy of the License at
* *
...@@ -19,7 +19,7 @@ ...@@ -19,7 +19,7 @@
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
namespace SkyWalking.Utils namespace SkyWalking.Common
{ {
internal static class EnumerableExtensions internal static class EnumerableExtensions
{ {
......
...@@ -16,36 +16,32 @@ ...@@ -16,36 +16,32 @@
* *
*/ */
using System; using System.Runtime.InteropServices;
using System.Threading;
using System.Threading.Tasks;
namespace SkyWalking.AspNet namespace SkyWalking.Common
{ {
internal static class AsyncContext internal static class PlatformInformation
{ {
public static void Run(Func<Task> task) private const string OSX = "Mac OS X";
private const string LINUX = "Linux";
private const string WINDOWS = "Windows";
public static string GetOSName()
{ {
using (new ContextScope()) if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows))
{ {
Task.Run(async () => await task()).GetAwaiter().GetResult(); return WINDOWS;
} }
} if (RuntimeInformation.IsOSPlatform(OSPlatform.Linux))
private class ContextScope : IDisposable
{
private readonly SynchronizationContext _current;
public ContextScope()
{ {
_current = SynchronizationContext.Current; return LINUX;
SynchronizationContext.SetSynchronizationContext(null);
} }
if (RuntimeInformation.IsOSPlatform(OSPlatform.OSX))
public void Dispose()
{ {
SynchronizationContext.SetSynchronizationContext(_current); return OSX;
} }
return "Unknown";
} }
} }
} }
...@@ -2,7 +2,7 @@ ...@@ -2,7 +2,7 @@
* Licensed to the OpenSkywalking under one or more * Licensed to the OpenSkywalking under one or more
* contributor license agreements. See the NOTICE file distributed with * contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership. * this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0 * The OpenSkywalking licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with * (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at * the License. You may obtain a copy of the License at
* *
...@@ -18,7 +18,7 @@ ...@@ -18,7 +18,7 @@
using System.Collections.Generic; using System.Collections.Generic;
namespace SkyWalking.Utils namespace SkyWalking.Common
{ {
public static class StackExtensions public static class StackExtensions
{ {
......
/* /*
* Licensed to the OpenSkywalking under one or more * Licensed to the OpenSkywalking under one or more
* contributor license agreements. See the NOTICE file distributed with * contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership. * this work for additional information regarding copyright ownership.
* The OpenSkywalking licenses this file to You under the Apache License, Version 2.0 * The OpenSkywalking licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with * (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at * the License. You may obtain a copy of the License at
* *
* http://www.apache.org/licenses/LICENSE-2.0 * http://www.apache.org/licenses/LICENSE-2.0
* *
* Unless required by applicable law or agreed to in writing, software * Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, * distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and * See the License for the specific language governing permissions and
* limitations under the License. * limitations under the License.
* *
*/ */
namespace SkyWalking.Components using System;
{
public class OfficialComponent : IComponent namespace SkyWalking.Common
{ {
public OfficialComponent(int id, string name) public static class StringOrIntValueHelpers
{ {
Id = id; public static StringOrIntValue ParseStringOrIntValue(string value)
Name = name; {
} return value.StartsWith("#") ? new StringOrIntValue(new string(value.AsSpan().Slice(1, value.Length - 1).ToArray())) : new StringOrIntValue(int.Parse(value));
}
public int Id { get; } }
public string Name { get; }
}
} }
\ No newline at end of file
/*
* Licensed to the OpenSkywalking under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The OpenSkywalking licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
*/
namespace SkyWalking.Context
{
public class CarrierItemHead : CarrierItem
{
public CarrierItemHead(CarrierItem next, string @namespace) : base(string.Empty, string.Empty, next, @namespace)
{
}
}
}
\ No newline at end of file
/*
* Licensed to the OpenSkywalking under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The OpenSkywalking licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
*/
using System.Collections.Generic;
using System.Linq;
using SkyWalking.Context.Ids;
namespace SkyWalking.Context
{
public class ContextCarrier : IContextCarrier
{
private ID _traceSegmentId;
/// <summary>
/// id of parent span
/// </summary>
private int _spanId = -1;
/// <summary>
/// id of parent application instance
/// </summary>
private int _parentApplicationInstanceId = 0;
/// <summary>
/// id of first application instance in this distributed trace
/// </summary>
private int _entryApplicationInstanceId = 0;
/// <summary>
/// peer(ipv4/ipv6/hostname + port) of the server , from client side .
/// </summary>
private string _peerHost;
private int _peerId;
/// <summary>
/// Operation/Service name of the first one in this distributed trace .
/// </summary>
private string _entryOperationName;
private int _entryOperationId;
/// <summary>
/// Operation/Service name of the parent one in this distributed trace .
/// </summary>
private string _parentOperationName;
private int _parentOperationId;
private DistributedTraceId _primaryDistributedTraceId;
private readonly string _namespace;
public ContextCarrier(string @namespace)
{
_namespace = @namespace;
}
public DistributedTraceId DistributedTraceId => _primaryDistributedTraceId;
public int EntryApplicationInstanceId
{
get => _entryApplicationInstanceId;
set => _entryApplicationInstanceId = value;
}
public string EntryOperationName
{
get => _entryOperationName;
set => _entryOperationName = "#" + value;
}
public int EntryOperationId
{
get => _entryOperationId;
set => _entryOperationId = value;
}
public int ParentApplicationInstanceId
{
get => _parentApplicationInstanceId;
set => _parentApplicationInstanceId = value;
}
public string ParentOperationName
{
get => _parentOperationName;
set => _parentOperationName = "#" + value;
}
public int ParentOperationId
{
get => _parentOperationId;
set => _parentOperationId = value;
}
public string PeerHost
{
get => _peerHost;
set => _peerHost = "#" + value;
}
public int PeerId
{
get => _peerId;
set => _peerId = value;
}
public int SpanId
{
get => _spanId;
set => _spanId = value;
}
public ID TraceSegmentId
{
get => _traceSegmentId;
set => _traceSegmentId = value;
}
public bool IsValid
{
get
{
return _traceSegmentId != null
&& _traceSegmentId.IsValid
&& _spanId > -1
&& _parentApplicationInstanceId != 0
&& _entryApplicationInstanceId != 0
&& !string.IsNullOrEmpty(_peerHost)
&& !string.IsNullOrEmpty(_parentOperationName)
&& !string.IsNullOrEmpty(_entryOperationName)
&& _primaryDistributedTraceId != null;
}
}
public IContextCarrier Deserialize(string text)
{
string[] parts = text?.Split("|".ToCharArray(), 8);
if (parts?.Length == 8)
{
_traceSegmentId = new ID(parts[0]);
_spanId = int.Parse(parts[1]);
_parentApplicationInstanceId = int.Parse(parts[2]);
_entryApplicationInstanceId = int.Parse(parts[3]);
_peerHost = parts[4];
_entryOperationName = parts[5];
_parentOperationName = parts[6];
_primaryDistributedTraceId = new PropagatedTraceId(parts[7]);
}
return this;
}
public string Serialize()
{
if (!IsValid)
{
return string.Empty;
}
return string.Join("|",
TraceSegmentId.Encode,
SpanId.ToString(),
ParentApplicationInstanceId.ToString(),
EntryApplicationInstanceId.ToString(),
PeerHost,
EntryOperationName,
ParentOperationName,
PrimaryDistributedTraceId.Encode);
}
public DistributedTraceId PrimaryDistributedTraceId => _primaryDistributedTraceId;
public CarrierItem Items
{
get
{
var carrierItem = new SW3CarrierItem(this, null, _namespace);
var head = new CarrierItemHead(carrierItem, _namespace);
return head;
}
}
public void SetDistributedTraceIds(IEnumerable<DistributedTraceId> distributedTraceIds)
{
_primaryDistributedTraceId = distributedTraceIds.FirstOrDefault();
}
}
}
\ No newline at end of file
/*
* Licensed to the OpenSkywalking under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The OpenSkywalking licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
*/
using System.Collections.Generic;
using System.Threading;
using SkyWalking.Context.Trace;
namespace SkyWalking.Context
{
/// <summary>
/// Context manager controls the whole context of tracing. Since .NET server application runs as same as Java,
/// We also provide the CONTEXT propagation based on ThreadLocal mechanism.
/// Meaning, each segment also related to singe thread.
/// </summary>
public class ContextManager : ITracingContextListener, IIgnoreTracerContextListener
{
static ContextManager()
{
var manager = new ContextManager();
TracingContext.ListenerManager.Add(manager);
IgnoredTracerContext.ListenerManager.Add(manager);
}
private static readonly AsyncLocal<ITracerContext> _context = new AsyncLocal<ITracerContext>();
private static ITracerContext GetOrCreateContext(string operationName, bool forceSampling)
{
var context = _context.Value;
if (context == null)
{
if (string.IsNullOrEmpty(operationName))
{
// logger.debug("No operation name, ignore this trace.");
_context.Value = new IgnoredTracerContext();
}
else
{
if (RuntimeEnvironment.Instance.Initialized)
{
// var suffixIdx = operationName.LastIndexOf('.');
// if (suffixIdx > -1 && AgentConfig.IgnoreSuffix.Contains(operationName.Substring(suffixIdx)))
// {
// _context.Value = new IgnoredTracerContext();
// }
// else
// {
var sampler = DefaultSampler.Instance;
if (forceSampling || sampler.Sampled())
{
_context.Value = new TracingContext();
}
else
{
_context.Value = new IgnoredTracerContext();
}
// }
}
else
{
_context.Value = new IgnoredTracerContext();
}
}
}
return _context.Value;
}
private static ITracerContext Context => _context.Value;
public static string GlobalTraceId
{
get
{
if (_context.Value != null)
{
return _context.Value.GetReadableGlobalTraceId();
}
return "N/A";
}
}
public static IContextSnapshot Capture => _context.Value?.Capture;
public static IDictionary<string, object> ContextProperties => _context.Value?.Properties;
public static ISpan CreateEntrySpan(string operationName, IContextCarrier carrier)
{
var samplingService = DefaultSampler.Instance;
if (carrier != null && carrier.IsValid)
{
samplingService.ForceSampled();
var context = GetOrCreateContext(operationName, true);
var span = context.CreateEntrySpan(operationName);
context.Extract(carrier);
return span;
}
else
{
var context = GetOrCreateContext(operationName, false);
return context.CreateEntrySpan(operationName);
}
}
public static ISpan CreateLocalSpan(string operationName)
{
var context = GetOrCreateContext(operationName, false);
return context.CreateLocalSpan(operationName);
}
public static ISpan CreateExitSpan(string operationName, IContextCarrier carrier, string remotePeer)
{
var context = GetOrCreateContext(operationName, false);
var span = context.CreateExitSpan(operationName, remotePeer);
context.Inject(carrier);
return span;
}
public static ISpan CreateExitSpan(string operationName, string remotePeer)
{
var context = GetOrCreateContext(operationName, false);
var span = context.CreateExitSpan(operationName, remotePeer);
return span;
}
public static void Inject(IContextCarrier carrier)
{
Context?.Inject(carrier);
}
public static void Extract(IContextCarrier carrier)
{
Context?.Extract(carrier);
}
public static void Continued(IContextSnapshot snapshot)
{
if (snapshot.IsValid && !snapshot.IsFromCurrent)
{
Context?.Continued(snapshot);
}
}
public static void StopSpan()
{
StopSpan(ActiveSpan);
}
public static ISpan ActiveSpan
{
get { return Context?.ActiveSpan; }
}
public static ITracerContext ActiveContext
{
get
{
return Context;
}
}
public static void StopSpan(ISpan span, ITracerContext context=null)
{
if (Context != null)
{
Context.StopSpan(span);
}
else if (context != null)
{
context.StopSpan(span);
}
}
public void AfterFinished(ITraceSegment traceSegment)
{
_context.Value = null;
}
public void AfterFinish(ITracerContext tracerContext)
{
_context.Value = null;
}
}
}
\ No newline at end of file
/*
* Licensed to the OpenSkywalking under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The OpenSkywalking licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
*/
using System.Collections.Generic;
using System.Linq;
using SkyWalking.Context.Ids;
namespace SkyWalking.Context
{
public class ContextSnapshot : IContextSnapshot
{
/// <summary>
/// Trace Segment Id of the parent trace segment
/// </summary>
private readonly ID _traceSegmentId;
/// <summary>
/// span id of the parent span , in parent trace segment
/// </summary>
private readonly int _spanId = -1;
private string _entryOperationName;
private string _parentOperationName;
private readonly DistributedTraceId _primaryDistributedTraceId;
private NullableValue _entryApplicationInstanceId = NullableValue.Null;
public ContextSnapshot(ID traceSegmentId, int spanId, IEnumerable<DistributedTraceId> distributedTraceIds)
{
_traceSegmentId = traceSegmentId;
_spanId = spanId;
_primaryDistributedTraceId = distributedTraceIds?.FirstOrDefault();
}
public string EntryOperationName
{
get => _entryOperationName;
set => _entryOperationName = "#" + value;
}
public string ParentOperationName
{
get => _parentOperationName;
set => _parentOperationName = "#" + value;
}
public DistributedTraceId DistributedTraceId => _primaryDistributedTraceId;
public int EntryApplicationInstanceId
{
get => _entryApplicationInstanceId.Value;
set => _entryApplicationInstanceId = new NullableValue(value);
}
public int SpanId => _spanId;
public bool IsFromCurrent => _traceSegmentId.Equals(ContextManager.Capture.TraceSegmentId);
public bool IsValid => _traceSegmentId != null
&& _spanId > -1
&& _entryApplicationInstanceId.HasValue
&& _primaryDistributedTraceId != null
&& string.IsNullOrEmpty(_entryOperationName)
&& string.IsNullOrEmpty(_parentOperationName);
public ID TraceSegmentId => _traceSegmentId;
public int EntryOperationId
{
set => _entryOperationName = value + "";
}
public int ParentOperationId
{
set => _parentOperationName = value + "";
}
}
}
\ No newline at end of file
/*
* Licensed to the OpenSkywalking under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The OpenSkywalking licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
*/
namespace SkyWalking.Context.Ids
{
public class NewDistributedTraceId : DistributedTraceId
{
public NewDistributedTraceId()
:base(GlobalIdGenerator.Generate())
{
}
}
}
/*
* Licensed to the OpenSkywalking under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The OpenSkywalking licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
*/
namespace SkyWalking.Context.Ids
{
/// <summary>
/// The <code>PropagatedTraceId</code> represents a {@link DistributedTraceId}, which is propagated from the peer.
/// </summary>
public class PropagatedTraceId : DistributedTraceId
{
public PropagatedTraceId(string id)
:base(id)
{
}
}
}
/*
* Licensed to the OpenSkywalking under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The OpenSkywalking licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
*/
using System;
using System.Collections.Generic;
using System.Runtime.CompilerServices;
using SkyWalking.Context.Trace;
using SkyWalking.Utils;
namespace SkyWalking.Context
{
public class IgnoredTracerContext : ITracerContext
{
private static readonly NoopSpan noopSpan = new NoopSpan();
private static readonly NoopEntrySpan noopEntrySpan=new NoopEntrySpan();
private readonly Stack<ISpan> _spans = new Stack<ISpan>();
public void Inject(IContextCarrier carrier)
{
}
public void Extract(IContextCarrier carrier)
{
}
public IContextSnapshot Capture { get; }
public ISpan ActiveSpan
{
get
{
_spans.TryPeek(out var span);
return span;
}
}
public IDictionary<string, object> Properties { get; } = new Dictionary<string, object>();
public void Continued(IContextSnapshot snapshot)
{
}
public string GetReadableGlobalTraceId()
{
return string.Empty;
}
public ISpan CreateEntrySpan(string operationName)
{
_spans.Push(noopEntrySpan);
return noopEntrySpan;
}
public ISpan CreateLocalSpan(string operationName)
{
_spans.Push(noopSpan);
return noopSpan;
}
public ISpan CreateExitSpan(string operationName, string remotePeer)
{
var exitSpan = new NoopExitSpan(remotePeer);
_spans.Push(exitSpan);
return exitSpan;
}
public void StopSpan(ISpan span)
{
_spans.TryPop(out _);
if (_spans.Count == 0)
{
ListenerManager.NotifyFinish(this);
foreach (var item in Properties)
{
if (item.Value is IDisposable disposable)
{
disposable.Dispose();
}
}
}
}
public static class ListenerManager
{
private static readonly List<IIgnoreTracerContextListener> _listeners = new List<IIgnoreTracerContextListener>();
[MethodImpl(MethodImplOptions.Synchronized)]
public static void Add(IIgnoreTracerContextListener listener)
{
_listeners.Add(listener);
}
public static void NotifyFinish(ITracerContext tracerContext)
{
foreach (var listener in _listeners)
{
listener.AfterFinish(tracerContext);
}
}
[MethodImpl(MethodImplOptions.Synchronized)]
public static void Remove(IIgnoreTracerContextListener listener)
{
_listeners.Remove(listener);
}
}
}
}
\ No newline at end of file
/*
* Licensed to the OpenSkywalking under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The OpenSkywalking licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
*/
using System;
namespace SkyWalking.Context
{
public class SW3CarrierItem : CarrierItem
{
private const string HEADER_NAME = "sw3";
private readonly IContextCarrier _carrier;
public SW3CarrierItem(IContextCarrier carrier, CarrierItem next, string @namespace)
: base(HEADER_NAME, carrier.Serialize(), next, @namespace)
{
_carrier = carrier;
}
public override string HeadValue
{
get => base.HeadValue;
set => _carrier.Deserialize(value);
}
}
}
\ No newline at end of file
/*
* Licensed to the OpenSkywalking under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The OpenSkywalking licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
*/
namespace SkyWalking.Context.Tag
{
/// <summary>
/// The span tags are supported by sky-walking engine.
/// As default, all tags will be stored, but these ones have particular meanings.
/// </summary>
public static class Tags
{
public static readonly StringTag Url = new StringTag("url");
/// <summary>
/// STATUS_CODE records the http status code of the response.
/// </summary>
public static readonly StringTag StatusCode = new StringTag("status_code");
/// <summary>
/// DB_TYPE records database type, such as sql, redis, cassandra and so on.
/// </summary>
public static readonly StringTag DbType = new StringTag("db.type");
/// <summary>
/// DB_INSTANCE records database instance name.
/// </summary>
public static readonly StringTag DbInstance = new StringTag("db.instance");
/// <summary>
/// DB_STATEMENT records the sql statement of the database access.
/// </summary>
public static readonly StringTag DbStatement = new StringTag("db.statement");
/// <summary>
/// DB_BIND_VARIABLES records the bind variables of sql statement.
/// </summary>
public static readonly StringTag DbBindVariables = new StringTag("db.bind_vars");
/// <summary>
/// MQ_BROKER records the broker address of message-middleware
/// </summary>
public static readonly StringTag MqBorker = new StringTag("mq.broker");
/// <summary>
/// MQ_TOPIC records the topic name of message-middleware
/// </summary>
public static readonly StringTag MqTopic = new StringTag("mq.topic");
public static class HTTP
{
public static readonly StringTag Method = new StringTag("http.method");
}
}
}
\ No newline at end of file
/*
* Licensed to the OpenSkywalking under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The OpenSkywalking licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
*/
using SkyWalking.Components;
namespace SkyWalking.Context.Trace
{
public class EntrySpan : StackBasedTracingSpan
{
private int _currentMaxDepth;
public EntrySpan(int spanId, int parentSpanId, string operationName)
: base(spanId, parentSpanId, operationName)
{
_stackDepth = 0;
}
public EntrySpan(int spanId, int parentSpanId, int operationId)
: base(spanId, parentSpanId, operationId)
{
_stackDepth = 0;
}
public override bool IsEntry => true;
public override bool IsExit => false;
public override ISpan Start()
{
if ((_currentMaxDepth = ++_stackDepth) == 1)
{
base.Start();
}
ClearWhenRestart();
return this;
}
public override ISpan Tag(string key, string value)
{
if (_stackDepth == _currentMaxDepth)
{
base.Tag(key, value);
}
return this;
}
public override ISpan SetLayer(SpanLayer layer)
{
if (_stackDepth == _currentMaxDepth)
{
return base.SetLayer(layer);
}
return this;
}
public override ISpan SetComponent(IComponent component)
{
if (_stackDepth == _currentMaxDepth)
{
return base.SetComponent(component);
}
return this;
}
public override ISpan SetComponent(string componentName)
{
if (_stackDepth == _currentMaxDepth)
{
return base.SetComponent(componentName);
}
return this;
}
public override string OperationName
{
get
{
return base.OperationName;
}
set
{
if (_stackDepth == _currentMaxDepth)
{
base.OperationName = value;
}
}
}
public override int OperationId
{
get
{
return base.OperationId;
}
set
{
if (_stackDepth == _currentMaxDepth)
{
base.OperationId = value;
}
}
}
private void ClearWhenRestart()
{
_componentId = 0;
_componentName = null;
_layer = null;
_logs = null;
_tags = null;
}
}
}
/*
* Licensed to the OpenSkywalking under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The OpenSkywalking licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
*/
using System;
using SkyWalking.Transport;
using SkyWalking.Components;
namespace SkyWalking.Context.Trace
{
public class ExitSpan : StackBasedTracingSpan, IWithPeerInfo
{
private readonly string _peer;
private readonly int _peerId;
public ExitSpan(int spanId, int parentSpanId, String operationName, String peer)
: base(spanId, parentSpanId, operationName)
{
_peer = peer;
_peerId = 0;
}
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 = 0;
}
public ExitSpan(int spanId, int parentSpanId, String operationName, int peerId)
: base(spanId, parentSpanId, operationName)
{
_peer = null;
_peerId = peerId;
}
public override bool IsEntry => false;
public override bool IsExit => true;
public int PeerId => _peerId;
public string Peer => _peer;
public override ISpan Start()
{
if (++_stackDepth == 1)
{
base.Start();
}
return base.Start();
}
public override ISpan Tag(string key, string value)
{
if (_stackDepth == 1)
{
base.Tag(key, value);
}
return this;
}
public override ISpan SetLayer(SpanLayer layer)
{
if (_stackDepth == 1)
{
return base.SetLayer(layer);
}
return this;
}
public override ISpan SetComponent(IComponent component)
{
if (_stackDepth == 1)
{
return base.SetComponent(component);
}
return this;
}
public override ISpan SetComponent(string componentName)
{
return _stackDepth == 1 ? base.SetComponent(componentName) : this;
}
public override string OperationName
{
get => base.OperationName;
set
{
if (_stackDepth == 1)
{
base.OperationName = value;
}
}
}
public override int OperationId
{
get => base.OperationId;
set
{
if (_stackDepth == 1)
{
base.OperationId = value;
}
}
}
public override SpanRequest Transform()
{
var spanObject = base.Transform();
spanObject.Peer = new StringOrIntValue(_peerId, _peer);
return spanObject;
}
}
}
/*
* Licensed to the OpenSkywalking under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The OpenSkywalking licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
*/
namespace SkyWalking.Context.Trace
{
public class LocalSpan : StackBasedTracingSpan
{
public LocalSpan(int spanId, int parentSpanId, string operationName) : base(spanId, parentSpanId, operationName)
{
}
public LocalSpan(int spanId, int parentSpanId, int operationId) : base(spanId, parentSpanId, operationId)
{
}
public override bool IsEntry => false;
public override bool IsExit => false;
}
}
/*
* Licensed to the OpenSkywalking under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The OpenSkywalking licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
*/
namespace SkyWalking.Context.Trace
{
public class NoopEntrySpan:NoopSpan
{
public override bool IsEntry { get; } = true;
}
}
\ No newline at end of file
/*
* Licensed to the OpenSkywalking under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The OpenSkywalking licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
*/
using System.Collections.Generic;
using System.Linq;
using SkyWalking.Transport;
using SkyWalking.Context.Ids;
namespace SkyWalking.Context.Trace
{
public class TraceSegment : ITraceSegment
{
private readonly IList<ITraceSegmentRef> _refs;
private readonly IList<AbstractTracingSpan> _spans;
private readonly DistributedTraceIdCollection _relatedGlobalTraces;
private bool _isSizeLimited;
public int ApplicationId => RuntimeEnvironment.Instance.ServiceId.Value;
public int ApplicationInstanceId => RuntimeEnvironment.Instance.ServiceInstanceId.Value;
public IEnumerable<ITraceSegmentRef> Refs => _refs;
public IEnumerable<DistributedTraceId> RelatedGlobalTraces => _relatedGlobalTraces.GetRelatedGlobalTraces();
public ID TraceSegmentId { get; }
public bool HasRef => _refs.Count > 0;
public bool IsIgnore { get; set; }
public bool IsSingleSpanSegment => _spans.Count == 1;
public TraceSegment()
{
TraceSegmentId = GlobalIdGenerator.Generate();
_spans = new List<AbstractTracingSpan>();
_relatedGlobalTraces = new DistributedTraceIdCollection();
_relatedGlobalTraces.Append(new NewDistributedTraceId());
_refs = new List<ITraceSegmentRef>();
}
public void Archive(AbstractTracingSpan finishedSpan)
{
_spans.Add(finishedSpan);
}
public ITraceSegment Finish(bool isSizeLimited)
{
_isSizeLimited = isSizeLimited;
return this;
}
/// <summary>
/// Establish the link between this segment and its parents.
/// </summary>
public void Ref(ITraceSegmentRef refSegment)
{
if (!_refs.Contains(refSegment))
{
_refs.Add(refSegment);
}
}
public void RelatedGlobalTrace(DistributedTraceId distributedTraceId)
{
_relatedGlobalTraces.Append(distributedTraceId);
}
public SegmentRequest Transform()
{
var upstreamSegment = new SegmentRequest
{
UniqueIds = _relatedGlobalTraces.GetRelatedGlobalTraces()
.Select(x => x.ToUniqueId()).ToArray()
};
upstreamSegment.Segment = new SegmentObjectRequest
{
SegmentId = TraceSegmentId.Transform(),
Spans = _spans.Select(x => x.Transform()).ToArray(),
ServiceId = ApplicationId,
ServiceInstanceId = ApplicationInstanceId
};
return upstreamSegment;
}
public override string ToString()
{
return "TraceSegment{"
+
$"traceSegmentId='{TraceSegmentId}', refs={_refs}, spans={_spans}, relatedGlobalTraces={_relatedGlobalTraces}"
+ "}";
}
}
}
\ No newline at end of file
/*
* Licensed to the OpenSkywalking under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The OpenSkywalking licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
*/
using System.Linq;
using SkyWalking.Transport;
using SkyWalking.Config;
using SkyWalking.Context.Ids;
namespace SkyWalking.Context.Trace
{
public class TraceSegmentRef : ITraceSegmentRef
{
private readonly SegmentRefType _type;
private readonly ID _traceSegmentId;
private readonly int _spanId = -1;
private readonly int _peerId = 0;
private readonly string _peerHost;
private readonly int _entryApplicationInstanceId = 0;
private readonly int _parentApplicationInstanceId = 0;
private readonly string _entryOperationName;
private readonly int _entryOperationId = 0;
private readonly string _parentOperationName;
private readonly int _parentOperationId = 0;
public TraceSegmentRef(IContextCarrier carrier)
{
_type = SegmentRefType.CrossProcess;
_traceSegmentId = carrier.TraceSegmentId;
_spanId = carrier.SpanId;
_parentApplicationInstanceId = carrier.ParentApplicationInstanceId;
_entryApplicationInstanceId = carrier.EntryApplicationInstanceId;
string host = carrier.PeerHost;
if (host.ToCharArray()[0] == '#')
{
_peerHost = host.Substring(1);
}
else
{
int.TryParse(host, out _peerId);
}
string entryOperationName = carrier.EntryOperationName;
if (entryOperationName.First() == '#')
{
_entryOperationName = entryOperationName.Substring(1);
}
else
{
int.TryParse(entryOperationName, out _entryOperationId);
}
string parentOperationName = carrier.EntryOperationName;
if (parentOperationName.First() == '#')
{
_parentOperationName = parentOperationName.Substring(1);
}
else
{
int.TryParse(parentOperationName, out _parentOperationId);
}
}
public TraceSegmentRef(IContextSnapshot contextSnapshot)
{
_type = SegmentRefType.CrossThread;
_traceSegmentId = contextSnapshot.TraceSegmentId;
_spanId = contextSnapshot.SpanId;
_parentApplicationInstanceId = RuntimeEnvironment.Instance.ServiceInstanceId.Value;
_entryApplicationInstanceId = contextSnapshot.EntryApplicationInstanceId;
string entryOperationName = contextSnapshot.EntryOperationName;
if (entryOperationName.First() == '#')
{
_entryOperationName = entryOperationName.Substring(1);
}
else
{
int.TryParse(entryOperationName, out _entryOperationId);
}
string parentOperationName = contextSnapshot.ParentOperationName;
if (parentOperationName.First() == '#')
{
_parentOperationName = parentOperationName.Substring(1);
}
else
{
int.TryParse(parentOperationName, out _parentOperationId);
}
}
public bool Equals(ITraceSegmentRef other)
{
if (other == null)
{
return false;
}
if (other == this)
{
return true;
}
if (!(other is TraceSegmentRef segmentRef))
{
return false;
}
if (_spanId != segmentRef._spanId)
{
return false;
}
return _traceSegmentId.Equals(segmentRef._traceSegmentId);
}
public override bool Equals(object obj)
{
var other = obj as ITraceSegmentRef;
return Equals(other);
}
public override int GetHashCode()
{
int result = _traceSegmentId.GetHashCode();
result = 31 * result + _spanId;
return result;
}
public string EntryOperationName => _entryOperationName;
public int EntryOperationId => _entryOperationId;
public int EntryApplicationInstanceId => _entryApplicationInstanceId;
public SegmentReferenceRequest Transform()
{
SegmentReferenceRequest segmentReference = new SegmentReferenceRequest();
if (_type == SegmentRefType.CrossProcess)
{
segmentReference.RefType = (int) SegmentRefType.CrossProcess;
segmentReference.NetworkAddress = new StringOrIntValue(_peerId, _peerHost);
}
else
{
segmentReference.RefType = (int) SegmentRefType.CrossThread;
segmentReference.NetworkAddress = new StringOrIntValue();
}
segmentReference.ParentServiceInstanceId = _parentApplicationInstanceId;
segmentReference.EntryServiceInstanceId = _entryApplicationInstanceId;
segmentReference.ParentSegmentId = _traceSegmentId.Transform();
segmentReference.ParentSpanId = _spanId;
segmentReference.EntryEndpointName = new StringOrIntValue(_entryOperationId, _entryOperationName);
segmentReference.ParentEndpointName = new StringOrIntValue(_parentOperationId, _parentOperationName);
return segmentReference;
}
}
}
/*
* Licensed to the OpenSkywalking under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The OpenSkywalking licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
*/
namespace SkyWalking.Context
{
public class TraceContextCarrierItem : CarrierItem
{
private const string HEAD_NAME = "Trace-Context";
public TraceContextCarrierItem(string headValue, CarrierItem next, string @namespace)
: base(HEAD_NAME, headValue, next, @namespace)
{
}
}
}
\ No newline at end of file
This diff is collapsed.
/*
* Licensed to the OpenSkywalking under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
*/
using System.Runtime.CompilerServices;
using SkyWalking.Utils;
namespace SkyWalking
{
public class DefaultSampler : ISampler
{
public static DefaultSampler Instance { get; } = new DefaultSampler();
private readonly AtomicInteger _idx = new AtomicInteger();
private int _samplePer3Secs;
private bool _sample_on;
public bool Sampled()
{
if (!_sample_on)
{
return true;
}
return _idx.Increment() < _samplePer3Secs;
}
public void ForceSampled()
{
if (_sample_on)
{
_idx.Increment();
}
}
[MethodImpl(MethodImplOptions.Synchronized)]
internal void SetSamplePer3Secs(int samplePer3Secs)
{
_samplePer3Secs = samplePer3Secs;
_sample_on = samplePer3Secs > -1;
}
internal void Reset()
{
_idx.Value = 0;
}
}
}
\ No newline at end of file
...@@ -19,8 +19,8 @@ ...@@ -19,8 +19,8 @@
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Diagnostics; using System.Diagnostics;
using SkyWalking.Common;
using SkyWalking.Logging; using SkyWalking.Logging;
using SkyWalking.Utils;
namespace SkyWalking.Diagnostics namespace SkyWalking.Diagnostics
{ {
......
...@@ -2,7 +2,7 @@ ...@@ -2,7 +2,7 @@
* Licensed to the OpenSkywalking under one or more * Licensed to the OpenSkywalking under one or more
* contributor license agreements. See the NOTICE file distributed with * contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership. * this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0 * The OpenSkywalking licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with * (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at * the License. You may obtain a copy of the License at
* *
...@@ -27,17 +27,17 @@ using SkyWalking.Logging; ...@@ -27,17 +27,17 @@ using SkyWalking.Logging;
namespace SkyWalking namespace SkyWalking
{ {
public class SkyWalkingAgentStartup : ISkyWalkingAgentStartup public class InstrumentStartup : IInstrumentStartup
{ {
private readonly TracingDiagnosticProcessorObserver _observer; private readonly TracingDiagnosticProcessorObserver _observer;
private readonly IEnumerable<IExecutionService> _services; private readonly IEnumerable<IExecutionService> _services;
private readonly ILogger _logger; private readonly ILogger _logger;
public SkyWalkingAgentStartup(TracingDiagnosticProcessorObserver observer, IEnumerable<IExecutionService> services, ILoggerFactory loggerFactory) public InstrumentStartup(TracingDiagnosticProcessorObserver observer, IEnumerable<IExecutionService> services, ILoggerFactory loggerFactory)
{ {
_observer = observer; _observer = observer;
_services = services; _services = services;
_logger = loggerFactory.CreateLogger(typeof(SkyWalkingAgentStartup)); _logger = loggerFactory.CreateLogger(typeof(InstrumentStartup));
} }
public async Task StartAsync(CancellationToken cancellationToken = default(CancellationToken)) public async Task StartAsync(CancellationToken cancellationToken = default(CancellationToken))
......
...@@ -2,7 +2,7 @@ ...@@ -2,7 +2,7 @@
* Licensed to the OpenSkywalking under one or more * Licensed to the OpenSkywalking under one or more
* contributor license agreements. See the NOTICE file distributed with * contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership. * this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0 * The OpenSkywalking licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with * (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at * the License. You may obtain a copy of the License at
* *
...@@ -17,6 +17,7 @@ ...@@ -17,6 +17,7 @@
*/ */
using System; using System;
using SkyWalking.Common;
namespace SkyWalking namespace SkyWalking
{ {
......
...@@ -20,16 +20,16 @@ using System; ...@@ -20,16 +20,16 @@ using System;
using System.Diagnostics; using System.Diagnostics;
using System.Threading; using System.Threading;
using System.Threading.Tasks; using System.Threading.Tasks;
using SkyWalking.Common;
using SkyWalking.Config; using SkyWalking.Config;
using SkyWalking.Logging; using SkyWalking.Logging;
using SkyWalking.Transport; using SkyWalking.Transport;
using SkyWalking.Utils;
namespace SkyWalking.Service namespace SkyWalking.Service
{ {
public class RegisterService : ExecutionService public class RegisterService : ExecutionService
{ {
private readonly InstrumentationConfig _config; private readonly InstrumentConfig _config;
private readonly IServiceRegister _serviceRegister; private readonly IServiceRegister _serviceRegister;
private readonly TransportConfig _transportConfig; private readonly TransportConfig _transportConfig;
...@@ -38,7 +38,7 @@ namespace SkyWalking.Service ...@@ -38,7 +38,7 @@ namespace SkyWalking.Service
loggerFactory) loggerFactory)
{ {
_serviceRegister = serviceRegister; _serviceRegister = serviceRegister;
_config = configAccessor.Get<InstrumentationConfig>(); _config = configAccessor.Get<InstrumentConfig>();
_transportConfig = configAccessor.Get<TransportConfig>(); _transportConfig = configAccessor.Get<TransportConfig>();
} }
......
...@@ -16,6 +16,7 @@ ...@@ -16,6 +16,7 @@
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<PackageReference Include="System.Diagnostics.DiagnosticSource" Version="4.5.1" /> <PackageReference Include="System.Diagnostics.DiagnosticSource" Version="4.5.1" />
<PackageReference Include="System.Memory" Version="4.5.2" />
<PackageReference Include="System.ValueTuple" Version="4.5.0" /> <PackageReference Include="System.ValueTuple" Version="4.5.0" />
</ItemGroup> </ItemGroup>
</Project> </Project>
\ No newline at end of file
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
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