In the early days of my career, I had the epiphany that “Best Practices” really do not exist or apply to most scenarios. It should be all driven by logic and common sense in the end. What makes much more sense is to find the standard /common practice compares to the mythological unicorn of “best practices” and see if has value and benefit in a specific case.
Powershell and Logging
Let’s pick the example of log files, they are an invaluable and irreplaceable source of information not just for developers, but for operation folks too.
If logging is so essential, why most of these “common” practices are not applied?
I come to the conclusion that monitoring and logging features are a key responsibility of the designer and they should not just be implemented, but well documented as a basic requirement.
But logging or monitoring features are sometimes perceived as friction, instead, they are the fundamental tool for troubleshooting, performance optimisation and security auditing.
PowerShell is more than a scripting language, but if testing libraries with tools like Pester are very popular, unfortunately not many PowerShell users (even advanced one) seem to care about logging.
I will do my best in this article to change your perspective.
So next time our applications are lacking logging features why don’t we pick one or some of these options? On a case by case, you’ll find some something that will probably give you a brand new magnifier lens to analyse how your scripts behave at runtime.
EventViewer
In “Windows Land ” that’s for sure where every windows sysadmin on the planet will check the application, security and system log, so why don’t you do yourself a favor and start to use the event viewer for your application logs?
Write-EventLog is a one-liner that is so simple to use. Whenever you throw an error you can log it as Info/Warning/Error.
Let’s make some example, you’re writing an interactive script that requires authentication and somebody provides the wrong credentials, log a Warning in Security Log! If it happens 1000 times across different servers in one week is it something it worth investigating right? If the application requires a JSON file with setting and that dependency is not met at startup you can write an Error in the Application Log, so on and so forth.
Not many administrators leverage the functions of WEF (Windows Event Forwarder), if you have multiple servers or endpoints you can collect in central point all the desired information. It’s free and very powerful, you can also pair it with PowerBi to visualize the data, just to give you an interesting article to read from my favorites of 2017.
FileSystem
Creating a log file on the filesystem, avoid the system volume (C:), it might seem obvious but choose whenever possible the D: or E: drive (where in general it’s assigned for persistent storage and third-party applications) and you’ll not fill the OS disk.
Treat your scripts or applications strictly as any other third-party tool/app.
If your application logging it’s very verbose log rotation, retention and compression could be not optional but necessary.
In Linux or Mac OS, all variable data in general or log files are stored in /var/logs unless the application is chrooted on a folder like /opt folder.
Syslog servers will be the most common/obvious way to collect logs in this case.
The typical log file should contain:
- Timestamp/DateTime
- ErrorLevel (info,warning,error,critical)
- Description/Message
Plus other things to track like optional parameters or detail regarding the error that can help you to have a clear picture of what happened and why.
Set-Content: https://docs.microsoft.com/en-us/powershell/module/microsoft.powershell.management/set-content?view=powershell-6
Will create a file
Add-Content: https://docs.microsoft.com/en-us/powershell/module/microsoft.powershell.management/add-content?view=powershell-6
Will append to a log file
Database
To scale out our applications we tend to balance the load and distribuite it on different servers or containers, so having a central point for our logs could be necessary and store logs on databases could be a good (or terrible) idea.
Invoke-SQLCommand: https://docs.microsoft.com/en-us/powershell/module/sqlserver/invoke-sqlcmd?view=sqlserver-ps
If you think that SQL Server (even the express edition) might be overkilled for your needs I can suggest you choosing simpler alternatives like SQLite (have a look at this nice article by PSCookieMonster)
Databases are not the only option for centralising our logs, even if they are distributed we can use separate tools like Splunk or Logstash to leave the logs where they are and collect and analyse that information later.
Chat-Bots / Chat-Ops
I’m serious. If your team will have a dedicated channel for logs and the application log is succinct writing on Microsoft Team or Slack is a viable option and can work out pretty well.
If your application is a simple function that should generate an email everytime it throws an error, why don’t create an email and send it out with the log message included or attached? Obvious, right? Well, you won’t believe it, but I could pay some of my bills if I had one dollar for each time I’ve suggested to implement it.
Send-MailMessage: https://docs.microsoft.com/en-us/powershell/module/microsoft.powershell.utility/send-mailmessage?view=powershell-6
SMS
There are a lot of SMS providers that can send SMS from email or have a webhook to send an SMS like Twilio.
AUDIO
Let’s be frank, having fun is essential especially when things go wrong. So why don’t log an error with an AUDIO MESSAGE? Yes. Have a look at my article on Text-To-Speech. If you want to save the audio file you can set the output to a file instead of listening in real-time.
Conclusions
Once again, there is no ‘one-size-fits-all’ implementation for logging… but will make your application more visible and with all its strengths and weaknesses, indeed my favorite part is that it will show all the heavy lifting and how smart the logic implemented is.
2 Replies to “PowerShell: When and Where Writing Logs Matters”