Skip to content
This repository has been archived by the owner on Apr 28, 2022. It is now read-only.

128 bit trace id not working with b3 propagation #143

Closed
Tanejaankush opened this issue Apr 5, 2019 · 6 comments · Fixed by #144
Closed

128 bit trace id not working with b3 propagation #143

Tanejaankush opened this issue Apr 5, 2019 · 6 comments · Fixed by #144

Comments

@Tanejaankush
Copy link

Tanejaankush commented Apr 5, 2019

Just added configurability in jaegertracing/jaeger-client-csharp#94 by proposing the following changes to the API:

  • Added environment variable JAEGER_TRACEID_128BIT
  • Added WithTraceId128Bit method to Configuration
  • Added WithTraceId128Bit method to Tracer.Builder
  • Adde UseTraceId128Bit property to Tracer

Go and C++ have done it through their options context and do not offer it through Configuration (either code or environment) yet. It would be great to discuss if we like to have this in configuration and if, what env-var to use.

Hey I am using "JAEGER_TRACEID_128BIT" environment variable to enable 128 bit trace id support but while I deploy application image in windows container it works fine but when I deploy the same image in kubernetes it never generates 128 bit traceid for the same image with same variables passed for deployement.

@Falco20019
Copy link
Collaborator

Falco20019 commented Apr 15, 2019

Can you see if other parameters are set from the behavior? Especially JAEGER_REPORTER_LOG_SPANS?

Your configuration seems a bit more complicated than necessary. If you do it as follows, it stays open for changes to the configuration:

services.AddOpenTracing();

// Adds the JAEGER Tracer.
services.AddSingleton<ITracer>(serviceProvider =>
{
	Tracer tracer = null;
	var hostingEnv = serviceProvider.GetRequiredService<IHostingEnvironment>();
	
	// Add project name as service name as a default to JAEGER client if not passed from outside as a parameter.
	serviceName = serviceName ?? hostingEnv.ApplicationName;

	// Initialize the configuration builder with environment (if set).
	var configurationBuilder = new ConfigurationBuilder()
		.AddEnvironmentVariables();
	
	if (hostingEnv.IsDevelopment()) {
		configurationBuilder.AddInMemoryCollection(new Dictionary<string, string>
		{
			{Jaeger.Configuration.JaegerServiceName, serviceName},
		});
	}

	// Get tracer instance with configurations.
	tracer = (Tracer)Jaeger.Configuration
		.FromIConfiguration(loggerFactory, configurationBuilder.Build())
		.GetTracer();

	// Allows code that can't use DI to also access the tracer.
	GlobalTracer.Register(tracer);

	return tracer;
});

I can't see any problem at the moment. You can try it using the numeric version which is also accepted in case kubernetes is not passing the boolean correctly:
docker run --rm --link jaeger_local --env JAEGER_SERVICE_NAME="facility.default" --env JAEGER_AGENT_HOST=jaeger_local --env JAEGER_AGENT_PORT=6831 --env JAEGER_SAMPLER_TYPE=const --env JAEGER_SAMPLER_PARAM=1 --env JAEGER_TRACEID_128BIT=1 --env JAEGER_REPORTER_LOG_SPANS=1 -p 1561:80 facility

But since all the environment variables are passed as string anyway, I don't think that's the problem. I don't have kubernetes in use right now, so it will takes some more time to test it. Can you post the YAML that you are using for k8s?

@Falco20019
Copy link
Collaborator

Falco20019 commented Apr 18, 2019

@Tanejaankush: I just tried it with kubernetes and can't reproduce your problem. I tried it with the following minimal example that I then started through docker build -t dotnet dotnet && docker stack deploy --compose-file docker-compose.yml test-env.

docker-compose.yml

version: '3.3'

services:
    dotnet:
        image: dotnet
        depends_on:
            - jaeger
        environment:
            - JAEGER_SERVICE_NAME=facility.default
            - JAEGER_AGENT_HOST=jaeger
            - JAEGER_AGENT_PORT=6831
            - JAEGER_SAMPLER_TYPE=const
            - JAEGER_SAMPLER_PARAM=1
            - JAEGER_TRACEID_128BIT=1
            - JAEGER_REPORTER_LOG_SPANS=1

    jaeger:
        image: jaegertracing/all-in-one:1.6
        ports:
            - "16686:16686"

dotnet/Dockerfile

FROM mcr.microsoft.com/dotnet/core/sdk:2.2 AS build-env
WORKDIR /app

