Skip to content

Commit f164a6f

Browse files
authored
feature: add fluentbuilder for configuration and custom exporters (#19)
1 parent 183773e commit f164a6f

8 files changed

Lines changed: 617 additions & 19 deletions

File tree

src/CodingWithCalvin.Otel4Vsix/CodingWithCalvin.Otel4Vsix.csproj

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@
99
<GenerateAssemblyInfo>false</GenerateAssemblyInfo>
1010

1111
<PackageId>CodingWithCalvin.Otel4Vsix</PackageId>
12-
<Version>0.0.15-local</Version>
12+
<Version>0.0.1</Version>
1313
<Authors>Calvin A. Allen</Authors>
1414
<Company>Coding With Calvin</Company>
1515
<Product>CodingWithCalvin.Otel4Vsix</Product>
@@ -40,10 +40,10 @@
4040
<PackageReference Include="OpenTelemetry" Version="1.10.0" />
4141
<PackageReference Include="OpenTelemetry.Api" Version="1.10.0" />
4242
<PackageReference Include="OpenTelemetry.Exporter.OpenTelemetryProtocol" Version="1.10.0" />
43-
<PackageReference Include="OpenTelemetry.Exporter.Console" Version="1.10.0" />
4443
<PackageReference Include="OpenTelemetry.Extensions.Hosting" Version="1.10.0" />
4544
<PackageReference Include="Google.Protobuf" Version="3.22.5" />
4645
<PackageReference Include="Grpc.Core.Api" Version="2.52.0" />
46+
<PackageReference Include="Microsoft.VisualStudio.Shell.15.0" Version="17.0.31903.59" />
4747
<PackageReference Include="Microsoft.SourceLink.GitHub" Version="8.0.0" PrivateAssets="all" />
4848
</ItemGroup>
4949
</Project>
Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
using System.Diagnostics;
2+
using System.Text;
3+
using OpenTelemetry;
4+
5+
namespace CodingWithCalvin.Otel4Vsix.Exporters;
6+
7+
/// <summary>
8+
/// An activity exporter that writes trace data to <see cref="System.Diagnostics.Debug"/>.
9+
/// Output appears in the Visual Studio Output window when debugging.
10+
/// </summary>
11+
internal sealed class DebugActivityExporter : BaseExporter<Activity>
12+
{
13+
private readonly string _prefix;
14+
15+
public DebugActivityExporter(string serviceName, string serviceVersion)
16+
{
17+
_prefix = $"[{serviceName} v{serviceVersion}]";
18+
}
19+
20+
/// <inheritdoc />
21+
public override ExportResult Export(in Batch<Activity> batch)
22+
{
23+
foreach (var activity in batch)
24+
{
25+
var sb = new StringBuilder();
26+
sb.AppendLine($"{_prefix} [TRACE] {activity.DisplayName}");
27+
sb.AppendLine($" TraceId: {activity.TraceId}");
28+
sb.AppendLine($" SpanId: {activity.SpanId}");
29+
sb.AppendLine($" Duration: {activity.Duration.TotalMilliseconds:F2}ms");
30+
sb.AppendLine($" Status: {activity.Status}");
31+
32+
if (activity.Tags != null)
33+
{
34+
foreach (var tag in activity.Tags)
35+
{
36+
sb.AppendLine($" {tag.Key}: {tag.Value}");
37+
}
38+
}
39+
40+
if (activity.Events != null)
41+
{
42+
foreach (var evt in activity.Events)
43+
{
44+
sb.AppendLine($" Event: {evt.Name} at {evt.Timestamp}");
45+
}
46+
}
47+
48+
System.Diagnostics.Trace.WriteLine(sb.ToString());
49+
}
50+
51+
return ExportResult.Success;
52+
}
53+
}
Lines changed: 75 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,75 @@
1+
using System;
2+
using Microsoft.Extensions.Logging;
3+
4+
namespace CodingWithCalvin.Otel4Vsix.Exporters;
5+
6+
/// <summary>
7+
/// A logger provider that writes to <see cref="System.Diagnostics.Debug"/>.
8+
/// </summary>
9+
internal sealed class DebugLoggerProvider : ILoggerProvider
10+
{
11+
private readonly string _serviceName;
12+
private readonly string _serviceVersion;
13+
14+
public DebugLoggerProvider(string serviceName, string serviceVersion)
15+
{
16+
_serviceName = serviceName;
17+
_serviceVersion = serviceVersion;
18+
}
19+
20+
public ILogger CreateLogger(string categoryName) => new DebugLogger(_serviceName, _serviceVersion, categoryName);
21+
22+
public void Dispose() { }
23+
}
24+
25+
/// <summary>
26+
/// A logger that writes to <see cref="System.Diagnostics.Debug"/>.
27+
/// </summary>
28+
internal sealed class DebugLogger : ILogger
29+
{
30+
private readonly string _prefix;
31+
private readonly string _categoryName;
32+
33+
public DebugLogger(string serviceName, string serviceVersion, string categoryName)
34+
{
35+
_prefix = $"[{serviceName} v{serviceVersion}]";
36+
_categoryName = categoryName;
37+
}
38+
39+
public IDisposable BeginScope<TState>(TState state) => NullScope.Instance;
40+
41+
public bool IsEnabled(LogLevel logLevel) => logLevel != LogLevel.None;
42+
43+
public void Log<TState>(LogLevel logLevel, EventId eventId, TState state, Exception exception, Func<TState, Exception, string> formatter)
44+
{
45+
if (!IsEnabled(logLevel))
46+
{
47+
return;
48+
}
49+
50+
var message = formatter(state, exception);
51+
var levelStr = logLevel switch
52+
{
53+
LogLevel.Trace => "TRACE",
54+
LogLevel.Debug => "DEBUG",
55+
LogLevel.Information => "INFO",
56+
LogLevel.Warning => "WARN",
57+
LogLevel.Error => "ERROR",
58+
LogLevel.Critical => "CRIT",
59+
_ => "NONE"
60+
};
61+
62+
System.Diagnostics.Trace.WriteLine($"{_prefix} [{levelStr}] {_categoryName}: {message}");
63+
64+
if (exception != null)
65+
{
66+
System.Diagnostics.Trace.WriteLine($" Exception: {exception}");
67+
}
68+
}
69+
70+
private sealed class NullScope : IDisposable
71+
{
72+
public static readonly NullScope Instance = new NullScope();
73+
public void Dispose() { }
74+
}
75+
}
Lines changed: 77 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,77 @@
1+
using System.Text;
2+
using OpenTelemetry;
3+
using OpenTelemetry.Metrics;
4+
5+
namespace CodingWithCalvin.Otel4Vsix.Exporters;
6+
7+
/// <summary>
8+
/// A metric exporter that writes metric data to <see cref="System.Diagnostics.Debug"/>.
9+
/// Output appears in the Visual Studio Output window when debugging.
10+
/// </summary>
11+
internal sealed class DebugMetricExporter : BaseExporter<Metric>
12+
{
13+
private readonly string _prefix;
14+
15+
public DebugMetricExporter(string serviceName, string serviceVersion)
16+
{
17+
_prefix = $"[{serviceName} v{serviceVersion}]";
18+
}
19+
20+
/// <inheritdoc />
21+
public override ExportResult Export(in Batch<Metric> batch)
22+
{
23+
foreach (var metric in batch)
24+
{
25+
var sb = new StringBuilder();
26+
sb.AppendLine($"{_prefix} [METRIC] {metric.Name}");
27+
28+
if (!string.IsNullOrEmpty(metric.Unit))
29+
{
30+
sb.AppendLine($" Unit: {metric.Unit}");
31+
}
32+
33+
if (!string.IsNullOrEmpty(metric.Description))
34+
{
35+
sb.AppendLine($" Description: {metric.Description}");
36+
}
37+
38+
foreach (var metricPoint in metric.GetMetricPoints())
39+
{
40+
sb.Append(" ");
41+
42+
switch (metric.MetricType)
43+
{
44+
case MetricType.LongSum:
45+
case MetricType.LongSumNonMonotonic:
46+
sb.AppendLine($"Value: {metricPoint.GetSumLong()}");
47+
break;
48+
case MetricType.DoubleSum:
49+
case MetricType.DoubleSumNonMonotonic:
50+
sb.AppendLine($"Value: {metricPoint.GetSumDouble()}");
51+
break;
52+
case MetricType.LongGauge:
53+
sb.AppendLine($"Value: {metricPoint.GetGaugeLastValueLong()}");
54+
break;
55+
case MetricType.DoubleGauge:
56+
sb.AppendLine($"Value: {metricPoint.GetGaugeLastValueDouble()}");
57+
break;
58+
case MetricType.Histogram:
59+
sb.AppendLine($"Count: {metricPoint.GetHistogramCount()}, Sum: {metricPoint.GetHistogramSum()}");
60+
break;
61+
default:
62+
sb.AppendLine($"Type: {metric.MetricType}");
63+
break;
64+
}
65+
66+
foreach (var tag in metricPoint.Tags)
67+
{
68+
sb.AppendLine($" {tag.Key}: {tag.Value}");
69+
}
70+
}
71+
72+
System.Diagnostics.Trace.WriteLine(sb.ToString());
73+
}
74+
75+
return ExportResult.Success;
76+
}
77+
}

0 commit comments

Comments
 (0)