Skip to content

Commit

Permalink
tracing optimizations + netcore examples
Browse files Browse the repository at this point in the history
  • Loading branch information
marcel-dempers committed May 27, 2021
1 parent d64c813 commit dceb5e2
Show file tree
Hide file tree
Showing 14 changed files with 403 additions and 10 deletions.
4 changes: 2 additions & 2 deletions tracing/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -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] |
+------------+ +-----------+
```
Expand Down
12 changes: 7 additions & 5 deletions tracing/applications-go/playlists-api/app.go
Original file line number Diff line number Diff line change
Expand Up @@ -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

Expand All @@ -40,7 +42,7 @@ func main() {
// Log the emitted spans to stdout.
Reporter: &config.ReporterConfig{
LogSpans: true,
LocalAgentHostPort: "jaeger:6831",
LocalAgentHostPort: jaeger_host_port,
},
}

Expand All @@ -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)
Expand All @@ -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{}

Expand All @@ -96,8 +98,8 @@ func main() {
)

videoResp, err :=http.DefaultClient.Do(req)

span.Finish()

if err != nil {
fmt.Println(err)
span.SetTag("error", true)
Expand Down Expand Up @@ -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()

Expand Down
65 changes: 65 additions & 0 deletions tracing/applications-go/videos-api-netcore/deploy.yaml
Original file line number Diff line number Diff line change
@@ -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 changes: 16 additions & 0 deletions tracing/applications-go/videos-api-netcore/dockerfile
Original file line number Diff line number Diff line change
@@ -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"]
Original file line number Diff line number Diff line change
@@ -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 changes: 32 additions & 0 deletions tracing/applications-go/videos-api-netcore/src/Program.cs
Original file line number Diff line number Diff line change
@@ -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>();
});
}
}
Original file line number Diff line number Diff line change
@@ -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 changes: 103 additions & 0 deletions tracing/applications-go/videos-api-netcore/src/Startup.cs
Original file line number Diff line number Diff line change
@@ -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();
});
}
}
}
Loading

0 comments on commit dceb5e2

Please sign in to comment.