For the automated tasks that my team and I create, we have a logging mechanism that I’ve been working on improving that we use. Basically, it’s a pair of advanced functions, one to set up a log, and the other to add entries into the log, which is a CSV file with three fields: status (Information, Warning, Fail, Verbose, and Debug), time of entry, and the details of the event. The script writer puts this Add-Log call with details, and, if it’s not Informational, the status, and the function handles the rest.
The more I look at improving our processes, trying to implement things like Pester unit tests (which naturally means moving more towards splitting functionality up into testable functions), the more I realize that this is not a scalable solution. If nothing else, if I add the Add-Log commands in the functions and run them without importing the commands and setting up the logs, they’ll throw errors, which makes unit testing hard. Not having them there, on the other hand, makes logging progress that much harder, because then I have to perform gymnastics around stream manipulation and capturing that information on the back end to output to the log. Which then won’t have the accurate timestamp, and likely won’t line up the different streams correctly in the log.
So, a lot of issues with doing it that way.
What I was thinking of was figuring out a way to manipulate the streams directly and output each of the 5 main streams (Information, Warning, Error, Verbose, Debug) to something that will handle the log appropriately depending on the source stream. I could do this by using proxy functions to wrap and overload the 5 corresponding Write cmdlets, and make sure those proxied cmdlets were loaded in each of the scripts, then I could just use those Write cmdlets. That would work, but one thing that I would love for this to also do would be missed entirely by this: I would love for it to capture all stream outputs, not just those originating from the Write cmdlets I’ve overloaded.
I’ve thought about writing a wrapper script to call other scripts with that would bake in the stream redirection, but that feels messy and fraught with issues.
Does anyone have any thoughts on how best to proceed with this? I’m going to continue doing some digging, but so far I’ve not seen a good way to do what I’m looking at.