Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add support for the InnerException(s) logging into Microsoft.Extensions.Logging.Console json formatter. #40507

Closed
dmitriyse opened this issue Aug 7, 2020 · 13 comments
Labels
area-Extensions-Logging help wanted [up-for-grabs] Good issue for external contributors
Milestone

Comments

@dmitriyse
Copy link

Background and Motivation

In the .Net 5.0 JSON formatter was added to the console logger.
But it's current implementation lacks the output of the Exception.InnerException information which is 100% useful.
See #34742

Proposed API

Add Exception.ToString() into additional JSON field (FullExceptionDetail).
Optionally this feature can be controlled by some flag in the JsonConsoleFormatterOptions
For example: IncludeFullExceptionDetail

Alternative

Add recursion into Exception.InnerException formatting.

@dmitriyse dmitriyse added the api-suggestion Early API idea and discussion, it is NOT ready for implementation label Aug 7, 2020
@Dotnet-GitSync-Bot
Copy link
Collaborator

I couldn't figure out the best area label to add to this issue. If you have write-permissions please help me learn by adding exactly one area label.

@Dotnet-GitSync-Bot Dotnet-GitSync-Bot added the untriaged New issue has not been triaged by the area owner label Aug 7, 2020
@ghost
Copy link

ghost commented Aug 7, 2020

Tagging subscribers to this area: @maryamariyan
See info in area-owners.md if you want to be subscribed.

@KalleOlaviNiemitalo
Copy link

If you're changing JsonConsoleFormatter to format Exception.InnerException (recursively or as a string), then I think it should use AggregateException.InnerExceptions instead when available.

@WernerMairl
Copy link
Contributor

Note:
AggregatedException.ToString() is implemented [here].

(

)

behavior: merge and print out distinct (innerexception+InnerExceptions) by calling .ToString() for each of them!

@maryamariyan maryamariyan added this to the 6.0.0 milestone Aug 12, 2020
@maryamariyan maryamariyan removed the untriaged New issue has not been triaged by the area owner label Aug 12, 2020
@maryamariyan
Copy link
Member

maryamariyan commented Aug 12, 2020

@dmitriyse for this proposal it would help if you could please provide an example logging usage and expected/actual output for it.

@maryamariyan
Copy link
Member

maryamariyan commented Aug 12, 2020

Seems like the best way forward for issue is if we changed the output from

image

To rather just have

"Exception" : "X"

where X is the exception.ToString() content (similar to what is done in SystemdConsoleFormatter or SimpleConsoleFormatter) and when FormatterOptions.JsonWriterOptions.Indented is false for JsonConsoleFormatter to write the exception.ToString() content in single line changing new lines to a whitespace otherwise with \n.

@maryamariyan maryamariyan added help wanted [up-for-grabs] Good issue for external contributors and removed api-suggestion Early API idea and discussion, it is NOT ready for implementation labels Aug 12, 2020
@maryamariyan maryamariyan modified the milestones: 6.0.0, 5.0.0 Aug 12, 2020
@WernerMairl
Copy link
Contributor

WernerMairl commented Aug 13, 2020

@maryamariyan your proposal looks nice and simple but i think the main purpose of this logger was providing output with more (predictable) structured output details specially for other engines that are interpreting logs (ApplicationInsights et.al)

the more complex way (and not easy to implement) may be using the full capabilities to implement hierarchies inside Json:

   "Exception": {
        "Message": "Root",
        "Type": "System.Exception",
        "StackTrace": [
            "   at Microsoft.Extensions.Logging.Console.Test.JsonConsoleFormatterTests.EnsureStackTrace(Exception[] exceptions) in C:\\work\\dev\\runtime\\src\\libraries\\Microsoft.Extensions.Logging.Console\\tests\\JsonConsoleFormatterTests.cs:line 62"
        ],
        "HResult": -2146233088,
        "InnerExceptions" : [
            {
             "Message": "InnerException1",
             "Type": "System.Exception",
             "InnerExceptions" : []
            },
            {
                "Message": "InnerException2",
                "Type": "System.Exception",
                "InnerExceptions" : []
            }
        ]
    }

using "InnerExceptions" (plural) as array allows to implement BOTH core usecases:

  • Exception.InnerException
  • AggregatedException.InnerExceptions

