General Logging In ObjectScript Classes (forDebugging)
I am trying to log certain program data in my ObjectScript REST class, to track down a bug I have. I am comparing two values at runtime, and one result does one thing, and another a different thing. Since this is a REST API class, I have no way of seeing in real time what the value is to debug. I cannot simply run the method in debug in Studio as it will not run properly being a REST class method, nor have the correct incoming header data to correctly replicate what is happening in the API at runtime when being hit by client apps. In other languages like C# or Java, when I would debug an API method like this, I would put in a line like
logger.Log("debug", {string containing any useful info for debugging the problem}...)
and then hit my services with the client app, run the scenario in question, and then check the logs and see what happened. I cannot figure out how to do this in ObjectScript. I've looked in the documentation for Logging, and all I've found so far are exception logging references, which is not what I'm after. Is there any way to do what I'm trying to do in ObjectScript classes?
One way to accomplish what you are describing is to use a temporary global: https://docs.intersystems.com/iris20231/csp/docbook/Doc.View.cls?KEY=GGB...
This allows you to store data in the IRISTEMP database that you can then retrieve like any other global. For example, if I were debugging a piece of code, I could write the following into the relevant Method:
Then later ZWRITE ^CacheTempNP to see what I have logged.
(Note: In the documentation, we recommend using a global mapping to set up your own naming convention for temporary globals instead of using the ^CacheTemp prefix. While I still recommend doing that if you plan to use temporary globals in non-testing code, just using ^CacheTemp instead is fine for debugging.)
@Jason Jones
Our main VS Code extension provides a UI for debugging a REST service. It will prompt for data to create a REST request, makes the request, and attaches the debugger to the IRIS process that handles the request so you can step through the code like any other method.
do LOG^%ETN
does an actual snapshot and you my examining the actual content at that point of time in SMP
I second this - using Do LOG^%ETN is very useful for grabbing the full stack and in memory values for later debugging ... this is where I usually start
I agree that LOG^%ETN, and ^%ETN as a process terminating trap routine, are the best way to log problems. But we should also mention that DO ^%ERN is the utility that will dump the data that LOG^%ETN places in the ^ERRORS multi-dim global. That dump includes state information, a complete call-stack dump, a list of all active local variables at each stack level, and in recent IRIS releases, it also includes a dump of all Class Objects with an oref active in memory. This is a lot of information for each ^ERRORS entry so you might not want to be over-enthusiastic with your calls on LOG^%ETN.
For quick and dirty logging I use:
kill ^Log at the beginning of the ClassMethod/Routine
Then use the following in your code to track what is going on:
set ^Log($increment(^Log))="Your message goes here. For example VariableX="_VariableX
Run your REST API and then take a look at ^Log.
You can either put lots of "set ^Log..." statements in, or just a few to narrow down where the issue is and just keep adding them till you get to the code in question. This might take a few iterations, but it generally works for me.