BTW if you are wondering if optional parameters can be used in combination with params, I made a quick test:
private static void LogInformation(string category, string caption, string description = null, params object[] args) { Console.WriteLine("{0} | {1} | Description:{2} | Params:{3}", category,caption, description, string.Join(", ", args)); } static void Main() { LogInformation("MyCategory", "MyCaption", null, "param1", "param2", "param3"); LogInformation("MyCategory", "MyCaption", null, 10, 25, 50); LogInformation("MyCategory", "MyCaption", "MyDescription"); LogInformation("MyCategory", "MyCaption"); Console.ReadLine(); }
Outputs this:
MyCategory | MyCaption | Description: | Params:param1, param2, param3 MyCategory | MyCaption | Description: | Params:10, 25, 50 MyCategory | MyCaption | Description:MyDescription | Params: MyCategory | MyCaption | Description: | Params:
That's an entirely valid idea and something we certainly can implement for Loupe 5, now the question is if we can do it in the main Agent without changing the .NET framework we are targeting. (2.0)
Right this is a 4.0 feature. Maybe a new minimal method signature: Log.XX(string category, string caption)?
Philosophically we are a bit cautious about this because we really want people to differentiate caption and description. The API is designed to put some subtle pressure on a developer to define a category, caption, and description and not just output a lame "Code was here" kind of message. In particular we treat caption and description quite differently in the back end. If you leave off a description we will actually parse the caption and look for a line break to then break it into a caption & description. I'll admit there are some places where just a caption is fine - typically down in verbose messages that are really low level items. So it's a balancing act. Given that I think we'd be more inclined to use an optional parameter than to create another overload.
Another reason we have caution about overloads is we actually get complaints (believe it or not) that we have too many overloads for the log messages from some developers. So, it's all about trying to balance things out.
Here's the fun bit: We're going to introduce a substantially new logging API in 5.0 to run side-by-side with the existing API. This will heavily leverage extension methods so you can easily create your own first-class logging overloads. That will let advanced users or users with special goals create optimized methods and let us continue to hunt for the best middle ground.
I would point out a caution about using interpolated strings for log messages - You're bypassing our customized string.Format. Why does this matter?
1. Our string.Format will never throw an exception if things aren't quite lined up, something's null that shouldn't be, the ToString fails for an item, etc. If there's a problem we still output a reasonable log message and note the problem in the bottom of the log message so it can be resolved. This is something of a "best of both worlds" safest strategy.
2. In some cases (but not all) we look for exception objects being passed and will also store them in the Exception area of our log message for maximum fidelity. To be fair, this isn't done in any of the Log.<Severity> methods.
I will be honest, in interpolated strings, I mostly abuse nameof. I didn’t know about Loupe’s custom safe string.Format. I will keep this in mind when the captions are a little more complex.
The future logging API extendable with extension methods sounds just perfect. Since you’ve mentioned Loupe 5.0 twice in this thread, I have to ask… when can we try it? :)
So, the big kickoff is just over a week away with the dev team - I fly out to the UK on the 4th to start meeting with the UI team. We've already made big progress on the agent rework but it's hugely in flight. We're currently doing clean up in prep for moving it to GitHub so we can evolve it in the open there with the participation of everyone. I'm hoping that shift happens in July; we have to complete a step to prove we have the right to OSS every line of code in the Agent and then get it to a point where "it compiles and the happy path runs".
We haven't internally decided how public beta to be with the 5.0 changes for the server but the Agent will be in the open, and we will probably ship it and a copy of Loupe Desktop that works with it earlier so folks can really work with the new data structures before they get locked in.
Alex Miller
The majority of my Log.XXX calls are very simple one-liners: Category, Caption and null for description. With interpolated strings, I barely use parameters and format my strings directly like this:
I think the code would be more concise if we could avoid that extra null value for description. Super easy, you would only have to to paste "=null" in ~100 overloads ;)
Thanks!