diff --git a/OpenTelemetry.sln b/OpenTelemetry.sln
index 0c5e72f5ea6..b76e95f5904 100644
--- a/OpenTelemetry.sln
+++ b/OpenTelemetry.sln
@@ -69,6 +69,17 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "samples", "samples", "{E359
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Exporters", "samples\Exporters\Exporters.csproj", "{6EC9DEC9-086F-4F29-BF3F-5FC7253829D5}"
EndProject
+Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "LoggingTracer", "LoggingTracer", "{D9C14CDA-5182-4DEA-8606-98FF1A388BD3}"
+ ProjectSection(SolutionItems) = preProject
+ samples\LoggingTracer\readme.md = samples\LoggingTracer\readme.md
+ EndProjectSection
+EndProject
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "LoggingTracer", "samples\LoggingTracer\LoggingTracer\LoggingTracer.csproj", "{1EEF77DF-7552-4265-B64C-FA13BC40C256}"
+EndProject
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "LoggingTracer.Demo.ConsoleApp", "samples\LoggingTracer\LoggingTracer.Demo.ConsoleApp\LoggingTracer.Demo.ConsoleApp.csproj", "{607B3861-4D69-43EF-84CE-19F18CD5339A}"
+EndProject
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "LoggingTracer.Demo.AspNetCore", "samples\LoggingTracer\LoggingTracer.Demo.AspNetCore\LoggingTracer.Demo.AspNetCore.csproj", "{1EB74FCE-55C5-476A-8BB0-C46B77FE1070}"
+EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
@@ -147,6 +158,18 @@ Global
{6EC9DEC9-086F-4F29-BF3F-5FC7253829D5}.Debug|Any CPU.Build.0 = Debug|Any CPU
{6EC9DEC9-086F-4F29-BF3F-5FC7253829D5}.Release|Any CPU.ActiveCfg = Release|Any CPU
{6EC9DEC9-086F-4F29-BF3F-5FC7253829D5}.Release|Any CPU.Build.0 = Release|Any CPU
+ {1EEF77DF-7552-4265-B64C-FA13BC40C256}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {1EEF77DF-7552-4265-B64C-FA13BC40C256}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {1EEF77DF-7552-4265-B64C-FA13BC40C256}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {1EEF77DF-7552-4265-B64C-FA13BC40C256}.Release|Any CPU.Build.0 = Release|Any CPU
+ {607B3861-4D69-43EF-84CE-19F18CD5339A}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {607B3861-4D69-43EF-84CE-19F18CD5339A}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {607B3861-4D69-43EF-84CE-19F18CD5339A}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {607B3861-4D69-43EF-84CE-19F18CD5339A}.Release|Any CPU.Build.0 = Release|Any CPU
+ {1EB74FCE-55C5-476A-8BB0-C46B77FE1070}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {1EB74FCE-55C5-476A-8BB0-C46B77FE1070}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {1EB74FCE-55C5-476A-8BB0-C46B77FE1070}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {1EB74FCE-55C5-476A-8BB0-C46B77FE1070}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
@@ -155,6 +178,10 @@ Global
{7CB2F02E-03FA-4FFF-89A5-C51F107623FD} = {61188153-47FB-4567-AC9B-79B2435853EB}
{F2F81E76-6A0E-466B-B673-EBBF1A9ED075} = {77C7929A-2EED-4AA6-8705-B5C443C8AA0F}
{6EC9DEC9-086F-4F29-BF3F-5FC7253829D5} = {E359BB2B-9AEC-497D-B321-7DF2450C3B8E}
+ {D9C14CDA-5182-4DEA-8606-98FF1A388BD3} = {E359BB2B-9AEC-497D-B321-7DF2450C3B8E}
+ {1EEF77DF-7552-4265-B64C-FA13BC40C256} = {D9C14CDA-5182-4DEA-8606-98FF1A388BD3}
+ {607B3861-4D69-43EF-84CE-19F18CD5339A} = {D9C14CDA-5182-4DEA-8606-98FF1A388BD3}
+ {1EB74FCE-55C5-476A-8BB0-C46B77FE1070} = {D9C14CDA-5182-4DEA-8606-98FF1A388BD3}
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {55639B5C-0770-4A22-AB56-859604650521}
diff --git a/samples/LoggingTracer/LoggingTracer.Demo.AspNetCore/LoggingTracer.Demo.AspNetCore.csproj b/samples/LoggingTracer/LoggingTracer.Demo.AspNetCore/LoggingTracer.Demo.AspNetCore.csproj
new file mode 100644
index 00000000000..0196370d0e9
--- /dev/null
+++ b/samples/LoggingTracer/LoggingTracer.Demo.AspNetCore/LoggingTracer.Demo.AspNetCore.csproj
@@ -0,0 +1,20 @@
+
+
+
+ netcoreapp2.2
+ InProcess
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/samples/LoggingTracer/LoggingTracer.Demo.AspNetCore/LoggingTracerExtensions.cs b/samples/LoggingTracer/LoggingTracer.Demo.AspNetCore/LoggingTracerExtensions.cs
new file mode 100644
index 00000000000..27e129078fd
--- /dev/null
+++ b/samples/LoggingTracer/LoggingTracer.Demo.AspNetCore/LoggingTracerExtensions.cs
@@ -0,0 +1,29 @@
+namespace LoggingTracer.Demo.AspNetCore
+{
+ using Microsoft.AspNetCore.Builder;
+ using Microsoft.Extensions.DependencyInjection;
+ using OpenTelemetry.Collector.AspNetCore;
+ using OpenTelemetry.Collector.Dependencies;
+ using OpenTelemetry.Trace;
+ using OpenTelemetry.Trace.Sampler;
+
+ static class LoggingTracerExtensions {
+ internal static void AddLoggingTracer(this IServiceCollection services)
+ {
+ services.AddSingleton(new global::LoggingTracer.LoggingTracer());
+
+ services.AddSingleton(Samplers.AlwaysSample);
+ services.AddSingleton(new RequestsCollectorOptions());
+ services.AddSingleton();
+
+ services.AddSingleton(new DependenciesCollectorOptions());
+ services.AddSingleton();
+ }
+
+ internal static void UseLoggingTracer(this IApplicationBuilder app)
+ {
+ app.ApplicationServices.GetService(); // get it instantiated
+ app.ApplicationServices.GetService(); // get it instantiated
+ }
+ }
+}
diff --git a/samples/LoggingTracer/LoggingTracer.Demo.AspNetCore/Program.cs b/samples/LoggingTracer/LoggingTracer.Demo.AspNetCore/Program.cs
new file mode 100644
index 00000000000..a190e76536b
--- /dev/null
+++ b/samples/LoggingTracer/LoggingTracer.Demo.AspNetCore/Program.cs
@@ -0,0 +1,17 @@
+namespace LoggingTracer.Demo.AspNetCore
+{
+ using Microsoft.AspNetCore;
+ using Microsoft.AspNetCore.Hosting;
+
+ public class Program
+ {
+ public static void Main(string[] args)
+ {
+ CreateWebHostBuilder(args).Build().Run();
+ }
+
+ public static IWebHostBuilder CreateWebHostBuilder(string[] args) =>
+ WebHost.CreateDefaultBuilder(args)
+ .UseStartup();
+ }
+}
diff --git a/samples/LoggingTracer/LoggingTracer.Demo.AspNetCore/Startup.cs b/samples/LoggingTracer/LoggingTracer.Demo.AspNetCore/Startup.cs
new file mode 100644
index 00000000000..d2e52cb7f7c
--- /dev/null
+++ b/samples/LoggingTracer/LoggingTracer.Demo.AspNetCore/Startup.cs
@@ -0,0 +1,30 @@
+namespace LoggingTracer.Demo.AspNetCore
+{
+ using Microsoft.AspNetCore.Builder;
+ using Microsoft.AspNetCore.Hosting;
+ using Microsoft.AspNetCore.Http;
+ using Microsoft.Extensions.DependencyInjection;
+
+ public class Startup
+ {
+ public void ConfigureServices(IServiceCollection services)
+ {
+ services.AddLoggingTracer();
+ }
+
+ public void Configure(IApplicationBuilder app, IHostingEnvironment env)
+ {
+ if (env.IsDevelopment())
+ {
+ app.UseDeveloperExceptionPage();
+ }
+
+ app.UseLoggingTracer();
+
+ app.Run(async (context) =>
+ {
+ await context.Response.WriteAsync("Hello World!");
+ });
+ }
+ }
+}
diff --git a/samples/LoggingTracer/LoggingTracer.Demo.AspNetCore/appsettings.Development.json b/samples/LoggingTracer/LoggingTracer.Demo.AspNetCore/appsettings.Development.json
new file mode 100644
index 00000000000..e203e9407e7
--- /dev/null
+++ b/samples/LoggingTracer/LoggingTracer.Demo.AspNetCore/appsettings.Development.json
@@ -0,0 +1,9 @@
+{
+ "Logging": {
+ "LogLevel": {
+ "Default": "Debug",
+ "System": "Information",
+ "Microsoft": "Information"
+ }
+ }
+}
diff --git a/samples/LoggingTracer/LoggingTracer.Demo.AspNetCore/appsettings.json b/samples/LoggingTracer/LoggingTracer.Demo.AspNetCore/appsettings.json
new file mode 100644
index 00000000000..d9d9a9bff6f
--- /dev/null
+++ b/samples/LoggingTracer/LoggingTracer.Demo.AspNetCore/appsettings.json
@@ -0,0 +1,10 @@
+{
+ "Logging": {
+ "LogLevel": {
+ "Default": "Information",
+ "Microsoft": "Warning",
+ "Microsoft.Hosting.Lifetime": "Information"
+ }
+ },
+ "AllowedHosts": "*"
+}
diff --git a/samples/LoggingTracer/LoggingTracer.Demo.ConsoleApp/LoggingTracer.Demo.ConsoleApp.csproj b/samples/LoggingTracer/LoggingTracer.Demo.ConsoleApp/LoggingTracer.Demo.ConsoleApp.csproj
new file mode 100644
index 00000000000..0071f95514d
--- /dev/null
+++ b/samples/LoggingTracer/LoggingTracer.Demo.ConsoleApp/LoggingTracer.Demo.ConsoleApp.csproj
@@ -0,0 +1,12 @@
+
+
+
+ Exe
+ netcoreapp2.2
+
+
+
+
+
+
+
diff --git a/samples/LoggingTracer/LoggingTracer.Demo.ConsoleApp/Program.cs b/samples/LoggingTracer/LoggingTracer.Demo.ConsoleApp/Program.cs
new file mode 100644
index 00000000000..c546dfdfa94
--- /dev/null
+++ b/samples/LoggingTracer/LoggingTracer.Demo.ConsoleApp/Program.cs
@@ -0,0 +1,31 @@
+namespace LoggingTracer.ConsoleApp
+{
+ using System.Threading;
+ using System.Threading.Tasks;
+ using OpenTelemetry.Trace;
+
+ public class Program
+ {
+ private static ITracer tracer = new LoggingTracer();
+
+ public static async Task Main(string[] args)
+ {
+ var builder = tracer.SpanBuilder("Main (span1)");
+ using (tracer.WithSpan(builder.StartSpan()))
+ {
+ await Task.Delay(100);
+ await Foo();
+ }
+ }
+
+ private static async Task Foo()
+ {
+ var builder = tracer.SpanBuilder("Foo (span2)");
+ using (tracer.WithSpan(builder.StartSpan()))
+ {
+ tracer.CurrentSpan.SetAttribute("myattribute", "mvalue");
+ await Task.Delay(100);
+ }
+ }
+ }
+}
diff --git a/samples/LoggingTracer/LoggingTracer/Logger.cs b/samples/LoggingTracer/LoggingTracer/Logger.cs
new file mode 100644
index 00000000000..d1fdfe573be
--- /dev/null
+++ b/samples/LoggingTracer/LoggingTracer/Logger.cs
@@ -0,0 +1,30 @@
+namespace LoggingTracer
+{
+ using System;
+ using System.Threading;
+
+ public static class Logger
+ {
+ private static DateTime startTime = DateTime.UtcNow;
+
+ static Logger()
+ {
+ PrintHeader();
+ }
+
+ public static void PrintHeader()
+ {
+ Console.WriteLine("MsSinceStart | ThreadId | API");
+ }
+
+ public static void Log(string s)
+ {
+ Console.WriteLine($"{MillisSinceStart(),12} | {Thread.CurrentThread.ManagedThreadId,8} | {s}");
+ }
+
+ private static int MillisSinceStart()
+ {
+ return (int)DateTime.UtcNow.Subtract(startTime).TotalMilliseconds;
+ }
+ }
+}
diff --git a/samples/LoggingTracer/LoggingTracer/LoggingBinaryFormat.cs b/samples/LoggingTracer/LoggingTracer/LoggingBinaryFormat.cs
new file mode 100644
index 00000000000..ccc5bd70db4
--- /dev/null
+++ b/samples/LoggingTracer/LoggingTracer/LoggingBinaryFormat.cs
@@ -0,0 +1,35 @@
+namespace LoggingTracer
+{
+ using System;
+ using System.Collections.Generic;
+ using OpenTelemetry.Context.Propagation;
+ using OpenTelemetry.Trace;
+
+ public sealed class LoggingBinaryFormat : IBinaryFormat
+ {
+ public ISet Fields => null;
+
+ public SpanContext Extract(T carrier, Func> getter)
+ {
+ Logger.Log($"LoggingBinaryFormat.Extract(...)");
+ return SpanContext.Blank;
+ }
+
+ public SpanContext FromByteArray(byte[] bytes)
+ {
+ Logger.Log($"LoggingBinaryFormat.FromByteArray(...)");
+ return SpanContext.Blank;
+ }
+
+ public void Inject(SpanContext spanContext, T carrier, Action setter)
+ {
+ Logger.Log($"LoggingBinaryFormat.Inject({spanContext}, ...)");
+ }
+
+ public byte[] ToByteArray(SpanContext spanContext)
+ {
+ Logger.Log($"LoggingBinaryFormat.ToByteArray({spanContext})");
+ return new byte[0];
+ }
+ }
+}
diff --git a/samples/LoggingTracer/LoggingTracer/LoggingScope.cs b/samples/LoggingTracer/LoggingTracer/LoggingScope.cs
new file mode 100644
index 00000000000..835e265900d
--- /dev/null
+++ b/samples/LoggingTracer/LoggingTracer/LoggingScope.cs
@@ -0,0 +1,45 @@
+namespace LoggingTracer
+{
+ using System.Threading;
+ using OpenTelemetry.Context;
+ using OpenTelemetry.Trace;
+
+ public static class CurrentSpanUtils
+ {
+ private static AsyncLocal asyncLocalContext = new AsyncLocal();
+
+ public static ISpan CurrentSpan => asyncLocalContext.Value;
+
+ public class LoggingScope : IScope
+ {
+ private readonly ISpan origContext;
+ private readonly ISpan span;
+ private readonly bool endSpan;
+
+ public LoggingScope(ISpan span, bool endSpan = true)
+ {
+ this.span = span;
+ this.endSpan = endSpan;
+ this.origContext = CurrentSpanUtils.asyncLocalContext.Value;
+ CurrentSpanUtils.asyncLocalContext.Value = span;
+ }
+
+ public void Dispose()
+ {
+ Logger.Log($"Scope.Dispose");
+ var current = asyncLocalContext.Value;
+ asyncLocalContext.Value = this.origContext;
+
+ if (current != this.origContext)
+ {
+ Logger.Log($"Scope.Dispose: current != this.origContext");
+ }
+
+ if (this.endSpan)
+ {
+ this.span.End();
+ }
+ }
+ }
+ }
+}
diff --git a/samples/LoggingTracer/LoggingTracer/LoggingSpan.cs b/samples/LoggingTracer/LoggingTracer/LoggingSpan.cs
new file mode 100644
index 00000000000..5a2aae4e384
--- /dev/null
+++ b/samples/LoggingTracer/LoggingTracer/LoggingSpan.cs
@@ -0,0 +1,89 @@
+namespace LoggingTracer
+{
+ using System.Collections.Generic;
+ using OpenTelemetry.Trace;
+
+ public class LoggingSpan : ISpan
+ {
+ public string Name { get; set; }
+
+ public SpanContext Context { get; set; }
+
+ public Status Status { get; set; }
+
+ public SpanKind? Kind { get; set; }
+
+ public bool HasEnded { get; set; }
+
+ public bool IsRecordingEvents => true;
+
+ public LoggingSpan(string name, SpanKind kind)
+ {
+ Logger.Log($"Span.ctor({name}, {kind})");
+ this.Name = name;
+ this.Kind = kind;
+ }
+
+ public void AddEvent(string name)
+ {
+ Logger.Log($"Span.AddEvent({name})");
+ }
+
+ public void AddEvent(string name, IDictionary attributes)
+ {
+ Logger.Log($"Span.AddEvent({name}, attributes: {attributes.Count})");
+ }
+
+ public void AddEvent(IEvent newEvent)
+ {
+ Logger.Log($"Span.AddEvent({newEvent})");
+ }
+
+ public void AddLink(ILink link)
+ {
+ Logger.Log($"Span.AddLink({link})");
+ }
+
+ public void End()
+ {
+ Logger.Log($"Span.End, Name: {this.Name}");
+ }
+
+ public void SetAttribute(string key, object value)
+ {
+ Logger.Log($"Span.SetAttribute({key}, {value})");
+ }
+
+ public void SetAttribute(string key, string value)
+ {
+ Logger.Log($"Span.SetAttribute({key}, {value})");
+ }
+
+ public void SetAttribute(string key, long value)
+ {
+ Logger.Log($"Span.SetAttribute({key}, {value})");
+ }
+
+ public void SetAttribute(string key, double value)
+ {
+ Logger.Log($"Span.SetAttribute({key}, {value})");
+ }
+
+ public void SetAttribute(string key, bool value)
+ {
+ Logger.Log($"Span.SetAttribute({key}, {value})");
+ }
+
+ public void SetAttribute(KeyValuePair keyValuePair)
+ {
+ Logger.Log($"Span.SetAttributes(attributes: {keyValuePair})");
+ this.SetAttribute(keyValuePair.Key, keyValuePair.Value);
+ }
+
+ public void UpdateName(string name)
+ {
+ Logger.Log($"Span.UpdateName({name})");
+ this.Name = name;
+ }
+ }
+}
diff --git a/samples/LoggingTracer/LoggingTracer/LoggingSpanBuilder.cs b/samples/LoggingTracer/LoggingTracer/LoggingSpanBuilder.cs
new file mode 100644
index 00000000000..40aae40f94e
--- /dev/null
+++ b/samples/LoggingTracer/LoggingTracer/LoggingSpanBuilder.cs
@@ -0,0 +1,133 @@
+namespace LoggingTracer
+{
+ using System.Collections.Generic;
+ using System.Diagnostics;
+ using System.Linq;
+ using OpenTelemetry.Context;
+ using OpenTelemetry.Trace;
+
+ public class LoggingSpanBuilder : ISpanBuilder
+ {
+ private string spanName;
+ private SpanKind spanKind;
+ private ISpan parent;
+ private SpanContext remoteParentSpanContext;
+ private ISpan span;
+
+ public LoggingSpanBuilder(string spanName, SpanKind spanKind)
+ {
+ Logger.Log($"SpanBuilder.ctor({spanName})");
+ this.spanName = spanName;
+ this.spanKind = spanKind;
+ this.span = new LoggingSpan(spanName, spanKind);
+ }
+
+ public LoggingSpanBuilder(string spanName, SpanKind spanKind, ISpan parent) : this(spanName, spanKind)
+ {
+ Logger.Log($"SpanBuilder.ctor({spanName}, {spanKind}, {parent})");
+ this.parent = parent;
+ }
+
+ public LoggingSpanBuilder(string spanName, SpanKind spanKind, SpanContext remoteParentSpanContext) : this(spanName, spanKind)
+ {
+ Logger.Log($"SpanBuilder.ctor({spanName}, {spanKind}, {remoteParentSpanContext})");
+ this.remoteParentSpanContext = remoteParentSpanContext;
+ }
+
+ public ISpanBuilder AddLink(SpanContext spanContext)
+ {
+ Logger.Log($"SpanBuilder.AddLink({spanContext})");
+ return this;
+ }
+
+ public ISpanBuilder AddLink(Activity activity)
+ {
+ Logger.Log($"SpanBuilder.AddLink({activity})");
+ return this;
+ }
+
+ public ISpanBuilder AddLink(ILink link)
+ {
+ Logger.Log($"SpanBuilder.AddLink({link})");
+ return this;
+ }
+
+ public ISpanBuilder AddLink(SpanContext context, IDictionary attributes)
+ {
+ Logger.Log($"SpanBuilder.AddLink({context}, {attributes.Count})");
+ return this;
+ }
+
+ public ISpanBuilder SetCreateChild(bool createChild)
+ {
+ Logger.Log($"SpanBuilder.SetCreateChild({createChild})");
+ return this;
+ }
+
+ public ISpanBuilder SetNoParent()
+ {
+ Logger.Log($"SpanBuilder.SetNoParent()");
+ return this;
+ }
+
+ public ISpanBuilder SetParent(ISpan parent)
+ {
+ Logger.Log($"SpanBuilder.SetParent({parent})");
+ return this;
+ }
+
+ public ISpanBuilder SetParent(Activity parent)
+ {
+ Logger.Log($"SpanBuilder.SetParent({parent})");
+ return this;
+ }
+
+ public ISpanBuilder SetParent(SpanContext remoteParent)
+ {
+ Logger.Log($"SpanBuilder.SetParent({remoteParent})");
+ return this;
+ }
+
+ public ISpanBuilder SetParentLinks(IEnumerable parentLinks)
+ {
+ Logger.Log($"SpanBuilder.SetParentLinks(parentLinks: {parentLinks.Count()})");
+ return this;
+ }
+
+ public ISpanBuilder SetRecordEvents(bool recordEvents)
+ {
+ Logger.Log($"SpanBuilder.SetRecordEvents({recordEvents})");
+ return this;
+ }
+
+ public ISpanBuilder SetSampler(ISampler sampler)
+ {
+ Logger.Log($"SpanBuilder.SetSampler({sampler})");
+ return this;
+ }
+
+ public ISpanBuilder SetSpanKind(SpanKind spanKind)
+ {
+ Logger.Log($"SpanBuilder.SetSpanKind({spanKind})");
+ return this;
+ }
+
+ public IScope StartScopedSpan()
+ {
+ Logger.Log($"SpanBuilder.StartScopedSpan()");
+ return new CurrentSpanUtils.LoggingScope(this.span);
+ }
+
+ public IScope StartScopedSpan(out ISpan currentSpan)
+ {
+ Logger.Log($"SpanBuilder.StartScopedSpan()");
+ return new CurrentSpanUtils.LoggingScope(currentSpan = this.span);
+ }
+
+ public ISpan StartSpan()
+ {
+ Logger.Log($"SpanBuilder.StartSpan()");
+ return this.span;
+ }
+ }
+}
diff --git a/samples/LoggingTracer/LoggingTracer/LoggingTextFormat.cs b/samples/LoggingTracer/LoggingTracer/LoggingTextFormat.cs
new file mode 100644
index 00000000000..66a0a77ccdc
--- /dev/null
+++ b/samples/LoggingTracer/LoggingTracer/LoggingTextFormat.cs
@@ -0,0 +1,23 @@
+namespace LoggingTracer
+{
+ using System;
+ using System.Collections.Generic;
+ using OpenTelemetry.Context.Propagation;
+ using OpenTelemetry.Trace;
+
+ public sealed class LoggingTextFormat : ITextFormat
+ {
+ public ISet Fields => null;
+
+ public SpanContext Extract(T carrier, Func> getter)
+ {
+ Logger.Log($"LoggingTextFormat.Extract(...)");
+ return SpanContext.Blank;
+ }
+
+ public void Inject(SpanContext spanContext, T carrier, Action setter)
+ {
+ Logger.Log($"LoggingTextFormat.Inject({spanContext}, ...)");
+ }
+ }
+}
diff --git a/samples/LoggingTracer/LoggingTracer/LoggingTracer.cs b/samples/LoggingTracer/LoggingTracer/LoggingTracer.cs
new file mode 100644
index 00000000000..5ba6ea108d6
--- /dev/null
+++ b/samples/LoggingTracer/LoggingTracer/LoggingTracer.cs
@@ -0,0 +1,44 @@
+namespace LoggingTracer
+{
+ using OpenTelemetry.Context;
+ using OpenTelemetry.Context.Propagation;
+ using OpenTelemetry.Trace;
+
+ public class LoggingTracer : ITracer
+ {
+ public ISpan CurrentSpan => CurrentSpanUtils.CurrentSpan;
+
+ public IBinaryFormat BinaryFormat => new LoggingBinaryFormat();
+
+ public ITextFormat TextFormat => new LoggingTextFormat();
+
+ public void RecordSpanData(SpanData span)
+ {
+ Logger.Log($"Tracer.RecordSpanData({span})");
+ }
+
+ public ISpanBuilder SpanBuilder(string spanName)
+ {
+ Logger.Log($"Tracer.SpanBuilder({spanName})");
+ return new LoggingSpanBuilder(spanName, SpanKind.Internal);
+ }
+
+ public ISpanBuilder SpanBuilderWithParent(string spanName, SpanKind spanKind = SpanKind.Internal, ISpan parent = null)
+ {
+ Logger.Log($"Tracer.SpanBuilderWithExplicitParent({spanName}, {spanKind}, {parent})");
+ return new LoggingSpanBuilder(spanName, spanKind, parent);
+ }
+
+ public ISpanBuilder SpanBuilderWithParentContext(string spanName, SpanKind spanKind = SpanKind.Internal, SpanContext remoteParentSpanContext = null)
+ {
+ Logger.Log($"Tracer.SpanBuilderWithRemoteParent");
+ return new LoggingSpanBuilder(spanName, spanKind, remoteParentSpanContext);
+ }
+
+ public IScope WithSpan(ISpan span)
+ {
+ Logger.Log($"Tracer.WithSpan");
+ return new CurrentSpanUtils.LoggingScope(span);
+ }
+ }
+}
diff --git a/samples/LoggingTracer/LoggingTracer/LoggingTracer.csproj b/samples/LoggingTracer/LoggingTracer/LoggingTracer.csproj
new file mode 100644
index 00000000000..587c124f279
--- /dev/null
+++ b/samples/LoggingTracer/LoggingTracer/LoggingTracer.csproj
@@ -0,0 +1,11 @@
+
+
+
+ netstandard2.0
+
+
+
+
+
+
+
diff --git a/samples/LoggingTracer/readme.md b/samples/LoggingTracer/readme.md
new file mode 100644
index 00000000000..53207416ff1
--- /dev/null
+++ b/samples/LoggingTracer/readme.md
@@ -0,0 +1,6 @@
+# LoggingTracer
+
+This is supposed to be a super-simple API implementation that helps to understand OpenTelemetry API layer. It is not a functional tracer in the sense that it creates meaningful spans. It just logs API calls.
+
+It basically just logs every single API call, with thread-id and a time-offset since start.
+