WeatherServiceRequests { get; set; } = null!;
10 | }
11 |
12 | public class WeatherServiceRequest
13 | {
14 | public Guid Id { get; set; }
15 | public string Note { get; set; } = string.Empty;
16 | }
17 |
--------------------------------------------------------------------------------
/src/c-complex/Demo.Service/WeatherForecast.cs:
--------------------------------------------------------------------------------
1 | namespace Demo.Service;
2 |
3 | public class WeatherForecast
4 | {
5 | public DateTime Date { get; set; }
6 |
7 | public int TemperatureC { get; set; }
8 |
9 | public int TemperatureF => 32 + (int)(TemperatureC / 0.5556);
10 |
11 | public string? Summary { get; set; }
12 | }
13 |
--------------------------------------------------------------------------------
/src/c-complex/Demo.Service/appsettings.Development.json:
--------------------------------------------------------------------------------
1 | {
2 | "ConnectionStrings": {
3 | "WeatherContext": "Host=localhost;Database=demo;Username=demo;Password=password"
4 | },
5 | "Logging": {
6 | "LogLevel": {
7 | "Default": "Information",
8 | "Microsoft.AspNetCore": "Warning"
9 | }
10 | }
11 | }
12 |
--------------------------------------------------------------------------------
/src/c-complex/Demo.Service/appsettings.json:
--------------------------------------------------------------------------------
1 | {
2 | "Logging": {
3 | "LogLevel": {
4 | "Default": "Information",
5 | "Microsoft.AspNetCore": "Warning"
6 | }
7 | },
8 | "AllowedHosts": "*"
9 | }
10 |
--------------------------------------------------------------------------------
/src/c-complex/Demo.WebApp/ClientApp/.env:
--------------------------------------------------------------------------------
1 | BROWSER=none
2 |
--------------------------------------------------------------------------------
/src/c-complex/Demo.WebApp/ClientApp/.env.development:
--------------------------------------------------------------------------------
1 | PORT=44303
2 | HTTPS=true
3 |
4 |
--------------------------------------------------------------------------------
/src/c-complex/Demo.WebApp/ClientApp/.gitignore:
--------------------------------------------------------------------------------
1 | # See https://help.github.com/ignore-files/ for more about ignoring files.
2 |
3 | # dependencies
4 | /node_modules
5 |
6 | # testing
7 | /coverage
8 |
9 | # production
10 | /build
11 |
12 | # misc
13 | .DS_Store
14 | .env.local
15 | .env.development.local
16 | .env.test.local
17 | .env.production.local
18 |
19 | npm-debug.log*
20 | yarn-debug.log*
21 | yarn-error.log*
22 |
--------------------------------------------------------------------------------
/src/c-complex/Demo.WebApp/ClientApp/public/favicon.ico:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/sgryphon/dotnet-distributed-tracing-examples/440df38a429288675d550c8d96e473d2c33eb67c/src/c-complex/Demo.WebApp/ClientApp/public/favicon.ico
--------------------------------------------------------------------------------
/src/c-complex/Demo.WebApp/ClientApp/public/manifest.json:
--------------------------------------------------------------------------------
1 | {
2 | "short_name": "Demo.WebApp",
3 | "name": "Demo.WebApp",
4 | "icons": [
5 | {
6 | "src": "favicon.ico",
7 | "sizes": "64x64 32x32 24x24 16x16",
8 | "type": "image/x-icon"
9 | }
10 | ],
11 | "start_url": "./index.html",
12 | "display": "standalone",
13 | "theme_color": "#000000",
14 | "background_color": "#ffffff"
15 | }
16 |
--------------------------------------------------------------------------------
/src/c-complex/Demo.WebApp/ClientApp/src/App.js:
--------------------------------------------------------------------------------
1 | import React, { Component } from 'react';
2 | import { Route } from 'react-router';
3 | import { Layout } from './components/Layout';
4 | import { Home } from './components/Home';
5 | import { FetchData } from './components/FetchData';
6 | import { Counter } from './components/Counter';
7 |
8 | import './custom.css'
9 |
10 | export default class App extends Component {
11 | static displayName = App.name;
12 |
13 | render () {
14 | return (
15 |
16 |
17 |
18 |
19 |
20 | );
21 | }
22 | }
23 |
--------------------------------------------------------------------------------
/src/c-complex/Demo.WebApp/ClientApp/src/App.test.js:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 | import ReactDOM from 'react-dom';
3 | import { MemoryRouter } from 'react-router-dom';
4 | import App from './App';
5 |
6 | it('renders without crashing', async () => {
7 | const div = document.createElement('div');
8 | ReactDOM.render(
9 |
10 |
11 | , div);
12 | await new Promise(resolve => setTimeout(resolve, 1000));
13 | });
14 |
--------------------------------------------------------------------------------
/src/c-complex/Demo.WebApp/ClientApp/src/components/Counter.js:
--------------------------------------------------------------------------------
1 | import React, { Component } from 'react';
2 |
3 | export class Counter extends Component {
4 | static displayName = Counter.name;
5 |
6 | constructor(props) {
7 | super(props);
8 | this.state = { currentCount: 0 };
9 | this.incrementCounter = this.incrementCounter.bind(this);
10 | }
11 |
12 | incrementCounter() {
13 | this.setState({
14 | currentCount: this.state.currentCount + 1
15 | });
16 | }
17 |
18 | render() {
19 | return (
20 |
21 |
Counter
22 |
23 |
This is a simple example of a React component.
24 |
25 |
Current count: {this.state.currentCount}
26 |
27 |
Increment
28 |
29 | );
30 | }
31 | }
32 |
--------------------------------------------------------------------------------
/src/c-complex/Demo.WebApp/ClientApp/src/components/Layout.js:
--------------------------------------------------------------------------------
1 | import React, { Component } from 'react';
2 | import { Container } from 'reactstrap';
3 | import { NavMenu } from './NavMenu';
4 |
5 | export class Layout extends Component {
6 | static displayName = Layout.name;
7 |
8 | render () {
9 | return (
10 |
11 |
12 |
13 | {this.props.children}
14 |
15 |
16 | );
17 | }
18 | }
19 |
--------------------------------------------------------------------------------
/src/c-complex/Demo.WebApp/ClientApp/src/components/NavMenu.css:
--------------------------------------------------------------------------------
1 | a.navbar-brand {
2 | white-space: normal;
3 | text-align: center;
4 | word-break: break-all;
5 | }
6 |
7 | html {
8 | font-size: 14px;
9 | }
10 | @media (min-width: 768px) {
11 | html {
12 | font-size: 16px;
13 | }
14 | }
15 |
16 | .box-shadow {
17 | box-shadow: 0 .25rem .75rem rgba(0, 0, 0, .05);
18 | }
19 |
--------------------------------------------------------------------------------
/src/c-complex/Demo.WebApp/ClientApp/src/custom.css:
--------------------------------------------------------------------------------
1 | /* Provide sufficient contrast against white background */
2 | a {
3 | color: #0366d6;
4 | }
5 |
6 | code {
7 | color: #E01A76;
8 | }
9 |
10 | .btn-primary {
11 | color: #fff;
12 | background-color: #1b6ec2;
13 | border-color: #1861ac;
14 | }
15 |
--------------------------------------------------------------------------------
/src/c-complex/Demo.WebApp/ClientApp/src/reportWebVitals.js:
--------------------------------------------------------------------------------
1 | const reportWebVitals = (onPerfEntry) => {
2 | if (onPerfEntry && onPerfEntry instanceof Function) {
3 | import('web-vitals').then(({ getCLS, getFID, getFCP, getLCP, getTTFB }) => {
4 | getCLS(onPerfEntry);
5 | getFID(onPerfEntry);
6 | getFCP(onPerfEntry);
7 | getLCP(onPerfEntry);
8 | getTTFB(onPerfEntry);
9 | });
10 | }
11 | };
12 |
13 | export default reportWebVitals;
14 |
--------------------------------------------------------------------------------
/src/c-complex/Demo.WebApp/ClientApp/src/setupProxy.js:
--------------------------------------------------------------------------------
1 | const createProxyMiddleware = require('http-proxy-middleware');
2 | const { env } = require('process');
3 |
4 | const target = env.ASPNETCORE_HTTPS_PORT ? `https://localhost:${env.ASPNETCORE_HTTPS_PORT}` :
5 | env.ASPNETCORE_URLS ? env.ASPNETCORE_URLS.split(';')[0] : 'http://localhost:42713';
6 |
7 | const context = [
8 | "/weatherforecast",
9 | ];
10 |
11 | module.exports = function(app) {
12 | const appProxy = createProxyMiddleware(context, {
13 | target: target,
14 | secure: false
15 | });
16 |
17 | app.use(appProxy);
18 | };
19 |
--------------------------------------------------------------------------------
/src/c-complex/Demo.WebApp/Controllers/WeatherMessage.cs:
--------------------------------------------------------------------------------
1 | namespace Demo;
2 |
3 | public interface WeatherMessage
4 | {
5 | string Note { get; }
6 | }
--------------------------------------------------------------------------------
/src/c-complex/Demo.WebApp/Pages/Error.cshtml:
--------------------------------------------------------------------------------
1 | @page
2 | @model ErrorModel
3 | @{
4 | ViewData["Title"] = "Error";
5 | }
6 |
7 | Error.
8 | An error occurred while processing your request.
9 |
10 | @if (Model.ShowRequestId)
11 | {
12 |
13 | Request ID: @Model.RequestId
14 |
15 | }
16 |
17 | Development Mode
18 |
19 | Swapping to the Development environment displays detailed information about the error that occurred.
20 |
21 |
22 | The Development environment shouldn't be enabled for deployed applications.
23 | It can result in displaying sensitive information from exceptions to end users.
24 | For local debugging, enable the Development environment by setting the ASPNETCORE_ENVIRONMENT environment variable to Development
25 | and restarting the app.
26 |
27 |
--------------------------------------------------------------------------------
/src/c-complex/Demo.WebApp/Pages/Error.cshtml.cs:
--------------------------------------------------------------------------------
1 | using System.Diagnostics;
2 | using Microsoft.AspNetCore.Mvc;
3 | using Microsoft.AspNetCore.Mvc.RazorPages;
4 |
5 | namespace Demo.WebApp.Pages;
6 |
7 | [ResponseCache(Duration = 0, Location = ResponseCacheLocation.None, NoStore = true)]
8 | public class ErrorModel : PageModel
9 | {
10 | private readonly ILogger _logger;
11 |
12 | public ErrorModel(ILogger logger)
13 | {
14 | _logger = logger;
15 | }
16 |
17 | public string? RequestId { get; set; }
18 |
19 | public bool ShowRequestId => !string.IsNullOrEmpty(RequestId);
20 |
21 | public void OnGet()
22 | {
23 | RequestId = Activity.Current?.Id ?? HttpContext.TraceIdentifier;
24 | }
25 | }
26 |
--------------------------------------------------------------------------------
/src/c-complex/Demo.WebApp/Pages/_ViewImports.cshtml:
--------------------------------------------------------------------------------
1 | @using Demo.WebApp
2 | @namespace Demo.WebApp.Pages
3 | @addTagHelper *, Microsoft.AspNetCore.Mvc.TagHelpers
4 |
--------------------------------------------------------------------------------
/src/c-complex/Demo.WebApp/Properties/launchSettings.json:
--------------------------------------------------------------------------------
1 | {
2 | "iisSettings": {
3 | "windowsAuthentication": false,
4 | "anonymousAuthentication": true,
5 | "iisExpress": {
6 | "applicationUrl": "http://localhost:42713",
7 | "sslPort": 44323
8 | }
9 | },
10 | "profiles": {
11 | "Demo.WebApp": {
12 | "commandName": "Project",
13 | "launchBrowser": true,
14 | "applicationUrl": "https://localhost:7107;http://localhost:5191",
15 | "environmentVariables": {
16 | "ASPNETCORE_ENVIRONMENT": "Development",
17 | "ASPNETCORE_HOSTINGSTARTUPASSEMBLIES": "Microsoft.AspNetCore.SpaProxy"
18 | }
19 | },
20 | "IIS Express": {
21 | "commandName": "IISExpress",
22 | "launchBrowser": true,
23 | "environmentVariables": {
24 | "ASPNETCORE_ENVIRONMENT": "Development",
25 | "ASPNETCORE_HOSTINGSTARTUPASSEMBLIES": "Microsoft.AspNetCore.SpaProxy"
26 | }
27 | }
28 | }
29 | }
30 |
--------------------------------------------------------------------------------
/src/c-complex/Demo.WebApp/WeatherForecast.cs:
--------------------------------------------------------------------------------
1 | namespace Demo.WebApp;
2 |
3 | public class WeatherForecast
4 | {
5 | public DateTime Date { get; set; }
6 |
7 | public int TemperatureC { get; set; }
8 |
9 | public int TemperatureF => 32 + (int)(TemperatureC / 0.5556);
10 |
11 | public string? Summary { get; set; }
12 | }
13 |
--------------------------------------------------------------------------------
/src/c-complex/Demo.WebApp/appsettings.Development.json:
--------------------------------------------------------------------------------
1 | {
2 | "Logging": {
3 | "LogLevel": {
4 | "Default": "Information",
5 | "Microsoft": "Warning",
6 | "Microsoft.AspNetCore.SpaProxy": "Information",
7 | "Microsoft.Hosting.Lifetime": "Information"
8 | }
9 | },
10 | "MassTransit": {
11 | "RabbitMq": {
12 | "Host": "localhost",
13 | "Port": 5672,
14 | "VirtualHost": "/",
15 | "Username": "user",
16 | "Password": "password"
17 | }
18 | }
19 | }
20 |
--------------------------------------------------------------------------------
/src/c-complex/Demo.WebApp/appsettings.json:
--------------------------------------------------------------------------------
1 | {
2 | "Logging": {
3 | "LogLevel": {
4 | "Default": "Information",
5 | "Microsoft": "Warning",
6 | "Microsoft.Hosting.Lifetime": "Information"
7 | }
8 | },
9 | "AllowedHosts": "*"
10 | }
11 |
--------------------------------------------------------------------------------
/src/c-complex/Demo.Worker/Demo.Worker.csproj:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | net6.0
5 | enable
6 | enable
7 | dotnet-Demo.Worker-335C2901-E48D-4CC3-BF7E-606029372F16
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
--------------------------------------------------------------------------------
/src/c-complex/Demo.Worker/Properties/launchSettings.json:
--------------------------------------------------------------------------------
1 | {
2 | "profiles": {
3 | "Demo.Worker": {
4 | "commandName": "Project",
5 | "dotnetRunMessages": true,
6 | "environmentVariables": {
7 | "DOTNET_ENVIRONMENT": "Development"
8 | }
9 | }
10 | }
11 | }
12 |
--------------------------------------------------------------------------------
/src/c-complex/Demo.Worker/WeatherMessage.cs:
--------------------------------------------------------------------------------
1 | namespace Demo;
2 |
3 | public interface WeatherMessage
4 | {
5 | string Note { get; }
6 | }
7 |
--------------------------------------------------------------------------------
/src/c-complex/Demo.Worker/WeatherMessageConsumer.cs:
--------------------------------------------------------------------------------
1 | using MassTransit;
2 |
3 | namespace Demo.Worker;
4 |
5 | public class WeatherMessageConsumer : IConsumer
6 | {
7 | private readonly ILogger _logger;
8 |
9 | public WeatherMessageConsumer(ILogger logger)
10 | {
11 | _logger = logger;
12 | }
13 |
14 | public async Task Consume(ConsumeContext context)
15 | {
16 | _logger.LogWarning(4002, "TRACING DEMO: Worker message received: {Note}", context.Message.Note);
17 | await Task.Delay(TimeSpan.FromMilliseconds(200), context.CancellationToken);
18 | }
19 | }
20 |
--------------------------------------------------------------------------------
/src/c-complex/Demo.Worker/Worker.cs:
--------------------------------------------------------------------------------
1 | namespace Demo.Worker;
2 |
3 | public class Worker : BackgroundService
4 | {
5 | private readonly ILogger _logger;
6 |
7 | public Worker(ILogger logger)
8 | {
9 | _logger = logger;
10 | }
11 |
12 | protected override async Task ExecuteAsync(CancellationToken stoppingToken)
13 | {
14 | while (!stoppingToken.IsCancellationRequested)
15 | {
16 | _logger.LogInformation("Worker running at: {time}", DateTimeOffset.Now);
17 | await Task.Delay(1000, stoppingToken);
18 | }
19 | }
20 | }
21 |
--------------------------------------------------------------------------------
/src/c-complex/Demo.Worker/appsettings.Development.json:
--------------------------------------------------------------------------------
1 | {
2 | "Logging": {
3 | "LogLevel": {
4 | "Default": "Information",
5 | "Microsoft.Hosting.Lifetime": "Information"
6 | }
7 | },
8 | "MassTransit": {
9 | "RabbitMq": {
10 | "Host": "localhost",
11 | "Port": 5672,
12 | "VirtualHost": "/",
13 | "Username": "user",
14 | "Password": "password"
15 | }
16 | }
17 | }
--------------------------------------------------------------------------------
/src/c-complex/Demo.Worker/appsettings.json:
--------------------------------------------------------------------------------
1 | {
2 | "Logging": {
3 | "LogLevel": {
4 | "Default": "Information",
5 | "Microsoft.Hosting.Lifetime": "Information"
6 | }
7 | }
8 | }
9 |
--------------------------------------------------------------------------------
/src/c-complex/docs/complex-demo.puml:
--------------------------------------------------------------------------------
1 | @startuml
2 |
3 | left to right direction
4 | skinparam handwritten true
5 | skinparam useBetaStyle true
6 |
18 |
19 | component Browser <>
20 | component Demo.WebApp
21 | component Demo.Service
22 | component Demo.Worker
23 | database PostgreSQL
24 | queue RabbitMQ
25 | rectangle Adminer
26 |
27 | Browser -- Demo.WebApp
28 | Demo.WebApp -- Demo.Service
29 | Demo.WebApp -- RabbitMQ
30 | RabbitMQ -- Demo.Worker
31 | Demo.Service -- PostgreSQL
32 | PostgreSQL -- Adminer
33 |
34 | @endml
35 |
--------------------------------------------------------------------------------
/src/c-complex/docs/complex-tracing.puml:
--------------------------------------------------------------------------------
1 | @startuml
2 |
3 | left to right direction
4 | skinparam handwritten true
5 | skinparam useBetaStyle true
6 |
18 |
19 | component Demo.WebApp {
20 | rectangle webapp_exporter as "Exporter" #ffffff
21 | }
22 | component Demo.Service {
23 | rectangle service_exporter as "Exporter" #ffffff
24 | }
25 | component Demo.Worker {
26 | rectangle worker_exporter as "Exporter" #ffffff
27 | }
28 |
29 | rectangle Elasticsearch [
30 | Elasticsearch
31 | (logs)
32 | ]
33 | rectangle Kibana
34 | rectangle Jaeger [
35 | Jaeger
36 | (traces)
37 | ]
38 |
39 | Demo.WebApp -- Elasticsearch
40 | Demo.Service -- Elasticsearch
41 | Demo.Worker -- Elasticsearch
42 | Elasticsearch -- Kibana
43 |
44 | webapp_exporter -- Jaeger
45 | service_exporter -- Jaeger
46 | worker_exporter -- Jaeger
47 |
48 | @endml
49 |
--------------------------------------------------------------------------------
/src/c-complex/docs/generated/complex-demo.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/sgryphon/dotnet-distributed-tracing-examples/440df38a429288675d550c8d96e473d2c33eb67c/src/c-complex/docs/generated/complex-demo.png
--------------------------------------------------------------------------------
/src/c-complex/docs/generated/complex-tracing.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/sgryphon/dotnet-distributed-tracing-examples/440df38a429288675d550c8d96e473d2c33eb67c/src/c-complex/docs/generated/complex-tracing.png
--------------------------------------------------------------------------------
/src/c-complex/images/elasticsearch-logs-complex.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/sgryphon/dotnet-distributed-tracing-examples/440df38a429288675d550c8d96e473d2c33eb67c/src/c-complex/images/elasticsearch-logs-complex.png
--------------------------------------------------------------------------------
/src/c-complex/images/jaeger-architecture-complex.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/sgryphon/dotnet-distributed-tracing-examples/440df38a429288675d550c8d96e473d2c33eb67c/src/c-complex/images/jaeger-architecture-complex.png
--------------------------------------------------------------------------------
/src/c-complex/images/jaeger-traces-complex.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/sgryphon/dotnet-distributed-tracing-examples/440df38a429288675d550c8d96e473d2c33eb67c/src/c-complex/images/jaeger-traces-complex.png
--------------------------------------------------------------------------------
/src/c-complex/start-complex-demo.sh:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 |
3 | version=$(dotnet gitversion /output json /showvariable InformationalVersion)
4 | tmux new-session -d 'ASPNETCORE_URLS="http://localhost:8002" npm run start --prefix Demo.WebApp/ClientApp'
5 | tmux split-window -h "dotnet run --project Demo.WebApp -p:InformationalVersion=$version -- --urls http://*:8002 --environment Development"
6 | tmux split-window -f "dotnet run --project Demo.Service -p:InformationalVersion=$version -- --urls https://*:44301 --environment Development"
7 | tmux split-window -h "dotnet run --project Demo.Worker -p:InformationalVersion=$version -- --environment Development"
8 | tmux attach-session -d
9 |
--------------------------------------------------------------------------------
/src/compare-serilog/Demo.WebApi/Demo.WebApi.http:
--------------------------------------------------------------------------------
1 | @Demo.WebApi_HostAddress = http://localhost:5240
2 |
3 | GET {{Demo.WebApi_HostAddress}}/weatherforecast/
4 | Accept: application/json
5 |
6 | ###
7 |
--------------------------------------------------------------------------------
/src/compare-serilog/Demo.WebApi/appsettings.Development.json:
--------------------------------------------------------------------------------
1 | {
2 | "Logging": {
3 | "LogLevel": {
4 | "Default": "Information",
5 | "Microsoft.AspNetCore": "Warning"
6 | }
7 | }
8 | }
9 |
--------------------------------------------------------------------------------
/src/compare-serilog/Demo.WebApi/appsettings.json:
--------------------------------------------------------------------------------
1 | {
2 | "Logging": {
3 | "LogLevel": {
4 | "Default": "Information",
5 | "Microsoft.AspNetCore": "Warning"
6 | }
7 | },
8 | "AllowedHosts": "*"
9 | }
10 |
--------------------------------------------------------------------------------
/src/compare-serilog/compare-serilog.sln:
--------------------------------------------------------------------------------
1 |
2 | Microsoft Visual Studio Solution File, Format Version 12.00
3 | # Visual Studio Version 17
4 | VisualStudioVersion = 17.0.31903.59
5 | MinimumVisualStudioVersion = 10.0.40219.1
6 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Demo.WebApi", "Demo.WebApi\Demo.WebApi.csproj", "{A754F190-5602-45FA-A86A-9F04F90432F0}"
7 | EndProject
8 | Global
9 | GlobalSection(SolutionConfigurationPlatforms) = preSolution
10 | Debug|Any CPU = Debug|Any CPU
11 | Release|Any CPU = Release|Any CPU
12 | EndGlobalSection
13 | GlobalSection(SolutionProperties) = preSolution
14 | HideSolutionNode = FALSE
15 | EndGlobalSection
16 | GlobalSection(ProjectConfigurationPlatforms) = postSolution
17 | {A754F190-5602-45FA-A86A-9F04F90432F0}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
18 | {A754F190-5602-45FA-A86A-9F04F90432F0}.Debug|Any CPU.Build.0 = Debug|Any CPU
19 | {A754F190-5602-45FA-A86A-9F04F90432F0}.Release|Any CPU.ActiveCfg = Release|Any CPU
20 | {A754F190-5602-45FA-A86A-9F04F90432F0}.Release|Any CPU.Build.0 = Release|Any CPU
21 | EndGlobalSection
22 | EndGlobal
23 |
--------------------------------------------------------------------------------
/src/d-collector/Demo.Service/Log.cs:
--------------------------------------------------------------------------------
1 | namespace Demo.Service;
2 |
3 | internal static class Log
4 | {
5 | // Using high performance logging pattern, see https://docs.microsoft.com/en-us/aspnet/core/fundamentals/logging/loggermessage
6 | internal static class Warning
7 | {
8 | public static readonly Action ServiceForecastRequest =
9 | LoggerMessage.Define(LogLevel.Warning,
10 | new EventId(4002, nameof(ServiceForecastRequest)),
11 | "TRACING DEMO: Back end service weather forecast requested");
12 | }
13 | }
14 |
--------------------------------------------------------------------------------
/src/d-collector/Demo.Service/Properties/launchSettings.json:
--------------------------------------------------------------------------------
1 | {
2 | "$schema": "https://json.schemastore.org/launchsettings.json",
3 | "iisSettings": {
4 | "windowsAuthentication": false,
5 | "anonymousAuthentication": true,
6 | "iisExpress": {
7 | "applicationUrl": "http://localhost:34203",
8 | "sslPort": 44331
9 | }
10 | },
11 | "profiles": {
12 | "Demo.Service": {
13 | "commandName": "Project",
14 | "dotnetRunMessages": true,
15 | "launchBrowser": true,
16 | "launchUrl": "swagger",
17 | "applicationUrl": "https://localhost:7189;http://localhost:5195",
18 | "environmentVariables": {
19 | "ASPNETCORE_ENVIRONMENT": "Development"
20 | }
21 | },
22 | "IIS Express": {
23 | "commandName": "IISExpress",
24 | "launchBrowser": true,
25 | "launchUrl": "swagger",
26 | "environmentVariables": {
27 | "ASPNETCORE_ENVIRONMENT": "Development"
28 | }
29 | }
30 | }
31 | }
32 |
--------------------------------------------------------------------------------
/src/d-collector/Demo.Service/WeatherContext.cs:
--------------------------------------------------------------------------------
1 | using Microsoft.EntityFrameworkCore;
2 |
3 | namespace Demo.Service;
4 |
5 | public class WeatherContext : DbContext
6 | {
7 | public WeatherContext(DbContextOptions context) : base(context) { }
8 |
9 | public DbSet WeatherServiceRequests { get; set; } = null!;
10 | }
11 |
12 | public class WeatherServiceRequest
13 | {
14 | public Guid Id { get; set; }
15 | public string Note { get; set; } = string.Empty;
16 | }
17 |
--------------------------------------------------------------------------------
/src/d-collector/Demo.Service/WeatherForecast.cs:
--------------------------------------------------------------------------------
1 | namespace Demo.Service;
2 |
3 | public class WeatherForecast
4 | {
5 | public DateTime Date { get; set; }
6 |
7 | public int TemperatureC { get; set; }
8 |
9 | public int TemperatureF => 32 + (int)(TemperatureC / 0.5556);
10 |
11 | public string? Summary { get; set; }
12 | }
13 |
--------------------------------------------------------------------------------
/src/d-collector/Demo.Service/appsettings.Development.json:
--------------------------------------------------------------------------------
1 | {
2 | "ConnectionStrings": {
3 | "WeatherContext": "Host=localhost;Database=demo;Username=demo;Password=password"
4 | },
5 | "Logging": {
6 | "LogLevel": {
7 | "Default": "Information",
8 | "Microsoft.AspNetCore": "Warning"
9 | }
10 | },
11 | "OpenTelemetry": {
12 | "OtlpExporter": {
13 | "Endpoint": "http://localhost:4317/",
14 | "ExportProcessorType": "Batch",
15 | "Protocol": "grpc"
16 | }
17 | }
18 | }
19 |
--------------------------------------------------------------------------------
/src/d-collector/Demo.Service/appsettings.json:
--------------------------------------------------------------------------------
1 | {
2 | "Logging": {
3 | "LogLevel": {
4 | "Default": "Information",
5 | "Microsoft.AspNetCore": "Warning"
6 | }
7 | },
8 | "AllowedHosts": "*"
9 | }
10 |
--------------------------------------------------------------------------------
/src/d-collector/Demo.WebApp/ClientApp/.env:
--------------------------------------------------------------------------------
1 | BROWSER=none
2 |
--------------------------------------------------------------------------------
/src/d-collector/Demo.WebApp/ClientApp/.env.development:
--------------------------------------------------------------------------------
1 | PORT=44303
2 | HTTPS=true
3 |
4 |
--------------------------------------------------------------------------------
/src/d-collector/Demo.WebApp/ClientApp/.gitignore:
--------------------------------------------------------------------------------
1 | # See https://help.github.com/ignore-files/ for more about ignoring files.
2 |
3 | # dependencies
4 | /node_modules
5 |
6 | # testing
7 | /coverage
8 |
9 | # production
10 | /build
11 |
12 | # misc
13 | .DS_Store
14 | .env.local
15 | .env.development.local
16 | .env.test.local
17 | .env.production.local
18 |
19 | npm-debug.log*
20 | yarn-debug.log*
21 | yarn-error.log*
22 |
--------------------------------------------------------------------------------
/src/d-collector/Demo.WebApp/ClientApp/public/favicon.ico:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/sgryphon/dotnet-distributed-tracing-examples/440df38a429288675d550c8d96e473d2c33eb67c/src/d-collector/Demo.WebApp/ClientApp/public/favicon.ico
--------------------------------------------------------------------------------
/src/d-collector/Demo.WebApp/ClientApp/public/manifest.json:
--------------------------------------------------------------------------------
1 | {
2 | "short_name": "Demo.WebApp",
3 | "name": "Demo.WebApp",
4 | "icons": [
5 | {
6 | "src": "favicon.ico",
7 | "sizes": "64x64 32x32 24x24 16x16",
8 | "type": "image/x-icon"
9 | }
10 | ],
11 | "start_url": "./index.html",
12 | "display": "standalone",
13 | "theme_color": "#000000",
14 | "background_color": "#ffffff"
15 | }
16 |
--------------------------------------------------------------------------------
/src/d-collector/Demo.WebApp/ClientApp/src/App.js:
--------------------------------------------------------------------------------
1 | import React, { Component } from 'react';
2 | import { Route } from 'react-router';
3 | import { Layout } from './components/Layout';
4 | import { Home } from './components/Home';
5 | import { FetchData } from './components/FetchData';
6 | import { Counter } from './components/Counter';
7 |
8 | import './custom.css'
9 |
10 | export default class App extends Component {
11 | static displayName = App.name;
12 |
13 | render () {
14 | return (
15 |
16 |
17 |
18 |
19 |
20 | );
21 | }
22 | }
23 |
--------------------------------------------------------------------------------
/src/d-collector/Demo.WebApp/ClientApp/src/App.test.js:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 | import ReactDOM from 'react-dom';
3 | import { MemoryRouter } from 'react-router-dom';
4 | import App from './App';
5 |
6 | it('renders without crashing', async () => {
7 | const div = document.createElement('div');
8 | ReactDOM.render(
9 |
10 |
11 | , div);
12 | await new Promise(resolve => setTimeout(resolve, 1000));
13 | });
14 |
--------------------------------------------------------------------------------
/src/d-collector/Demo.WebApp/ClientApp/src/components/Counter.js:
--------------------------------------------------------------------------------
1 | import React, { Component } from 'react';
2 |
3 | export class Counter extends Component {
4 | static displayName = Counter.name;
5 |
6 | constructor(props) {
7 | super(props);
8 | this.state = { currentCount: 0 };
9 | this.incrementCounter = this.incrementCounter.bind(this);
10 | }
11 |
12 | incrementCounter() {
13 | this.setState({
14 | currentCount: this.state.currentCount + 1
15 | });
16 | }
17 |
18 | render() {
19 | return (
20 |
21 |
Counter
22 |
23 |
This is a simple example of a React component.
24 |
25 |
Current count: {this.state.currentCount}
26 |
27 |
Increment
28 |
29 | );
30 | }
31 | }
32 |
--------------------------------------------------------------------------------
/src/d-collector/Demo.WebApp/ClientApp/src/components/Layout.js:
--------------------------------------------------------------------------------
1 | import React, { Component } from 'react';
2 | import { Container } from 'reactstrap';
3 | import { NavMenu } from './NavMenu';
4 |
5 | export class Layout extends Component {
6 | static displayName = Layout.name;
7 |
8 | render () {
9 | return (
10 |
11 |
12 |
13 | {this.props.children}
14 |
15 |
16 | );
17 | }
18 | }
19 |
--------------------------------------------------------------------------------
/src/d-collector/Demo.WebApp/ClientApp/src/components/NavMenu.css:
--------------------------------------------------------------------------------
1 | a.navbar-brand {
2 | white-space: normal;
3 | text-align: center;
4 | word-break: break-all;
5 | }
6 |
7 | html {
8 | font-size: 14px;
9 | }
10 | @media (min-width: 768px) {
11 | html {
12 | font-size: 16px;
13 | }
14 | }
15 |
16 | .box-shadow {
17 | box-shadow: 0 .25rem .75rem rgba(0, 0, 0, .05);
18 | }
19 |
--------------------------------------------------------------------------------
/src/d-collector/Demo.WebApp/ClientApp/src/custom.css:
--------------------------------------------------------------------------------
1 | /* Provide sufficient contrast against white background */
2 | a {
3 | color: #0366d6;
4 | }
5 |
6 | code {
7 | color: #E01A76;
8 | }
9 |
10 | .btn-primary {
11 | color: #fff;
12 | background-color: #1b6ec2;
13 | border-color: #1861ac;
14 | }
15 |
--------------------------------------------------------------------------------
/src/d-collector/Demo.WebApp/ClientApp/src/reportWebVitals.js:
--------------------------------------------------------------------------------
1 | const reportWebVitals = (onPerfEntry) => {
2 | if (onPerfEntry && onPerfEntry instanceof Function) {
3 | import('web-vitals').then(({ getCLS, getFID, getFCP, getLCP, getTTFB }) => {
4 | getCLS(onPerfEntry);
5 | getFID(onPerfEntry);
6 | getFCP(onPerfEntry);
7 | getLCP(onPerfEntry);
8 | getTTFB(onPerfEntry);
9 | });
10 | }
11 | };
12 |
13 | export default reportWebVitals;
14 |
--------------------------------------------------------------------------------
/src/d-collector/Demo.WebApp/ClientApp/src/setupProxy.js:
--------------------------------------------------------------------------------
1 | const createProxyMiddleware = require('http-proxy-middleware');
2 | const { env } = require('process');
3 |
4 | const target = env.ASPNETCORE_HTTPS_PORT ? `https://localhost:${env.ASPNETCORE_HTTPS_PORT}` :
5 | env.ASPNETCORE_URLS ? env.ASPNETCORE_URLS.split(';')[0] : 'http://localhost:42713';
6 |
7 | const context = [
8 | "/weatherforecast",
9 | ];
10 |
11 | module.exports = function(app) {
12 | const appProxy = createProxyMiddleware(context, {
13 | target: target,
14 | secure: false
15 | });
16 |
17 | app.use(appProxy);
18 | };
19 |
--------------------------------------------------------------------------------
/src/d-collector/Demo.WebApp/Controllers/WeatherMessage.cs:
--------------------------------------------------------------------------------
1 | namespace Demo;
2 |
3 | public interface WeatherMessage
4 | {
5 | string Note { get; }
6 | }
--------------------------------------------------------------------------------
/src/d-collector/Demo.WebApp/Log.cs:
--------------------------------------------------------------------------------
1 | namespace Demo.WebApp;
2 |
3 | internal static class Log
4 | {
5 | // Using high performance logging pattern, see https://docs.microsoft.com/en-us/aspnet/core/fundamentals/logging/loggermessage
6 | internal static class Warning
7 | {
8 | public static readonly Action WebAppForecastRequestForwarded =
9 | LoggerMessage.Define(LogLevel.Warning,
10 | new EventId(4001, nameof(WebAppForecastRequestForwarded)),
11 | "TRACING DEMO: WebApp API weather forecast request forwarded");
12 | }
13 | }
14 |
--------------------------------------------------------------------------------
/src/d-collector/Demo.WebApp/Pages/Error.cshtml:
--------------------------------------------------------------------------------
1 | @page
2 | @model ErrorModel
3 | @{
4 | ViewData["Title"] = "Error";
5 | }
6 |
7 | Error.
8 | An error occurred while processing your request.
9 |
10 | @if (Model.ShowRequestId)
11 | {
12 |
13 | Request ID: @Model.RequestId
14 |
15 | }
16 |
17 | Development Mode
18 |
19 | Swapping to the Development environment displays detailed information about the error that occurred.
20 |
21 |
22 | The Development environment shouldn't be enabled for deployed applications.
23 | It can result in displaying sensitive information from exceptions to end users.
24 | For local debugging, enable the Development environment by setting the ASPNETCORE_ENVIRONMENT environment variable to Development
25 | and restarting the app.
26 |
27 |
--------------------------------------------------------------------------------
/src/d-collector/Demo.WebApp/Pages/Error.cshtml.cs:
--------------------------------------------------------------------------------
1 | using System.Diagnostics;
2 | using Microsoft.AspNetCore.Mvc;
3 | using Microsoft.AspNetCore.Mvc.RazorPages;
4 |
5 | namespace Demo.WebApp.Pages;
6 |
7 | [ResponseCache(Duration = 0, Location = ResponseCacheLocation.None, NoStore = true)]
8 | public class ErrorModel : PageModel
9 | {
10 | private readonly ILogger _logger;
11 |
12 | public ErrorModel(ILogger logger)
13 | {
14 | _logger = logger;
15 | }
16 |
17 | public string? RequestId { get; set; }
18 |
19 | public bool ShowRequestId => !string.IsNullOrEmpty(RequestId);
20 |
21 | public void OnGet()
22 | {
23 | RequestId = Activity.Current?.Id ?? HttpContext.TraceIdentifier;
24 | }
25 | }
26 |
--------------------------------------------------------------------------------
/src/d-collector/Demo.WebApp/Pages/_ViewImports.cshtml:
--------------------------------------------------------------------------------
1 | @using Demo.WebApp
2 | @namespace Demo.WebApp.Pages
3 | @addTagHelper *, Microsoft.AspNetCore.Mvc.TagHelpers
4 |
--------------------------------------------------------------------------------
/src/d-collector/Demo.WebApp/Properties/launchSettings.json:
--------------------------------------------------------------------------------
1 | {
2 | "iisSettings": {
3 | "windowsAuthentication": false,
4 | "anonymousAuthentication": true,
5 | "iisExpress": {
6 | "applicationUrl": "http://localhost:42713",
7 | "sslPort": 44323
8 | }
9 | },
10 | "profiles": {
11 | "Demo.WebApp": {
12 | "commandName": "Project",
13 | "launchBrowser": true,
14 | "applicationUrl": "https://localhost:7107;http://localhost:5191",
15 | "environmentVariables": {
16 | "ASPNETCORE_ENVIRONMENT": "Development",
17 | "ASPNETCORE_HOSTINGSTARTUPASSEMBLIES": "Microsoft.AspNetCore.SpaProxy"
18 | }
19 | },
20 | "IIS Express": {
21 | "commandName": "IISExpress",
22 | "launchBrowser": true,
23 | "environmentVariables": {
24 | "ASPNETCORE_ENVIRONMENT": "Development",
25 | "ASPNETCORE_HOSTINGSTARTUPASSEMBLIES": "Microsoft.AspNetCore.SpaProxy"
26 | }
27 | }
28 | }
29 | }
30 |
--------------------------------------------------------------------------------
/src/d-collector/Demo.WebApp/WeatherForecast.cs:
--------------------------------------------------------------------------------
1 | namespace Demo.WebApp;
2 |
3 | public class WeatherForecast
4 | {
5 | public DateTime Date { get; set; }
6 |
7 | public int TemperatureC { get; set; }
8 |
9 | public int TemperatureF => 32 + (int)(TemperatureC / 0.5556);
10 |
11 | public string? Summary { get; set; }
12 | }
13 |
--------------------------------------------------------------------------------
/src/d-collector/Demo.WebApp/appsettings.Development.json:
--------------------------------------------------------------------------------
1 | {
2 | "Logging": {
3 | "LogLevel": {
4 | "Default": "Information",
5 | "Microsoft": "Warning",
6 | "Microsoft.AspNetCore.SpaProxy": "Information",
7 | "Microsoft.Hosting.Lifetime": "Information"
8 | }
9 | },
10 | "MassTransit": {
11 | "RabbitMq": {
12 | "Host": "localhost",
13 | "Port": 5672,
14 | "VirtualHost": "/",
15 | "Username": "user",
16 | "Password": "password"
17 | }
18 | },
19 | "OpenTelemetry": {
20 | "OtlpExporter": {
21 | "Endpoint": "http://localhost:4317/",
22 | "ExportProcessorType": "Batch",
23 | "Protocol": "grpc"
24 | }
25 | }
26 | }
27 |
--------------------------------------------------------------------------------
/src/d-collector/Demo.WebApp/appsettings.json:
--------------------------------------------------------------------------------
1 | {
2 | "Logging": {
3 | "LogLevel": {
4 | "Default": "Information",
5 | "Microsoft": "Warning",
6 | "Microsoft.Hosting.Lifetime": "Information"
7 | }
8 | },
9 | "AllowedHosts": "*"
10 | }
11 |
--------------------------------------------------------------------------------
/src/d-collector/Demo.Worker/DemoActivitySource.cs:
--------------------------------------------------------------------------------
1 | // using System.Diagnostics;
2 |
3 | // namespace Demo.Worker;
4 |
5 | // public static class DemoActivitySource
6 | // {
7 | // public static ActivitySource? Instance { get; set; }
8 | // }
--------------------------------------------------------------------------------
/src/d-collector/Demo.Worker/Log.cs:
--------------------------------------------------------------------------------
1 | namespace Demo.Worker;
2 |
3 | internal static class Log
4 | {
5 | // Using high performance logging pattern, see https://docs.microsoft.com/en-us/aspnet/core/fundamentals/logging/loggermessage
6 | internal static class Warning
7 | {
8 | public static readonly Action WorkerMessageReceived =
9 | LoggerMessage.Define(LogLevel.Warning,
10 | new EventId(4003, nameof(WorkerMessageReceived)),
11 | "TRACING DEMO: Worker message received: {Note}");
12 | // public static readonly Action WorkerComplete =
13 | // LoggerMessage.Define(LogLevel.Warning,
14 | // new EventId(4004, nameof(WorkerComplete)),
15 | // "TRACING DEMO: Worker complete");
16 | }
17 | }
18 |
--------------------------------------------------------------------------------
/src/d-collector/Demo.Worker/Properties/launchSettings.json:
--------------------------------------------------------------------------------
1 | {
2 | "profiles": {
3 | "Demo.Worker": {
4 | "commandName": "Project",
5 | "dotnetRunMessages": true,
6 | "environmentVariables": {
7 | "DOTNET_ENVIRONMENT": "Development"
8 | }
9 | }
10 | }
11 | }
12 |
--------------------------------------------------------------------------------
/src/d-collector/Demo.Worker/WeatherMessage.cs:
--------------------------------------------------------------------------------
1 | namespace Demo;
2 |
3 | public interface WeatherMessage
4 | {
5 | string Note { get; }
6 | }
7 |
--------------------------------------------------------------------------------
/src/d-collector/Demo.Worker/Worker.cs:
--------------------------------------------------------------------------------
1 | namespace Demo.Worker;
2 |
3 | public class Worker : BackgroundService
4 | {
5 | private readonly ILogger _logger;
6 |
7 | public Worker(ILogger logger)
8 | {
9 | _logger = logger;
10 | }
11 |
12 | protected override async Task ExecuteAsync(CancellationToken stoppingToken)
13 | {
14 | while (!stoppingToken.IsCancellationRequested)
15 | {
16 | _logger.LogInformation("Worker running at: {time}", DateTimeOffset.Now);
17 | await Task.Delay(1000, stoppingToken);
18 | }
19 | }
20 | }
21 |
--------------------------------------------------------------------------------
/src/d-collector/Demo.Worker/appsettings.Development.json:
--------------------------------------------------------------------------------
1 | {
2 | "Logging": {
3 | "LogLevel": {
4 | "Default": "Information",
5 | "Microsoft.Hosting.Lifetime": "Information"
6 | }
7 | },
8 | "MassTransit": {
9 | "RabbitMq": {
10 | "Host": "localhost",
11 | "Port": 5672,
12 | "VirtualHost": "/",
13 | "Username": "user",
14 | "Password": "password"
15 | }
16 | },
17 | "OpenTelemetry": {
18 | "OtlpExporter": {
19 | "Endpoint": "http://localhost:4317/",
20 | "ExportProcessorType": "Batch",
21 | "Protocol": "grpc"
22 | }
23 | }
24 | }
--------------------------------------------------------------------------------
/src/d-collector/Demo.Worker/appsettings.json:
--------------------------------------------------------------------------------
1 | {
2 | "Logging": {
3 | "LogLevel": {
4 | "Default": "Information",
5 | "Microsoft.Hosting.Lifetime": "Information"
6 | }
7 | }
8 | }
9 |
--------------------------------------------------------------------------------
/src/d-collector/docs/generated/collector-tracing.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/sgryphon/dotnet-distributed-tracing-examples/440df38a429288675d550c8d96e473d2c33eb67c/src/d-collector/docs/generated/collector-tracing.png
--------------------------------------------------------------------------------
/src/d-collector/docs/generated/tracing-complexity.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/sgryphon/dotnet-distributed-tracing-examples/440df38a429288675d550c8d96e473d2c33eb67c/src/d-collector/docs/generated/tracing-complexity.png
--------------------------------------------------------------------------------
/src/d-collector/images/otel-azure-logs.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/sgryphon/dotnet-distributed-tracing-examples/440df38a429288675d550c8d96e473d2c33eb67c/src/d-collector/images/otel-azure-logs.png
--------------------------------------------------------------------------------
/src/d-collector/images/otel-azure-map.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/sgryphon/dotnet-distributed-tracing-examples/440df38a429288675d550c8d96e473d2c33eb67c/src/d-collector/images/otel-azure-map.png
--------------------------------------------------------------------------------
/src/d-collector/images/otel-azure-tracing.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/sgryphon/dotnet-distributed-tracing-examples/440df38a429288675d550c8d96e473d2c33eb67c/src/d-collector/images/otel-azure-tracing.png
--------------------------------------------------------------------------------
/src/d-collector/images/otel-jaeger-architecture.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/sgryphon/dotnet-distributed-tracing-examples/440df38a429288675d550c8d96e473d2c33eb67c/src/d-collector/images/otel-jaeger-architecture.png
--------------------------------------------------------------------------------
/src/d-collector/images/otel-jaeger-summary.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/sgryphon/dotnet-distributed-tracing-examples/440df38a429288675d550c8d96e473d2c33eb67c/src/d-collector/images/otel-jaeger-summary.png
--------------------------------------------------------------------------------
/src/d-collector/images/otel-jaeger-trace.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/sgryphon/dotnet-distributed-tracing-examples/440df38a429288675d550c8d96e473d2c33eb67c/src/d-collector/images/otel-jaeger-trace.png
--------------------------------------------------------------------------------
/src/d-collector/images/otel-loki-graph.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/sgryphon/dotnet-distributed-tracing-examples/440df38a429288675d550c8d96e473d2c33eb67c/src/d-collector/images/otel-loki-graph.png
--------------------------------------------------------------------------------
/src/d-collector/images/otel-loki-logs.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/sgryphon/dotnet-distributed-tracing-examples/440df38a429288675d550c8d96e473d2c33eb67c/src/d-collector/images/otel-loki-logs.png
--------------------------------------------------------------------------------
/src/d-collector/images/tmux-collector-demo.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/sgryphon/dotnet-distributed-tracing-examples/440df38a429288675d550c8d96e473d2c33eb67c/src/d-collector/images/tmux-collector-demo.png
--------------------------------------------------------------------------------
/src/d-collector/loki-config.yaml:
--------------------------------------------------------------------------------
1 | ---
2 | server:
3 | http_listen_port: 3100
4 | memberlist:
5 | join_members:
6 | - loki:7946
7 | schema_config:
8 | configs:
9 | - from: 2021-08-01
10 | store: boltdb-shipper
11 | object_store: s3
12 | schema: v11
13 | index:
14 | prefix: index_
15 | period: 24h
16 | common:
17 | path_prefix: /loki
18 | replication_factor: 1
19 | storage:
20 | s3:
21 | endpoint: loki-minio:9000
22 | insecure: true
23 | bucketnames: loki-data
24 | access_key_id: loki
25 | secret_access_key: supersecret
26 | s3forcepathstyle: true
27 | ring:
28 | kvstore:
29 | store: memberlist
30 | ruler:
31 | storage:
32 | s3:
33 | bucketnames: loki-ruler
--------------------------------------------------------------------------------
/src/d-collector/otel-collector-config.yaml:
--------------------------------------------------------------------------------
1 | receivers:
2 | otlp:
3 | protocols:
4 | grpc:
5 | http:
6 |
7 | processors:
8 | batch:
9 |
10 | exporters:
11 | azuremonitor:
12 | instrumentation_key: "${AZ_INSTRUMENTATION_KEY}"
13 | jaeger:
14 | endpoint: jaeger:14250
15 | tls:
16 | insecure: true
17 | logging:
18 | logLevel: info
19 | loki:
20 | endpoint: http://loki:3100/loki/api/v1/push
21 | format: json
22 | labels:
23 | resource:
24 | deployment.environment: "deployment_environment"
25 | host.name: "host_name"
26 | service.name: "service_name"
27 | service.namespace: "service_namespace"
28 | record:
29 | severity: "severity"
30 | tenant_id: tenant1
31 | tls:
32 | insecure: true
33 |
34 | service:
35 | pipelines:
36 | traces:
37 | receivers: [otlp]
38 | processors: [batch]
39 | exporters: [logging, jaeger, azuremonitor]
40 | logs:
41 | receivers: [otlp]
42 | processors: []
43 | exporters: [logging, loki, azuremonitor]
44 |
--------------------------------------------------------------------------------
/src/d-collector/remove-infrastructure.ps1:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env pwsh
2 |
3 | <# .SYNOPSIS
4 | Remove the Azure infrastructure. #>
5 | [CmdletBinding()]
6 | param (
7 | ## Deployment environment, e.g. Prod, Dev, QA, Stage, Test.
8 | [string]$Environment = 'Dev'
9 | )
10 |
11 | $ErrorActionPreference="Stop"
12 |
13 | $SubscriptionId = $(az account show --query id --output tsv)
14 | Write-Verbose "Removing from context subscription ID $SubscriptionId"
15 |
16 | $appName = 'tracedemo'
17 |
18 | $rgName = "rg-$appName-$Environment-001".ToLowerInvariant()
19 |
20 | az group delete --name $rgName
21 |
--------------------------------------------------------------------------------
/src/d-collector/start-collector-demo.sh:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 |
3 | version=$(dotnet gitversion /output json /showvariable InformationalVersion)
4 | az_instrumentation_key=$(az monitor app-insights component show -a appi-tracedemo-dev -g rg-tracedemo-dev-001 -o tsv --query instrumentationKey)
5 |
6 | tmux new-session -d 'ASPNETCORE_URLS="http://localhost:8002" npm run start --prefix Demo.WebApp/ClientApp'
7 | tmux split-window -h "dotnet run --project Demo.WebApp -p:InformationalVersion=$version -- --urls http://*:8002 --environment Development"
8 | tmux split-window -f "dotnet run --project Demo.Service -p:InformationalVersion=$version -- --urls https://*:44301 --environment Development"
9 | tmux split-window -h "dotnet run --project Demo.Worker -p:InformationalVersion=$version -- --environment Development"
10 | tmux split-window -fhp 67 "docker run -it --rm -e AZ_INSTRUMENTATION_KEY=$az_instrumentation_key --network demo_default -p 4317:4317 -v $PWD/otel-collector-config.yaml:/etc/otelcol-contrib/config.yaml otel/opentelemetry-collector-contrib:0.50.0"
11 |
12 | tmux attach-session -d
13 |
14 |
--------------------------------------------------------------------------------
/src/d-collector/start-complex-demo.sh:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 |
3 | version=$(dotnet gitversion /output json /showvariable InformationalVersion)
4 | tmux new-session -d 'ASPNETCORE_URLS="http://localhost:8002" npm run start --prefix Demo.WebApp/ClientApp'
5 | tmux split-window -h "dotnet run --project Demo.WebApp -p:InformationalVersion=$version -- --urls http://*:8002 --environment Development"
6 | tmux split-window -f "dotnet run --project Demo.Service -p:InformationalVersion=$version -- --urls https://*:44301 --environment Development"
7 | tmux split-window -h "dotnet run --project Demo.Worker -p:InformationalVersion=$version -- --environment Development"
8 | tmux attach-session -d
9 |
--------------------------------------------------------------------------------
/src/dotnet8/Demo.WebApi/Demo.WebApi.csproj:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | net8.0
5 | enable
6 | enable
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
--------------------------------------------------------------------------------
/src/dotnet8/Demo.WebApi/Demo.WebApi.http:
--------------------------------------------------------------------------------
1 | @Demo.WebApi_HostAddress = http://localhost:5054
2 |
3 | GET {{Demo.WebApi_HostAddress}}/weatherforecast/
4 | Accept: application/json
5 |
6 | ###
7 |
--------------------------------------------------------------------------------
/src/dotnet8/Demo.WebApi/appsettings.Development.json:
--------------------------------------------------------------------------------
1 | {
2 | "Logging": {
3 | "LogLevel": {
4 | "Default": "Information",
5 | "Microsoft.AspNetCore": "Warning"
6 | }
7 | }
8 | }
9 |
--------------------------------------------------------------------------------
/src/dotnet8/Demo.WebApi/appsettings.json:
--------------------------------------------------------------------------------
1 | {
2 | "Logging": {
3 | "LogLevel": {
4 | "Default": "Information",
5 | "Microsoft.AspNetCore": "Warning"
6 | },
7 | "Console": {
8 | "IncludeScopes": true
9 | }
10 | },
11 | "AllowedHosts": "*"
12 | }
13 |
--------------------------------------------------------------------------------
/src/dotnet8/demo-web-app/.eslintrc.json:
--------------------------------------------------------------------------------
1 | {
2 | "extends": "next/core-web-vitals"
3 | }
4 |
--------------------------------------------------------------------------------
/src/dotnet8/demo-web-app/.gitignore:
--------------------------------------------------------------------------------
1 | # See https://help.github.com/articles/ignoring-files/ for more about ignoring files.
2 |
3 | # dependencies
4 | /node_modules
5 | /.pnp
6 | .pnp.js
7 | .yarn/install-state.gz
8 |
9 | # testing
10 | /coverage
11 |
12 | # next.js
13 | /.next/
14 | /out/
15 |
16 | # production
17 | /build
18 |
19 | # misc
20 | .DS_Store
21 | *.pem
22 |
23 | # debug
24 | npm-debug.log*
25 | yarn-debug.log*
26 | yarn-error.log*
27 |
28 | # local env files
29 | .env*.local
30 |
31 | # vercel
32 | .vercel
33 |
34 | # typescript
35 | *.tsbuildinfo
36 | next-env.d.ts
37 |
--------------------------------------------------------------------------------
/src/dotnet8/demo-web-app/app/favicon.ico:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/sgryphon/dotnet-distributed-tracing-examples/440df38a429288675d550c8d96e473d2c33eb67c/src/dotnet8/demo-web-app/app/favicon.ico
--------------------------------------------------------------------------------
/src/dotnet8/demo-web-app/app/globals.css:
--------------------------------------------------------------------------------
1 | @tailwind base;
2 | @tailwind components;
3 | @tailwind utilities;
4 |
5 | :root {
6 | --foreground-rgb: 0, 0, 0;
7 | --background-start-rgb: 214, 219, 220;
8 | --background-end-rgb: 255, 255, 255;
9 | }
10 |
11 | @media (prefers-color-scheme: dark) {
12 | :root {
13 | --foreground-rgb: 255, 255, 255;
14 | --background-start-rgb: 0, 0, 0;
15 | --background-end-rgb: 0, 0, 0;
16 | }
17 | }
18 |
19 | body {
20 | color: rgb(var(--foreground-rgb));
21 | background: linear-gradient(
22 | to bottom,
23 | transparent,
24 | rgb(var(--background-end-rgb))
25 | )
26 | rgb(var(--background-start-rgb));
27 | }
28 |
29 | @layer utilities {
30 | .text-balance {
31 | text-wrap: balance;
32 | }
33 | }
34 |
--------------------------------------------------------------------------------
/src/dotnet8/demo-web-app/app/layout.tsx:
--------------------------------------------------------------------------------
1 | import type { Metadata } from "next";
2 | import { Inter } from "next/font/google";
3 | import "./globals.css";
4 |
5 | const inter = Inter({ subsets: ["latin"] });
6 |
7 | export const metadata: Metadata = {
8 | title: "Create Next App",
9 | description: "Generated by create next app",
10 | };
11 |
12 | export default function RootLayout({
13 | children,
14 | }: Readonly<{
15 | children: React.ReactNode;
16 | }>) {
17 | return (
18 |
19 | {children}
20 |
21 | );
22 | }
23 |
--------------------------------------------------------------------------------
/src/dotnet8/demo-web-app/next.config.mjs:
--------------------------------------------------------------------------------
1 | /** @type {import('next').NextConfig} */
2 | const nextConfig = {};
3 |
4 | export default nextConfig;
5 |
--------------------------------------------------------------------------------
/src/dotnet8/demo-web-app/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "demo-web-app",
3 | "version": "0.1.0",
4 | "private": true,
5 | "scripts": {
6 | "dev": "next dev",
7 | "build": "next build",
8 | "start": "next start",
9 | "lint": "next lint"
10 | },
11 | "dependencies": {
12 | "@opentelemetry/api": "^1.9.0",
13 | "@opentelemetry/context-zone": "^1.25.0",
14 | "@opentelemetry/instrumentation-fetch": "^0.52.0",
15 | "@opentelemetry/instrumentation-xml-http-request": "^0.52.0",
16 | "next": "14.2.4",
17 | "react": "^18",
18 | "react-dom": "^18"
19 | },
20 | "devDependencies": {
21 | "@types/node": "^20",
22 | "@types/react": "^18",
23 | "@types/react-dom": "^18",
24 | "eslint": "^8",
25 | "eslint-config-next": "14.2.4",
26 | "postcss": "^8",
27 | "tailwindcss": "^3.4.1",
28 | "typescript": "^5"
29 | }
30 | }
31 |
--------------------------------------------------------------------------------
/src/dotnet8/demo-web-app/postcss.config.mjs:
--------------------------------------------------------------------------------
1 | /** @type {import('postcss-load-config').Config} */
2 | const config = {
3 | plugins: {
4 | tailwindcss: {},
5 | },
6 | };
7 |
8 | export default config;
9 |
--------------------------------------------------------------------------------
/src/dotnet8/demo-web-app/public/vercel.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/src/dotnet8/demo-web-app/tailwind.config.ts:
--------------------------------------------------------------------------------
1 | import type { Config } from "tailwindcss";
2 |
3 | const config: Config = {
4 | content: [
5 | "./pages/**/*.{js,ts,jsx,tsx,mdx}",
6 | "./components/**/*.{js,ts,jsx,tsx,mdx}",
7 | "./app/**/*.{js,ts,jsx,tsx,mdx}",
8 | ],
9 | theme: {
10 | extend: {
11 | backgroundImage: {
12 | "gradient-radial": "radial-gradient(var(--tw-gradient-stops))",
13 | "gradient-conic":
14 | "conic-gradient(from 180deg at 50% 50%, var(--tw-gradient-stops))",
15 | },
16 | },
17 | },
18 | plugins: [],
19 | };
20 | export default config;
21 |
--------------------------------------------------------------------------------
/src/dotnet8/demo-web-app/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "compilerOptions": {
3 | "lib": ["dom", "dom.iterable", "esnext"],
4 | "allowJs": true,
5 | "skipLibCheck": true,
6 | "strict": true,
7 | "noEmit": true,
8 | "esModuleInterop": true,
9 | "module": "esnext",
10 | "moduleResolution": "bundler",
11 | "resolveJsonModule": true,
12 | "isolatedModules": true,
13 | "jsx": "preserve",
14 | "incremental": true,
15 | "plugins": [
16 | {
17 | "name": "next"
18 | }
19 | ],
20 | "paths": {
21 | "@/*": ["./*"]
22 | }
23 | },
24 | "include": ["next-env.d.ts", "**/*.ts", "**/*.tsx", ".next/types/**/*.ts"],
25 | "exclude": ["node_modules"]
26 | }
27 |
--------------------------------------------------------------------------------
/src/example-2024/Demo.WebApi/Demo.WebApi.http:
--------------------------------------------------------------------------------
1 | @Demo.WebApi_HostAddress = http://localhost:5295
2 |
3 | GET {{Demo.WebApi_HostAddress}}/weatherforecast/
4 | Accept: application/json
5 |
6 | ###
7 |
--------------------------------------------------------------------------------
/src/example-2024/Demo.WebApi/Extensions/MachineNameLogEnricher.cs:
--------------------------------------------------------------------------------
1 | using Microsoft.Extensions.Diagnostics.Enrichment;
2 | using OpenTelemetry.Resources;
3 |
4 | namespace Demo.WebApi.Extensions;
5 |
6 | public class MachineNameLogEnricher : IStaticLogEnricher
7 | {
8 | const string AttributeHostName = "host.name";
9 |
10 | public void Enrich(IEnrichmentTagCollector collector)
11 | {
12 | collector.Add(AttributeHostName, Environment.MachineName);
13 | }
14 | }
15 |
--------------------------------------------------------------------------------
/src/example-2024/Demo.WebApi/ServiceInformation.cs:
--------------------------------------------------------------------------------
1 | using System.Diagnostics;
2 | using System.Reflection;
3 |
4 | namespace Demo.WebApi;
5 |
6 | public static class ServiceInformation
7 | {
8 | static ServiceInformation()
9 | {
10 | var assembly = Assembly.GetExecutingAssembly();
11 | var assemblyName = assembly!.GetName();
12 | var versionAttribute = assembly
13 | .GetCustomAttributes(false)
14 | .OfType()
15 | .FirstOrDefault();
16 | InstanceId = Guid.NewGuid().ToString();
17 | ServiceName = assemblyName.Name!;
18 | ActivitySource = new ActivitySource(ServiceName);
19 | Version =
20 | versionAttribute?.InformationalVersion
21 | ?? assemblyName.Version?.ToString()
22 | ?? string.Empty;
23 | }
24 |
25 | public static ActivitySource ActivitySource { get; }
26 |
27 | public static string InstanceId { get; }
28 |
29 | public static string ServiceName { get; }
30 |
31 | public static string Version { get; }
32 | }
33 |
--------------------------------------------------------------------------------
/src/example-2024/Demo.WebApi/appsettings.Development.json:
--------------------------------------------------------------------------------
1 | {
2 | "OpenTelemetry": {
3 | "Debug": false,
4 | "Exporters": {
5 | "Otlp:Seq": {
6 | "Endpoint": "http://127.0.0.1:5341/ingest/otlp/v1/logs",
7 | "Protocol": "HttpProtobuf"
8 | },
9 | "Otlp:Jaeger": {
10 | "Endpoint": "http://127.0.0.1:4317",
11 | "Protocol": "Grpc"
12 | }
13 | },
14 | "Logs": {
15 | "Exporters": [
16 | "Otlp:Seq"
17 | ]
18 | },
19 | "OtlpDebug": false,
20 | "Traces": {
21 | "Exporters": [
22 | "Otlp"
23 | ]
24 | }
25 | }
26 | }
27 |
--------------------------------------------------------------------------------
/src/example-2024/Demo.WebApi/wwwroot/placeholder.txt:
--------------------------------------------------------------------------------
1 | For static web files
2 |
--------------------------------------------------------------------------------
/src/example-2024/container/Containerfile-nginx-otel:
--------------------------------------------------------------------------------
1 |
2 | FROM nginx:1.26.2 AS nginx
3 | RUN apt update ; apt install -y curl gnupg ca-certificates debian-archive-keyring
4 | RUN curl https://nginx.org/keys/nginx_signing.key | gpg --dearmor | tee /usr/share/keyrings/nginx-archive-keyring.gpg >/dev/null
5 | RUN echo "deb [signed-by=/usr/share/keyrings/nginx-archive-keyring.gpg] http://nginx.org/packages/debian bookworm nginx" | tee /etc/apt/sources.list.d/nginx.list
6 | RUN apt update
7 | RUN apt install -y nginx-module-otel
8 | RUN echo "load_module modules/ngx_otel_module.so;\n$(cat /etc/nginx/nginx.conf)" > /etc/nginx/nginx.conf
9 |
--------------------------------------------------------------------------------
/src/example-2024/container/nginx-app.conf:
--------------------------------------------------------------------------------
1 | map $remote_addr $for {
2 | ~^[0-9.]+$ "for=$remote_addr"; # IPv4 client address
3 | ~^[0-9A-Fa-f:.]+$ "for=\"[$remote_addr]\""; # IPv6 bracketed and quoted
4 | default "for=unknown"; # Unix socket
5 | }
6 | server {
7 | listen [::]:8180;
8 | listen 8180;
9 | proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
10 | proxy_set_header Forwarded "$for;proto=$scheme;";
11 | location /v1/ {
12 | proxy_pass http://otel-collector:4318/v1/;
13 | }
14 | location / {
15 | proxy_pass http://demo-app:8080/;
16 | }
17 | }
18 |
--------------------------------------------------------------------------------
/src/example-2024/container/nginx-otel-app.conf:
--------------------------------------------------------------------------------
1 | map $remote_addr $for {
2 | ~^[0-9.]+$ "for=$remote_addr"; # IPv4 client address
3 | ~^[0-9A-Fa-f:.]+$ "for=\"[$remote_addr]\""; # IPv6 bracketed and quoted
4 | default "for=unknown"; # Unix socket
5 | }
6 | server {
7 | listen [::]:8180;
8 | listen 8180;
9 | proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
10 | proxy_set_header Forwarded "$for;proto=$scheme;";
11 | location /v1/ {
12 | proxy_pass http://otel-collector:4318/v1/;
13 | }
14 | location / {
15 | otel_trace on;
16 | otel_trace_context propagate;
17 | proxy_pass http://demo-app:8080/;
18 | }
19 | }
20 | otel_service_name demo:nginx;
21 | otel_exporter {
22 | endpoint otel-collector:4317;
23 | }
--------------------------------------------------------------------------------
/src/example-2024/container/otel-collector-config.yaml:
--------------------------------------------------------------------------------
1 | receivers:
2 | otlp:
3 | protocols:
4 | grpc:
5 | endpoint: '[::]:4317'
6 | http:
7 | endpoint: '[::]:4318'
8 | exporters:
9 | debug:
10 | verbosity: detailed
11 | otlphttp:
12 | endpoint: http://seq:5341/ingest/otlp/
13 | otlp/jaeger:
14 | endpoint: jaeger:4317
15 | tls:
16 | insecure: true
17 | service:
18 | pipelines:
19 | traces:
20 | receivers: [otlp]
21 | exporters: [debug, otlp/jaeger]
22 | metrics:
23 | receivers: [otlp]
24 | exporters: [debug]
25 | logs:
26 | receivers: [otlp]
27 | exporters: [debug, otlphttp]
28 |
--------------------------------------------------------------------------------
/src/example-2024/demo-web-app/.env.development:
--------------------------------------------------------------------------------
1 | NEXT_PUBLIC_API_URL="https://localhost:44302/"
2 | NEXT_PUBLIC_ENVIRONMENT="LocalDev"
3 | NEXT_PUBLIC_PATH_BASE=""
4 | NEXT_PUBLIC_TRACE_OTLP_EXPORTER_URL=""
5 | NEXT_PUBLIC_TRACE_PROPAGATE_CORS_URLS="localhost:8002,localhost:44302"
6 | NEXT_PUBLIC_VERSION="0.0.1-next.dev"
7 |
--------------------------------------------------------------------------------
/src/example-2024/demo-web-app/.env.production:
--------------------------------------------------------------------------------
1 | NEXT_PUBLIC_API_URL="#{ClientConfig.ApiUrl}#"
2 | NEXT_PUBLIC_ENVIRONMENT="#{ClientConfig.Environment}#"
3 | NEXT_PUBLIC_PATH_BASE="#{ClientConfig.PathBase}#"
4 | NEXT_PUBLIC_TRACE_OTLP_EXPORTER_URL="#{ClientConfig.TraceOtlpExporterUrl}#"
5 | NEXT_PUBLIC_TRACE_PROPAGATE_CORS_URLS="#{ClientConfig.TracePropagateCorsUrls}#"
6 | NEXT_PUBLIC_VERSION="$BUILD_VERSION"
7 |
--------------------------------------------------------------------------------
/src/example-2024/demo-web-app/.eslintrc.json:
--------------------------------------------------------------------------------
1 | {
2 | "extends": "next/core-web-vitals"
3 | }
4 |
--------------------------------------------------------------------------------
/src/example-2024/demo-web-app/.gitignore:
--------------------------------------------------------------------------------
1 | # See https://help.github.com/articles/ignoring-files/ for more about ignoring files.
2 |
3 | # dependencies
4 | /node_modules
5 | /.pnp
6 | .pnp.js
7 | .yarn/install-state.gz
8 |
9 | # testing
10 | /coverage
11 |
12 | # next.js
13 | /.next/
14 | /out/
15 |
16 | # production
17 | /build
18 |
19 | # misc
20 | .DS_Store
21 | *.pem
22 |
23 | # debug
24 | npm-debug.log*
25 | yarn-debug.log*
26 | yarn-error.log*
27 |
28 | # local env files
29 | .env*.local
30 |
31 | # vercel
32 | .vercel
33 |
34 | # typescript
35 | *.tsbuildinfo
36 | next-env.d.ts
37 |
--------------------------------------------------------------------------------
/src/example-2024/demo-web-app/app/appConfig.ts:
--------------------------------------------------------------------------------
1 | 'use client'
2 |
3 | interface AppConfig {
4 | environment: string
5 | pathBase: string
6 | traceOtlpExporterUrl: string
7 | tracePropagateCorsUrls: string
8 | version: string
9 | }
10 |
11 | const windowAppConfig = typeof window !== 'undefined' ? (window as any).appConfig as AppConfig : undefined
12 |
13 | export const appConfig: AppConfig = windowAppConfig || {
14 | environment: '',
15 | pathBase: '',
16 | traceOtlpExporterUrl: '',
17 | tracePropagateCorsUrls: '',
18 | version: '',
19 | }
20 |
--------------------------------------------------------------------------------
/src/example-2024/demo-web-app/app/favicon.ico:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/sgryphon/dotnet-distributed-tracing-examples/440df38a429288675d550c8d96e473d2c33eb67c/src/example-2024/demo-web-app/app/favicon.ico
--------------------------------------------------------------------------------
/src/example-2024/demo-web-app/app/globals.css:
--------------------------------------------------------------------------------
1 | @tailwind base;
2 | @tailwind components;
3 | @tailwind utilities;
4 |
5 | :root {
6 | --foreground-rgb: 0, 0, 0;
7 | --background-start-rgb: 214, 219, 220;
8 | --background-end-rgb: 255, 255, 255;
9 | }
10 |
11 | @media (prefers-color-scheme: dark) {
12 | :root {
13 | --foreground-rgb: 255, 255, 255;
14 | --background-start-rgb: 0, 0, 0;
15 | --background-end-rgb: 0, 0, 0;
16 | }
17 | }
18 |
19 | body {
20 | color: rgb(var(--foreground-rgb));
21 | background: linear-gradient(
22 | to bottom,
23 | transparent,
24 | rgb(var(--background-end-rgb))
25 | )
26 | rgb(var(--background-start-rgb));
27 | }
28 |
29 | @layer utilities {
30 | .text-balance {
31 | text-wrap: balance;
32 | }
33 | }
34 |
--------------------------------------------------------------------------------
/src/example-2024/demo-web-app/next.config.mjs:
--------------------------------------------------------------------------------
1 | /** @type {import('next').NextConfig} */
2 | const nextConfig = {
3 | output: 'export'
4 | };
5 |
6 | export default nextConfig;
7 |
--------------------------------------------------------------------------------
/src/example-2024/demo-web-app/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "demo-web-app",
3 | "version": "0.1.0",
4 | "private": true,
5 | "scripts": {
6 | "dev": "next dev",
7 | "build": "next build",
8 | "start": "next start",
9 | "lint": "next lint"
10 | },
11 | "dependencies": {
12 | "@opentelemetry/context-zone": "^1.26.0",
13 | "@opentelemetry/exporter-trace-otlp-http": "^0.53.0",
14 | "@opentelemetry/instrumentation-fetch": "^0.53.0",
15 | "@opentelemetry/instrumentation-xml-http-request": "^0.53.0",
16 | "@opentelemetry/sdk-trace-web": "^1.26.0",
17 | "@vercel/otel": "^1.9.1",
18 | "next": "14.2.4",
19 | "react": "^18",
20 | "react-dom": "^18"
21 | },
22 | "devDependencies": {
23 | "@types/node": "^20",
24 | "@types/react": "^18",
25 | "@types/react-dom": "^18",
26 | "eslint": "^8",
27 | "eslint-config-next": "14.2.4",
28 | "postcss": "^8",
29 | "tailwindcss": "^3.4.1",
30 | "typescript": "^5"
31 | }
32 | }
33 |
--------------------------------------------------------------------------------
/src/example-2024/demo-web-app/postcss.config.mjs:
--------------------------------------------------------------------------------
1 | /** @type {import('postcss-load-config').Config} */
2 | const config = {
3 | plugins: {
4 | tailwindcss: {},
5 | },
6 | };
7 |
8 | export default config;
9 |
--------------------------------------------------------------------------------
/src/example-2024/demo-web-app/public/vercel.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/src/example-2024/demo-web-app/tailwind.config.ts:
--------------------------------------------------------------------------------
1 | import type { Config } from "tailwindcss";
2 |
3 | const config: Config = {
4 | content: [
5 | "./pages/**/*.{js,ts,jsx,tsx,mdx}",
6 | "./components/**/*.{js,ts,jsx,tsx,mdx}",
7 | "./app/**/*.{js,ts,jsx,tsx,mdx}",
8 | ],
9 | theme: {
10 | extend: {
11 | backgroundImage: {
12 | "gradient-radial": "radial-gradient(var(--tw-gradient-stops))",
13 | "gradient-conic":
14 | "conic-gradient(from 180deg at 50% 50%, var(--tw-gradient-stops))",
15 | },
16 | },
17 | },
18 | plugins: [],
19 | };
20 | export default config;
21 |
--------------------------------------------------------------------------------
/src/example-2024/demo-web-app/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "compilerOptions": {
3 | "lib": ["dom", "dom.iterable", "esnext"],
4 | "allowJs": true,
5 | "skipLibCheck": true,
6 | "strict": true,
7 | "noEmit": true,
8 | "esModuleInterop": true,
9 | "module": "esnext",
10 | "moduleResolution": "bundler",
11 | "resolveJsonModule": true,
12 | "isolatedModules": true,
13 | "jsx": "preserve",
14 | "incremental": true,
15 | "plugins": [
16 | {
17 | "name": "next"
18 | }
19 | ],
20 | "paths": {
21 | "@/*": ["./*"]
22 | }
23 | },
24 | "include": ["next-env.d.ts", "**/*.ts", "**/*.tsx", ".next/types/**/*.ts"],
25 | "exclude": ["node_modules"]
26 | }
27 |
--------------------------------------------------------------------------------
/src/example-2024/docs/containers-web-client-and-api.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/sgryphon/dotnet-distributed-tracing-examples/440df38a429288675d550c8d96e473d2c33eb67c/src/example-2024/docs/containers-web-client-and-api.png
--------------------------------------------------------------------------------
/src/example-2024/docs/dynamic-web-client-traces.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/sgryphon/dotnet-distributed-tracing-examples/440df38a429288675d550c8d96e473d2c33eb67c/src/example-2024/docs/dynamic-web-client-traces.png
--------------------------------------------------------------------------------
/src/example-2024/docs/jaeger-traces-web-client.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/sgryphon/dotnet-distributed-tracing-examples/440df38a429288675d550c8d96e473d2c33eb67c/src/example-2024/docs/jaeger-traces-web-client.png
--------------------------------------------------------------------------------
/src/example-2024/docs/seq-correlated-logs-markup.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/sgryphon/dotnet-distributed-tracing-examples/440df38a429288675d550c8d96e473d2c33eb67c/src/example-2024/docs/seq-correlated-logs-markup.png
--------------------------------------------------------------------------------
/src/example-2024/docs/seq-correlated-logs.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/sgryphon/dotnet-distributed-tracing-examples/440df38a429288675d550c8d96e473d2c33eb67c/src/example-2024/docs/seq-correlated-logs.png
--------------------------------------------------------------------------------
/src/example-2024/example-2024.sln:
--------------------------------------------------------------------------------
1 |
2 | Microsoft Visual Studio Solution File, Format Version 12.00
3 | # Visual Studio Version 17
4 | VisualStudioVersion = 17.0.31903.59
5 | MinimumVisualStudioVersion = 10.0.40219.1
6 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Demo.WebApi", "Demo.WebApi\Demo.WebApi.csproj", "{C5C1DB85-F46D-46CF-A81F-13397787BD59}"
7 | EndProject
8 | Global
9 | GlobalSection(SolutionConfigurationPlatforms) = preSolution
10 | Debug|Any CPU = Debug|Any CPU
11 | Release|Any CPU = Release|Any CPU
12 | EndGlobalSection
13 | GlobalSection(SolutionProperties) = preSolution
14 | HideSolutionNode = FALSE
15 | EndGlobalSection
16 | GlobalSection(ProjectConfigurationPlatforms) = postSolution
17 | {C5C1DB85-F46D-46CF-A81F-13397787BD59}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
18 | {C5C1DB85-F46D-46CF-A81F-13397787BD59}.Debug|Any CPU.Build.0 = Debug|Any CPU
19 | {C5C1DB85-F46D-46CF-A81F-13397787BD59}.Release|Any CPU.ActiveCfg = Release|Any CPU
20 | {C5C1DB85-F46D-46CF-A81F-13397787BD59}.Release|Any CPU.Build.0 = Release|Any CPU
21 | EndGlobalSection
22 | EndGlobal
23 |
--------------------------------------------------------------------------------
/src/example-2024/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "dependencies": {
3 | "@opentelemetry/context-zone": "^1.25.1",
4 | "@opentelemetry/instrumentation-fetch": "^0.52.1",
5 | "@opentelemetry/instrumentation-xml-http-request": "^0.52.1"
6 | }
7 | }
8 |
--------------------------------------------------------------------------------