Debugging Action Handlers

Debugging your application and fixing bugs can be a daunting task, but luckily there are several solutions to help you tackle the issue quickly and efficiently. From logging errors to using a debugger, there are multiple options available to help you identify and resolve issues.


Logging errors can be a useful way of tracking down problems as it can provide deeper insight into your application. In client applications, you can use the standard System.out.println() in Java or print() in Python to print to the console. However, for Action Handlers, you must use the logger provided in the context:

public ActionResult handleEvent(Action action, GrainContext context) {
  context.getLogger().info("Your message here");

You can view logs printed with the logger by running gx log or opening the file specified below:

  1. Cluster - /grainite/log/gxapps.log

  2. Single node docker container - ~/dx/gxapps.log

Counters and Gauges

Counter and gauge metrics are essential tools for developers when it comes to debugging applications, gathering statistics, and monitoring performance. They provide valuable insights, allowing developers to identify and address any potential issues or bottlenecks in their applications.

Counters and gauges are also useful for gathering and tracking data over time, such as total requests served, average response time, or peak usage. This data can be used to make informed decisions about the design and optimization of applications, as well as to detect and prevent potential problems.

The APIs also support attaching additional labels to metrics, enabling more detailed tracking.

public ActionResult handleEvent(Action action, GrainContext context) {
  context.counter("my_counter", CounterParam.of("source", actionSource)).inc();
  context.gauge("my_gauge", CounterParam.of("source", actionSource)).set(100);

It is important to bear in mind that counters and gauges are not persistent. In other words, when the server is restarted, the metrics are not retained. We recommend using Prometheus for long-term metrics monitoring with counters and gauges. For more information, please refer to the Monitoring page.


The debugger is currently only supported for Java action handlers.

Grainite's single node docker images expose port 6000 which is jetty's debug port. You can remotely attach to this using your IDE's debugger.

For VS Code, you can install the GX extension which makes it simple to attach to jetty's debug session.

Alternatively, you can add the following configuration to your launch.json to attach to the debug session:

    "version": "0.2.0",
    "configurations": [
            "type": "java",
            "name": "Debug Grainite",
            "request": "attach",
            "hostName": "localhost",
            "port": 6000

Last updated