diff --git a/.github/workflows/release-udp-exporter.yml b/.github/workflows/release-udp-exporter.yml new file mode 100644 index 00000000..558e95b8 --- /dev/null +++ b/.github/workflows/release-udp-exporter.yml @@ -0,0 +1,85 @@ +name: Release ADOT OTLP UDP Exporter + +on: + workflow_dispatch: + inputs: + version: + description: 'Version number for deployment e.g. 0.1.0' + required: true + type: string + +jobs: + build-test-publish: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v3 + + - name: Set up .NET CLI + uses: actions/setup-dotnet@v2 + with: + dotnet-version: '8.0.x' + + - name: Download and run X-Ray Daemon + run: | + mkdir xray-daemon + cd xray-daemon + wget https://s3.us-west-2.amazonaws.com/aws-xray-assets.us-west-2/xray-daemon/aws-xray-daemon-linux-3.x.zip + unzip aws-xray-daemon-linux-3.x.zip + ./xray -o -n us-west-2 -f ./daemon-logs.log --log-level debug & + + - name: Create NuGet.Config with multiple sources + working-directory: sample-applications/udp-exporter-test-app + run: | + cat > NuGet.Config << EOF + + + + + + + + + EOF + + # Show the created config + cat NuGet.Config + + + - name: Build & Package the UDP exporter locally + working-directory: exporters/AWS.OpenTelemetry.Exporter.Otlp.Udp + run: | + dotnet pack -c Release + + - name: Run Sample App in Background + working-directory: sample-applications/udp-exporter-test-app + run: | + # Install the locally built version of the UDP exporter + dotnet add package AWS.OpenTelemetry.Exporter.Otlp.Udp + # Start validation app + dotnet run & + # Wait for validation app to initialize + sleep 5 + + - name: Call Sample App Endpoint + run: | + curl localhost:8080/test + + - name: Verify X-Ray daemon received traces + run: | + sleep 10 + echo "X-Ray daemon logs:" + cat xray-daemon/daemon-logs.log + + # Check if the daemon received and processed some data + if grep -q "sending.*batch" xray-daemon/daemon-logs.log; then + echo "✅ X-Ray daemon processed trace data (AWS upload errors are expected)" + exit 0 + elif grep -q "processor:.*segment" xray-daemon/daemon-logs.log; then + echo "✅ X-Ray daemon processed segment data (AWS upload errors are expected)" + exit 0 + else + echo "❌ No evidence of traces being received by X-Ray daemon" + exit 1 + fi + + # TODO: Steps to publish to NuGet diff --git a/sample-applications/udp-exporter-test-app/Controllers/AppController.cs b/sample-applications/udp-exporter-test-app/Controllers/AppController.cs new file mode 100644 index 00000000..dcb22376 --- /dev/null +++ b/sample-applications/udp-exporter-test-app/Controllers/AppController.cs @@ -0,0 +1,122 @@ +using System; +using Amazon.S3; +using Microsoft.AspNetCore.Mvc; +using System.Diagnostics; +using System.Net.Http; +using Microsoft.AspNetCore.Http.Extensions; +using OpenTelemetry; +using OpenTelemetry.Metrics; +using OpenTelemetry.Instrumentation; +using System.Diagnostics.Metrics; +using OpenTelemetry.Resources; +using OpenTelemetry.Trace; + +namespace dotnet_sample_app.Controllers +{ + [ApiController] + [Route("[controller]")] + public class AppController : ControllerBase + { + private readonly AmazonS3Client s3Client = new AmazonS3Client(); + private readonly HttpClient httpClient = new HttpClient(); + private static Random rand = new Random(DateTime.Now.Millisecond); + + public static readonly ActivitySource tracer = new( + "dotnet-sample-app"); + + public AppController() {} + + [HttpGet] + [Route("/outgoing-http-call")] + public string OutgoingHttp() + { + using var activity = tracer.StartActivity("outgoing-http-call"); + activity?.SetTag("language", "dotnet"); + activity?.SetTag("signal", "trace"); + + var res = httpClient.GetAsync("https://aws.amazon.com/").Result; + string statusCode = res.StatusCode.ToString(); + + // Request Based Metrics + Startup.metricEmitter.emitReturnTimeMetric(MimicLatency()); + int loadSize = MimicPayLoadSize(); + Startup.metricEmitter.apiRequestSentMetric(); + Startup.metricEmitter.updateTotalBytesSentMetric(loadSize); + + return GetTraceId(); + } + + [HttpGet] + [Route("/test")] + public string AWSSDKCall() + { + using var activity = tracer.StartActivity("test_parent_span"); + activity?.SetTag("language", "dotnet"); + activity?.SetTag("signal", "trace"); + activity?.SetTag("test.attribute", "test_value"); + + string traceId = activity?.TraceId.ToString() ?? "no-trace-available"; + + return traceId; + } + + [HttpGet] + [Route("/")] + public string Default() + { + return "Application started!"; + } + + [HttpGet] + [Route("/outgoing-sampleapp")] + public string OutgoingSampleApp() + { + using var activity = tracer.StartActivity("outgoing-sampleapp"); + activity?.SetTag("language", "dotnet"); + activity?.SetTag("signal", "trace"); + string statusCode = ""; + + if (Program.cfg.SampleAppPorts.Length == 0) { + var res = httpClient.GetAsync("https://aws.amazon.com/").Result; + statusCode = res.StatusCode.ToString(); + } + else { + foreach (string port in Program.cfg.SampleAppPorts) { + if (!String.IsNullOrEmpty(port)) { + string uri = string.Format("http://127.0.0.1:{0}/outgoing-sampleapp", port); + var res = httpClient.GetAsync(uri).Result; + statusCode = res.StatusCode.ToString(); + } + } + } + + // Request Based Metrics + Startup.metricEmitter.emitReturnTimeMetric(MimicLatency()); + int loadSize = MimicPayLoadSize(); + Startup.metricEmitter.apiRequestSentMetric(); + Startup.metricEmitter.updateTotalBytesSentMetric(loadSize); + + return GetTraceId(); + } + + private string GetTraceId() + { + var traceId = Activity.Current.TraceId.ToHexString(); + var version = "1"; + var epoch = traceId.Substring(0, 8); + var random = traceId.Substring(8); + return "{" + "\"traceId\"" + ": " + "\"" + version + "-" + epoch + "-" + random + "\"" + "}"; + } + + private static int MimicPayLoadSize() + { + return rand.Next(101); + } + + private static int MimicLatency() + { + return rand.Next(100,500); + } + } + +} diff --git a/sample-applications/udp-exporter-test-app/Controllers/Config.cs b/sample-applications/udp-exporter-test-app/Controllers/Config.cs new file mode 100644 index 00000000..0903c6c6 --- /dev/null +++ b/sample-applications/udp-exporter-test-app/Controllers/Config.cs @@ -0,0 +1,45 @@ +using System.IO; +using YamlDotNet.Serialization; +using YamlDotNet.Serialization.NamingConventions; + +namespace dotnet_sample_app.Controllers +{ + public class Config + { + public string Host; + public string Port; + public int TimeInterval; + public int RandomTimeAliveIncrementer; + public int RandomTotalHeapSizeUpperBound; + public int RandomThreadsActiveUpperBound; + public int RandomCpuUsageUpperBound; + public string[] SampleAppPorts; + + public Config() { + this.Host = "0.0.0.0"; + this.Port = "8080"; + this.TimeInterval = 1; + this.RandomTimeAliveIncrementer = 1; + this.RandomTotalHeapSizeUpperBound = 100; + this.RandomThreadsActiveUpperBound = 10; + this.RandomCpuUsageUpperBound = 100; + this.SampleAppPorts = new string[0]; + } + + public static Config ReadInFile(string file) { + var deserializer = new DeserializerBuilder() + .WithNamingConvention(PascalCaseNamingConvention.Instance) + .Build(); + + Config returnConfig = null; + try { + returnConfig = deserializer.Deserialize(File.ReadAllText(file)); + } + catch { + returnConfig = new Config(); + } + return returnConfig; + + } + } +} diff --git a/sample-applications/udp-exporter-test-app/Controllers/MetricEmitter.cs b/sample-applications/udp-exporter-test-app/Controllers/MetricEmitter.cs new file mode 100644 index 00000000..c8569754 --- /dev/null +++ b/sample-applications/udp-exporter-test-app/Controllers/MetricEmitter.cs @@ -0,0 +1,185 @@ +using System; +using System.Collections.Generic; +using System.Threading; +using System.Threading.Tasks; +using OpenTelemetry; +using System.Diagnostics.Metrics; +using OpenTelemetry.Metrics; +using OpenTelemetry.Instrumentation; + +namespace dotnet_sample_app.Controllers +{ + public class MetricEmitter + { + const string DIMENSION_API_NAME = "apiName"; + const string DIMENSION_STATUS_CODE = "statusCode"; + + static string API_COUNTER_METRIC = "total_api_requests"; + static string API_LATENCY_METRIC = "latency_time"; + static string API_SUM_METRIC = "total_bytes_sent"; + static string API_TOTAL_TIME_METRIC = "time_alive"; + static string API_TOTAL_HEAP_SIZE = "total_heap_size"; + static string API_TOTAL_THREAD_SIZE = "threads_active"; + static string API_CPU_USAGE = "cpu_usage"; + + public Histogram apiLatencyRecorder; + public Counter totalTimeSentObserver; + public ObservableUpDownCounter totalHeapSizeObserver; + public UpDownCounter totalThreadsObserver; + + private long apiRequestSent = 0; + private long totalBytesSent = 0; + private long totalHeapSize = 0; + private int cpuUsage = 0; + private int totalTime = 1; + private int totalThreads = 0; + private bool threadsBool = true; + private int returnTime = 100; + + private static Random rand = new Random(DateTime.Now.Millisecond); + + private KeyValuePair[] requestAttributes = new KeyValuePair[] { + new KeyValuePair("signal", "metric"), + new KeyValuePair("language", "dotnet"), + new KeyValuePair("metricType", "request")}; + + private KeyValuePair[] randomAttributes = new KeyValuePair[] { + new KeyValuePair("signal", "metric"), + new KeyValuePair("language", "dotnet"), + new KeyValuePair("metricType", "random")}; + + public MetricEmitter() + { + Meter meter = new Meter("adot", "1.0"); + + string latencyMetricName = API_LATENCY_METRIC; + string totalApiRequestSent = API_COUNTER_METRIC; + string totalApiBytesSentMetricName = API_SUM_METRIC; + string totaltimealiveMetricName = API_TOTAL_TIME_METRIC; + string totalHeapSizeMetricName = API_TOTAL_HEAP_SIZE; + string totalThreadsMetricName = API_TOTAL_THREAD_SIZE; + string cpuUsageMetricName = API_CPU_USAGE; + + string instanceId = Environment.GetEnvironmentVariable("INSTANCE_ID"); + if (instanceId != null && !instanceId.Trim().Equals("")) + { + latencyMetricName = API_LATENCY_METRIC + "_" + instanceId; + totalApiRequestSent = API_COUNTER_METRIC + "_" + instanceId; + totalApiBytesSentMetricName = API_SUM_METRIC + "_" + instanceId; + totaltimealiveMetricName = API_TOTAL_TIME_METRIC + "_" + instanceId; + totalHeapSizeMetricName = API_TOTAL_HEAP_SIZE + "_" + instanceId; + totalThreadsMetricName = API_TOTAL_THREAD_SIZE + "_" + instanceId; + cpuUsageMetricName = API_CPU_USAGE + "_" + instanceId; + + } + + + meter.CreateObservableCounter(totalApiRequestSent,() => { + return new Measurement(apiRequestSent, requestAttributes); + }, + "1", + "Increments by one every time a sampleapp endpoint is used"); + + meter.CreateObservableCounter(totalApiBytesSentMetricName, () => { + return new Measurement(totalBytesSent, requestAttributes); + }, + "By", + "Keeps a sum of the total amount of bytes sent while the application is alive"); + + meter.CreateObservableGauge(cpuUsageMetricName, () => { + return new Measurement(cpuUsage, randomAttributes); + }, + "1", + "Cpu usage percent"); + + meter.CreateObservableUpDownCounter(totalHeapSizeMetricName, () => { + return new Measurement(totalHeapSize, randomAttributes); + }, + "1", + "The current total heap size”"); + + apiLatencyRecorder = meter.CreateHistogram(latencyMetricName, + "ms", + "Measures latency time in buckets of 100 300 and 500"); + + totalThreadsObserver = meter.CreateUpDownCounter(totalThreadsMetricName, + "1", + "The total number of threads active”"); + + totalTimeSentObserver = meter.CreateCounter(totaltimealiveMetricName, + "ms", + "Measures the total time the application has been alive"); + + + totalTimeSentObserver.Add(totalTime, randomAttributes); + totalThreadsObserver.Add(totalThreads++, randomAttributes); + apiLatencyRecorder.Record(returnTime, requestAttributes); + } + + public void emitReturnTimeMetric(int returnTime) { + apiLatencyRecorder.Record( + returnTime, requestAttributes); + } + + public void apiRequestSentMetric() { + this.apiRequestSent += 1; + Console.WriteLine("apiBs: "+ this.apiRequestSent); + } + + public void updateTotalBytesSentMetric(int bytes) { + totalBytesSent += bytes; + Console.WriteLine("Total amount of bytes sent while the application is alive:"+ totalBytesSent); + } + + public void updateTotalHeapSizeMetric() { + this.totalHeapSize += rand.Next(0,1) * Program.cfg.RandomTotalHeapSizeUpperBound; + } + + public void updateTotalThreadSizeMetric() { + if (threadsBool) { + if (totalThreads < Program.cfg.RandomThreadsActiveUpperBound) { + totalThreadsObserver.Add(1, randomAttributes); + totalThreads += 1; + } + else { + threadsBool = false; + totalThreads -= 1; + } + } + else { + if (totalThreads > 0) { + totalThreadsObserver.Add(-1, randomAttributes); + totalThreads -= 1; + } + else { + threadsBool = true; + totalThreads += 1; + } + } + } + + public void updateCpuUsageMetric() { + this.cpuUsage = rand.Next(0,1) * Program.cfg.RandomCpuUsageUpperBound; + } + + public void updateTotalTimeMetric() { + totalTimeSentObserver.Add(Program.cfg.RandomTimeAliveIncrementer, randomAttributes); + } + + public async Task UpdateRandomMetrics(CancellationToken cancellationToken = default) { + void update() { + updateTotalTimeMetric(); + updateTotalHeapSizeMetric(); + updateTotalThreadSizeMetric(); + updateCpuUsageMetric(); + } + + while (true) { + var delayTask = Task.Delay(Program.cfg.TimeInterval * 1000, cancellationToken); + await Task.Run(() => update()); + await delayTask; + } + } + + } +} diff --git a/sample-applications/udp-exporter-test-app/Dockerfile b/sample-applications/udp-exporter-test-app/Dockerfile new file mode 100644 index 00000000..3627e713 --- /dev/null +++ b/sample-applications/udp-exporter-test-app/Dockerfile @@ -0,0 +1,13 @@ +FROM mcr.microsoft.com/dotnet/sdk:7.0 AS build-env +WORKDIR /app +COPY . ./ +RUN dotnet publish *.csproj -c Release -o out + +FROM mcr.microsoft.com/dotnet/aspnet:7.0 +WORKDIR /app +COPY . ./ +ENV AWS_REGION=us-west-2 +ENV OTEL_EXPORTER_OTLP_ENDPOINT=http://otel:4317 +COPY --from=build-env /app/out . +ENTRYPOINT ["dotnet", "dotnet-sample-app.dll"] + diff --git a/sample-applications/udp-exporter-test-app/Program.cs b/sample-applications/udp-exporter-test-app/Program.cs new file mode 100644 index 00000000..162f9ceb --- /dev/null +++ b/sample-applications/udp-exporter-test-app/Program.cs @@ -0,0 +1,26 @@ +using Microsoft.AspNetCore.Hosting; +using Microsoft.Extensions.Hosting; +using dotnet_sample_app.Controllers; +using System; + +namespace dotnet_sample_app +{ + public class Program + { + public static Config cfg = Config.ReadInFile("config.yaml"); + + public static void Main(string[] args) + { + CreateHostBuilder(args).Build().Run(); + } + + public static IHostBuilder CreateHostBuilder(string[] args) => + Host.CreateDefaultBuilder(args) + .ConfigureWebHostDefaults(webBuilder => + { + webBuilder.UseStartup(); + string listenAddress = "http://"+cfg.Host+":"+cfg.Port; + webBuilder.UseUrls(listenAddress); + }); + } +} diff --git a/sample-applications/udp-exporter-test-app/Properties/launchSettings.json b/sample-applications/udp-exporter-test-app/Properties/launchSettings.json new file mode 100644 index 00000000..119da20d --- /dev/null +++ b/sample-applications/udp-exporter-test-app/Properties/launchSettings.json @@ -0,0 +1,27 @@ +{ + "$schema": "http://json.schemastore.org/launchsettings.json", + "iisSettings": { + "windowsAuthentication": false, + "anonymousAuthentication": true, + "iisExpress": { + } + }, + "profiles": { + "IIS Express": { + "commandName": "IISExpress", + "launchBrowser": true, + "environmentVariables": { + "ASPNETCORE_ENVIRONMENT": "Development" + } + }, + "dotnet-sample-app": { + "commandName": "Project", + "launchBrowser": true, + "environmentVariables": { + "ASPNETCORE_ENVIRONMENT": "Development", + "OTEL_EXPORTER_OTLP_ENDPOINT": "http://localhost:4317", + "OTEL_EXPORTER_OTLP_INSECURE": "True" + } + } + } +} diff --git a/sample-applications/udp-exporter-test-app/README.md b/sample-applications/udp-exporter-test-app/README.md new file mode 100644 index 00000000..201a2c76 --- /dev/null +++ b/sample-applications/udp-exporter-test-app/README.md @@ -0,0 +1,50 @@ +## .NET Opentelemetry Sample App + +### Description + +This .NET Sample App will emit Traces and Metrics. There are two types of metrics emitted; +Request Based and Random Based. +Metrics are generated as soon as the application is ran or deployed without any additional effort. These are considered the random based metrics which track a mock of TimeAlive, TotalHeapSize, ThreadsActive and CpuUsage. The boundaries for these metrics are standard and can be found in the configuration file (YAML) called config.yaml. + +Additionally, you can generate Traces and request based Metrics by making requests to the following exposed endpoints: + +1. / + 1. Ensures the application is running +2. /outgoing-http-call + 1. Makes a HTTP request to aws.amazon.com (http://aws.amazon.com/) +3. /aws-sdk-call + 1. Makes a call to AWS S3 to list buckets for the account corresponding to the provided AWS credentials +4. /outgoing-sampleapp + 1. Makes a call to all other sample app ports configured at `:/outgoing-sampleapp`. If none available, makes a HTTP request to www.amazon.com (http://www.amazon.com/) + +[Sample App Spec](../SampleAppSpec.md) + +* Non-conformance: This SDK language is not missing any features or extensions required other than Resource Detectors +* Workarounds: No workarounds are being used in this application + +### Getting Started: + +#### Running the application (local) + +In order to run the application + +- Clone the repository +`git clone https://github.com/aws-observability/aws-otel-community.git` +- Switch into the directory +`cd sample-apps/dotnet-sample-app` +- Install dependencies +`dotnet build` +- Run the .NET server +`dotnet run` +Now the application is ran and the endpoints can be called at `0.0.0.0:8080/`. + +#### Docker + +In order to build the Docker image and run it in a container + +- Build the image +`docker build -t dotnet-sample-app .` +- Run the image in a container +`docker run -p 8080:8080 dotnet-sample-app` + + diff --git a/sample-applications/udp-exporter-test-app/Startup.cs b/sample-applications/udp-exporter-test-app/Startup.cs new file mode 100644 index 00000000..fbbd0b5c --- /dev/null +++ b/sample-applications/udp-exporter-test-app/Startup.cs @@ -0,0 +1,115 @@ +using Microsoft.AspNetCore.Builder; +using Microsoft.AspNetCore.Hosting; +using Microsoft.Extensions.Configuration; +using Microsoft.Extensions.DependencyInjection; +using Microsoft.Extensions.Hosting; +using OpenTelemetry; +using OpenTelemetry.Contrib.Extensions.AWSXRay.Trace; +using OpenTelemetry.Resources; +using OpenTelemetry.Trace; +using OpenTelemetry.Metrics; +using System; +using System.Diagnostics; +using dotnet_sample_app.Controllers; +using AWS.OpenTelemetry.Exporter.Otlp.Udp; + + +namespace dotnet_sample_app +{ + public class Startup + { + public static MetricEmitter metricEmitter = new MetricEmitter(); + + 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.AddControllers(); + + AppContext.SetSwitch("System.Net.Http.SocketsHttpHandler.Http2UnencryptedSupport", true); + + if(!String.IsNullOrEmpty(Environment.GetEnvironmentVariable("OTEL_RESOURCE_ATTRIBUTES"))) { + var resourceBuilder = ResourceBuilder.CreateDefault().AddTelemetrySdk(); + Sdk.CreateTracerProviderBuilder() + .AddSource("dotnet-sample-app") + .SetResourceBuilder(resourceBuilder) + .AddAWSInstrumentation() + .AddAspNetCoreInstrumentation() + .AddHttpClientInstrumentation() + .AddOtlpExporter(options => + { + options.Endpoint = new Uri(Environment.GetEnvironmentVariable("OTEL_EXPORTER_OTLP_ENDPOINT")); + }) + .AddOtlpUdpExporter(resourceBuilder.Build(), "localhost:2000") + .Build(); + } + else { + var resourceBuilder = ResourceBuilder.CreateDefault() + .AddService(serviceName: "dotnet-sample-app") // Added first + .AddTelemetrySdk(); + Sdk.CreateTracerProviderBuilder() + .AddSource("dotnet-sample-app") + .SetResourceBuilder(resourceBuilder) + .AddAWSInstrumentation() + .AddAspNetCoreInstrumentation() + .AddHttpClientInstrumentation() + .AddOtlpExporter(options => + { + options.Endpoint = new Uri(Environment.GetEnvironmentVariable("OTEL_EXPORTER_OTLP_ENDPOINT")); + }) + .AddOtlpUdpExporter(resourceBuilder.Build(), "localhost:2000") + .Build(); + } + + Sdk.CreateMeterProviderBuilder() + .AddMeter("adot") + .AddOtlpExporter() + .Build(); + + Sdk.SetDefaultTextMapPropagator(new AWSXRayPropagator()); + + + } + + // 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.UseRouting(); + + app.UseAuthorization(); + + app.UseEndpoints(endpoints => + { + endpoints.MapControllers(); + }); + + metricEmitter.UpdateRandomMetrics(); + } + } + + public static class TracerProviderBuilderExtensions + { + public static TracerProviderBuilder AddOtlpUdpExporter( + this TracerProviderBuilder builder, + Resource resource, + string endpoint) + { + return builder.AddProcessor( + new BatchActivityExportProcessor( + new OtlpUdpExporter(resource, endpoint) + ) + ); + } + } +} \ No newline at end of file diff --git a/sample-applications/udp-exporter-test-app/appsettings.Development.json b/sample-applications/udp-exporter-test-app/appsettings.Development.json new file mode 100644 index 00000000..8983e0fc --- /dev/null +++ b/sample-applications/udp-exporter-test-app/appsettings.Development.json @@ -0,0 +1,9 @@ +{ + "Logging": { + "LogLevel": { + "Default": "Information", + "Microsoft": "Warning", + "Microsoft.Hosting.Lifetime": "Information" + } + } +} diff --git a/sample-applications/udp-exporter-test-app/appsettings.json b/sample-applications/udp-exporter-test-app/appsettings.json new file mode 100644 index 00000000..d9d9a9bf --- /dev/null +++ b/sample-applications/udp-exporter-test-app/appsettings.json @@ -0,0 +1,10 @@ +{ + "Logging": { + "LogLevel": { + "Default": "Information", + "Microsoft": "Warning", + "Microsoft.Hosting.Lifetime": "Information" + } + }, + "AllowedHosts": "*" +} diff --git a/sample-applications/udp-exporter-test-app/collector-config-local.yml b/sample-applications/udp-exporter-test-app/collector-config-local.yml new file mode 100644 index 00000000..0dbbeae0 --- /dev/null +++ b/sample-applications/udp-exporter-test-app/collector-config-local.yml @@ -0,0 +1,28 @@ +receivers: + otlp: + protocols: + grpc: + endpoint: 0.0.0.0:4317 + +exporters: + debug: + verbosity: detailed + awsxray: + region: us-west-2 + awsemf: + region: us-west-2 + +service: + pipelines: + traces: + receivers: + - otlp + exporters: + - debug + - awsxray + metrics: + receivers: + - otlp + exporters: + - debug + - awsemf diff --git a/sample-applications/udp-exporter-test-app/config.yaml b/sample-applications/udp-exporter-test-app/config.yaml new file mode 100644 index 00000000..674baf1a --- /dev/null +++ b/sample-applications/udp-exporter-test-app/config.yaml @@ -0,0 +1,9 @@ +--- +Host: "0.0.0.0" # Host - String Address +Port: "8080" # Port - String Port +TimeInterval: 1 # Interval - Time in seconds to generate new metrics +RandomTimeAliveIncrementer: 1 # Metric - Amount to incremement metric by every TimeInterval +RandomTotalHeapSizeUpperBound: 100 # Metric - UpperBound for TotalHeapSize for random metric value every TimeInterval +RandomThreadsActiveUpperBound: 10 # Metric - UpperBound for ThreadsActive for random metric value every TimeInterval +RandomCpuUsageUpperBound: 100 # Metric - UppperBound for CpuUsage for random metric value every TimeInterval +SampleAppPorts: [] # Sampleapp ports to make calls to diff --git a/sample-applications/udp-exporter-test-app/docker-compose.yml b/sample-applications/udp-exporter-test-app/docker-compose.yml new file mode 100644 index 00000000..e566dbd3 --- /dev/null +++ b/sample-applications/udp-exporter-test-app/docker-compose.yml @@ -0,0 +1,28 @@ +version: "3.7" +services: + otel: + image: amazon/aws-otel-collector:latest + command: --config /config/collector-config-local.yml + volumes: + - ~/.aws:/home/aoc/.aws:ro + - .:/config + environment: + - AWS_REGION=us-west-2 + ports: + - '4317:4317' + + app: + build: + context: . + dockerfile: Dockerfile + environment: + - AWS_REGION=us-west-2 + - INSTANCE_ID + - LISTEN_ADDRESS=0.0.0.0:8080 + - OTEL_RESOURCE_ATTRIBUTES=service.name=adot-integ-test + - OTEL_EXPORTER_OTLP_ENDPOINT=http://otel:4317 + - ASPNETCORE_URLS=http://+:8080 + ports: + - '8080:8080' + volumes: + - ~/.aws:/root/.aws:ro diff --git a/sample-applications/udp-exporter-test-app/dotnet-sample-app.csproj b/sample-applications/udp-exporter-test-app/dotnet-sample-app.csproj new file mode 100644 index 00000000..4101fa30 --- /dev/null +++ b/sample-applications/udp-exporter-test-app/dotnet-sample-app.csproj @@ -0,0 +1,20 @@ + + + net8.0 + dotnet_sample_app + + + + + + + + + + + + + + + +