btw.: Exception.Data should also be added on every level of exception...(#35922 )

@WernerMairl
Copy link
Contributor

i have created a first draft that implements InnerExceptions AND Exception.Data output:

WernerMairl@39235fa

The test is creating the following exception hierarchy:

            Exception innerException = new Exception("InnerException");
            innerException.Data.Add("innerKey1", "innerExceptionDictionaryEntry1");
            innerException.Data.Add("innerKey2", "innerExceptionDictionaryEntry2");

            Exception rootException = new Exception("Root",innerException);
            rootException.Data.Add("rootKey1", "rootExceptionDictionaryEntry1");
            rootException.Data.Add("rootKey2", "rootExceptionDictionaryEntry2");

and the reuslting json looks like:

{
    "Timestamp": null,
    "EventId": 0,
    "LogLevel": "Error",
    "Category": "category",
    "Message": "mystate",
    "Exception": {
        "Message": "Root",
        "Type": "System.Exception",
        "StackTrace": [
            "   at Microsoft.Extensions.Logging.Console.Test.JsonConsoleFormatterTests.EnsureStackTrace(Exception[] exceptions) in C:\\work\\dev\\runtime\\src\\libraries\\Microsoft.Extensions.Logging.Console\\tests\\JsonConsoleFormatterTests.cs:line 62"
        ],
        "HResult": -2146233088,
        "Data": {
            "rootKey1": "rootExceptionDictionaryEntry1",
            "rootKey2": "rootExceptionDictionaryEntry2"
        },
        "InnerExceptions": [
            {
                "Message": "InnerException",
                "Type": "System.Exception",
                "StackTrace": [
                    "   at Microsoft.Extensions.Logging.Console.Test.JsonConsoleFormatterTests.EnsureStackTrace(Exception[] exceptions) in C:\\work\\dev\\runtime\\src\\libraries\\Microsoft.Extensions.Logging.Console\\tests\\JsonConsoleFormatterTests.cs:line 62"
                ],
                "HResult": -2146233088,
                "Data": {
                    "innerKey1": "innerExceptionDictionaryEntry1",
                    "innerKey2": "innerExceptionDictionaryEntry2"
                }
            }
        ]
    }
}

if we agree to go this way, i can polish the code and prepare a PR

@maryamariyan
Copy link
Member

maryamariyan commented Aug 14, 2020

@WernerMairl the proposal looks good and is an improvement to what is already there.

A limitation to it though is that sometimes different exception types may embed extra content into exception.ToString that would otherwise get lost if we not use ToString instead.
maryamariyan/runtime@f214269

cc: @tarekgh @eerhardt @davidfowl

@tarekgh
Copy link
Member

tarekgh commented Aug 14, 2020

I am wondering, do we also handle the AggregateException?

@WernerMairl
Copy link
Contributor

Yes, AggregateException is covered by the implementation!

@WernerMairl
Copy link
Contributor

About exception.ToString() and extra content
Yes, I see the same concerns....

On the other side, we have a lot of problems/risks with Exception.ToString:
Each ToString() override does his own formatting for stacktrace, innerexceptions etc...
this does not looks like a consistent output
and now we are working on adding Exception.Data output on top of this....

Assuming that we cannot do significant changes on System.Exception.ToString() I'm proposing the following

a) logging extension should ignore Exception.ToString() because output content and format is not predictable.
b) logging extension should print out all the properties implemented in System.Exception (Message, Stacktrace, HResult, Data) in a consisten way
c) logging extension is traversing the innerException(s) hierarchy
c) logging extension has a few customization points where the user can
- enable Exception.Data output
- implement logging for custom exception properties

For the moment the Jsonformatter is following exactly the way proposed above, and maybe we should follow the same way for the other Console Loggers....

just my 2 cent...

WernerMairl added a commit to WernerMairl/runtime that referenced this issue Aug 14, 2020
Exception.InnerException and AggregateException.InnerExceptions are added to the Json output.

Fix dotnet#40507
@maryamariyan
Copy link
Member

maryamariyan commented Aug 14, 2020

a) logging extension should ignore Exception.ToString() because output content and format is not predictable.

It would be as unpredictable for SystemdConsoleFormatter and SimpleConsoleFormatter, and we would still be left inconsistent if we keep using exception.ToString() for the other two formatter.

c) logging extension has a few customization points where the user can

  • enable Exception.Data output
  • implement logging for custom exception properties

I think you're thinking in terms of using JsonConsoleFormatterOptions for further customization. If so, I believe there is no such customization yet for Exception.Data.

Your PR is a definite improvement to what is already in the code base, which is not using System.Exception.ToString(). I think for us to completely move away from exception.ToString, a little bit more design discussion needs to happen, perhaps coming up with some customization as you said.

My thought process is for 5.0 maybe we can switch back to using ToString instead. Perhaps we could move away from it in 6.0 timeframe when we have properly designed it and have clear ideas for the other two formatters as well.

That said if others provide approvals for the PR then we could go right ahead with your approach.

maryamariyan pushed a commit to maryamariyan/runtime that referenced this issue Aug 15, 2020
Exception.InnerException and AggregateException.InnerExceptions are added to the Json output.

Fix dotnet#40507
@ghost ghost locked as resolved and limited conversation to collaborators Dec 7, 2020
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
area-Extensions-Logging help wanted [up-for-grabs] Good issue for external contributors
Projects
None yet
Development

Successfully merging a pull request may close this issue.

7 participants