未验证 提交 76f397bc 编写于 作者: S snakorse 提交者: GitHub

feature: v8 protocol support (#314)

* fix conflict and compatibility of hosting

* feature: v8 protocol support

* bugfix: UniqueId should support string part

* bugfix: StringOrNumValue gethashcode null exception fix.

* feature: Component add id value.

* optimize: Remove the jar binaries.

* optimize: Remove md5 for performance reason.

* bugfix: Fix the java bootstrap script error.

* bugfix: Component id not being passed to oap server properly.

* optimize: Prefer to use the integer value when do transport to reduce the payload.

* optimize: Set the HeaderVersions.SW6 as default.

* bugfix: Register the CLRStatsService and its dependency into IOC

* bugfix: Set HeaderVersions.SW8 as default

* Optimize: Remove old protocol related code && Change traceId to string && Support config instance name
Co-authored-by: NElderJames <shunjiey@hotmail.com>
Co-authored-by: N郭刚平 <gangping.guo@xiaobao100.com>
上级 8cb2a1fd
......@@ -265,4 +265,6 @@ tools/
*.proto
generated/
generated-v3/
/sample/java-integration-demo/agent
......@@ -2,3 +2,6 @@
[submodule "src/SkyApm.Transport.Grpc.Protocol/protocol"]
path = src/SkyApm.Transport.Grpc.Protocol/protocol
url = https://github.com/apache/incubator-skywalking-data-collect-protocol
[submodule "src/SkyApm.Transport.Grpc.Protocol/protocol-v3"]
path = src/SkyApm.Transport.Grpc.Protocol/protocol-v3
url = https://github.com/apache/incubator-skywalking-data-collect-protocol
......@@ -9,6 +9,8 @@
<PackageReference Include="BenchmarkDotNet" Version="0.*" />
<ProjectReference Include="..\..\src\SkyApm.Core\SkyApm.Core.csproj" />
<ProjectReference Include="..\..\src\SkyApm.Utilities.Configuration\SkyApm.Utilities.Configuration.csproj" />
</ItemGroup>
</Project>
using BenchmarkDotNet.Attributes;
using SkyApm.Config;
using SkyApm.Tracing;
using SkyApm.Utilities.Configuration;
using System;
using System.Collections;
using System.Linq;
namespace SkyApm.Benchmark
{
public class UniqueIdGenerate
{
private static readonly IUniqueIdGenerator Generator = new UniqueIdGenerator(new RuntimeEnvironment());
private static readonly IUniqueIdGenerator Generator;
static UniqueIdGenerate()
{
var configFactory = new ConfigurationFactory(null, Enumerable.Empty<IAdditionalConfigurationSource>());
var configAccessor = new ConfigAccessor(configFactory);
Generator = new UniqueIdGenerator(configAccessor);
}
[Benchmark]
public void Generate() => Generator.Generate();
......
using BenchmarkDotNet.Attributes;
using SkyApm.Tracing;
namespace SkyApm.Benchmark
{
public class UniqueIdParse
{
private static readonly IUniqueIdParser Parser = new UniqueIdParser();
private static readonly string Id = new UniqueId(long.MaxValue, long.MaxValue, long.MaxValue).ToString();
[Benchmark]
public void Parse() => Parser.TryParse(Id, out _);
}
}
......@@ -3,7 +3,7 @@
"ServiceName": "asp-net-core-backend",
"Namespace": "",
"HeaderVersions": [
"sw6"
"sw8"
],
"Sampling": {
"SamplePer3Secs": -1,
......@@ -15,7 +15,7 @@
},
"Transport": {
"Interval": 3000,
"ProtocolVersion": "v6",
"ProtocolVersion": "v8",
"QueueSize": 30000,
"BatchSize": 3000,
"gRPC": {
......
......@@ -66,6 +66,13 @@ namespace SkyApm.Sample.Frontend.Controllers
return Ok(message);
}
[HttpGet("hellojava")]
public async Task<IActionResult> HelloJava()
{
var message = await new HttpClient().GetStringAsync("http://localhost:8086/sayhello");
return Ok(message);
}
#if NETCOREAPP2_1
#else
[HttpGet("greeter/grpc-net")]
......
......@@ -3,7 +3,7 @@
"ServiceName": "asp-net-core-frontend",
"Namespace": "",
"HeaderVersions": [
"sw6"
"sw8"
],
"Sampling": {
"SamplePer3Secs": -1,
......@@ -15,7 +15,7 @@
},
"Transport": {
"Interval": 3000,
"ProtocolVersion": "v6",
"ProtocolVersion": "v8",
"QueueSize": 30000,
"BatchSize": 3000,
"gRPC": {
......
......@@ -11,7 +11,6 @@
<CopyToPublishDirectory>PreserveNewest</CopyToPublishDirectory>
</Content>
</ItemGroup>
<ItemGroup Condition="'$(TargetFramework)' == 'netcoreapp2.1'">
<PackageReference Include="Microsoft.Extensions.Hosting" Version="2.1.0" />
</ItemGroup>
......
......@@ -20,26 +20,26 @@ namespace SkyApm.Common
{
public static class Components
{
public static readonly StringOrIntValue ASPNETCORE= new StringOrIntValue("AspNetCore");
public static readonly StringOrIntValue ASPNETCORE= new StringOrIntValue(3001, "AspNetCore");
public static readonly StringOrIntValue HTTPCLIENT = new StringOrIntValue("HttpClient");
public static readonly StringOrIntValue HTTPCLIENT = new StringOrIntValue(2, "HttpClient");
public static readonly StringOrIntValue ENTITYFRAMEWORKCORE = new StringOrIntValue("EntityFrameworkCore");
public static readonly StringOrIntValue ENTITYFRAMEWORKCORE = new StringOrIntValue(3002, "EntityFrameworkCore");
public static readonly StringOrIntValue SQLCLIENT = new StringOrIntValue("SqlClient");
public static readonly StringOrIntValue SQLCLIENT = new StringOrIntValue(3003, "SqlClient");
public static readonly StringOrIntValue CAP = new StringOrIntValue("CAP");
public static readonly StringOrIntValue CAP = new StringOrIntValue(3004, "CAP");
public static readonly StringOrIntValue ENTITYFRAMEWORKCORE_SQLITE = new StringOrIntValue("EntityFrameworkCore.Sqlite");
public static readonly StringOrIntValue ENTITYFRAMEWORKCORE_SQLITE = new StringOrIntValue(3011, "EntityFrameworkCore.Sqlite");
public static readonly StringOrIntValue POMELO_ENTITYFRAMEWORKCORE_MYSQL = new StringOrIntValue("Pomelo.EntityFrameworkCore.MySql");
public static readonly StringOrIntValue POMELO_ENTITYFRAMEWORKCORE_MYSQL = new StringOrIntValue(3012, "Pomelo.EntityFrameworkCore.MySql");
public static readonly StringOrIntValue NPGSQL_ENTITYFRAMEWORKCORE_POSTGRESQL = new StringOrIntValue("Npgsql.EntityFrameworkCore.PostgreSQL");
public static readonly StringOrIntValue NPGSQL_ENTITYFRAMEWORKCORE_POSTGRESQL = new StringOrIntValue(3013, "Npgsql.EntityFrameworkCore.PostgreSQL");
public static readonly StringOrIntValue ASPNET = new StringOrIntValue("AspNet");
public static readonly StringOrIntValue ASPNET = new StringOrIntValue(3015, "AspNet");
public static readonly StringOrIntValue SMART_SQL = new StringOrIntValue("SmartSql");
public static readonly StringOrIntValue SMART_SQL = new StringOrIntValue(3016, "SmartSql");
public static readonly StringOrIntValue GRPC = new StringOrIntValue("GRPC");
public static readonly StringOrIntValue GRPC = new StringOrIntValue(23, "GRPC");
}
}
\ No newline at end of file
/*
* Licensed to the SkyAPM under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The SkyAPM 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 SkyApm.Common
{
public struct StringOrNumValue<T> : IEquatable<StringOrNumValue<T>> where T : struct
{
private readonly Nullable<T> _numValue;
private readonly string _stringValue;
public StringOrNumValue(T value)
{
_numValue = value;
_stringValue = null;
}
public bool HasValue => HasNumValue || HasStringValue;
public bool HasNumValue => _numValue != null;
public bool HasStringValue => _stringValue != null;
public StringOrNumValue(string value)
{
_numValue = null;
_stringValue = value;
}
public StringOrNumValue(T numValue, string stringValue)
{
_numValue = numValue;
_stringValue = stringValue;
}
public T GetNumValue() => _numValue ?? default(T);
public string GetStringValue() => _stringValue;
public (string, T) GetValue()
{
return (_stringValue, _numValue ?? default(T));
}
public override string ToString()
{
if (HasNumValue) return _numValue.ToString();
return _stringValue;
}
public bool Equals(StringOrNumValue<T> other)
{
return _numValue.Equals(other._numValue) && _stringValue == other._stringValue;
}
public override bool Equals(object obj)
{
return obj is StringOrNumValue<T> other && Equals(other);
}
public override int GetHashCode()
{
unchecked
{
var hashCode = _numValue.GetHashCode();
if(_stringValue != null)
hashCode = (hashCode * 397) ^ _stringValue.GetHashCode();
return hashCode;
}
}
public static implicit operator StringOrNumValue<T>(string value) => new StringOrNumValue<T>(value);
public static implicit operator StringOrNumValue<T>(T value) => new StringOrNumValue<T>(value);
public static bool operator ==(StringOrNumValue<T> left, StringOrNumValue<T> right) => left.Equals(right);
public static bool operator !=(StringOrNumValue<T> left, StringOrNumValue<T> right) => !left.Equals(right);
}
}
......@@ -29,14 +29,15 @@ namespace SkyApm.Config
public string ApplicationCode { get; set; }
public string ServiceName { get; set; }
public string ServiceInstanceName { get; set; }
public string[] HeaderVersions { get; set; }
}
public static class HeaderVersions
{
public static string SW3 { get; } = "sw3";
public static string SW6 { get; } = "sw6";
public static string SW8 { get; } = "sw8";
}
}
\ No newline at end of file
......@@ -33,13 +33,11 @@ namespace SkyApm.Config
/// </summary>
public int BatchSize { get; set; } = 3000;
public string ProtocolVersion { get; set; } = ProtocolVersions.V6;
public string ProtocolVersion { get; set; } = ProtocolVersions.V8;
}
public static class ProtocolVersions
{
public static string V5 { get; } = "v5";
public static string V6 { get; } = "v6";
public static string V8 { get; } = "v8";
}
}
\ No newline at end of file
......@@ -23,14 +23,8 @@ namespace SkyApm
{
public interface IRuntimeEnvironment
{
NullableValue ServiceId { get; }
NullableValue ServiceInstanceId { get; }
bool Initialized { get; }
Guid InstanceId { get; }
IEnvironmentProvider Environment { get; }
}
}
\ No newline at end of file
......@@ -26,20 +26,22 @@ namespace SkyApm.Tracing
bool? Sampled { get; }
UniqueId TraceId { get; }
string TraceId { get; }
UniqueId ParentSegmentId { get; }
string ParentSegmentId { get; }
int ParentSpanId { get; }
int ParentServiceInstanceId { get; }
int EntryServiceInstanceId { get; }
string ParentServiceId { get; }
string ParentServiceInstanceId { get; }
string EntryServiceInstanceId { get; }
StringOrIntValue NetworkAddress { get; }
StringOrIntValue EntryEndpoint { get; }
StringOrIntValue ParentEndpoint { get; }
}
}
\ No newline at end of file
......@@ -20,6 +20,6 @@ namespace SkyApm.Tracing
{
public interface IUniqueIdGenerator
{
UniqueId Generate();
string Generate();
}
}
\ No newline at end of file
/*
* Licensed to the SkyAPM under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The SkyAPM 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 SkyApm.Tracing
{
public interface IUniqueIdParser
{
bool TryParse(string text, out UniqueId uniqueId);
}
}
\ No newline at end of file
......@@ -16,19 +16,21 @@
*
*/
using SkyApm.Common;
namespace SkyApm.Tracing.Segments
{
public class SegmentContext
{
public UniqueId SegmentId { get; }
public string SegmentId { get; }
public UniqueId TraceId { get; }
public string TraceId { get; }
public SegmentSpan Span { get; }
public int ServiceId { get; }
public string ServiceId { get; }
public int ServiceInstanceId { get; }
public string ServiceInstanceId { get; }
public bool Sampled { get; }
......@@ -36,7 +38,7 @@ namespace SkyApm.Tracing.Segments
public SegmentReferenceCollection References { get; } = new SegmentReferenceCollection();
public SegmentContext(UniqueId traceId, UniqueId segmentId, bool sampled, int serviceId, int serviceInstanceId,
public SegmentContext(string traceId, string segmentId, bool sampled, string serviceId, string serviceInstanceId,
string operationName, SpanType spanType)
{
TraceId = traceId;
......
......@@ -26,13 +26,17 @@ namespace SkyApm.Tracing.Segments
{
public Reference Reference { get; set; }
public UniqueId ParentSegmentId { get; set; }
public string ParentSegmentId { get; set; }
public int ParentSpanId { get; set; }
public int ParentServiceInstanceId { get; set; }
public string TraceId { get; set; }
public int EntryServiceInstanceId { get; set; }
public string ParentServiceId { get; set; }
public string ParentServiceInstanceId { get; set; }
public string EntryServiceInstanceId { get; set; }
public StringOrIntValue NetworkAddress { get; set; }
......
......@@ -26,10 +26,7 @@ namespace SkyApm.Transport
{
public interface IServiceRegister
{
Task<NullableValue> RegisterServiceAsync(ServiceRequest serviceRequest,
CancellationToken cancellationToken = default(CancellationToken));
Task<NullableValue> RegisterServiceInstanceAsync(ServiceInstanceRequest serviceInstanceRequest,
Task<bool> ReportInstancePropertiesAsync(ServiceInstancePropertiesRequest serviceInstancePropertiesRequest,
CancellationToken cancellationToken = default(CancellationToken));
}
}
\ No newline at end of file
......@@ -20,7 +20,7 @@ namespace SkyApm.Transport
{
public class PingRequest
{
public int ServiceInstanceId { get; set; }
public string ServiceName { get; set; }
public string InstanceId { get; set; }
}
......
......@@ -23,32 +23,18 @@ namespace SkyApm.Transport
{
public class SegmentRequest
{
public IEnumerable<UniqueIdRequest> UniqueIds { get; set; }
public string TraceId { get; set; }
public SegmentObjectRequest Segment { get; set; }
}
public class UniqueIdRequest
{
public long Part1 { get; set; }
public long Part2 { get; set; }
public long Part3 { get; set; }
public override string ToString()
{
return $"{Part1}.{Part2}.{Part3}";
}
}
public class SegmentObjectRequest
{
public UniqueIdRequest SegmentId { get; set; }
public string SegmentId { get; set; }
public int ServiceId { get; set; }
public string ServiceId { get; set; }
public int ServiceInstanceId { get; set; }
public string ServiceInstanceId { get; set; }
public IList<SpanRequest> Spans { get; set; } = new List<SpanRequest>();
}
......@@ -84,13 +70,17 @@ namespace SkyApm.Transport
public class SegmentReferenceRequest
{
public UniqueIdRequest ParentSegmentId { get; set; }
public string TraceId { get; set; }
public string ParentSegmentId { get; set; }
public string ParentServiceId { get; set; }
public int ParentServiceInstanceId { get; set; }
public string ParentServiceInstanceId { get; set; }
public int ParentSpanId { get; set; }
public int EntryServiceInstanceId { get; set; }
public string EntryServiceInstanceId { get; set; }
public int RefType { get; set; }
......
using System;
using System.Collections.Generic;
using System.Text;
namespace SkyApm.Transport
{
public class ServiceInstancePropertiesRequest
{
public string ServiceId { get; set; }
public string ServiceInstanceId { get; set; }
public AgentOsInfoRequest Properties { get; set; }
}
}
/*
* Licensed to the SkyAPM under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The SkyAPM 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 SkyApm.Transport
{
public class ServiceInstanceRequest
{
public int ServiceId { get; set; }
public string InstanceUUID { get; set; }
public AgentOsInfoRequest Properties { get; set; }
}
}
\ No newline at end of file
......@@ -25,8 +25,6 @@ using SkyApm.Service;
using SkyApm.Tracing;
using SkyApm.Transport;
using SkyApm.Transport.Grpc;
using SkyApm.Transport.Grpc.V5;
using SkyApm.Transport.Grpc.V6;
using SkyApm.Utilities.Configuration;
using SkyApm.Utilities.Logging;
......@@ -39,8 +37,8 @@ namespace SkyApm.Agent.AspNet.Extensions
services.AddSingleton<ISegmentDispatcher, AsyncQueueSegmentDispatcher>();
services.AddSingleton<IExecutionService, RegisterService>();
services.AddSingleton<IExecutionService, PingService>();
services.AddSingleton<IExecutionService, ServiceDiscoveryV5Service>();
services.AddSingleton<IExecutionService, SegmentReportService>();
services.AddSingleton<IExecutionService, CLRStatsService>();
services.AddSingleton<IInstrumentStartup, InstrumentStartup>();
services.AddSingleton<IRuntimeEnvironment>(RuntimeEnvironment.Instance);
services.AddSingleton<TracingDiagnosticProcessorObserver>();
......@@ -51,15 +49,13 @@ namespace SkyApm.Agent.AspNet.Extensions
services.AddSingleton<ITracingContext, Tracing.TracingContext>();
services.AddSingleton<ICarrierPropagator, CarrierPropagator>();
services.AddSingleton<ICarrierFormatter, Sw3CarrierFormatter>();
services.AddSingleton<ICarrierFormatter, Sw6CarrierFormatter>();
services.AddSingleton<ICarrierFormatter, Sw8CarrierFormatter>();
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>();
......@@ -68,8 +64,8 @@ namespace SkyApm.Agent.AspNet.Extensions
services.AddSingleton<IExecutionService>(p => p.GetService<SimpleCountSamplingInterceptor>());
services.AddSingleton<ISamplingInterceptor, RandomSamplingInterceptor>();
services.AddSingleton<ISkyApmClientV5, SkyApmClientV5>();
services.AddSingleton<ISegmentReporter, SegmentReporter>();
services.AddSingleton<ICLRStatsReporter, CLRStatsReporter>();
services.AddSingleton<ConnectionManager>();
services.AddSingleton<IPingCaller, PingCaller>();
services.AddSingleton<IServiceRegister, ServiceRegister>();
......
......@@ -30,8 +30,6 @@ using SkyApm.Service;
using SkyApm.Tracing;
using SkyApm.Transport;
using SkyApm.Transport.Grpc;
using SkyApm.Transport.Grpc.V5;
using SkyApm.Transport.Grpc.V6;
using SkyApm.Utilities.Configuration;
using SkyApm.Utilities.DependencyInjection;
using SkyApm.Utilities.Logging;
......@@ -59,8 +57,8 @@ namespace Microsoft.Extensions.DependencyInjection
services.AddSingleton<ISegmentDispatcher, AsyncQueueSegmentDispatcher>();
services.AddSingleton<IExecutionService, RegisterService>();
services.AddSingleton<IExecutionService, PingService>();
services.AddSingleton<IExecutionService, ServiceDiscoveryV5Service>();
services.AddSingleton<IExecutionService, SegmentReportService>();
services.AddSingleton<IExecutionService, CLRStatsService>();
services.AddSingleton<IInstrumentStartup, InstrumentStartup>();
services.AddSingleton<IRuntimeEnvironment>(RuntimeEnvironment.Instance);
services.AddSingleton<TracingDiagnosticProcessorObserver>();
......@@ -85,15 +83,13 @@ namespace Microsoft.Extensions.DependencyInjection
{
services.AddSingleton<ITracingContext, TracingContext>();
services.AddSingleton<ICarrierPropagator, CarrierPropagator>();
services.AddSingleton<ICarrierFormatter, Sw3CarrierFormatter>();
services.AddSingleton<ICarrierFormatter, Sw6CarrierFormatter>();
services.AddSingleton<ICarrierFormatter, Sw8CarrierFormatter>();
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;
......@@ -110,8 +106,8 @@ namespace Microsoft.Extensions.DependencyInjection
private static IServiceCollection AddGrpcTransport(this IServiceCollection services)
{
services.AddSingleton<ISkyApmClientV5, SkyApmClientV5>();
services.AddSingleton<ISegmentReporter, SegmentReporter>();
services.AddSingleton<ICLRStatsReporter, CLRStatsReporter>();
services.AddSingleton<ConnectionManager>();
services.AddSingleton<IPingCaller, PingCaller>();
services.AddSingleton<IServiceRegister, ServiceRegister>();
......
......@@ -25,14 +25,8 @@ namespace SkyApm
{
public static IRuntimeEnvironment Instance { get; } = new RuntimeEnvironment();
public NullableValue ServiceId { get; internal set; }
public bool Initialized {get; internal set; }
public NullableValue ServiceInstanceId { get; internal set; }
public bool Initialized => ServiceId.HasValue && ServiceInstanceId.HasValue;
public Guid InstanceId { get; } = Guid.NewGuid();
public IEnvironmentProvider Environment { get; set; }
}
}
\ No newline at end of file
......@@ -29,6 +29,7 @@ namespace SkyApm.Service
{
private readonly IPingCaller _pingCaller;
private readonly TransportConfig _transportConfig;
private readonly InstrumentConfig _instrumentConfig;
public PingService(IConfigAccessor configAccessor, IPingCaller pingCaller,
IRuntimeEnvironment runtimeEnvironment,
......@@ -37,11 +38,9 @@ namespace SkyApm.Service
{
_pingCaller = pingCaller;
_transportConfig = configAccessor.Get<TransportConfig>();
_instrumentConfig = configAccessor.Get<InstrumentConfig>();
}
protected override bool CanExecute() =>
_transportConfig.ProtocolVersion == ProtocolVersions.V6 && base.CanExecute();
protected override TimeSpan DueTime { get; } = TimeSpan.FromSeconds(30);
protected override TimeSpan Period { get; } = TimeSpan.FromSeconds(60);
......@@ -52,8 +51,8 @@ namespace SkyApm.Service
await _pingCaller.PingAsync(
new PingRequest
{
ServiceInstanceId = RuntimeEnvironment.ServiceInstanceId.Value,
InstanceId = RuntimeEnvironment.InstanceId.ToString("N")
ServiceName = _instrumentConfig.ServiceName ?? _instrumentConfig.ApplicationCode,
InstanceId = _instrumentConfig.ServiceInstanceName
}, cancellationToken);
Logger.Information($"Ping server @{DateTimeOffset.UtcNow}");
}
......
......@@ -46,71 +46,57 @@ namespace SkyApm.Service
protected override TimeSpan Period { get; } = TimeSpan.FromSeconds(30);
protected override bool CanExecute() =>
_transportConfig.ProtocolVersion == ProtocolVersions.V6 && !RuntimeEnvironment.Initialized;
protected override bool CanExecute() => !RuntimeEnvironment.Initialized;
protected override async Task ExecuteAsync(CancellationToken cancellationToken)
{
await RegisterServiceAsync(cancellationToken);
await RegisterServiceInstanceAsync(cancellationToken);
await ReportServiceInstancePropertiesAsync(cancellationToken);
}
private async Task RegisterServiceAsync(CancellationToken cancellationToken)
private async Task ReportServiceInstancePropertiesAsync(CancellationToken cancellationToken)
{
if (!RuntimeEnvironment.ServiceId.HasValue)
var properties = new AgentOsInfoRequest
{
var request = new ServiceRequest
{
ServiceName = _config.ServiceName ?? _config.ApplicationCode
};
var value = await Polling(3,
() => _serviceRegister.RegisterServiceAsync(request, cancellationToken),
HostName = DnsHelpers.GetHostName(),
IpAddress = DnsHelpers.GetIpV4s(),
OsName = PlatformInformation.GetOSName(),
ProcessNo = Process.GetCurrentProcess().Id,
Language = "dotnet"
};
var request = new ServiceInstancePropertiesRequest
{
ServiceId = _config.ServiceName ?? _config.ApplicationCode,
ServiceInstanceId = _config.ServiceInstanceName,
Properties = properties
};
var result = await Polling(3,
() => _serviceRegister.ReportInstancePropertiesAsync(request, cancellationToken),
cancellationToken);
if (value.HasValue && RuntimeEnvironment is RuntimeEnvironment environment)
{
environment.ServiceId = value;
Logger.Information($"Registered Service[Id={environment.ServiceId.Value}].");
}
if (result && RuntimeEnvironment is RuntimeEnvironment environment)
{
environment.Initialized = true;
Logger.Information($"Reported Service Instance Properties[Service={request.ServiceId},InstanceId={request.ServiceInstanceId}].");
}
}
private async Task RegisterServiceInstanceAsync(CancellationToken cancellationToken)
private static async Task<NullableValue> Polling(int retry, Func<Task<NullableValue>> execute, CancellationToken cancellationToken)
{
if (RuntimeEnvironment.ServiceId.HasValue && !RuntimeEnvironment.ServiceInstanceId.HasValue)
{
var properties = new AgentOsInfoRequest
{
HostName = DnsHelpers.GetHostName(),
IpAddress = DnsHelpers.GetIpV4s(),
OsName = PlatformInformation.GetOSName(),
ProcessNo = Process.GetCurrentProcess().Id,
Language = "dotnet"
};
var request = new ServiceInstanceRequest
{
ServiceId = RuntimeEnvironment.ServiceId.Value,
InstanceUUID = RuntimeEnvironment.InstanceId.ToString("N"),
Properties = properties
};
var value = await Polling(3,
() => _serviceRegister.RegisterServiceInstanceAsync(request, cancellationToken),
cancellationToken);
if (value.HasValue && RuntimeEnvironment is RuntimeEnvironment environment)
{
environment.ServiceInstanceId = value;
Logger.Information($"Registered ServiceInstance[Id={environment.ServiceInstanceId.Value}].");
}
}
return await Polling(retry, execute, result => result.HasValue, NullableValue.Null, cancellationToken);
}
private static async Task<bool> Polling(int retry, Func<Task<bool>> execute, CancellationToken cancellationToken)
{
return await Polling(retry, execute, result => result, false, cancellationToken);
}
private static async Task<NullableValue> Polling(int retry, Func<Task<NullableValue>> execute,
private static async Task<T> Polling<T>(int retry, Func<Task<T>> execute, Func<T,bool> successPredicate, T failureResult,
CancellationToken cancellationToken)
{
var index = 0;
while (index++ < retry)
{
var value = await execute();
if (value.HasValue)
if (successPredicate(value))
{
return value;
}
......@@ -118,7 +104,7 @@ namespace SkyApm.Service
await Task.Delay(500, cancellationToken);
}
return NullableValue.Null;
return failureResult;
}
}
}
\ No newline at end of file
/*
* Licensed to the SkyAPM under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The SkyAPM 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.Diagnostics;
using System.Threading;
using System.Threading.Tasks;
using SkyApm.Common;
using SkyApm.Config;
using SkyApm.Logging;
using SkyApm.Transport;
namespace SkyApm.Service
{
public class ServiceDiscoveryV5Service : ExecutionService
{
private readonly InstrumentConfig _config;
private readonly TransportConfig _transportConfig;
private readonly ISkyApmClientV5 skyApmClient;
protected override TimeSpan DueTime { get; } = TimeSpan.Zero;
protected override TimeSpan Period { get; } = TimeSpan.FromSeconds(30);
public ServiceDiscoveryV5Service(IConfigAccessor configAccessor, ISkyApmClientV5 skyApmClient,
IRuntimeEnvironment runtimeEnvironment, ILoggerFactory loggerFactory)
: base(runtimeEnvironment, loggerFactory)
{
_config = configAccessor.Get<InstrumentConfig>();
_transportConfig = configAccessor.Get<TransportConfig>();
this.skyApmClient = skyApmClient;
}
protected override async Task ExecuteAsync(CancellationToken cancellationToken)
{
await RegisterApplication(cancellationToken);
await RegisterApplicationInstance(cancellationToken);
await Heartbeat(cancellationToken);
}
protected override bool CanExecute() =>
_transportConfig.ProtocolVersion == ProtocolVersions.V5 && !RuntimeEnvironment.Initialized;
private async Task RegisterApplication(CancellationToken cancellationToken)
{
if (!RuntimeEnvironment.ServiceId.HasValue)
{
var value = await Polling(3,
() => skyApmClient.RegisterApplicationAsync(_config.ServiceName ?? _config.ApplicationCode, cancellationToken),
cancellationToken);
if (value.HasValue && RuntimeEnvironment is RuntimeEnvironment environment)
{
environment.ServiceId = value;
Logger.Information($"Registered Application[Id={environment.ServiceId.Value}].");
}
}
}
private async Task RegisterApplicationInstance(CancellationToken cancellationToken)
{
if (RuntimeEnvironment.ServiceId.HasValue && !RuntimeEnvironment.ServiceInstanceId.HasValue)
{
var osInfoRequest = new AgentOsInfoRequest
{
HostName = DnsHelpers.GetHostName(),
IpAddress = DnsHelpers.GetIpV4s(),
OsName = PlatformInformation.GetOSName(),
ProcessNo = Process.GetCurrentProcess().Id
};
var value = await Polling(3,
() => skyApmClient.RegisterApplicationInstanceAsync(RuntimeEnvironment.ServiceId.Value,
RuntimeEnvironment.InstanceId,
DateTimeOffset.UtcNow.ToUnixTimeMilliseconds(), osInfoRequest, cancellationToken),
cancellationToken);
if (value.HasValue && RuntimeEnvironment is RuntimeEnvironment environment)
{
environment.ServiceInstanceId = value;
Logger.Information(
$"Registered Application Instance[Id={environment.ServiceInstanceId.Value}].");
}
}
}
private static async Task<NullableValue> Polling(int retry, Func<Task<NullableValue>> execute,
CancellationToken cancellationToken)
{
var index = 0;
while (index++ < retry)
{
var value = await execute();
if (value.HasValue)
{
return value;
}
await Task.Delay(500, cancellationToken);
}
return NullableValue.Null;
}
private async Task Heartbeat(CancellationToken cancellationToken)
{
if (RuntimeEnvironment.Initialized)
{
try
{
await skyApmClient.HeartbeatAsync(RuntimeEnvironment.ServiceInstanceId.Value,
DateTimeOffset.UtcNow.ToUnixTimeMilliseconds(), cancellationToken);
Logger.Debug($"Heartbeat at {DateTimeOffset.UtcNow}.");
}
catch (Exception e)
{
Logger.Error("Heartbeat error.", e);
}
}
}
}
}
\ No newline at end of file
......@@ -26,15 +26,17 @@ namespace SkyApm.Tracing
public bool? Sampled { get; set; }
public UniqueId TraceId { get; }
public string TraceId { get; }
public UniqueId ParentSegmentId { get; }
public string ParentSegmentId { get; }
public int ParentSpanId { get; }
public string ParentServiceId { get; }
public string ParentServiceInstanceId { get; }
public int ParentServiceInstanceId { get; }
public int EntryServiceInstanceId { get; }
public string EntryServiceInstanceId { get; }
public StringOrIntValue NetworkAddress { get; set; }
......@@ -42,14 +44,16 @@ namespace SkyApm.Tracing
public StringOrIntValue ParentEndpoint { get; set; }
public Carrier(UniqueId traceId, UniqueId parentSegmentId, int parentSpanId, int parentServiceInstanceId,
int entryServiceInstanceId)
public Carrier(string traceId, string parentSegmentId, int parentSpanId, string parentServiceInstanceId,
string entryServiceInstanceId, string parentServiceId = default)
{
TraceId = traceId;
ParentSegmentId = parentSegmentId;
ParentSpanId = parentSpanId;
ParentServiceInstanceId = parentServiceInstanceId;
EntryServiceInstanceId = entryServiceInstanceId;
ParentServiceId = parentServiceId;
}
}
}
\ No newline at end of file
......@@ -39,7 +39,8 @@ namespace SkyApm.Tracing
var reference = segmentContext.References.FirstOrDefault();
var carrier = new Carrier(segmentContext.TraceId, segmentContext.SegmentId, segmentContext.Span.SpanId,
segmentContext.ServiceInstanceId, reference?.EntryServiceInstanceId ?? segmentContext.ServiceInstanceId)
segmentContext.ServiceInstanceId, reference?.EntryServiceInstanceId ?? segmentContext.ServiceInstanceId,
segmentContext.ServiceId)
{
NetworkAddress = segmentContext.Span.Peer,
EntryEndpoint = reference?.EntryEndpoint ?? segmentContext.Span.OperationName,
......
......@@ -28,20 +28,22 @@ namespace SkyApm.Tracing
public bool? Sampled { get; }
public UniqueId TraceId { get; }
public string TraceId { get; }
public UniqueId ParentSegmentId { get; }
public string ParentSegmentId { get; }
public int ParentSpanId { get; }
public int ParentServiceInstanceId { get; }
public string ParentServiceInstanceId { get; }
public int EntryServiceInstanceId { get; }
public string EntryServiceInstanceId { get; }
public StringOrIntValue NetworkAddress { get; }
public StringOrIntValue EntryEndpoint { get; }
public StringOrIntValue ParentEndpoint { get; }
public string ParentServiceId { get; }
}
}
\ No newline at end of file
......@@ -19,6 +19,7 @@
using System;
using System.Linq;
using SkyApm.Common;
using SkyApm.Config;
using SkyApm.Tracing.Segments;
namespace SkyApm.Tracing
......@@ -31,13 +32,15 @@ namespace SkyApm.Tracing
private readonly IRuntimeEnvironment _runtimeEnvironment;
private readonly ISamplerChainBuilder _samplerChainBuilder;
private readonly IUniqueIdGenerator _uniqueIdGenerator;
private readonly InstrumentConfig _instrumentConfig;
public SegmentContextFactory(IRuntimeEnvironment runtimeEnvironment,
ISamplerChainBuilder samplerChainBuilder,
IUniqueIdGenerator uniqueIdGenerator,
IEntrySegmentContextAccessor entrySegmentContextAccessor,
ILocalSegmentContextAccessor localSegmentContextAccessor,
IExitSegmentContextAccessor exitSegmentContextAccessor)
IExitSegmentContextAccessor exitSegmentContextAccessor,
IConfigAccessor configAccessor)
{
_runtimeEnvironment = runtimeEnvironment;
_samplerChainBuilder = samplerChainBuilder;
......@@ -45,6 +48,7 @@ namespace SkyApm.Tracing
_entrySegmentContextAccessor = entrySegmentContextAccessor;
_localSegmentContextAccessor = localSegmentContextAccessor;
_exitSegmentContextAccessor = exitSegmentContextAccessor;
_instrumentConfig = configAccessor.Get<InstrumentConfig>();
}
public SegmentContext CreateEntrySegment(string operationName, ICarrier carrier)
......@@ -52,8 +56,10 @@ namespace SkyApm.Tracing
var traceId = GetTraceId(carrier);
var segmentId = GetSegmentId();
var sampled = GetSampled(carrier, operationName);
var segmentContext = new SegmentContext(traceId, segmentId, sampled, _runtimeEnvironment.ServiceId.Value,
_runtimeEnvironment.ServiceInstanceId.Value, operationName, SpanType.Entry);
var segmentContext = new SegmentContext(traceId, segmentId, sampled,
_instrumentConfig.ServiceName ?? _instrumentConfig.ApplicationCode,
_instrumentConfig.ServiceInstanceName,
operationName, SpanType.Entry);
if (carrier.HasValue)
{
......@@ -66,7 +72,9 @@ namespace SkyApm.Tracing
ParentSpanId = carrier.ParentSpanId,
ParentSegmentId = carrier.ParentSegmentId,
EntryServiceInstanceId = carrier.EntryServiceInstanceId,
ParentServiceInstanceId = carrier.ParentServiceInstanceId
ParentServiceInstanceId = carrier.ParentServiceInstanceId,
TraceId = carrier.TraceId,
ParentServiceId = carrier.ParentServiceId,
};
segmentContext.References.Add(segmentReference);
}
......@@ -81,8 +89,10 @@ namespace SkyApm.Tracing
var traceId = GetTraceId(parentSegmentContext);
var segmentId = GetSegmentId();
var sampled = GetSampled(parentSegmentContext, operationName);
var segmentContext = new SegmentContext(traceId, segmentId, sampled, _runtimeEnvironment.ServiceId.Value,
_runtimeEnvironment.ServiceInstanceId.Value, operationName, SpanType.Local);
var segmentContext = new SegmentContext(traceId, segmentId, sampled,
_instrumentConfig.ServiceName ?? _instrumentConfig.ApplicationCode,
_instrumentConfig.ServiceInstanceName,
operationName, SpanType.Local);
if (parentSegmentContext != null)
{
......@@ -97,7 +107,9 @@ namespace SkyApm.Tracing
ParentSegmentId = parentSegmentContext.SegmentId,
EntryServiceInstanceId =
parentReference?.EntryServiceInstanceId ?? parentSegmentContext.ServiceInstanceId,
ParentServiceInstanceId = parentSegmentContext.ServiceInstanceId
ParentServiceInstanceId = parentSegmentContext.ServiceInstanceId,
ParentServiceId = parentSegmentContext.ServiceId,
TraceId = parentSegmentContext.TraceId
};
segmentContext.References.Add(reference);
}
......@@ -112,8 +124,10 @@ namespace SkyApm.Tracing
var traceId = GetTraceId(parentSegmentContext);
var segmentId = GetSegmentId();
var sampled = GetSampled(parentSegmentContext, operationName, networkAddress);
var segmentContext = new SegmentContext(traceId, segmentId, sampled, _runtimeEnvironment.ServiceId.Value,
_runtimeEnvironment.ServiceInstanceId.Value, operationName, SpanType.Exit);
var segmentContext = new SegmentContext(traceId, segmentId, sampled,
_instrumentConfig.ServiceName ?? _instrumentConfig.ApplicationCode,
_instrumentConfig.ServiceInstanceName,
operationName, SpanType.Exit);
if (parentSegmentContext != null)
{
......@@ -128,7 +142,9 @@ namespace SkyApm.Tracing
ParentSegmentId = parentSegmentContext.SegmentId,
EntryServiceInstanceId =
parentReference?.EntryServiceInstanceId ?? parentSegmentContext.ServiceInstanceId,
ParentServiceInstanceId = parentSegmentContext.ServiceInstanceId
ParentServiceInstanceId = parentSegmentContext.ServiceInstanceId,
ParentServiceId = parentSegmentContext.ServiceId,
TraceId = parentSegmentContext.TraceId
};
segmentContext.References.Add(reference);
}
......@@ -157,17 +173,17 @@ namespace SkyApm.Tracing
}
}
private UniqueId GetTraceId(ICarrier carrier)
private string GetTraceId(ICarrier carrier)
{
return carrier.HasValue ? carrier.TraceId : _uniqueIdGenerator.Generate();
}
private UniqueId GetTraceId(SegmentContext parentSegmentContext)
private string GetTraceId(SegmentContext parentSegmentContext)
{
return parentSegmentContext?.TraceId ?? _uniqueIdGenerator.Generate();
}
private UniqueId GetSegmentId()
private string GetSegmentId()
{
return _uniqueIdGenerator.Generate();
}
......
/*
* Licensed to the SkyAPM under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The SkyAPM 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 SkyApm.Common;
using SkyApm.Config;
namespace SkyApm.Tracing
{
public class Sw3CarrierFormatter : ICarrierFormatter
{
private readonly IUniqueIdParser _uniqueIdParser;
public Sw3CarrierFormatter(IUniqueIdParser uniqueIdParser, IConfigAccessor configAccessor)
{
_uniqueIdParser = uniqueIdParser;
var config = configAccessor.Get<InstrumentConfig>();
Key = string.IsNullOrEmpty(config.Namespace)
? HeaderVersions.SW3
: $"{config.Namespace}-{HeaderVersions.SW3}";
Enable = config.HeaderVersions != null && config.HeaderVersions.Contains(HeaderVersions.SW3);
}
public string Key { get; }
public bool Enable { get; }
public ICarrier Decode(string content)
{
NullableCarrier Defer()
{
return NullableCarrier.Instance;
}
if (string.IsNullOrEmpty(content))
return Defer();
var parts = content.Split('|');
if (parts.Length < 8)
return Defer();
if (!_uniqueIdParser.TryParse(parts[0], out var segmentId))
return Defer();
if (!int.TryParse(parts[1], out var parentSpanId))
return Defer();
if (!int.TryParse(parts[2], out var parentServiceInstanceId))
return Defer();
if (!int.TryParse(parts[3], out var entryServiceInstanceId))
return Defer();
if (!_uniqueIdParser.TryParse(parts[7], out var traceId))
return Defer();
return new Carrier(traceId, segmentId, parentSpanId, parentServiceInstanceId,
entryServiceInstanceId)
{
NetworkAddress = StringOrIntValueHelpers.ParseStringOrIntValue(parts[4]),
EntryEndpoint = StringOrIntValueHelpers.ParseStringOrIntValue(parts[5]),
ParentEndpoint = StringOrIntValueHelpers.ParseStringOrIntValue(parts[6])
};
}
public string Encode(ICarrier carrier)
{
if (!carrier.HasValue)
return string.Empty;
return string.Join("|",
carrier.ParentSegmentId.ToString(),
carrier.ParentSpanId.ToString(),
carrier.ParentServiceInstanceId.ToString(),
carrier.EntryServiceInstanceId.ToString(),
ConvertStringOrIntValue(carrier.NetworkAddress),
ConvertStringOrIntValue(carrier.EntryEndpoint),
ConvertStringOrIntValue(carrier.ParentEndpoint),
carrier.TraceId.ToString());
}
private static string ConvertStringOrIntValue(StringOrIntValue value)
{
if (value.HasIntValue)
{
return value.GetIntValue().ToString();
}
return "#" + value.GetStringValue();
}
}
}
\ No newline at end of file
......@@ -22,21 +22,19 @@ using SkyApm.Config;
namespace SkyApm.Tracing
{
public class Sw6CarrierFormatter : ICarrierFormatter
public class Sw8CarrierFormatter : ICarrierFormatter
{
private readonly IUniqueIdParser _uniqueIdParser;
private readonly IBase64Formatter _base64Formatter;
public Sw6CarrierFormatter(IUniqueIdParser uniqueIdParser, IBase64Formatter base64Formatter,
public Sw8CarrierFormatter(IBase64Formatter base64Formatter,
IConfigAccessor configAccessor)
{
_uniqueIdParser = uniqueIdParser;
_base64Formatter = base64Formatter;
var config = configAccessor.Get<InstrumentConfig>();
Key = string.IsNullOrEmpty(config.Namespace)
? HeaderVersions.SW6
: $"{config.Namespace}-{HeaderVersions.SW6}";
Enable = config.HeaderVersions == null || config.HeaderVersions.Contains(HeaderVersions.SW6);
? HeaderVersions.SW8
: $"{config.Namespace}-{HeaderVersions.SW8}";
Enable = config.HeaderVersions == null || config.HeaderVersions.Contains(HeaderVersions.SW8);
}
public string Key { get; }
......@@ -54,42 +52,31 @@ namespace SkyApm.Tracing
return Defer();
var parts = content.Split('-');
if (parts.Length < 7)
if (parts.Length < 8)
return Defer();
if (!int.TryParse(parts[0], out var sampled))
return Defer();
if (!_uniqueIdParser.TryParse(_base64Formatter.Decode(parts[1]), out var traceId))
return Defer();
if (!_uniqueIdParser.TryParse(_base64Formatter.Decode(parts[2]), out var segmentId))
return Defer();
var traceId = _base64Formatter.Decode(parts[1]);
var segmentId = _base64Formatter.Decode(parts[2]);
if (!int.TryParse(parts[3], out var parentSpanId))
return Defer();
if (!int.TryParse(parts[4], out var parentServiceInstanceId))
return Defer();
var parentService = _base64Formatter.Decode(parts[4]);
var parentServiceInstance = _base64Formatter.Decode(parts[5]);
var parentEndpoint = _base64Formatter.Decode(parts[6]);
var networkAddress = _base64Formatter.Decode(parts[7]);
if (!int.TryParse(parts[5], out var entryServiceInstanceId))
return Defer();
var carrier = new Carrier(traceId, segmentId, parentSpanId, parentServiceInstanceId,
entryServiceInstanceId)
var carrier = new Carrier(traceId, segmentId, parentSpanId, parentServiceInstance,
default, parentService)
{
NetworkAddress = StringOrIntValueHelpers.ParseStringOrIntValue(_base64Formatter.Decode(parts[6])),
NetworkAddress = networkAddress,
ParentEndpoint = parentEndpoint,
Sampled = sampled != 0
};
if (parts.Length >= 9)
{
carrier.ParentEndpoint =
StringOrIntValueHelpers.ParseStringOrIntValue(_base64Formatter.Decode(parts[7]));
carrier.EntryEndpoint =
StringOrIntValueHelpers.ParseStringOrIntValue(_base64Formatter.Decode(parts[8]));
}
return carrier;
}
......@@ -99,24 +86,13 @@ namespace SkyApm.Tracing
return string.Empty;
return string.Join("-",
carrier.Sampled != null && carrier.Sampled.Value ? "1" : "0",
_base64Formatter.Encode(carrier.TraceId.ToString()),
_base64Formatter.Encode(carrier.ParentSegmentId.ToString()),
_base64Formatter.Encode(carrier.TraceId),
_base64Formatter.Encode(carrier.ParentSegmentId),
carrier.ParentSpanId.ToString(),
carrier.ParentServiceInstanceId.ToString(),
carrier.EntryServiceInstanceId.ToString(),
_base64Formatter.Encode(ConvertStringOrIntValue(carrier.NetworkAddress)),
_base64Formatter.Encode(ConvertStringOrIntValue(carrier.ParentEndpoint)),
_base64Formatter.Encode(ConvertStringOrIntValue(carrier.EntryEndpoint)));
}
private static string ConvertStringOrIntValue(StringOrIntValue value)
{
if (value.HasIntValue)
{
return value.GetIntValue().ToString();
}
return "#" + value.GetStringValue();
_base64Formatter.Encode(carrier.ParentServiceId),
_base64Formatter.Encode(carrier.ParentServiceInstanceId),
_base64Formatter.Encode(carrier.ParentEndpoint.ToString()),
_base64Formatter.Encode(carrier.NetworkAddress.ToString()));
}
}
}
\ No newline at end of file
......@@ -16,7 +16,10 @@
*
*/
using SkyApm.Config;
using System;
using System.Security.Cryptography;
using System.Text;
using System.Threading;
namespace SkyApm.Tracing
......@@ -24,18 +27,35 @@ namespace SkyApm.Tracing
public class UniqueIdGenerator : IUniqueIdGenerator
{
private readonly ThreadLocal<long> sequence = new ThreadLocal<long>(() => 0);
private readonly IRuntimeEnvironment _runtimeEnvironment;
private readonly InstrumentConfig _instrumentConfig;
private readonly string _instanceIdentity;
public UniqueIdGenerator(IRuntimeEnvironment runtimeEnvironment)
public UniqueIdGenerator(IConfigAccessor configAccessor)
{
_runtimeEnvironment = runtimeEnvironment;
_instrumentConfig = configAccessor.Get<InstrumentConfig>();
_instanceIdentity = GetMD5(_instrumentConfig.ServiceInstanceName);
}
public UniqueId Generate()
public string Generate()
{
return new UniqueId(_runtimeEnvironment.ServiceInstanceId.Value,
Thread.CurrentThread.ManagedThreadId,
DateTimeOffset.UtcNow.ToUnixTimeMilliseconds() * 10000 + GetSequence());
var part1 = _instanceIdentity;
var part2 = Thread.CurrentThread.ManagedThreadId;
var part3 = DateTimeOffset.UtcNow.ToUnixTimeMilliseconds() * 10000 + GetSequence();
return $"{part1}.{part2}.{part3}";
}
private string GetMD5(string data)
{
using (var md5 = new MD5CryptoServiceProvider())
{
var hash = md5.ComputeHash(Encoding.UTF8.GetBytes(data));
var sb = new StringBuilder(32);
foreach (var item in hash)
{
sb.Append(item.ToString("x2"));
}
return sb.ToString();
}
}
private long GetSequence()
......
/*
* Licensed to the SkyAPM under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The SkyAPM 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 SkyApm.Tracing
{
public class UniqueIdParser : IUniqueIdParser
{
public bool TryParse(string text, out UniqueId uniqueId)
{
uniqueId = default(UniqueId);
if (string.IsNullOrEmpty(text)) return false;
#if SPAN
var id = text.AsSpan();
var index = FindIndex(id);
if (index < 1) return false;
var id1 = id.Slice(0, index);
index = FindIndex(id.Slice(index + 1));
if (index < 1) return false;
if (!long.TryParse(id1, out var part0)) return false;
if (!long.TryParse(id.Slice(id1.Length + 1, index), out var part1)) return false;
if (!long.TryParse(id.Slice(id1.Length + index + 2), out var part2)) return false;
#else
var parts = text.Split("\\.".ToCharArray(), 3);
if (parts.Length < 3) return false;
if (!long.TryParse(parts[0], out var part0)) return false;
if (!long.TryParse(parts[1], out var part1)) return false;
if (!long.TryParse(parts[2], out var part2)) return false;
#endif
uniqueId = new UniqueId(part0, part1, part2);
return true;
}
#if SPAN
private static int FindIndex(ReadOnlySpan<char> id)
{
var index = 0;
do
{
if (id[index] == '\\' || id[index] == '.')
return index;
} while (++index < id.Length);
return -1;
}
#endif
}
}
......@@ -28,14 +28,11 @@ namespace SkyApm.Transport
{
var segmentRequest = new SegmentRequest
{
UniqueIds = new[]
{
MapUniqueId(segmentContext.TraceId)
}
TraceId = segmentContext.TraceId
};
var segmentObjectRequest = new SegmentObjectRequest
{
SegmentId = MapUniqueId(segmentContext.SegmentId),
SegmentId = segmentContext.SegmentId,
ServiceId = segmentContext.ServiceId,
ServiceInstanceId = segmentContext.ServiceInstanceId
};
......@@ -56,7 +53,9 @@ namespace SkyApm.Transport
foreach (var reference in segmentContext.References)
span.References.Add(new SegmentReferenceRequest
{
ParentSegmentId = MapUniqueId(reference.ParentSegmentId),
TraceId = reference.TraceId,
ParentSegmentId = reference.ParentSegmentId,
ParentServiceId = reference.ParentServiceId,
ParentServiceInstanceId = reference.ParentServiceInstanceId,
ParentSpanId = reference.ParentSpanId,
ParentEndpointName = reference.ParentEndpoint,
......@@ -80,15 +79,5 @@ namespace SkyApm.Transport
segmentObjectRequest.Spans.Add(span);
return segmentRequest;
}
private static UniqueIdRequest MapUniqueId(UniqueId uniqueId)
{
return new UniqueIdRequest
{
Part1 = uniqueId.Part1,
Part2 = uniqueId.Part2,
Part3 = uniqueId.Part3
};
}
}
}
\ No newline at end of file
......@@ -22,6 +22,7 @@
<ItemGroup>
<Protobuf Include="protocol/**/*.proto" ProtoRoot="protocol" OutputDir="%(RelativePath)generated" CompileOutputs="false" />
<Protobuf Include="protocol-v3/**/*.proto" ProtoRoot="protocol-v3" OutputDir="%(RelativePath)generated-v3" CompileOutputs="false" />
</ItemGroup>
<PropertyGroup>
......
Subproject commit c91b65dd8fac2c5866d79834ae73c3c445ce11cf
Subproject commit 87ed1f4e31b0517a7efff27d46a47829c7f533f9
......@@ -19,17 +19,29 @@
using System;
using System.Threading;
using System.Threading.Tasks;
using SkyApm.Common;
using SkyApm.Config;
using SkyApm.Logging;
using SkyWalking.NetworkProtocol.V3;
namespace SkyApm.Transport
namespace SkyApm.Transport.Grpc
{
public interface ISkyApmClientV5
public class CLRStatsReporter : ICLRStatsReporter
{
Task<NullableValue> RegisterApplicationAsync(string applicationCode, CancellationToken cancellationToken = default(CancellationToken));
private readonly TransportConfig _transportConfig;
private readonly ICLRStatsReporter _clrStatsReporterV8;
Task<NullableValue> RegisterApplicationInstanceAsync(int applicationId, Guid agentUUID, long registerTime, AgentOsInfoRequest osInfoRequest,
CancellationToken cancellationToken = default(CancellationToken));
public CLRStatsReporter(ConnectionManager connectionManager, ILoggerFactory loggerFactory,
IConfigAccessor configAccessor, IRuntimeEnvironment runtimeEnvironment)
{
_transportConfig = configAccessor.Get<TransportConfig>();
_clrStatsReporterV8 = new V8.CLRStatsReporter(connectionManager, loggerFactory, configAccessor, runtimeEnvironment);
}
Task HeartbeatAsync(int applicationInstance, long heartbeatTime, CancellationToken cancellationToken = default(CancellationToken));
public async Task ReportAsync(CLRStatsRequest statsRequest,
CancellationToken cancellationToken = default(CancellationToken))
{
if (_transportConfig.ProtocolVersion == ProtocolVersions.V8)
await _clrStatsReporterV8.ReportAsync(statsRequest);
}
}
}
}
\ No newline at end of file
......@@ -28,5 +28,6 @@ namespace SkyApm.Transport.Grpc.Common
public static readonly string RegisterServiceError = "Register service fail.";
public static readonly string RegisterServiceInstanceError = "Register service instance fail.";
public static readonly string PingError = "Ping server fail.";
public static readonly string ReportServiceInstancePropertiesError = "Report service instance properties fail.";
}
}
\ No newline at end of file
/*
* Licensed to the SkyAPM under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The SkyAPM 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.Linq;
using Google.Protobuf;
using SkyApm.Common;
using SkyWalking.NetworkProtocol;
namespace SkyApm.Transport.Grpc.Common
{
internal static class SegmentV6Helpers
{
public static UpstreamSegment Map(SegmentRequest request)
{
var upstreamSegment = new UpstreamSegment();
upstreamSegment.GlobalTraceIds.AddRange(request.UniqueIds.Select(MapToUniqueId).ToArray());
var traceSegment = new SegmentObject
{
TraceSegmentId = MapToUniqueId(request.Segment.SegmentId),
ServiceId = request.Segment.ServiceId,
ServiceInstanceId = request.Segment.ServiceInstanceId,
IsSizeLimited = false
};
traceSegment.Spans.Add(request.Segment.Spans.Select(MapToSpan).ToArray());
upstreamSegment.Segment = traceSegment.ToByteString();
return upstreamSegment;
}
private static UniqueId MapToUniqueId(UniqueIdRequest uniqueIdRequest)
{
var uniqueId = new UniqueId();
uniqueId.IdParts.Add(uniqueIdRequest.Part1);
uniqueId.IdParts.Add(uniqueIdRequest.Part2);
uniqueId.IdParts.Add(uniqueIdRequest.Part3);
return uniqueId;
}
private static SpanObjectV2 MapToSpan(SpanRequest request)
{
var spanObject = new SpanObjectV2
{
SpanId = request.SpanId,
ParentSpanId = request.ParentSpanId,
StartTime = request.StartTime,
EndTime = request.EndTime,
SpanType = (SpanType) request.SpanType,
SpanLayer = (SpanLayer) request.SpanLayer,
IsError = request.IsError
};
ReadStringOrIntValue(spanObject, request.Component, ComponentReader, ComponentIdReader);
ReadStringOrIntValue(spanObject, request.OperationName, OperationNameReader, OperationNameIdReader);
ReadStringOrIntValue(spanObject, request.Peer, PeerReader, PeerIdReader);
spanObject.Tags.Add(request.Tags.Select(x => new KeyStringValuePair {Key = x.Key, Value = x.Value}));
spanObject.Refs.AddRange(request.References.Select(MapToSegmentReference).ToArray());
spanObject.Logs.AddRange(request.Logs.Select(MapToLogMessage).ToArray());
return spanObject;
}
private static SegmentReference MapToSegmentReference(SegmentReferenceRequest referenceRequest)
{
var reference = new SegmentReference
{
ParentServiceInstanceId = referenceRequest.ParentServiceInstanceId,
EntryServiceInstanceId = referenceRequest.EntryServiceInstanceId,
ParentSpanId = referenceRequest.ParentSpanId,
RefType = (RefType) referenceRequest.RefType,
ParentTraceSegmentId = MapToUniqueId(referenceRequest.ParentSegmentId)
};
ReadStringOrIntValue(reference, referenceRequest.NetworkAddress, NetworkAddressReader,
NetworkAddressIdReader);
ReadStringOrIntValue(reference, referenceRequest.EntryEndpointName, EntryEndpointReader,
EntryEndpointIdReader);
ReadStringOrIntValue(reference, referenceRequest.ParentEndpointName, ParentEndpointReader,
ParentEndpointIdReader);
return reference;
}
private static Log MapToLogMessage(LogDataRequest request)
{
var logMessage = new Log {Time = request.Timestamp};
logMessage.Data.AddRange(request.Data.Select(x => new KeyStringValuePair {Key = x.Key, Value = x.Value})
.ToArray());
return logMessage;
}
private static void ReadStringOrIntValue<T>(T instance, StringOrIntValue stringOrIntValue,
Action<T, string> stringValueReader, Action<T, int> intValueReader)
{
if (stringOrIntValue.HasStringValue)
{
stringValueReader.Invoke(instance, stringOrIntValue.GetStringValue());
}
else if (stringOrIntValue.HasIntValue)
{
intValueReader.Invoke(instance, stringOrIntValue.GetIntValue());
}
}
private static readonly Action<SpanObjectV2, string> ComponentReader = (s, val) => s.Component = val;
private static readonly Action<SpanObjectV2, int> ComponentIdReader = (s, val) => s.ComponentId = val;
private static readonly Action<SpanObjectV2, string> OperationNameReader = (s, val) => s.OperationName = val;
private static readonly Action<SpanObjectV2, int> OperationNameIdReader = (s, val) => s.OperationNameId = val;
private static readonly Action<SpanObjectV2, string> PeerReader = (s, val) => s.Peer = val;
private static readonly Action<SpanObjectV2, int> PeerIdReader = (s, val) => s.PeerId = val;
private static readonly Action<SegmentReference, string> NetworkAddressReader =
(s, val) => s.NetworkAddress = val;
private static readonly Action<SegmentReference, int> NetworkAddressIdReader =
(s, val) => s.NetworkAddressId = val;
private static readonly Action<SegmentReference, string>
EntryEndpointReader = (s, val) => s.EntryEndpoint = val;
private static readonly Action<SegmentReference, int> EntryEndpointIdReader =
(s, val) => s.EntryEndpointId = val;
private static readonly Action<SegmentReference, string> ParentEndpointReader =
(s, val) => s.ParentEndpoint = val;
private static readonly Action<SegmentReference, int> ParentEndpointIdReader =
(s, val) => s.ParentEndpointId = val;
}
}
\ No newline at end of file
......@@ -20,39 +20,25 @@ using System;
using System.Linq;
using Google.Protobuf;
using SkyApm.Common;
using SkyWalking.NetworkProtocol;
using SkyWalking.NetworkProtocol.V3;
namespace SkyApm.Transport.Grpc.Common
{
internal static class SegmentV5Helpers
internal static class SegmentV8Helpers
{
public static UpstreamSegment Map(SegmentRequest request)
public static SegmentObject Map(SegmentRequest request)
{
var upstreamSegment = new UpstreamSegment();
upstreamSegment.GlobalTraceIds.AddRange(request.UniqueIds.Select(MapToUniqueId).ToArray());
var traceSegment = new TraceSegmentObject
var traceSegment = new SegmentObject
{
TraceSegmentId = MapToUniqueId(request.Segment.SegmentId),
ApplicationId = request.Segment.ServiceId,
ApplicationInstanceId = request.Segment.ServiceInstanceId,
TraceId = request.TraceId, //todo: is there chances request.UniqueIds.Count > 1 ?
TraceSegmentId = request.Segment.SegmentId,
Service = request.Segment.ServiceId,
ServiceInstance = request.Segment.ServiceInstanceId,
IsSizeLimited = false
};
traceSegment.Spans.Add(request.Segment.Spans.Select(MapToSpan).ToArray());
upstreamSegment.Segment = traceSegment.ToByteString();
return upstreamSegment;
}
private static UniqueId MapToUniqueId(UniqueIdRequest uniqueIdRequest)
{
var uniqueId = new UniqueId();
uniqueId.IdParts.Add(uniqueIdRequest.Part1);
uniqueId.IdParts.Add(uniqueIdRequest.Part2);
uniqueId.IdParts.Add(uniqueIdRequest.Part3);
return uniqueId;
return traceSegment;
}
private static SpanObject MapToSpan(SpanRequest request)
......@@ -65,68 +51,65 @@ namespace SkyApm.Transport.Grpc.Common
EndTime = request.EndTime,
SpanType = (SpanType) request.SpanType,
SpanLayer = (SpanLayer) request.SpanLayer,
IsError = request.IsError
IsError = request.IsError,
};
ReadStringOrIntValue(spanObject, request.Component, ComponentReader, ComponentIdReader);
ReadStringOrIntValue(spanObject, request.OperationName, OperationNameReader, OperationNameIdReader);
ReadStringOrIntValue(spanObject, request.Peer, PeerReader, PeerIdReader);
spanObject.Tags.Add(request.Tags.Select(x => new KeyWithStringValue {Key = x.Key, Value = x.Value}));
spanObject.Tags.Add(request.Tags.Select(x => new KeyStringValuePair {Key = x.Key, Value = x.Value}));
spanObject.Refs.AddRange(request.References.Select(MapToSegmentReference).ToArray());
spanObject.Logs.AddRange(request.Logs.Select(MapToLogMessage).ToArray());
return spanObject;
}
private static TraceSegmentReference MapToSegmentReference(SegmentReferenceRequest referenceRequest)
private static SegmentReference MapToSegmentReference(SegmentReferenceRequest referenceRequest)
{
var reference = new TraceSegmentReference
var reference = new SegmentReference
{
ParentApplicationInstanceId = referenceRequest.ParentServiceInstanceId,
EntryApplicationInstanceId = referenceRequest.EntryServiceInstanceId,
TraceId = referenceRequest.TraceId,
ParentService = referenceRequest.ParentServiceId,
ParentServiceInstance = referenceRequest.ParentServiceInstanceId,
ParentSpanId = referenceRequest.ParentSpanId,
RefType = (RefType) referenceRequest.RefType,
ParentTraceSegmentId = MapToUniqueId(referenceRequest.ParentSegmentId)
ParentTraceSegmentId = referenceRequest.ParentSegmentId,
ParentEndpoint = referenceRequest.ParentEndpointName.ToString(),
NetworkAddressUsedAtPeer = referenceRequest.NetworkAddress.ToString()
};
ReadStringOrIntValue(reference, referenceRequest.NetworkAddress, NetworkAddressReader, NetworkAddressIdReader);
ReadStringOrIntValue(reference, referenceRequest.EntryEndpointName, EntryServiceReader, EntryServiceIdReader);
ReadStringOrIntValue(reference, referenceRequest.ParentEndpointName, ParentServiceReader, ParentServiceIdReader);
return reference;
}
private static LogMessage MapToLogMessage(LogDataRequest request)
private static Log MapToLogMessage(LogDataRequest request)
{
var logMessage = new LogMessage {Time = request.Timestamp};
logMessage.Data.AddRange(request.Data.Select(x => new KeyWithStringValue {Key = x.Key, Value = x.Value}).ToArray());
var logMessage = new Log {Time = request.Timestamp};
logMessage.Data.AddRange(request.Data.Select(x => new KeyStringValuePair {Key = x.Key, Value = x.Value})
.ToArray());
return logMessage;
}
private static void ReadStringOrIntValue<T>(T instance, StringOrIntValue stringOrIntValue, Action<T, string> stringValueReader, Action<T, int> intValueReader)
private static void ReadStringOrIntValue<T>(T instance, StringOrIntValue stringOrIntValue,
Action<T, string> stringValueReader, Action<T, int> intValueReader)
{
if (stringOrIntValue.HasStringValue)
// We should first check and prefer the int value to reduce the network transport payload
// in case both int and string value is present.
if (stringOrIntValue.HasIntValue)
{
stringValueReader.Invoke(instance, stringOrIntValue.GetStringValue());
intValueReader.Invoke(instance, stringOrIntValue.GetIntValue());
}
else if (stringOrIntValue.HasIntValue)
else if (stringOrIntValue.HasStringValue)
{
intValueReader.Invoke(instance, stringOrIntValue.GetIntValue());
stringValueReader.Invoke(instance, stringOrIntValue.GetStringValue());
}
}
private static readonly Action<SpanObject, string> ComponentReader = (s, val) => s.Component = val;
private static readonly Action<SpanObject, string> ComponentReader = (s, val) => { /*nolonger support*/};
private static readonly Action<SpanObject, int> ComponentIdReader = (s, val) => s.ComponentId = val;
private static readonly Action<SpanObject, string> OperationNameReader = (s, val) => s.OperationName = val;
private static readonly Action<SpanObject, int> OperationNameIdReader = (s, val) => s.OperationNameId = val;
private static readonly Action<SpanObject, int> OperationNameIdReader = (s, val) => { /*nolonger support*/ };
private static readonly Action<SpanObject, string> PeerReader = (s, val) => s.Peer = val;
private static readonly Action<SpanObject, int> PeerIdReader = (s, val) => s.PeerId = val;
private static readonly Action<TraceSegmentReference, string> NetworkAddressReader = (s, val) => s.NetworkAddress = val;
private static readonly Action<TraceSegmentReference, int> NetworkAddressIdReader = (s, val) => s.NetworkAddressId = val;
private static readonly Action<TraceSegmentReference, string> EntryServiceReader = (s, val) => s.EntryServiceName = val;
private static readonly Action<TraceSegmentReference, int> EntryServiceIdReader = (s, val) => s.EntryServiceId = val;
private static readonly Action<TraceSegmentReference, string> ParentServiceReader = (s, val) => s.ParentServiceName = val;
private static readonly Action<TraceSegmentReference, int> ParentServiceIdReader = (s, val) => s.ParentServiceId = val;
private static readonly Action<SpanObject, int> PeerIdReader = (s, val) => { /*nolonger support*/ };
}
}
\ No newline at end of file
......@@ -21,7 +21,7 @@ using System.Threading;
using System.Threading.Tasks;
using SkyApm.Logging;
namespace SkyApm.Transport.Grpc.V6
namespace SkyApm.Transport.Grpc
{
public class ConnectService: ExecutionService
{
......
......@@ -16,16 +16,32 @@
*
*/
using System.Collections.Generic;
using System;
using System.Threading;
using System.Threading.Tasks;
using SkyApm.Config;
using SkyApm.Logging;
using SkyWalking.NetworkProtocol;
using SkyApm.Transport.Grpc.Common;
namespace SkyApm.Transport
namespace SkyApm.Transport.Grpc
{
public class ServiceRequest
public class PingCaller : IPingCaller
{
public string ServiceName { get; set; }
private readonly TransportConfig _transportConfig;
private readonly IPingCaller _pingCallerV8;
public Dictionary<string, string> Tags { get; set; }
public Dictionary<string,string> Properties { get; set; }
public PingCaller(ConnectionManager connectionManager, ILoggerFactory loggerFactory,
IConfigAccessor configAccessor)
{
_transportConfig = configAccessor.Get<TransportConfig>();
_pingCallerV8 = new V8.PingCaller(connectionManager, loggerFactory, configAccessor);
}
public async Task PingAsync(PingRequest request, CancellationToken cancellationToken = default(CancellationToken))
{
if (_transportConfig.ProtocolVersion == ProtocolVersions.V8)
await _pingCallerV8.PingAsync(request, cancellationToken);
}
}
}
\ No newline at end of file
......@@ -21,32 +21,26 @@ using System.Threading;
using System.Threading.Tasks;
using SkyApm.Config;
using SkyApm.Logging;
using SegmentReporterV5 = SkyApm.Transport.Grpc.V5.SegmentReporter;
using SegmentReporterV6 = SkyApm.Transport.Grpc.V6.SegmentReporter;
namespace SkyApm.Transport.Grpc
{
public class SegmentReporter : ISegmentReporter
{
private readonly ISegmentReporter _segmentReporterV5;
private readonly ISegmentReporter _segmentReporterV6;
private readonly ISegmentReporter _segmentReporterV8;
private readonly TransportConfig _transportConfig;
public SegmentReporter(ConnectionManager connectionManager, IConfigAccessor configAccessor,
ILoggerFactory loggerFactory)
{
_transportConfig = configAccessor.Get<TransportConfig>();
_segmentReporterV5 = new V5.SegmentReporter(connectionManager, configAccessor, loggerFactory);
_segmentReporterV6 = new V6.SegmentReporter(connectionManager, configAccessor, loggerFactory);
_segmentReporterV8 = new V8.SegmentReporter(connectionManager, configAccessor, loggerFactory);
}
public async Task ReportAsync(IReadOnlyCollection<SegmentRequest> segmentRequests,
CancellationToken cancellationToken = default(CancellationToken))
{
if (_transportConfig.ProtocolVersion == ProtocolVersions.V6)
await _segmentReporterV6.ReportAsync(segmentRequests, cancellationToken);
if (_transportConfig.ProtocolVersion == ProtocolVersions.V5)
await _segmentReporterV5.ReportAsync(segmentRequests, cancellationToken);
if (_transportConfig.ProtocolVersion == ProtocolVersions.V8)
await _segmentReporterV8.ReportAsync(segmentRequests, cancellationToken);
}
}
}
\ No newline at end of file
/*
/*
* Licensed to the SkyAPM under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
......@@ -17,45 +17,33 @@
*/
using System;
namespace SkyApm.Tracing
using System.Threading;
using System.Threading.Tasks;
using SkyApm.Common;
using SkyApm.Config;
using SkyApm.Logging;
using SkyApm.Transport.Grpc.Common;
namespace SkyApm.Transport.Grpc
{
public struct UniqueId : IEquatable<UniqueId>
public class ServiceRegister : IServiceRegister
{
public long Part1 { get; }
public long Part2 { get; }
private readonly TransportConfig _transportConfig;
private readonly IServiceRegister _serviceRegisterV8;
public long Part3 { get; }
public UniqueId(long part1, long part2, long part3)
public ServiceRegister(ConnectionManager connectionManager, IConfigAccessor configAccessor,
ILoggerFactory loggerFactory)
{
Part1 = part1;
Part2 = part2;
Part3 = part3;
_transportConfig = configAccessor.Get<TransportConfig>();
_serviceRegisterV8 = new V8.ServiceRegister(connectionManager, configAccessor, loggerFactory);
}
public override string ToString() => $"{Part1}.{Part2}.{Part3}";
public bool Equals(UniqueId other) =>
Part1 == other.Part1 && Part2 == other.Part2 && Part3 == other.Part3;
public override bool Equals(object obj) =>
obj is UniqueId other && Equals(other);
public override int GetHashCode()
public async Task<bool> ReportInstancePropertiesAsync(ServiceInstancePropertiesRequest serviceInstancePropertiesRequest,
CancellationToken cancellationToken = default(CancellationToken))
{
unchecked
{
var hashCode = Part1.GetHashCode();
hashCode = (hashCode * 397) ^ Part2.GetHashCode();
hashCode = (hashCode * 397) ^ Part3.GetHashCode();
return hashCode;
}
if (_transportConfig.ProtocolVersion == ProtocolVersions.V8)
return await _serviceRegisterV8.ReportInstancePropertiesAsync(serviceInstancePropertiesRequest, cancellationToken);
return true;
}
public static bool operator ==(UniqueId left, UniqueId right) => left.Equals(right);
public static bool operator !=(UniqueId left, UniqueId right) => !left.Equals(right);
}
}
}
\ No newline at end of file
/*
* Licensed to the SkyAPM under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The SkyAPM 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.Threading;
using System.Threading.Tasks;
using SkyApm.Common;
using SkyApm.Config;
using SkyApm.Logging;
using SkyWalking.NetworkProtocol;
using SkyApm.Transport.Grpc.Common;
namespace SkyApm.Transport.Grpc.V5
{
public class SkyApmClientV5 : ISkyApmClientV5
{
private readonly ConnectionManager _connectionManager;
private readonly ILogger _logger;
private readonly GrpcConfig _config;
public SkyApmClientV5(ConnectionManager connectionManager, IConfigAccessor configAccessor,
ILoggerFactory loggerFactory)
{
_connectionManager = connectionManager;
_config = configAccessor.Get<GrpcConfig>();
_logger = loggerFactory.CreateLogger(typeof(SkyApmClientV5));
}
public async Task<NullableValue> RegisterApplicationAsync(string applicationCode,
CancellationToken cancellationToken = default(CancellationToken))
{
if (!_connectionManager.Ready)
{
return NullableValue.Null;
}
var connection = _connectionManager.GetConnection();
var client = new ApplicationRegisterService.ApplicationRegisterServiceClient(connection);
return await new Call(_logger, _connectionManager).Execute(async () =>
{
var applicationMapping = await client.applicationCodeRegisterAsync(
new Application {ApplicationCode = applicationCode},
_config.GetMeta(), _config.GetTimeout(), cancellationToken);
return new NullableValue(applicationMapping?.Application?.Value ?? 0);
},
() => NullableValue.Null,
() => ExceptionHelpers.RegisterApplicationError);
}
public async Task<NullableValue> RegisterApplicationInstanceAsync(int applicationId, Guid agentUUID,
long registerTime, AgentOsInfoRequest osInfoRequest,
CancellationToken cancellationToken = default(CancellationToken))
{
if (!_connectionManager.Ready)
{
return NullableValue.Null;
}
var connection = _connectionManager.GetConnection();
var client = new InstanceDiscoveryService.InstanceDiscoveryServiceClient(connection);
var applicationInstance = new ApplicationInstance
{
ApplicationId = applicationId,
AgentUUID = agentUUID.ToString("N"),
RegisterTime = registerTime,
Osinfo = new OSInfo
{
OsName = osInfoRequest.OsName,
Hostname = osInfoRequest.HostName,
ProcessNo = osInfoRequest.ProcessNo
}
};
applicationInstance.Osinfo.Ipv4S.AddRange(osInfoRequest.IpAddress);
return await new Call(_logger, _connectionManager).Execute(async () =>
{
var applicationInstanceMapping = await client.registerInstanceAsync(applicationInstance, null,
_config.GetTimeout(), cancellationToken);
return new NullableValue(applicationInstanceMapping?.ApplicationInstanceId ?? 0);
},
() => NullableValue.Null,
() => ExceptionHelpers.RegisterApplicationInstanceError);
}
public async Task HeartbeatAsync(int applicationInstance, long heartbeatTime,
CancellationToken cancellationToken = default(CancellationToken))
{
if (!_connectionManager.Ready)
{
return;
}
var connection = _connectionManager.GetConnection();
var client = new InstanceDiscoveryService.InstanceDiscoveryServiceClient(connection);
var heartbeat = new ApplicationInstanceHeartbeat
{
ApplicationInstanceId = applicationInstance,
HeartbeatTime = heartbeatTime
};
await new Call(_logger, _connectionManager).Execute(
async () => await client.heartbeatAsync(heartbeat, _config.GetMeta(), _config.GetTimeout(), cancellationToken),
() => ExceptionHelpers.HeartbeatError);
}
}
}
\ No newline at end of file
/*
* Licensed to the SkyAPM under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The SkyAPM 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.Threading;
using System.Threading.Tasks;
using SkyApm.Common;
using SkyApm.Config;
using SkyApm.Logging;
using SkyWalking.NetworkProtocol;
using SkyApm.Transport.Grpc.Common;
namespace SkyApm.Transport.Grpc.V6
{
public class ServiceRegister : IServiceRegister
{
private const string OS_NAME = "os_name";
private const string HOST_NAME = "host_name";
private const string IPV4 = "ipv4";
private const string PROCESS_NO = "process_no";
private const string LANGUAGE = "language";
private readonly ConnectionManager _connectionManager;
private readonly ILogger _logger;
private readonly GrpcConfig _config;
public ServiceRegister(ConnectionManager connectionManager, IConfigAccessor configAccessor,
ILoggerFactory loggerFactory)
{
_connectionManager = connectionManager;
_config = configAccessor.Get<GrpcConfig>();
_logger = loggerFactory.CreateLogger(typeof(ServiceRegister));
}
public async Task<NullableValue> RegisterServiceAsync(ServiceRequest serviceRequest,
CancellationToken cancellationToken = default(CancellationToken))
{
if (!_connectionManager.Ready)
{
return NullableValue.Null;
}
var connection = _connectionManager.GetConnection();
return await new Call(_logger, _connectionManager).Execute(async () =>
{
var client = new Register.RegisterClient(connection);
var services = new Services();
services.Services_.Add(new Service
{
ServiceName = serviceRequest.ServiceName
});
var mapping = await client.doServiceRegisterAsync(services,
_config.GetMeta(), _config.GetTimeout(), cancellationToken);
foreach (var service in mapping.Services)
if (service.Key == serviceRequest.ServiceName)
return new NullableValue(service.Value);
return NullableValue.Null;
},
() => NullableValue.Null,
() => ExceptionHelpers.RegisterServiceError);
}
public async Task<NullableValue> RegisterServiceInstanceAsync(ServiceInstanceRequest serviceInstanceRequest,
CancellationToken cancellationToken = default(CancellationToken))
{
if (!_connectionManager.Ready)
{
return NullableValue.Null;
}
var connection = _connectionManager.GetConnection();
return await new Call(_logger, _connectionManager).Execute(async () =>
{
var client = new Register.RegisterClient(connection);
var instance = new ServiceInstance
{
ServiceId = serviceInstanceRequest.ServiceId,
InstanceUUID = serviceInstanceRequest.InstanceUUID,
Time = DateTimeOffset.UtcNow.ToUnixTimeMilliseconds()
};
instance.Properties.Add(new KeyStringValuePair
{Key = OS_NAME, Value = serviceInstanceRequest.Properties.OsName});
instance.Properties.Add(new KeyStringValuePair
{Key = HOST_NAME, Value = serviceInstanceRequest.Properties.HostName});
instance.Properties.Add(new KeyStringValuePair
{Key = PROCESS_NO, Value = serviceInstanceRequest.Properties.ProcessNo.ToString()});
instance.Properties.Add(new KeyStringValuePair
{Key = LANGUAGE, Value = serviceInstanceRequest.Properties.Language});
foreach (var ip in serviceInstanceRequest.Properties.IpAddress)
instance.Properties.Add(new KeyStringValuePair
{Key = IPV4, Value = ip});
var serviceInstances = new ServiceInstances();
serviceInstances.Instances.Add(instance);
var mapping = await client.doServiceInstanceRegisterAsync(serviceInstances,
_config.GetMeta(), _config.GetTimeout(), cancellationToken);
foreach (var serviceInstance in mapping.ServiceInstances)
if (serviceInstance.Key == serviceInstanceRequest.InstanceUUID)
return new NullableValue(serviceInstance.Value);
return NullableValue.Null;
},
() => NullableValue.Null,
() => ExceptionHelpers.RegisterServiceInstanceError);
}
}
}
\ No newline at end of file
......@@ -21,16 +21,17 @@ using System.Threading;
using System.Threading.Tasks;
using SkyApm.Config;
using SkyApm.Logging;
using SkyWalking.NetworkProtocol;
using SkyWalking.NetworkProtocol.V3;
namespace SkyApm.Transport.Grpc.V6
namespace SkyApm.Transport.Grpc.V8
{
public class CLRStatsReporter : ICLRStatsReporter
internal class CLRStatsReporter : ICLRStatsReporter
{
private readonly ConnectionManager _connectionManager;
private readonly ILogger _logger;
private readonly GrpcConfig _config;
private readonly IRuntimeEnvironment _runtimeEnvironment;
private readonly InstrumentConfig _instrumentConfig;
public CLRStatsReporter(ConnectionManager connectionManager, ILoggerFactory loggerFactory,
IConfigAccessor configAccessor, IRuntimeEnvironment runtimeEnvironment)
......@@ -39,6 +40,7 @@ namespace SkyApm.Transport.Grpc.V6
_logger = loggerFactory.CreateLogger(typeof(CLRStatsReporter));
_config = configAccessor.Get<GrpcConfig>();
_runtimeEnvironment = runtimeEnvironment;
_instrumentConfig = configAccessor.Get<InstrumentConfig>();
}
public async Task ReportAsync(CLRStatsRequest statsRequest,
......@@ -55,7 +57,8 @@ namespace SkyApm.Transport.Grpc.V6
{
var request = new CLRMetricCollection
{
ServiceInstanceId = _runtimeEnvironment.ServiceInstanceId.Value
Service = _instrumentConfig.ServiceName ?? _instrumentConfig.ApplicationCode,
ServiceInstance = _instrumentConfig.ServiceInstanceName,
};
var metric = new CLRMetric
{
......
......@@ -21,12 +21,12 @@ using System.Threading;
using System.Threading.Tasks;
using SkyApm.Config;
using SkyApm.Logging;
using SkyWalking.NetworkProtocol;
using SkyWalking.NetworkProtocol.V3;
using SkyApm.Transport.Grpc.Common;
namespace SkyApm.Transport.Grpc.V6
namespace SkyApm.Transport.Grpc.V8
{
public class PingCaller : IPingCaller
internal class PingCaller : IPingCaller
{
private readonly ConnectionManager _connectionManager;
private readonly ILogger _logger;
......@@ -50,12 +50,11 @@ namespace SkyApm.Transport.Grpc.V6
var connection = _connectionManager.GetConnection();
return new Call(_logger, _connectionManager).Execute(async () =>
{
var client = new ServiceInstancePing.ServiceInstancePingClient(connection);
await client.doPingAsync(new ServiceInstancePingPkg
var client = new ManagementService.ManagementServiceClient(connection);
await client.keepAliveAsync(new InstancePingPkg
{
ServiceInstanceId = request.ServiceInstanceId,
ServiceInstanceUUID = request.InstanceId,
Time = DateTimeOffset.UtcNow.ToUnixTimeMilliseconds()
Service = request.ServiceName,
ServiceInstance = request.InstanceId,
}, _config.GetMeta(), _config.GetTimeout(), cancellationToken);
},
() => ExceptionHelpers.PingError);
......
......@@ -23,10 +23,10 @@ using System.Threading;
using System.Threading.Tasks;
using SkyApm.Config;
using SkyApm.Logging;
using SkyWalking.NetworkProtocol;
using SkyWalking.NetworkProtocol.V3;
using SkyApm.Transport.Grpc.Common;
namespace SkyApm.Transport.Grpc.V6
namespace SkyApm.Transport.Grpc.V8
{
internal class SegmentReporter : ISegmentReporter
{
......@@ -60,7 +60,7 @@ namespace SkyApm.Transport.Grpc.V6
client.collect(_config.GetMeta(), _config.GetReportTimeout(), cancellationToken))
{
foreach (var segment in segmentRequests)
await asyncClientStreamingCall.RequestStream.WriteAsync(SegmentV6Helpers.Map(segment));
await asyncClientStreamingCall.RequestStream.WriteAsync(SegmentV8Helpers.Map(segment));
await asyncClientStreamingCall.RequestStream.CompleteAsync();
await asyncClientStreamingCall.ResponseAsync;
}
......
......@@ -17,62 +17,74 @@
*/
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Threading;
using System.Threading.Tasks;
using SkyApm.Common;
using SkyApm.Config;
using SkyApm.Logging;
using SkyWalking.NetworkProtocol;
using SkyWalking.NetworkProtocol.V3;
using SkyApm.Transport.Grpc.Common;
using System.Linq;
namespace SkyApm.Transport.Grpc.V5
namespace SkyApm.Transport.Grpc.V8
{
internal class SegmentReporter : ISegmentReporter
internal class ServiceRegister : IServiceRegister
{
private const string OS_NAME = "os_name";
private const string HOST_NAME = "host_name";
private const string IPV4 = "ipv4";
private const string PROCESS_NO = "process_no";
private const string LANGUAGE = "language";
private readonly ConnectionManager _connectionManager;
private readonly ILogger _logger;
private readonly GrpcConfig _config;
public SegmentReporter(ConnectionManager connectionManager, IConfigAccessor configAccessor,
public ServiceRegister(ConnectionManager connectionManager, IConfigAccessor configAccessor,
ILoggerFactory loggerFactory)
{
_connectionManager = connectionManager;
_config = configAccessor.Get<GrpcConfig>();
_logger = loggerFactory.CreateLogger(typeof(SegmentReporter));
_logger = loggerFactory.CreateLogger(typeof(ServiceRegister));
}
public async Task ReportAsync(IReadOnlyCollection<SegmentRequest> segmentRequests,
CancellationToken cancellationToken = default(CancellationToken))
public async Task<bool> ReportInstancePropertiesAsync(ServiceInstancePropertiesRequest serviceInstancePropertiesRequest, CancellationToken cancellationToken = default)
{
if (!_connectionManager.Ready)
{
return;
return false;
}
var connection = _connectionManager.GetConnection();
try
return await new Call(_logger, _connectionManager).Execute(async () =>
{
var stopwatch = Stopwatch.StartNew();
var client = new TraceSegmentService.TraceSegmentServiceClient(connection);
using (var asyncClientStreamingCall =
client.collect(_config.GetMeta(), _config.GetReportTimeout(), cancellationToken))
var client = new ManagementService.ManagementServiceClient(connection);
var instance = new InstanceProperties
{
foreach (var segment in segmentRequests)
await asyncClientStreamingCall.RequestStream.WriteAsync(SegmentV5Helpers.Map(segment));
await asyncClientStreamingCall.RequestStream.CompleteAsync();
await asyncClientStreamingCall.ResponseAsync;
}
Service = serviceInstancePropertiesRequest.ServiceId,
ServiceInstance = serviceInstancePropertiesRequest.ServiceInstanceId,
};
stopwatch.Stop();
_logger.Information($"Report {segmentRequests.Count} trace segment. cost: {stopwatch.Elapsed}s");
}
catch (Exception ex)
{
_logger.Error("Report trace segment fail.", ex);
_connectionManager.Failure(ex);
}
instance.Properties.Add(new KeyStringValuePair
{ Key = OS_NAME, Value = serviceInstancePropertiesRequest.Properties.OsName });
instance.Properties.Add(new KeyStringValuePair
{ Key = HOST_NAME, Value = serviceInstancePropertiesRequest.Properties.HostName });
instance.Properties.Add(new KeyStringValuePair
{ Key = PROCESS_NO, Value = serviceInstancePropertiesRequest.Properties.ProcessNo.ToString() });
instance.Properties.Add(new KeyStringValuePair
{ Key = LANGUAGE, Value = serviceInstancePropertiesRequest.Properties.Language });
foreach (var ip in serviceInstancePropertiesRequest.Properties.IpAddress)
instance.Properties.Add(new KeyStringValuePair
{ Key = IPV4, Value = ip });
var mapping = await client.reportInstancePropertiesAsync(instance,
_config.GetMeta(), _config.GetTimeout(), cancellationToken);
//todo: should assert the result?
return true;
},
() => false,
() => ExceptionHelpers.ReportServiceInstancePropertiesError);
}
}
}
\ No newline at end of file
......@@ -16,6 +16,7 @@
*
*/
using System;
using System.Collections.Generic;
using System.IO;
using Microsoft.Extensions.Configuration;
......@@ -32,13 +33,14 @@ namespace SkyApm.Utilities.Configuration
{
{"SkyWalking:Namespace", string.Empty},
{"SkyWalking:ServiceName", "My_Service"},
{"SkyWalking:HeaderVersions:0", HeaderVersions.SW6},
{"Skywalking:ServiceInstanceName", Guid.NewGuid().ToString("N")},
{"SkyWalking:HeaderVersions:0", HeaderVersions.SW8},
{"SkyWalking:Sampling:SamplePer3Secs", "-1"},
{"SkyWalking:Sampling:Percentage", "-1"},
{"SkyWalking:Logging:Level", "Information"},
{"SkyWalking:Logging:FilePath", defaultLogFile},
{"SkyWalking:Transport:Interval", "3000"},
{"SkyWalking:Transport:ProtocolVersion", ProtocolVersions.V6},
{"SkyWalking:Transport:ProtocolVersion", ProtocolVersions.V8},
{"SkyWalking:Transport:QueueSize", "30000"},
{"SkyWalking:Transport:BatchSize", "3000"},
{"SkyWalking:Transport:gRPC:Servers", "localhost:11800"},
......
/*
* Licensed to the SkyAPM under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The SkyAPM 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 SkyApm.Tracing;
using System;
using Xunit;
namespace SkyApm.Core.Tests
{
public class UniqueIdParserTest
{
private static readonly IUniqueIdParser Parser = new UniqueIdParser();
[Theory]
[InlineData(null, false)]
[InlineData("", false)]
[InlineData("1", false)]
[InlineData("1.1", false)]
[InlineData("1.1.", false)]
[InlineData("1.1.a", false)]
[InlineData("1.1.1.1", false)]
[InlineData("1\\1.-1", true)]
public void TryParse_Return(string text, bool result) =>
Assert.Equal(result, Parser.TryParse(text, out _));
[Theory]
[InlineData("1.2.3", 1, 2, 3)]
[InlineData("123.456.789", 123, 456, 789)]
[InlineData("-1.-2.-3", -1, -2, -3)]
[InlineData("9223372036854775807.9223372036854775807.9223372036854775807", 9223372036854775807, 9223372036854775807, 9223372036854775807)]
[InlineData("-9223372036854775807.-9223372036854775807.-9223372036854775807", -9223372036854775807, -9223372036854775807, -9223372036854775807)]
public void TryParse_Out(string text, long part1, long part2, long part3)
{
Parser.TryParse(text, out var id);
Assert.Equal(part1, id.Part1);
Assert.Equal(part2, id.Part2);
Assert.Equal(part3, id.Part3);
}
}
}
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册