The debug logs in SalesForce are great; they’re a rich mine of information about the execution of the various parts of the platform. However in some cases they can be too rich; trying to trace through code or inspect variables using System.debug() statements can be a bit of a pain to say the least. Then there’s the case in integration projects where you’re waiting for a third party to call into your app via a webservice and you want to monitor the incoming calls, are they occurring, are they having any issues, what kind of data are they passing? This is more of a monitoring use case and again the debug logs don’t really lend themselves to this kind of use. And let’s not even get started on trying to debug @future calls.
There are a couple of ways to fix these kinds of issues, one is a more configurable logging system and the other is a console or stdout that you can send random messages to. I initially set out to create the first, a more configurable logging framework, but during it’s development I found the need for the second and it’s that which I want to share with you in this post. The logging framework for those that are interested is a work in progress and should be following shortly.
I’m not going to dive into the architecture or design of the implementation right now, instead I’m going for a quick overview of how to use it followed by how to set it up so that you can give it a spin yourselves – then when I’m feeling more verbose I’ll explain why it is the way it is.
So, what have we got then? Well essentially it’s a system that will allow you to type:
Console.Write('A message from far far away');
in your APEX and then have the message appear in a “console” like this:
To achieve this you need the Console class and a few associated bits and pieces which can be found in this unmanaged package (prod/dev or sandbox). The static class Console has one method: Write. There are two overloads to Write. There’s Write(string message, boolean DoItNow) where message is obviously the message to log and DoItNow controls if it’s done synchronously or not. The second overload is Write(string message) this is always a synchronous call.
You will then need to log into the Console web application using your SalesForce credentials. No data is stored in this app; it’s purely a messaging bus. Then start making some Console.Write() calls from APEX, in fact go and just execute some anonymous code to prove it works.
And that’s it – it really is that easy to use.
There are, as ever, a few caveats;
- Firstly you need a HTML5 browser!
- It currently needs port 81 open – it’s the websocket connection that receives the broadcast messages… I hope to change this going forward.
- Be aware that the log has to insert a dummy record for the message to be sent, therefore if your code throws any unhandled exceptions the log messages won’t be sent.
- For this same reason be careful when using the synchronous method as each call will contribute to your DML limits.
- Finally when you’re using the code from within a method marked as @future you will always have to use the synchronous call.
The order in which the messages are delivered to the console cannot be guaranteed however the console should always display the messages in the correct time order; inserting late arriving messages in the right location.
If left dormant the console may disconnect itself, a Connection Closed message will appear in the window you will need to refresh the page to reconnect. I will work around this in the future but for now this is just the way it is.
This started out life as a bit of fun and a way to play with some different technologies; it’s only whilst doing it that I realised it could be of real use to others and that I should post it here. It’s for that reason that you need to remember it’s a little rough around the edges – for example because I have to create a ConsoleLog__c object for each message you send you will see the number of records for that object increasing over time; I need to write a schedulable task to clean them down – I haven’t… it’s things like that which give this project it’s roughness.
I will wax lyrical soon about the architecture of it and where I see the whole thing going. But in the meantime please have a play with it and let me know what you think. Could it be useful to you? What features would make it more beneficial? Or is it really just that bad that I should walk away from it all right now?