mirror of
https://github.com/marcel-dempers/docker-development-youtube-series.git
synced 2025-06-04 16:56:56 +00:00
tracing optimizations + netcore examples
This commit is contained in:
parent
d64c813018
commit
dceb5e2946
@ -105,13 +105,13 @@ This is intentional to demonstrate a busy network.
|
||||
|
||||
+------------+ +---------------+ +--------------+
|
||||
| videos-web +---->+ playlists-api +--->+ playlists-db |
|
||||
| | | | | |
|
||||
| | | | | [redis] |
|
||||
+------------+ +-----+---------+ +--------------+
|
||||
|
|
||||
v
|
||||
+-----+------+ +-----------+
|
||||
| videos-api +------>+ videos-db |
|
||||
| | | |
|
||||
| | | [redis] |
|
||||
+------------+ +-----------+
|
||||
|
||||
```
|
||||
|
@ -23,6 +23,8 @@ const serviceName = "playlists-api"
|
||||
var environment = os.Getenv("ENVIRONMENT")
|
||||
var redis_host = os.Getenv("REDIS_HOST")
|
||||
var redis_port = os.Getenv("REDIS_PORT")
|
||||
var jaeger_host_port = os.Getenv("JAEGER_HOST_PORT")
|
||||
|
||||
var ctx = context.Background()
|
||||
var rdb *redis.Client
|
||||
|
||||
@ -40,7 +42,7 @@ func main() {
|
||||
// Log the emitted spans to stdout.
|
||||
Reporter: &config.ReporterConfig{
|
||||
LogSpans: true,
|
||||
LocalAgentHostPort: "jaeger:6831",
|
||||
LocalAgentHostPort: jaeger_host_port,
|
||||
},
|
||||
}
|
||||
|
||||
@ -60,7 +62,7 @@ func main() {
|
||||
opentracing.HTTPHeadersCarrier(r.Header),
|
||||
)
|
||||
|
||||
span := tracer.StartSpan("/ GET", ext.RPCServerOption(spanCtx))
|
||||
span := tracer.StartSpan("playlists-api: GET /", ext.RPCServerOption(spanCtx))
|
||||
defer span.Finish()
|
||||
|
||||
cors(w)
|
||||
@ -80,7 +82,7 @@ func main() {
|
||||
vs := []videos{}
|
||||
for vi := range playlists[pi].Videos {
|
||||
|
||||
span, _ := opentracing.StartSpanFromContext(ctx, "videos-api GET")
|
||||
span, _ := opentracing.StartSpanFromContext(ctx, "playlists-api: videos-api GET /id")
|
||||
|
||||
v := videos{}
|
||||
|
||||
@ -96,8 +98,8 @@ func main() {
|
||||
)
|
||||
|
||||
videoResp, err :=http.DefaultClient.Do(req)
|
||||
|
||||
span.Finish()
|
||||
|
||||
if err != nil {
|
||||
fmt.Println(err)
|
||||
span.SetTag("error", true)
|
||||
@ -149,7 +151,7 @@ func main() {
|
||||
|
||||
func getPlaylists(ctx context.Context)(response string){
|
||||
|
||||
span, _ := opentracing.StartSpanFromContext(ctx, "redis-get")
|
||||
span, _ := opentracing.StartSpanFromContext(ctx, "playlists-api: redis-get")
|
||||
defer span.Finish()
|
||||
playlistData, err := rdb.Get(ctx, "playlists").Result()
|
||||
|
||||
|
65
tracing/applications-go/videos-api-netcore/deploy.yaml
Normal file
65
tracing/applications-go/videos-api-netcore/deploy.yaml
Normal file
@ -0,0 +1,65 @@
|
||||
apiVersion: apps/v1
|
||||
kind: Deployment
|
||||
metadata:
|
||||
name: videos-api
|
||||
labels:
|
||||
app: videos-api
|
||||
spec:
|
||||
selector:
|
||||
matchLabels:
|
||||
app: videos-api
|
||||
replicas: 1
|
||||
strategy:
|
||||
type: RollingUpdate
|
||||
rollingUpdate:
|
||||
maxSurge: 1
|
||||
maxUnavailable: 0
|
||||
template:
|
||||
metadata:
|
||||
labels:
|
||||
app: videos-api
|
||||
spec:
|
||||
containers:
|
||||
- name: videos-api
|
||||
image: aimvector/jaeger-tracing:videos-api-netcore-1.0.0
|
||||
imagePullPolicy : Always
|
||||
ports:
|
||||
- containerPort: 10010
|
||||
env:
|
||||
- name: "ENVIRONMENT"
|
||||
value: "DEBUG"
|
||||
- name: "REDIS_HOST"
|
||||
value: "videos-db"
|
||||
- name: "REDIS_PORT"
|
||||
value: "6379"
|
||||
- name: "JAEGER_AGENT_HOST"
|
||||
value: "jaeger"
|
||||
- name: "JAEGER_AGENT_PORT"
|
||||
value: "6831"
|
||||
- name: "JAEGER_SERVICE_NAME"
|
||||
value: "videos-api"
|
||||
- name: "JAEGER_REPORTER_LOG_SPANS"
|
||||
value: "true"
|
||||
- name: "JAEGER_SAMPLER_TYPE"
|
||||
value: "const"
|
||||
- name: "JAEGER_PROPAGATION"
|
||||
value: "jaeger"
|
||||
---
|
||||
apiVersion: v1
|
||||
kind: Service
|
||||
metadata:
|
||||
name: videos-api
|
||||
labels:
|
||||
app: videos-api
|
||||
spec:
|
||||
type: ClusterIP
|
||||
selector:
|
||||
app: videos-api
|
||||
ports:
|
||||
- protocol: TCP
|
||||
name: http
|
||||
port: 10010
|
||||
targetPort: 10010
|
||||
---
|
||||
|
||||
|
16
tracing/applications-go/videos-api-netcore/dockerfile
Normal file
16
tracing/applications-go/videos-api-netcore/dockerfile
Normal file
@ -0,0 +1,16 @@
|
||||
#docker run -it -v ${PWD}:/work -p 5000:5000 -w /work aimvector/jaeger-tracing:videos-api-netcore-1.0.0 bash
|
||||
FROM mcr.microsoft.com/dotnet/sdk:5.0 as dev
|
||||
|
||||
WORKDIR /work/
|
||||
|
||||
FROM mcr.microsoft.com/dotnet/sdk:5.0 as build
|
||||
|
||||
WORKDIR /work/
|
||||
COPY ./src/videos-api.csproj /work/videos-api.csproj
|
||||
RUN dotnet restore
|
||||
|
||||
COPY ./src/ /work/
|
||||
RUN mkdir /out/
|
||||
RUN dotnet publish --no-restore --output /out/ --configuration Release
|
||||
|
||||
ENTRYPOINT ["dotnet", "run"]
|
@ -0,0 +1,75 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Threading.Tasks;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using Microsoft.Extensions.Logging;
|
||||
using StackExchange.Redis;
|
||||
using System.Text.Json;
|
||||
using System.Text.Json.Serialization;
|
||||
using OpenTracing;
|
||||
using OpenTracing.Propagation;
|
||||
|
||||
namespace videos_api.Controllers
|
||||
{
|
||||
[ApiController]
|
||||
[Route("")]
|
||||
public class VideosController : ControllerBase
|
||||
{
|
||||
private readonly ITracer _tracer;
|
||||
private readonly string _redisHost;
|
||||
private readonly string _redisPort;
|
||||
private readonly ConnectionMultiplexer _redis;
|
||||
private readonly ILogger<VideosController> _logger;
|
||||
private readonly JsonSerializerOptions _serializationOptions;
|
||||
|
||||
public VideosController(ILogger<VideosController> logger, ITracer tracer)
|
||||
{
|
||||
_redisHost = Environment.GetEnvironmentVariable("REDIS_HOST");
|
||||
_redisPort = Environment.GetEnvironmentVariable("REDIS_PORT");
|
||||
_redis = ConnectionMultiplexer.Connect(_redisHost + ":" + _redisPort);
|
||||
_logger = logger;
|
||||
_tracer = tracer ?? throw new ArgumentNullException(nameof(tracer));
|
||||
|
||||
_serializationOptions = new JsonSerializerOptions
|
||||
{
|
||||
PropertyNameCaseInsensitive = true
|
||||
};
|
||||
}
|
||||
|
||||
[HttpGet]
|
||||
[Route("/{id}")]
|
||||
public Videos Get(string id)
|
||||
{
|
||||
ISpanContext traceContext = _tracer.Extract(BuiltinFormats.HttpHeaders, new TextMapExtractAdapter(GetHeaders()));
|
||||
|
||||
string videoContent;
|
||||
|
||||
using (var scope = _tracer.BuildSpan("videos-api-net: redis-get")
|
||||
.AsChildOf(traceContext)
|
||||
.StartActive(true))
|
||||
{
|
||||
|
||||
|
||||
|
||||
IDatabase db = _redis.GetDatabase();
|
||||
videoContent = db.StringGet(id);
|
||||
}
|
||||
|
||||
var video = JsonSerializer.Deserialize<Videos>(videoContent,_serializationOptions);
|
||||
return video;
|
||||
|
||||
}
|
||||
|
||||
public Dictionary<string, string> GetHeaders()
|
||||
{
|
||||
var headers = new Dictionary<string, string>();
|
||||
foreach (var header in Request.Headers)
|
||||
{
|
||||
headers.Add(header.Key, header.Value);
|
||||
}
|
||||
|
||||
return headers;
|
||||
}
|
||||
}
|
||||
}
|
32
tracing/applications-go/videos-api-netcore/src/Program.cs
Normal file
32
tracing/applications-go/videos-api-netcore/src/Program.cs
Normal file
@ -0,0 +1,32 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Threading.Tasks;
|
||||
using Microsoft.AspNetCore.Hosting;
|
||||
using Microsoft.Extensions.Configuration;
|
||||
using Microsoft.Extensions.Hosting;
|
||||
using Microsoft.Extensions.Logging;
|
||||
|
||||
namespace videos_api
|
||||
{
|
||||
public class Program
|
||||
{
|
||||
public static void Main(string[] args)
|
||||
{
|
||||
CreateHostBuilder(args).Build().Run();
|
||||
}
|
||||
|
||||
public static IHostBuilder CreateHostBuilder(string[] args) =>
|
||||
Host.CreateDefaultBuilder(args)
|
||||
.ConfigureLogging(logging =>
|
||||
{
|
||||
logging.ClearProviders();
|
||||
logging.AddConsole();
|
||||
})
|
||||
.ConfigureWebHostDefaults(webBuilder =>
|
||||
{
|
||||
webBuilder.UseUrls("http://*:10010");
|
||||
webBuilder.UseStartup<Startup>();
|
||||
});
|
||||
}
|
||||
}
|
@ -0,0 +1,31 @@
|
||||
{
|
||||
"$schema": "http://json.schemastore.org/launchsettings.json",
|
||||
"iisSettings": {
|
||||
"windowsAuthentication": false,
|
||||
"anonymousAuthentication": true,
|
||||
"iisExpress": {
|
||||
"applicationUrl": "http://localhost:27460",
|
||||
"sslPort": 44312
|
||||
}
|
||||
},
|
||||
"profiles": {
|
||||
"IIS Express": {
|
||||
"commandName": "IISExpress",
|
||||
"launchBrowser": true,
|
||||
"launchUrl": "swagger",
|
||||
"environmentVariables": {
|
||||
"ASPNETCORE_ENVIRONMENT": "Development"
|
||||
}
|
||||
},
|
||||
"videos_api": {
|
||||
"commandName": "Project",
|
||||
"dotnetRunMessages": "true",
|
||||
"launchBrowser": true,
|
||||
"launchUrl": "swagger",
|
||||
"applicationUrl": "https://localhost:5001;http://localhost:5000",
|
||||
"environmentVariables": {
|
||||
"ASPNETCORE_ENVIRONMENT": "Development"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
103
tracing/applications-go/videos-api-netcore/src/Startup.cs
Normal file
103
tracing/applications-go/videos-api-netcore/src/Startup.cs
Normal file
@ -0,0 +1,103 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Threading.Tasks;
|
||||
using Microsoft.AspNetCore.Builder;
|
||||
using Microsoft.AspNetCore.Hosting;
|
||||
using Microsoft.AspNetCore.HttpsPolicy;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using Microsoft.Extensions.Configuration;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
using Microsoft.Extensions.Hosting;
|
||||
using Microsoft.Extensions.Logging;
|
||||
using Microsoft.OpenApi.Models;
|
||||
using Jaeger;
|
||||
using Jaeger.Reporters;
|
||||
using Jaeger.Samplers;
|
||||
using Jaeger.Senders;
|
||||
using Jaeger.Senders.Thrift;
|
||||
using OpenTracing;
|
||||
using OpenTracing.Contrib.NetCore.Configuration;
|
||||
using OpenTracing.Util;
|
||||
|
||||
|
||||
namespace videos_api
|
||||
{
|
||||
public class Startup
|
||||
{
|
||||
public Startup(IConfiguration configuration)
|
||||
{
|
||||
Configuration = configuration;
|
||||
}
|
||||
|
||||
public IConfiguration Configuration { get; }
|
||||
|
||||
// This method gets called by the runtime. Use this method to add services to the container.
|
||||
public void ConfigureServices(IServiceCollection services)
|
||||
{
|
||||
services.AddLogging(loggingBuilder =>
|
||||
{
|
||||
loggingBuilder.AddConfiguration(Configuration.GetSection("Logging"));
|
||||
loggingBuilder.AddConsole();
|
||||
loggingBuilder.AddDebug();
|
||||
});
|
||||
|
||||
services.AddSingleton<ITracer>(serviceProvider =>
|
||||
{
|
||||
ILoggerFactory loggerFactory = serviceProvider.GetRequiredService<ILoggerFactory>();
|
||||
Jaeger.Configuration.SenderConfiguration.DefaultSenderResolver = new SenderResolver(loggerFactory)
|
||||
.RegisterSenderFactory<ThriftSenderFactory>();
|
||||
|
||||
var config = Jaeger.Configuration.FromEnv(loggerFactory);
|
||||
ITracer tracer = config.GetTracer();
|
||||
GlobalTracer.Register(tracer);
|
||||
return tracer;
|
||||
|
||||
// var loggerFactory = serviceProvider.GetRequiredService<ILoggerFactory>();
|
||||
// var sampler = new ConstSampler(sample: true);
|
||||
|
||||
// var tracer = new Tracer.Builder("videos-api")
|
||||
// .WithReporter(
|
||||
// new RemoteReporter.Builder()
|
||||
// .WithLoggerFactory(loggerFactory)
|
||||
// .WithSender(
|
||||
// new UdpSender("jaeger", 6831, 0))
|
||||
// .Build())
|
||||
// .WithLoggerFactory(loggerFactory)
|
||||
// .WithSampler(sampler)
|
||||
// .Build();
|
||||
|
||||
// GlobalTracer.Register(tracer);
|
||||
// return tracer;
|
||||
|
||||
});
|
||||
|
||||
services.AddOpenTracing();
|
||||
|
||||
services.AddControllers();
|
||||
services.AddSwaggerGen(c =>
|
||||
{
|
||||
c.SwaggerDoc("v1", new OpenApiInfo { Title = "videos_api", Version = "v1" });
|
||||
});
|
||||
}
|
||||
|
||||
// This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
|
||||
public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
|
||||
{
|
||||
if (env.IsDevelopment())
|
||||
{
|
||||
app.UseDeveloperExceptionPage();
|
||||
app.UseSwagger();
|
||||
app.UseSwaggerUI(c => c.SwaggerEndpoint("/swagger/v1/swagger.json", "videos_api v1"));
|
||||
}
|
||||
|
||||
app.UseHttpsRedirection();
|
||||
app.UseRouting();
|
||||
app.UseAuthorization();
|
||||
app.UseEndpoints(endpoints =>
|
||||
{
|
||||
endpoints.MapControllers();
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
13
tracing/applications-go/videos-api-netcore/src/Videos.cs
Normal file
13
tracing/applications-go/videos-api-netcore/src/Videos.cs
Normal file
@ -0,0 +1,13 @@
|
||||
using System;
|
||||
|
||||
namespace videos_api
|
||||
{
|
||||
public class Videos
|
||||
{
|
||||
public string Id { get; set; }
|
||||
public string Title { get; set; }
|
||||
public string Description { get; set; }
|
||||
public string Imageurl { get; set; }
|
||||
public string Url { get; set; }
|
||||
}
|
||||
}
|
@ -0,0 +1,9 @@
|
||||
{
|
||||
"Logging": {
|
||||
"LogLevel": {
|
||||
"Default": "Information",
|
||||
"Microsoft": "Warning",
|
||||
"Microsoft.Hosting.Lifetime": "Information"
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,10 @@
|
||||
{
|
||||
"Logging": {
|
||||
"LogLevel": {
|
||||
"Default": "Information",
|
||||
"Microsoft": "Warning",
|
||||
"Microsoft.Hosting.Lifetime": "Information"
|
||||
}
|
||||
},
|
||||
"AllowedHosts": "*"
|
||||
}
|
@ -0,0 +1,15 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk.Web">
|
||||
|
||||
<PropertyGroup>
|
||||
<TargetFramework>net5.0</TargetFramework>
|
||||
<RootNamespace>videos_api</RootNamespace>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Jaeger" Version="1.0.0" />
|
||||
<PackageReference Include="OpenTracing.Contrib.NetCore" Version="0.7.1" />
|
||||
<PackageReference Include="StackExchange.Redis" Version="2.2.4" />
|
||||
<PackageReference Include="Swashbuckle.AspNetCore" Version="5.6.3" />
|
||||
</ItemGroup>
|
||||
|
||||
</Project>
|
@ -25,6 +25,7 @@ const serviceName = "videos-api"
|
||||
var environment = os.Getenv("ENVIRONMENT")
|
||||
var redis_host = os.Getenv("REDIS_HOST")
|
||||
var redis_port = os.Getenv("REDIS_PORT")
|
||||
var jaeger_host_port = os.Getenv("JAEGER_HOST_PORT")
|
||||
var flaky = os.Getenv("FLAKY")
|
||||
var delay = os.Getenv("DELAY")
|
||||
|
||||
@ -45,7 +46,7 @@ func main() {
|
||||
// Log the emitted spans to stdout.
|
||||
Reporter: &config.ReporterConfig{
|
||||
LogSpans: true,
|
||||
LocalAgentHostPort: "jaeger:6831",
|
||||
LocalAgentHostPort: jaeger_host_port,
|
||||
},
|
||||
}
|
||||
|
||||
@ -65,7 +66,7 @@ func main() {
|
||||
opentracing.HTTPHeadersCarrier(r.Header),
|
||||
)
|
||||
|
||||
span := tracer.StartSpan("/id GET", ext.RPCServerOption(spanCtx))
|
||||
span := tracer.StartSpan("videos-api: GET /id", ext.RPCServerOption(spanCtx))
|
||||
defer span.Finish()
|
||||
|
||||
if flaky == "true" {
|
||||
@ -98,7 +99,7 @@ func main() {
|
||||
|
||||
func video(writer http.ResponseWriter, request *http.Request, p httprouter.Params, ctx context.Context)(response string){
|
||||
|
||||
span, _ := opentracing.StartSpanFromContext(ctx, "redis-get")
|
||||
span, _ := opentracing.StartSpanFromContext(ctx, "videos-api: redis-get")
|
||||
defer span.Finish()
|
||||
id := p.ByName("id")
|
||||
|
||||
|
@ -18,6 +18,7 @@ services:
|
||||
- "ENVIRONMENT=DEBUG"
|
||||
- "REDIS_HOST=playlists-db"
|
||||
- "REDIS_PORT=6379"
|
||||
- "JAEGER_HOST_PORT=jaeger:6831"
|
||||
ports:
|
||||
- 81:10010
|
||||
networks:
|
||||
@ -39,12 +40,32 @@ services:
|
||||
- "ENVIRONMENT=DEBUG"
|
||||
- "REDIS_HOST=videos-db"
|
||||
- "REDIS_PORT=6379"
|
||||
- "JAEGER_HOST_PORT=jaeger:6831"
|
||||
#- "DELAY=true"
|
||||
#- "FLAKY=true"
|
||||
ports:
|
||||
- 82:10010
|
||||
networks:
|
||||
- tracing
|
||||
# videos-api-netcore:
|
||||
# container_name: videos-api
|
||||
# image: aimvector/jaeger-tracing:videos-api-netcore-1.0.0
|
||||
# build:
|
||||
# context: ./applications-go/videos-api-netcore
|
||||
# environment:
|
||||
# - "ENVIRONMENT=DEBUG"
|
||||
# - "REDIS_HOST=videos-db"
|
||||
# - "REDIS_PORT=6379"
|
||||
# - "JAEGER_AGENT_HOST=jaeger"
|
||||
# - "JAEGER_AGENT_PORT=6831"
|
||||
# - "JAEGER_SERVICE_NAME=videos-api"
|
||||
# - "JAEGER_REPORTER_LOG_SPANS=true"
|
||||
# - "JAEGER_SAMPLER_TYPE=const"
|
||||
# - "JAEGER_PROPAGATION=jaeger"
|
||||
# ports:
|
||||
# - 82:5000
|
||||
# networks:
|
||||
# - tracing
|
||||
videos-db:
|
||||
container_name: videos-db
|
||||
image: redis:6.0-alpine
|
||||
|
Loading…
x
Reference in New Issue
Block a user