ではエントリポイントの Global.asax.cs に設定していく。
必要に応じた設定をすることになるが、今回は最小限とする。
カスタム計装したいものがある場合は ActivietySource などを DI に登録すると便利だろう。
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Security.Policy;
using System.Web;
using System.Web.Http;
using System.Web.Mvc;
using System.Web.Optimization;
using System.Web.Routing;
using Microsoft.Extensions.Options;
namespace OtelServer
{
publicclassWebApiApplication : System.Web.HttpApplication
{
protectedvoid Application_Start()
{
AreaRegistration.RegisterAllAreas();
GlobalConfiguration.Configure(WebApiConfig.Register);
FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters);
RouteConfig.RegisterRoutes(RouteTable.Routes);
BundleConfig.RegisterBundles(BundleTable.Bundles);
}
}
}
↓↓↓↓↓
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Security.Policy;
using System.Web;
using System.Web.Http;
using System.Web.Mvc;
using System.Web.Optimization;
using System.Web.Routing;
using Microsoft.Extensions.Options;
using OpenTelemetry;
using OpenTelemetry.Metrics;
using OpenTelemetry.Resources;
using OpenTelemetry.Trace;
namespace OtelServer
{
publicclassWebApiApplication : System.Web.HttpApplication
{
privatestaticstring otlpEndpoint ="http://localhost:4318";
private TracerProvider tracerProvider;
private MeterProvider meterProvider;
protectedvoid Application_Start()
{
var resource = ResourceBuilder.CreateDefault()
.AddService("OTelServer", "otel-dotnet-fx");
tracerProvider = Sdk.CreateTracerProviderBuilder()
.SetResourceBuilder(resource)
.AddAspNetInstrumentation()
.AddSqlClientInstrumentation(options => {
options.SetDbStatementForText =true; // SQL クエリも投稿する設定
})
#if DEBUG
.AddConsoleExporter()
#endif
.AddOtlpExporter(options =>
{
options.Endpoint =new Uri($"{otlpEndpoint}/v1/traces");
})
.Build();
meterProvider = Sdk.CreateMeterProviderBuilder()
.SetResourceBuilder(resource)
.AddRuntimeInstrumentation()
.AddAspNetInstrumentation()
.AddSqlClientInstrumentation()
#if DEBUG
.AddConsoleExporter()
#endif
.AddOtlpExporter(options =>
{
options.Endpoint =new Uri($"{otlpEndpoint}/v1/metrics");
})
.Build();
AreaRegistration.RegisterAllAreas();
GlobalConfiguration.Configure(WebApiConfig.Register);
FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters);
RouteConfig.RegisterRoutes(RouteTable.Routes);
BundleConfig.RegisterBundles(BundleTable.Bundles);
}
protectedvoid Application_End()
{
tracerProvider?.Dispose();
meterProvider?.Dispose();
}
}
}
また SQL Server データベースへのアクセスを見たいので、テンプレートについてきた ValuesController.cs で適当なクエリを投げることにする。
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Net.Http;
using System.Web.Http;
namespace OtelServer.Controllers
{
publicclassValuesController : ApiController
{
// GET api/valuespublic IEnumerable<string> Get()
{
returnnew[] { "value1", "value2" };
}
}
}
↓↓↓↓↓
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Net.Http;
using System.Web.Http;
using Microsoft.Data.SqlClient;
namespace OtelServer.Controllers
{
publicclassValuesController : ApiController
{
// 本番では DI 推奨privatestaticreadonlystring connectionString =@"Server=(localdb)\MSSQLLocalDB";
// GET api/valuespublic IEnumerable<string> Get()
{
var values =new List<string> { "value1", "value2" };
// SQL Server に適当なクエリを送る using (var connection =new SqlConnection(connectionString))
{
connection.Open();
using (var command =new SqlCommand("SELECT GETDATE() AS CurrentTime;", connection))
using (var reader = command.ExecuteReader())
{
while (reader.Read())
{
values.Add(reader["CurrentTime"].ToString());
}
}
}
return values;
}
}
}
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using System.Windows.Forms;
namespace OTelClient
{
internalstaticclassProgram
{
/// <summary>/// アプリケーションのメイン エントリ ポイントです。/// </summary>
[STAThread]
staticvoid Main()
{
Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(false);
Application.Run(new Form1());
}
}
}
↓↓↓↓↓
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using System.Windows.Forms;
using OpenTelemetry;
using OpenTelemetry.Metrics;
using OpenTelemetry.Resources;
using OpenTelemetry.Trace;
namespace OTelClient
{
internalstaticclassProgram
{
privatestaticstring otlpEndpoint ="http://localhost:4318";
/// <summary>/// アプリケーションのメイン エントリ ポイントです。/// </summary>
[STAThread]
staticvoid Main()
{
var resource = ResourceBuilder.CreateDefault()
.AddService("OTelClient", "otel-dotnet-fx");
using (
var tracerProvider = Sdk.CreateTracerProviderBuilder()
.SetResourceBuilder(resource)
.AddHttpClientInstrumentation()
#if DEBUG
.AddConsoleExporter()
#endif
.AddOtlpExporter(options =>
{
options.Endpoint =new Uri($"{otlpEndpoint}/v1/traces");
})
.Build()
)
using (
var meterProvider = Sdk.CreateMeterProviderBuilder()
.SetResourceBuilder(resource)
.AddHttpClientInstrumentation()
#if DEBUG
.AddConsoleExporter()
#endif
.AddOtlpExporter(options =>
{
options.Endpoint =new Uri($"{otlpEndpoint}/v1/metrics");
})
.Build()
)
{
Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(false);
Application.Run(new Form1());
}
}
}
}
ASP.NET サーバーアプリケーションへのアクセスを見たいので、ボタンをクリックしたら HTTP リクエストすることにする。
フォームに適当にボタンを配置したらダブルクリックして生成したイベントハンドラを書き換える。
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Net.Http;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
namespace OTelClient
{
publicpartialclassForm1 : Form
{
public Form1()
{
InitializeComponent();
}
}
}
↓↓↓↓↓
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Net.Http;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
namespace OTelClient
{
publicpartialclassForm1 : Form
{
// 本番では DI 推奨privatereadonly HttpClient httpClient =new HttpClient();
public Form1()
{
InitializeComponent();
}
privateasyncvoid button1_Click(object sender, EventArgs e)
{
// サーバーアプリケーションに適当な HTTP リクエストを送るvar res =await httpClient.GetAsync("http://localhost:61266/api/values");
var content =await res.Content.ReadAsStringAsync();
MessageBox.Show(content);
}
}
}