Complex objects and dictionaries often contain far more data than a log entry really needs. Logging them directly can flood the log with noise or produce unreadable output.
A better approach is to extract only the most relevant values and create a compact summary:
var summary = dataMap.Select(x => new
{
Key = x.Key,
Count = x.Value.Count,
Status = x.Value.Status
});
logger.LogInformation("DataSummary={Summary}", summary);
This keeps the log focused on what matters: identifiers, counts, and simple status values. The result is easier to scan, easier to search, and more useful during debugging or monitoring.
When data is loaded from a list or a database, there is always a chance that nothing is found. If the code still tries to access properties on a missing object, the log statement itself can crash the application.
A simple null check makes the behavior explicit and keeps the log stable:
var item = items.FirstOrDefault(x => x.Id == id);
if (item == null)
{
logger.LogWarning("No item found for Id={Id}", id);
}
else
{
logger.LogInformation(
"Id={Id}, Type={Type}",
item.Id,
item.Type);
}
This version clearly separates the “not found” case from the normal case and produces meaningful log messages for both situations.
When a more compact style is preferred, null operators can be used instead:
logger.LogInformation(
"Id={Id}, Type={Type}",
item?.Id ?? "<unknown>",
item?.Type ?? "<unknown>");
Both approaches prevent runtime errors and ensure that logging remains reliable even when data is incomplete.
Once a custom dimension is extracted, you can filter and analyze it like any normal column.
Filter by Text Value
requests
| where tostring(customDimensions["Region"]) == "EU"
This keeps only rows where the Region custom dimension matches the value.
Filter by Numeric Value
If the value represents a number, convert it first:
requests
| extend DurationMs = todouble(customDimensions["DurationMs"])
| where DurationMs > 1000
Reuse Extracted Values
Using extend lets you reuse the value multiple times:
traces
| extend UserId = tostring(customDimensions["UserId"])
| where UserId != ""
| summarize Count = count() by UserId
Tips
extend when the value appears more than once in your query.These patterns help you build fast, readable queries that work reliably across dashboards and alerts.
Good logging is one of the most underrated tools in software development.
When done right, logs explain what your application is doing — even when things go wrong.
Logging is not just about writing messages to a file or console.
It’s about choosing what to log and how to log it safely and clearly.
Common pitfalls include:
Accessing properties on objects that may be null
Logging complex data structures without readable output
Producing logs that are too verbose or too vague
Creating unnecessary data just for logging purposes
This collection focuses on practical, everyday logging patterns:
Writing null-safe log statements
Turning collections into human-readable output
Logging only the information that matters
Choosing simple and efficient data structures for log data
Each example is intentionally small and generic, so the ideas can be reused in any .NET project.
Value
These patterns help you create logs that are stable, readable, and genuinely useful — especially when debugging production issues.
Selecting a custom dimension means extracting a value from the dynamic field and showing it as a normal column.
Basic Example
If your logs contain a custom dimension called UserId, use this query:
What this does:
You can select multiple custom dimensions in the same query:
Tips
tostring() unless you know the value is numeric or boolean.project to control exactly what columns appear in the output.This pattern is ideal for building reports or exporting data because it turns hidden metadata into visible columns that anyone can understand.
Testing HttpClient setup is a task many teams underestimate until something breaks in production. Modern .NET applications rely heavily on HttpClientFactory to add features such as retries, logging, authentication, or caching. These behaviors are implemented through message handlers that form a pipeline around every outgoing request.
If one handler is missing or misordered, the entire behavior changes—sometimes silently. A retry handler that never runs or a logging handler that is skipped can lead to confusing and costly issues. That’s why verifying the correct handlers are attached during application startup is essential.
However, developers quickly discover that it is not straightforward to test this. The built-in HttpClient does not expose its handler chain publicly, and typical unit-testing approaches cannot reveal what the factory actually constructs.
This Snipp explains the entire picture:
• the problem developers face when trying to validate HttpClient pipelines
• the cause, which is rooted in .NET’s internal design
• the resolution, with a practical reflection-based method to inspect handlers exactly as the runtime creates them
Following these Snipps, you will be able to reliably confirm that your handlers—such as retry and logging—are attached and working as intended.
If you've ever thought about trying Linux but felt overwhelmed by technical jargon or complex setup, Linux Mint might be exactly what you’re looking for. Designed for everyday users, it offers a clean and familiar interface, quick setup, and a focus on stability and ease of use.
Linux Mint is based on Ubuntu, one of the most widely used Linux distributions. This means you benefit from a huge software ecosystem, long-term support, and a strong community — without needing to dive deep into command-line tools unless you want to.
Linux Mint offers different desktop environments (such as Cinnamon, MATE, or Xfce), each balancing speed and visual appearance differently. You can choose what fits your hardware and personal preference best. The Software Manager also makes finding and installing applications as easy as in any modern app store.
Linux Mint is a practical starting point for anyone who wants a stable, user-friendly Linux experience — whether you're learning something new, switching operating systems entirely, or simply exploring alternatives.
We all like to believe we’d speak up against injustice — until the moment comes. The video presents a powerful real-life experiment: A professor unexpectedly orders a student, Alexis, to leave the lecture hall. No explanation. No misconduct. And no objections from her classmates.
Only after the door closes does the professor reveal the purpose of his shocking act. He asks the class why no one defended their peer. The uncomfortable truth: people stay silent when they aren’t personally affected.
The message hits hard — laws and justice aren’t self-sustaining. They rely on individuals willing to stand up for what’s right. If we ignore injustice simply because it doesn’t target us, we risk facing it ourselves with no one left to defend us.
This short demonstration challenges us to reflect on our own behavior:
Justice needs voices. Silence only protects the unjust.
Video: One of The Greatest Lectures in The World. - GROWTH™ - YouTube
Many talk about inflation — but the data tells a very different story. Switzerland, once again, offers one of the clearest signals of what is really happening in the global economy.
What’s happening in Switzerland
Why this matters
Switzerland is a global safe haven. In times of uncertainty, capital flows into the country, pushing up the Swiss franc and weighing on economic activity. This pattern often appears earlier in Switzerland than elsewhere, making it a reliable early indicator of broader global weakness.
Key insight
Central banks publicly warn about inflation, but in reality they are responding to economic slowdown. Rate cuts are not a sign of strength — they are a symptom of underlying weakness. Markets and consumers already see this: inflation expectations remain low, while concerns about jobs and income are rising.
Bottom line
The real risk is not inflation, but prolonged economic stagnation. To understand where the global economy is heading, it’s better to focus on data — and Switzerland provides one of the clearest views.
To test HttpClient handlers effectively, you need to inspect the internal handler chain that .NET builds at runtime. Since this chain is stored in a private field, reflection is the only reliable method to access it. The approach is safe, does not modify production code, and gives you full visibility into the pipeline.
The process begins by resolving your service from the DI container. If your service stores the HttpClient in a protected field, you can access it using reflection:
var field = typeof(MyClient)
.GetField("_httpClient", BindingFlags.Instance | BindingFlags.NonPublic);
var httpClient = (HttpClient)field.GetValue(serviceInstance);
Next, retrieve the private _handler field from HttpMessageInvoker:
var handlerField = typeof(HttpMessageInvoker)
.GetField("_handler", BindingFlags.Instance | BindingFlags.NonPublic);
var current = handlerField.GetValue(httpClient);
Finally, walk through the entire handler chain:
var handlers = new List<DelegatingHandler>();
while (current is DelegatingHandler delegating)
{
handlers.Add(delegating);
current = delegating.InnerHandler;
}
With this list, you can assert the presence of your custom handlers:
Assert.Contains(handlers, h => h is HttpRetryHandler);
Assert.Contains(handlers, h => h is HttpLogHandler);
This gives your test real confidence that the HttpClient pipeline is constructed correctly—exactly as it will run in production.