# Copy csproj and restore as distinct layers
COPY test-env/*.csproj ./
RUN dotnet restore

# Copy everything else and build
COPY test-env/. ./
RUN dotnet publish -c Release -o out

# Build runtime image
FROM mcr.microsoft.com/dotnet/core/runtime:2.2-alpine
WORKDIR /app
COPY --from=build-env /app/out .
ENTRYPOINT ["dotnet", "test-env.dll"]

dotnet/test-env/test-env.csproj

<Project Sdk="Microsoft.NET.Sdk">
  <PropertyGroup>
    <OutputType>Exe</OutputType>
    <TargetFramework>netcoreapp2.2</TargetFramework>
    <RootNamespace>test_env</RootNamespace>
  </PropertyGroup>
  <ItemGroup>
    <PackageReference Include="Jaeger" Version="0.3.1" />
    <PackageReference Include="Microsoft.Extensions.Logging.Console" Version="2.1.1" />
  </ItemGroup>
</Project>

dotnet/test-env/Program.cs

using System;
using Jaeger;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.Logging;

namespace test_env
{
    class Program
    {
        static void Main(string[] args)
        {
            var loggerFactory = new LoggerFactory().AddConsole();
            var configurationBuilder = new ConfigurationBuilder()
                .AddEnvironmentVariables();

            // Get tracer instance with configurations.
            var tracer = (Tracer)Jaeger.Configuration
                .FromIConfiguration(loggerFactory, configurationBuilder.Build())
                .GetTracer();

            using (var scope = tracer.BuildSpan("TestOperation").StartActive())
            {
                scope.Span.Log("It works!");
            }

            tracer.Dispose();
        }
    }
}

I was using the 2.2 runtime based on alpine Linux. I get the following output on the console:

dotnet_1  | info: Jaeger.Configuration[0]
dotnet_1  |       Initialized Tracer(ServiceName=facility.default, Version=CSharp-0.3.1.0, Reporter=CompositeReporter(Reporters=RemoteReporter(Sender=UdpSender(UdpTransport=ThriftUdpClientTransport(Client=172.24.0.2:6831))), LoggingReporter(Logger=Microsoft.Extensions.Logging.Logger`1[Jaeger.Reporters.LoggingReporter])), Sampler=ConstSampler(True), IPv4=-1407713277, Tags=[jaeger.version, CSharp-0.3.1.0], [hostname, 057fb052eadd], [ip, 172.24.0.3], ZipkinSharedRpcSpan=False, ExpandExceptionLogs=FalseUseTraceId128Bit=True)
dotnet_1  | info: Jaeger.Reporters.LoggingReporter[0]
dotnet_1  |       Span reported: bcb4adb3bfd4d93c10471f542b32fefc:10471f542b32fefc:0:1 - TestOperation

Can you send me the log of your code? In the Initialized Tracer line you see that the UseTraceId128Bit=True should be there.

@Falco20019
Copy link
Collaborator

Seems correct to me.

{"user":"system","levelName":"INFO","level":20,"dateTime":"2019-04-18T11:30:08.4005463Z","epochTimestampNS":1555587008400000000,"data":{"span":"2dd4bf8929a43f92:25baa42cc45e9848:d7f1fca37a79489f:1 - Result OkObjectResult","sourceContext":"Jaeger.Reporters.LoggingReporter","trace_Id":"86a9b9e94fbd82982dd4bf8929a43f92","method":"GET","correlationParentId":"58bba6d2-d100-4d78-8ba7-e1244d0f88f4","correlationOriginId":"58bba6d2-d100-4d78-8ba7-e1244d0f88f4","correlationCurrentId":"58bba6d2-d100-4d78-8ba7-e1244d0f88f4","actionName":"Logistics.Services.Facility.API.Controllers.FacilityController.GetFacility (Facility.API)","requestPath":"/facility/api/v1/Facility/1029","message":"Span reported: {span}"}}

Which contains:
"span":"2dd4bf8929a43f92:25baa42cc45e9848:d7f1fca37a79489f:1"
"trace_Id":"86a9b9e94fbd82982dd4bf8929a43f92"

I'm wondering a why the span only shows the lower half of the trace-id, but it definetly created a trace-id with 128 bit.

@Falco20019
Copy link
Collaborator

Falco20019 commented Apr 18, 2019

Ok, so the problem is not, that the client is not generating 128bit TraceIDs but it's not correctly extracting it from an incoming trace. This makes a huge difference, since the flag only affects generation of new IDs.

I just see that you now added JAEGER_PROPAGATION=b3 in the latest envs. The B3 flag currently only supports 64bit incoming. I will update the code to support it, because I can't find any reason to not do it and it seems that the Java client (from which we ported the code) also supports it now.

@Falco20019 Falco20019 changed the title 128 bit trace id working fine in Windows container but not with Kubernetes 128 bit trace id not working with b3 propagation Apr 18, 2019
@Tanejaankush
Copy link
Author

Ok, so the problem is not, that the client is not generating 128bit TraceIDs but it's not correctly extracting it from an incoming trace. This makes a huge difference, since the flag only affects generation of new IDs.

I just see that you now added JAEGER_PROPAGATION=b3 in the latest envs. The B3 flag currently only supports 64bit incoming. I will update the code to support it, because I can't find any reason to not do it and it seems that the Java client (from which we ported the code) also supports it now.

Awaiting the new version of JAEGER client :)

@Falco20019
Copy link
Collaborator

@Tanejaankush: I just released v0.3.2 on NuGET. Please update your project and see if the issue is resolved. If not, please feel free to reopen this issue.

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

Successfully merging a pull request may close this issue.

2 participants