I'm missing something here as the numerous articles suggest it should work. The plan will be to create a custom logger implementation so I can store various values in a structured way.
However, for now the basics don't seem to work.
I'm trying to using scopes within ILogger
to set certain values e.g. transactionId
.
I'm using Azure Functions. In the startup I've added
public override void Configure(IFunctionsHostBuilder builder)
{
builder.Services.AddLogging();
Which works fine. In the function I'm trying this..
public class Test_Http
{
private readonly ILogger logger;
public Test_Http(ILogger<TestHttp> log)
{
this.logger = log;
}
[FunctionName("TestHttp")]
public async Task<IActionResult> Run(
[HttpTrigger(AuthorizationLevel.Anonymous, "get", "post", Route = null)] HttpRequest req,
ILogger log)
{
// This works fine, SomeId is replace.
// When using a custom logger I can see 2 values in the state.
logger.LogInformation("Message '{SomeId}'", "TheID");
using (logger.BeginScope(new Dictionary<string, object>
{
["SomeId"] = "SOME ID"
}))
{
// SomeId is not replaced as I would expect.
// State in a custom logger contains a single value.
logger.LogInformation("A log from within scope {SomeId}");
}
}
}
What am I missing?!
Thanks.
As far as I know, when using a dictionary type
inside logger.BeginScope
method, then the key-value pair
in the collection is added to the application insights telemetry as custom properties
(doc is here). It will not replace the {SomeId}
in your example.
If you want to replace it, you need to explicitly add a value in logger.LogInformation
method. For example:
Dictionary<string, object> a = new Dictionary<string, object>
{
//SomeId only adds as a custom property for telemetry data.
["SomeId"] = "SOME ID"
};
using (logger.BeginScope(a))
{
//you need to explicitly add a value to replace {SomeId}
logger.LogInformation("A log from within scope {SomeId}",a.Values.First());
}