Skip to content

Missing Ilogger parameters #3078

Closed
Closed

Description

@ollie10

Package

Sentry

.NET Flavor

.NET Core

.NET Version

8.0.0

OS

Windows

SDK Version

8.0.0

Self-Hosted Sentry Version

No response

Steps to Reproduce

Hi everyone, I have a (maybe) dummy question. I'm using Sentry for Asp.NET using as logging methods the one shipped in the framework via Microsoft.Extensions.Logging

I'm logging errors and exceptions passing sometimes parameters like in this way:

_logger.LogError("ERROR - User Registration Failed Invalid Recaptcha", new { RegisterModel = registerModel, RecaptchaResponse = recaptchaResponse });

The question is: Where am I supposed to see these parameters in the Sentry interface? I mean, logging is working pretty fine, especially with the exceptions caught. I see everything I need; I just never see, in any case, those parameters.

Am I doing something wrong, or is this the expected behavior?

Expected Result

I would expect to see the parameters as a dictionary or a deserialized object in Sentry Event

Actual Result

Nothing about those parameters is shown on the event details

Activity

  1. moved this to Waiting for: Product Owner in GitHub Issues with 👀 2on Jan 23, 2024
  2. jamescrosswell commented on Jan 24, 2024

    @jamescrosswell
    Collaborator

    Hm, typically you log errors when you have an exception, in which case the exception can be passed as well and you get full stack trace details etc. on the Issues dashboard in Sentry):

    try
    {
    Dependency.Work("some work");
    }
    catch (Exception e)
    {
    // Handle an exception and log it:
    logger.LogError(e, "7 - An event that includes the scope key-value (A, B, C) and also the breadcrumbs: (2, 4, 6) and events (3, 5)");
    }

    If you wanted additional information to be sent to Sentry, one way to do it would be via the logger state:

    using (logger.BeginScope(new Dictionary<string, string>
    {
    {"A", "some value"},
    {"B", "more value"},
    }))
    {
    logger.LogWarning("4 - Breadcrumb that only exists inside this scope");
    logger.LogError("5 - An event that includes the scoped key-value (A, B) above and also the breadcrumbs: (2, 4) and event (3)");

    Under the hood that information gets passed through to Sentry like so:

    switch (property.Value)
    {
    case string stringTagValue:
    @event.SetTag(property.Key, stringTagValue);
    break;
    case Guid guidTagValue when guidTagValue != Guid.Empty:
    @event.SetTag(property.Key, guidTagValue.ToString());
    break;
    case Enum enumValue:
    @event.SetTag(property.Key, enumValue.ToString());
    break;
    default:
    {
    if (property.Value?.GetType().IsPrimitive == true)
    {
    @event.SetTag(property.Key, Convert.ToString(property.Value, CultureInfo.InvariantCulture)!);
    }
    break;
    }
    }

    So basically the State has to be an IEnumerable<KeyValuePair<string, object>> and the values can be string, Guid, Enum or some primitive (like int). If you want to pass a complex model like RegisterModel you'd need to first serialize this to JSON or something (so that it could be supplied as a string).

  3. moved this from Waiting for: Product Owner to No status in GitHub Issues with 👀 2on Jan 24, 2024
  4. ollie10 commented on Jan 24, 2024

    @ollie10
    Author

    Hello @jamescrosswell I see your point; that's said, the solution is not very user-friendly.
    Besides that, there are plenty of cases in which you want to log an error without an exception, like in those cases where you have logic errors. That's why the LogError of ILogger has a method that doesn't need an exception to log the data.

    Anyway, if there is no other way, I will give it a try with the scopes way. Many thanks for the help

  5. moved this to Waiting for: Product Owner in GitHub Issues with 👀 2on Jan 24, 2024
  6. moved this from Waiting for: Product Owner to No status in GitHub Issues with 👀 2on Jan 24, 2024
  7. jamescrosswell commented on Jan 24, 2024

    @jamescrosswell
    Collaborator

    Anyway, if there is no other way, I will give it a try with the scopes way. Many thanks for the help

    Hey @ollie10 ,

    I don't think there's any other way that Sentry could get data from the logger. In the code you provided above, you're making a call to this extension method:

            /// <summary>
            /// Formats and writes an error log message.
            /// </summary>
            /// <param name="logger">The <see cref="ILogger"/> to write to.</param>
            /// <param name="message">Format string of the log message in message template format. Example: <c>"User {User} logged in from {Address}"</c></param>
            /// <param name="args">An object array that contains zero or more objects to format.</param>
            /// <example>logger.LogError("Processing request from {Address}", address)</example>
            public static void LogError(this ILogger logger, string? message, params object?[] args)
            {
                logger.Log(LogLevel.Error, message, args);
            }

    So the logger doesn't do anything with registerModel and recaptchaResponse. The params args in that extension method would only ever be used to format the message (if you were using message templating).

    If you can think of an easier way to pass data from the logger to Sentry, we could look into it though. We're always looking for ways to make Sentry easier to use.

  8. ollie10 commented on Jan 24, 2024

    @ollie10
    Author

    @jamescrosswell you are totally and absolutely right, i don't know why I was thinking that it worked in another way, perhaps I was using another library.

    Surely the way you mentioned could be to pass everything as parameters and then stringify those as parameters in the message, but at that point I would have everything in a single-line string on Sentry I suppose. It could help, but for bigger objects, it will be tricky.

    I don't know if it could be helpful to adopt a solution like this one: https://github.com/serilog/serilog/wiki/Structured-Data or some similar thing.

    In the other case, I could also create a custom Exception using the Data Property: Exception.Data property to add there my custom objects as properties; those surely would be available in the Sentry Dashboard, right?

    I don't know if you want to give it some thought; if there could be an easier way, it could be a point of improvement

  9. 14 remaining items

  10. ollie10 commented on Feb 19, 2024

    @ollie10
    Author

    Hello @jamescrosswell any news on this topic? I keep receiving logs without precious information in them. Having a stack trace is useful, but if the data from a form, generates decisions in your code, and you cannot see that data, it's not useful in this case
    Many thanks

  11. jamescrosswell commented on Feb 19, 2024

    @jamescrosswell
    Collaborator

    Hello @jamescrosswell any news on this topic? I keep receiving logs without precious information in them. Having a stack trace is useful, but if the data from a form, generates decisions in your code, and you cannot see that data, it's not useful in this case

    Hey @ollie10, did you check the sample project illustrating this? Is that not the behaviour you're after?

  12. moved this from Waiting for: Product Owner to No status in GitHub Issues with 👀 2on Feb 19, 2024
  13. ollie10 commented on Feb 19, 2024

    @ollie10
    Author

    Hello @jamescrosswell yes but this works only for simple types. What if you have 40 parameters? Surely you can JsonSerializer.Serialize everything there, but you will have a whole chunk of parameters in the message. It's not very user-friendly.

    At least you can do the same as I said in the comment but the interface won't show you everything as I told you in that message

  14. moved this to Waiting for: Product Owner in GitHub Issues with 👀 2on Feb 19, 2024
  15. jamescrosswell commented on Feb 19, 2024

    @jamescrosswell
    Collaborator

    Surely you can JsonSerializer.Serialize everything there, but you will have a whole chunk of parameters in the message.

    I'm not sure if you saw the comment in the code for the sample:

    // example structured logging where keys (in the template above) go as tag keys and values below:

    So if you're using structured message templates with MEL, Sentry creates tags for each of the parameters passed to the message template.

    Is that not what you're after?

  16. moved this from Waiting for: Product Owner to No status in GitHub Issues with 👀 2on Feb 19, 2024
  17. locked and limited conversation to collaborators on Feb 29, 2024
  18. converted this issue into a discussion #3184 on Feb 29, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions