<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:media="http://search.yahoo.com/mrss/"><channel><title>2025-04 on Funky Si's Test</title><link>https://blog-test.funkysi1701.com/2025/04/</link><description>Recent content in 2025-04 on Funky Si's Test</description><generator>Hugo -- gohugo.io</generator><language>en-gb</language><managingEditor>funkysi1701@gmail.com (Simon Foster)</managingEditor><webMaster>funkysi1701@gmail.com (Simon Foster)</webMaster><lastBuildDate>Mon, 21 Apr 2025 20:00:00 +0000</lastBuildDate><atom:link href="https://blog-test.funkysi1701.com/2025/04/index.xml" rel="self" type="application/rss+xml"/><item><title>New in .NET Aspire 9.2: diagrams</title><link>https://blog-test.funkysi1701.com/posts/2025/aspire-9.2/</link><author>funkysi1701@gmail.com (funkysi1701)</author><pubDate>Mon, 21 Apr 2025 20:00:00 +0000</pubDate><guid>https://blog-test.funkysi1701.com/posts/2025/aspire-9.2/</guid><category term="DotNet">DotNet</category><category term="Aspire">Aspire</category><category term="InfrastructureDiagrams">InfrastructureDiagrams</category><category term="VisualStudio">VisualStudio</category><category term="Docker">Docker</category><category term="Microservices">Microservices</category><category term="Grafana">Grafana</category><category term="Programming">Programming</category><media:content medium="image" type="image/png" url="https://blog-test.funkysi1701.com/images/work.PNG"/><description>&lt;p&gt;.NET Aspire 9.2 is here, bringing exciting new features to simplify infrastructure visualization. Whether you&amp;rsquo;re managing microservices or exploring Docker-based architectures, this release makes it easier than ever to create detailed infrastructure diagrams with minimal effort. Let’s dive into the highlights and see how you can use these tools to streamline your workflow.&lt;/p&gt;
&lt;p&gt;For details of what .NET Aspire is, check out my &lt;a href="https://blog-test.funkysi1701.com/posts/2024/aspire"&gt;post&lt;/a&gt;
from last year. For the official announcement see &lt;a href="https://aspire.dev/whats-new/aspire-13-1/" target="_blank" rel="noopener noreferrer"&gt;What&amp;rsquo;s new in .NET Aspire 9.2&lt;/a&gt;
&lt;/p&gt;
&lt;p&gt;My favourite feature from this release is the ability to quickly and easily spin up infrastructure diagrams like this:&lt;/p&gt;
&lt;p&gt;
&lt;img class="img-fluid" alt="Aspire Diagram" src="https://blog-test.funkysi1701.com/images/aspire-9.2.jpg" loading="lazy"
width="764" height="675"
/&gt;
&lt;/p&gt;
&lt;p&gt;&lt;em&gt;An example infrastructure diagram created using .NET Aspire 9.2.&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;I also created one last week for my blog about &lt;a href="https://blog-test.funkysi1701.com/posts/2025/opentelemetry-logs/"&gt;Grafana&lt;/a&gt;
:&lt;/p&gt;
&lt;p&gt;
&lt;img class="img-fluid" alt="Grafana Example" src="https://blog-test.funkysi1701.com/images/grafana-loki-arch.png" loading="lazy"
width="811" height="593"
/&gt;
&lt;/p&gt;
&lt;h2 id="so-what-code-is-needed-to-create-one-of-these-diagrams"&gt;So what code is needed to create one of these diagrams?&lt;a class="anchor ms-1" href="#so-what-code-is-needed-to-create-one-of-these-diagrams" aria-label="Permalink: So what code is needed to create one of these diagrams?"&gt;&lt;i class="fas fa-link" aria-hidden="true"&gt;&lt;/i&gt;&lt;/a&gt;&lt;/h2&gt;
&lt;ol&gt;
&lt;li&gt;Open Visual Studio and create a new project of type &amp;ldquo;.NET Aspire App Host&amp;rdquo;&lt;/li&gt;
&lt;li&gt;Edit the Program.cs and add docker containers for anything you want to display on the diagram&lt;/li&gt;
&lt;li&gt;The syntax for this is is shown in my Grafana example:&lt;/li&gt;
&lt;/ol&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-csharp" data-lang="csharp"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;var&lt;/span&gt; builder = DistributedApplication.CreateBuilder(args);
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;// Add a .NET application container&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;var&lt;/span&gt; dotnet = builder.AddContainer(&lt;span style="color:#e6db74"&gt;&amp;#34;dotnet-application&amp;#34;&lt;/span&gt;, &lt;span style="color:#e6db74"&gt;&amp;#34;anyimage&amp;#34;&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; .WithHttpEndpoint(port: &lt;span style="color:#ae81ff"&gt;80&lt;/span&gt;, targetPort: &lt;span style="color:#ae81ff"&gt;80&lt;/span&gt;); &lt;span style="color:#75715e"&gt;// Expose HTTP port 80&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;// Add a Loki container for log aggregation&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;var&lt;/span&gt; loki = builder.AddContainer(&lt;span style="color:#e6db74"&gt;&amp;#34;loki&amp;#34;&lt;/span&gt;, &lt;span style="color:#e6db74"&gt;&amp;#34;grafana/loki&amp;#34;&lt;/span&gt;, &lt;span style="color:#e6db74"&gt;&amp;#34;3.4.3&amp;#34;&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; .WithHttpEndpoint(port: &lt;span style="color:#ae81ff"&gt;3100&lt;/span&gt;, targetPort: &lt;span style="color:#ae81ff"&gt;3100&lt;/span&gt;); &lt;span style="color:#75715e"&gt;// Expose HTTP port 3100&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;// Add an Alloy container for telemetry processing&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;var&lt;/span&gt; alloy = builder.AddContainer(&lt;span style="color:#e6db74"&gt;&amp;#34;alloy&amp;#34;&lt;/span&gt;, &lt;span style="color:#e6db74"&gt;&amp;#34;grafana/alloy&amp;#34;&lt;/span&gt;, &lt;span style="color:#e6db74"&gt;&amp;#34;v1.8.1&amp;#34;&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; .WithHttpEndpoint(port: &lt;span style="color:#ae81ff"&gt;12345&lt;/span&gt;, targetPort: &lt;span style="color:#ae81ff"&gt;12345&lt;/span&gt;, name: &lt;span style="color:#e6db74"&gt;&amp;#34;UI&amp;#34;&lt;/span&gt;) &lt;span style="color:#75715e"&gt;// Expose UI&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; .WithHttpEndpoint(port: &lt;span style="color:#ae81ff"&gt;4317&lt;/span&gt;, targetPort: &lt;span style="color:#ae81ff"&gt;4317&lt;/span&gt;, name: &lt;span style="color:#e6db74"&gt;&amp;#34;gRPC&amp;#34;&lt;/span&gt;) &lt;span style="color:#75715e"&gt;// Expose gRPC&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; .WithHttpEndpoint(port: &lt;span style="color:#ae81ff"&gt;4318&lt;/span&gt;, targetPort: &lt;span style="color:#ae81ff"&gt;4318&lt;/span&gt;, &lt;span style="color:#e6db74"&gt;&amp;#34;http&amp;#34;&lt;/span&gt;); &lt;span style="color:#75715e"&gt;// Expose HTTP&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;// Add a Grafana container for visualization&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;var&lt;/span&gt; grafana = builder.AddContainer(&lt;span style="color:#e6db74"&gt;&amp;#34;grafana&amp;#34;&lt;/span&gt;, &lt;span style="color:#e6db74"&gt;&amp;#34;grafana/grafana&amp;#34;&lt;/span&gt;, &lt;span style="color:#e6db74"&gt;&amp;#34;11.6.0&amp;#34;&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; .WithHttpEndpoint(port: &lt;span style="color:#ae81ff"&gt;3000&lt;/span&gt;, targetPort: &lt;span style="color:#ae81ff"&gt;3000&lt;/span&gt;); &lt;span style="color:#75715e"&gt;// Expose HTTP port 3000&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;// Define relationships between containers&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;dotnet.WithReferenceRelationship(alloy); &lt;span style="color:#75715e"&gt;// Logs flow from .NET app to Alloy&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;alloy.WithReferenceRelationship(loki); &lt;span style="color:#75715e"&gt;// Logs flow from Alloy to Loki&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;loki.WithReferenceRelationship(grafana); &lt;span style="color:#75715e"&gt;// Logs flow from Loki to Grafana&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;builder.Build().Run();
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;The parameters for &lt;strong&gt;AddContainer()&lt;/strong&gt; are a name that gets displayed on the diagram, the docker image name, and the tag. The tag is optional and it will use latest if omitted. For my Grafana example, the first docker container I added is for any dotnet application. I can use any docker image for this, as all I want is a container labelled &amp;ldquo;dotnet-application&amp;rdquo;. The &lt;strong&gt;.WithHttpEndpoint&lt;/strong&gt; is for public ports to be displayed so you can see how communication is flowing between containers.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;.WithReferenceRelationship()&lt;/strong&gt; is how you define what calls what. So dotnet.WithReferenceRelationship(alloy) adds an arrow pointing from my dotnet application to alloy, suggesting that open telemetry logs flow from my application to alloy. You can also add calls in both directions by adding alloy.WithReferenceRelationship(dotnet) this will change the arrow to point in both directions.&lt;/p&gt;
&lt;p&gt;At my work we use a microservice architecture so I thought it might be fun to try and map out what calls what:&lt;/p&gt;
&lt;p&gt;
&lt;img class="img-fluid" alt="Work Architecture" src="https://blog-test.funkysi1701.com/images/work.PNG" loading="lazy"
width="2622" height="1869"
/&gt;
&lt;/p&gt;
&lt;p&gt;&lt;em&gt;A simplified view of a microservices architecture at work (service names anonymized).&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;I made a start mapping a few of our services, but this doesn&amp;rsquo;t cover everything and I have replaced the names of the services so no commerical secrets can be identified. I was surprised at how complex the system is.&lt;/p&gt;
&lt;h3 id="real-world-applications"&gt;Real-World Applications&lt;a class="anchor ms-1" href="#real-world-applications" aria-label="Permalink: Real-World Applications"&gt;&lt;i class="fas fa-link" aria-hidden="true"&gt;&lt;/i&gt;&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;The ability to generate infrastructure diagrams is invaluable for:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Microservices Architecture&lt;/strong&gt;: Visualize how services interact and identify bottlenecks.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Debugging&lt;/strong&gt;: Quickly understand communication flows to troubleshoot issues.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Documentation&lt;/strong&gt;: Create up-to-date diagrams for team collaboration and onboarding.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="conclusion"&gt;Conclusion&lt;a class="anchor ms-1" href="#conclusion" aria-label="Permalink: Conclusion"&gt;&lt;i class="fas fa-link" aria-hidden="true"&gt;&lt;/i&gt;&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;.NET Aspire 9.2 makes it easier than ever to create detailed infrastructure diagrams, saving time and improving collaboration. Whether you&amp;rsquo;re managing microservices or exploring Docker-based architectures, these tools can help you visualize and optimize your systems. Give it a try and see how it can enhance your workflow!&lt;/p&gt;
&lt;p&gt;Have you tried .NET Aspire 9.2? What features are you most excited about? Share your thoughts and experiences in the comments below!&lt;/p&gt;</description></item><item><title>OpenTelemetry logs via Grafana Loki</title><link>https://blog-test.funkysi1701.com/posts/2025/opentelemetry-logs/</link><author>funkysi1701@gmail.com (funkysi1701)</author><pubDate>Mon, 14 Apr 2025 20:00:00 +0000</pubDate><guid>https://blog-test.funkysi1701.com/posts/2025/opentelemetry-logs/</guid><category term="OpenTelemetry">OpenTelemetry</category><category term="Grafana">Grafana</category><category term="Loki">Loki</category><category term="Alloy">Alloy</category><category term="Logging">Logging</category><category term="Monitoring">Monitoring</category><category term="Docker">Docker</category><category term="DotNet">DotNet</category><category term="Tech">Tech</category><media:content medium="image" type="image/png" url="https://blog-test.funkysi1701.com/images/grafana-loki-arch.png"/><description>&lt;p&gt;Logs are a critical part of monitoring and debugging modern applications. By integrating OpenTelemetry logs with Grafana using Loki and Alloy, you can centralize your log data, making it easier to analyze and monitor your .NET applications. In this blog, I&amp;rsquo;ll walk you through the setup process and share how these tools work together to streamline log aggregation and visualization.&lt;/p&gt;
&lt;p&gt;I have blogged about &lt;a href="https://blog-test.funkysi1701.com/posts/2025/setting-up-grafana/"&gt;Grafana&lt;/a&gt;
before but until now I haven&amp;rsquo;t added logs to Grafana let&amp;rsquo;s have a look at how that works.&lt;/p&gt;
&lt;p&gt;My dotnet application makes use of OpenTelemetry. I have been sending this telemetry to an Aspire Dashboard running in Docker. This allows me to view logs, metrics and traces.&lt;/p&gt;
&lt;p&gt;Grafana has several tools that can help with logs.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Loki&lt;/strong&gt;: A log aggregation system designed to store and query logs from applications and infrastructure.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Alloy&lt;/strong&gt;: An OpenTelemetry collector that processes and forwards telemetry data.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;OpenTelemetry&lt;/strong&gt;: A set of APIs, libraries, and tools for collecting and exporting telemetry data like logs, metrics, and traces.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;I am using Alloy to collect OpenTelemetry from my application and send it to Loki, The logs in Loki can then be read by Grafana.&lt;/p&gt;
&lt;h2 id="setting-up-loki-and-alloy-with-docker-compose"&gt;Setting Up Loki and Alloy with Docker Compose&lt;a class="anchor ms-1" href="#setting-up-loki-and-alloy-with-docker-compose" aria-label="Permalink: Setting Up Loki and Alloy with Docker Compose"&gt;&lt;i class="fas fa-link" aria-hidden="true"&gt;&lt;/i&gt;&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;To start off let&amp;rsquo;s add Alloy and Loki to my docker compose file.&lt;/p&gt;
&lt;h3 id="docker-compose-configuration"&gt;Docker Compose Configuration&lt;a class="anchor ms-1" href="#docker-compose-configuration" aria-label="Permalink: Docker Compose Configuration"&gt;&lt;i class="fas fa-link" aria-hidden="true"&gt;&lt;/i&gt;&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;The &lt;code&gt;docker-compose.yml&lt;/code&gt; file defines the services for Loki and Alloy. Here&amp;rsquo;s what each section does:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Loki&lt;/strong&gt;: Runs the Loki container on port 3100 and uses a local configuration file.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Alloy&lt;/strong&gt;: Runs the Alloy container, exposing ports for receiving telemetry data and processing logs.&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-docker-compose.yml" data-lang="docker-compose.yml"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;# Docker Compose configuration for Loki and Alloy&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;command&lt;/span&gt;: -&lt;span style="color:#ae81ff"&gt;config.file=/etc/loki/local-config.yaml&lt;/span&gt; &lt;span style="color:#75715e"&gt;# Specifies the configuration file for Loki&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;alloy&lt;/span&gt;:
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;image&lt;/span&gt;: &lt;span style="color:#ae81ff"&gt;grafana/alloy:v1.8.1&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;container_name&lt;/span&gt;: &lt;span style="color:#ae81ff"&gt;monitoring_alloy&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;ports&lt;/span&gt;:
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; - &lt;span style="color:#ae81ff"&gt;12345&lt;/span&gt;:&lt;span style="color:#ae81ff"&gt;12345&lt;/span&gt; &lt;span style="color:#75715e"&gt;# HTTP server for Alloy&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; - &lt;span style="color:#ae81ff"&gt;4317&lt;/span&gt;:&lt;span style="color:#ae81ff"&gt;4317&lt;/span&gt; &lt;span style="color:#75715e"&gt;# gRPC endpoint for OpenTelemetry&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; - &lt;span style="color:#ae81ff"&gt;4319&lt;/span&gt;:&lt;span style="color:#ae81ff"&gt;4318&lt;/span&gt; &lt;span style="color:#75715e"&gt;# HTTP endpoint for OpenTelemetry&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;volumes&lt;/span&gt;:
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; - &lt;span style="color:#ae81ff"&gt;./config.alloy:/etc/alloy/config.alloy&lt;/span&gt; &lt;span style="color:#75715e"&gt;# Mount Alloy configuration&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;command&lt;/span&gt;: &lt;span style="color:#ae81ff"&gt;run --server.http.listen-addr=0.0.0.0:12345 --storage.path=/var/lib/alloy/data /etc/alloy/config.alloy&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;depends_on&lt;/span&gt;:
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; - &lt;span style="color:#ae81ff"&gt;loki&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Here is the config file for Alloy.&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code class="language-alloy.config" data-lang="alloy.config"&gt;otelcol.receiver.otlp &amp;#34;default&amp;#34; {
http {}
grpc {}
output {
logs = [otelcol.processor.batch.default.input]
}
}
otelcol.processor.batch &amp;#34;default&amp;#34; {
output {
logs = [
otelcol.exporter.otlphttp.loki.input,
]
}
}
otelcol.exporter.otlphttp &amp;#34;loki&amp;#34; {
client {
endpoint = &amp;#34;http://loki:3100/otlp&amp;#34;
}
}
&lt;/code&gt;&lt;/pre&gt;&lt;h3 id="how-the-components-work-together"&gt;How the Components Work Together&lt;a class="anchor ms-1" href="#how-the-components-work-together" aria-label="Permalink: How the Components Work Together"&gt;&lt;i class="fas fa-link" aria-hidden="true"&gt;&lt;/i&gt;&lt;/a&gt;&lt;/h3&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;Application Logs&lt;/strong&gt;: The .NET application generates logs and sends them to Alloy on port 4317.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Alloy Processing&lt;/strong&gt;: Alloy processes the logs and forwards them to Loki on port 3100.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Loki Storage&lt;/strong&gt;: Loki stores the logs, making them available for querying.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Grafana Visualization&lt;/strong&gt;: Grafana connects to Loki as a data source, allowing you to visualize and analyze the logs.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;
&lt;img class="img-fluid" alt="Architecture Diagram" src="https://blog-test.funkysi1701.com/images/grafana-loki-arch.png" loading="lazy"
width="811" height="593"
/&gt;
&lt;/p&gt;
&lt;h3 id="handling-aspire-dashboard-logs"&gt;Handling Aspire Dashboard Logs&lt;a class="anchor ms-1" href="#handling-aspire-dashboard-logs" aria-label="Permalink: Handling Aspire Dashboard Logs"&gt;&lt;i class="fas fa-link" aria-hidden="true"&gt;&lt;/i&gt;&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;By default, sending logs to Alloy and Loki means Aspire Dashboard will no longer receive them. To resolve this, you can configure the &lt;code&gt;AddOpenTelemetryExporters&lt;/code&gt; method in your .NET application to send logs to multiple destinations.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-Extensions.cs" data-lang="Extensions.cs"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;if&lt;/span&gt; (useOtlpExporter)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;{
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#75715e"&gt;// The following lines enable the OTLP exporter (requires the OpenTelemetry.Exporter.OpenTelemetryProtocol package)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; builder.Services.AddOpenTelemetry()
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; .WithLogging(logging =&amp;gt; logging.AddOtlpExporter(options =&amp;gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; options.Endpoint = &lt;span style="color:#66d9ef"&gt;new&lt;/span&gt; Uri(builder.Configuration[&lt;span style="color:#e6db74"&gt;&amp;#34;OTEL_EXPORTER_OTLP_ENDPOINT&amp;#34;&lt;/span&gt;]);
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; }))
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; .WithLogging(logging =&amp;gt; logging.AddOtlpExporter(options =&amp;gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; options.Endpoint = &lt;span style="color:#66d9ef"&gt;new&lt;/span&gt; Uri(builder.Configuration[&lt;span style="color:#e6db74"&gt;&amp;#34;GrafanaExporter&amp;#34;&lt;/span&gt;]);
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; }))
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; .WithMetrics(metrics =&amp;gt; metrics.AddOtlpExporter(options =&amp;gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; options.Endpoint = &lt;span style="color:#66d9ef"&gt;new&lt;/span&gt; Uri(builder.Configuration[&lt;span style="color:#e6db74"&gt;&amp;#34;OTEL_EXPORTER_OTLP_ENDPOINT&amp;#34;&lt;/span&gt;]);
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; }))
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; .WithTracing(tracing =&amp;gt; tracing.AddOtlpExporter(options =&amp;gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; options.Endpoint = &lt;span style="color:#66d9ef"&gt;new&lt;/span&gt; Uri(builder.Configuration[&lt;span style="color:#e6db74"&gt;&amp;#34;OTEL_EXPORTER_OTLP_ENDPOINT&amp;#34;&lt;/span&gt;]);
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; }));
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;If I update the AddOpenTelemetryExporters method in my Extensions.cs file in my .Net Aspire ServiceDefaults project, I can get my logs (or traces/metrics) to be sent to as many different places as I want. In my case I am sending to Allot and Aspire Dashboard.&lt;/p&gt;
&lt;h2 id="conclusion"&gt;Conclusion&lt;a class="anchor ms-1" href="#conclusion" aria-label="Permalink: Conclusion"&gt;&lt;i class="fas fa-link" aria-hidden="true"&gt;&lt;/i&gt;&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Integrating OpenTelemetry logs with Grafana using Loki and Alloy provides a powerful solution for centralized log aggregation and monitoring. This setup simplifies debugging and enhances visibility into your application&amp;rsquo;s behaviour. If you haven&amp;rsquo;t tried it yet, give it a go and let me know your thoughts in the comments!&lt;/p&gt;</description></item><item><title>Exploring ChatGPT image generation</title><link>https://blog-test.funkysi1701.com/posts/2025/fun-with-ai/</link><author>funkysi1701@gmail.com (funkysi1701)</author><pubDate>Mon, 07 Apr 2025 20:00:00 +0000</pubDate><guid>https://blog-test.funkysi1701.com/posts/2025/fun-with-ai/</guid><category term="AI">AI</category><category term="ChatGPT">ChatGPT</category><category term="ImageGeneration">ImageGeneration</category><category term="FunwithAI">FunwithAI</category><category term="Technology">Technology</category><category term="Creativity">Creativity</category><category term="MachineLearning">MachineLearning</category><media:content medium="image" type="image/png" url="https://blog-test.funkysi1701.com/images/ai-version-of-me.png"/><description>&lt;h2 id="fun-with-ai"&gt;Fun with AI&lt;a class="anchor ms-1" href="#fun-with-ai" aria-label="Permalink: Fun with AI"&gt;&lt;i class="fas fa-link" aria-hidden="true"&gt;&lt;/i&gt;&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;AI tools like &lt;a href="https://chatgpt.com/" target="_blank" rel="noopener noreferrer"&gt;ChatGPT&lt;/a&gt;
are evolving rapidly, and their creative capabilities are nothing short of amazing. Recently, I decided to test its image generation features with a fun and quirky prompt. The results? A personalized action figure concept that blew my mind! Let me walk you through the process and share the results.&lt;/p&gt;
&lt;p&gt;I used the following prompt:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-txt" data-lang="txt"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;Draw an action figure toy of the person in this photo.
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;The action figure should be full-figure and displayed in its original blister pack packaging.
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;On top of the box is the name of the toy &amp;#34;Software Developer&amp;#34; across a single line of text.
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;In the blister pack packaging, next to the figure, show the toy&amp;#39;s accessories,
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;including a Microsoft laptop,
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;cup of coffee,
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;the Visual Studio app,
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;GitHub app,
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;and the Azure app.
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;There should be a label on the corner of the box that says &amp;#34;Limited Edition&amp;#34;.
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;This figure should look like a premium toy and everything should be inside the plastic!
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;table border="0" cellpadding="0" cellspacing="0" &gt;
&lt;tr style="border-width:0px 0px 0px 0px"&gt;
&lt;td style="border-width:0px 0px 0px 0px"&gt;
and I supplied the following image:
&lt;/td&gt;
&lt;td style="border-width:0px 0px 0px 0px"&gt;
and this is the result:
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style="border-width:0px 0px 0px 0px"&gt;
&lt;td style="border-width:0px 0px 0px 0px"&gt;
&lt;img src="https://blog-test.funkysi1701.com/images/ndc-simon.jpg" alt="A picture of me as the source image" width="300" height="400" class="img-fluid" /&gt;
&lt;/td&gt;
&lt;td style="border-width:0px 0px 0px 0px"&gt;
&lt;img src="https://blog-test.funkysi1701.com/images/ai-version-of-me.png" alt="AI generated version of me" width="300" height="400" class="img-fluid" /&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;/table&gt;
&lt;p&gt;Pretty cool, right? Well I can&amp;rsquo;t take the credit for the prompt, It comes from &lt;a href="https://www.linkedin.com/posts/amyru_out-of-all-the-chatgpt-image-generation-capabilities-activity-7312549043610521601-BPqJ?utm_source=share&amp;amp;utm_medium=member_desktop&amp;amp;rcm=ACoAAAOBLj4B-Ls737kwBrHA1oRvkACb_CoRCQw2X0v1gk7q4r3w8Q9x5a6b0h4j2c1nqZz7g&amp;amp;lipi=urn%3Ali%3Apage%3Ad_flagship3_profile_view_base_post_primary%3B5JdYtG6mQeKx%2FfWl8V9jNQ%3D%3D" target="_blank" rel="noopener noreferrer"&gt;Amy Ru&lt;/a&gt;
on LinkedIn.&lt;/p&gt;
&lt;p&gt;Have you tried ChatGPT&amp;rsquo;s image generation features? What creative prompts have you used? Share your experiences in the comments below!&lt;/p&gt;</description></item></channel></rss>