Skip to main content
Redhat Developers  Logo
  • Products

    Platforms

    • Red Hat Enterprise Linux
      Red Hat Enterprise Linux Icon
    • Red Hat AI
      Red Hat AI
    • Red Hat OpenShift
      Openshift icon
    • Red Hat Ansible Automation Platform
      Ansible icon
    • View All Red Hat Products

    Featured

    • Red Hat build of OpenJDK
    • Red Hat Developer Hub
    • Red Hat JBoss Enterprise Application Platform
    • Red Hat OpenShift Dev Spaces
    • Red Hat OpenShift Local
    • Red Hat Developer Sandbox

      Try Red Hat products and technologies without setup or configuration fees for 30 days with this shared Openshift and Kubernetes cluster.
    • Try at no cost
  • Technologies

    Featured

    • AI/ML
      AI/ML Icon
    • Linux
      Linux Icon
    • Kubernetes
      Cloud icon
    • Automation
      Automation Icon showing arrows moving in a circle around a gear
    • View All Technologies
    • Programming Languages & Frameworks

      • Java
      • Python
      • JavaScript
    • System Design & Architecture

      • Red Hat architecture and design patterns
      • Microservices
      • Event-Driven Architecture
      • Databases
    • Developer Productivity

      • Developer productivity
      • Developer Tools
      • GitOps
    • Automated Data Processing

      • AI/ML
      • Data Science
      • Apache Kafka on Kubernetes
    • Platform Engineering

      • DevOps
      • DevSecOps
      • Ansible automation for applications and services
    • Secure Development & Architectures

      • Security
      • Secure coding
  • Learn

    Featured

    • Kubernetes & Cloud Native
      Openshift icon
    • Linux
      Rhel icon
    • Automation
      Ansible cloud icon
    • AI/ML
      AI/ML Icon
    • View All Learning Resources

    E-Books

    • GitOps Cookbook
    • Podman in Action
    • Kubernetes Operators
    • The Path to GitOps
    • View All E-books

    Cheat Sheets

    • Linux Commands
    • Bash Commands
    • Git
    • systemd Commands
    • View All Cheat Sheets

    Documentation

    • Product Documentation
    • API Catalog
    • Legacy Documentation
  • Developer Sandbox

    Developer Sandbox

    • Access Red Hat’s products and technologies without setup or configuration, and start developing quicker than ever before with our new, no-cost sandbox environments.
    • Explore Developer Sandbox

    Featured Developer Sandbox activities

    • Get started with your Developer Sandbox
    • OpenShift virtualization and application modernization using the Developer Sandbox
    • Explore all Developer Sandbox activities

    Ready to start developing apps?

    • Try at no cost
  • Blog
  • Events
  • Videos

Manage JFR across instances with Cryostat and GraphQL

May 17, 2022
Andrew Azores
Related topics:
ContainersJavaKubernetes
Related products:
Red Hat OpenShift Container Platform

Share:

    Cryostat manages the monitoring of Java applications using Java Flight Recorder (JFR) in the cloud. Cryostat 2.1 includes support for GraphQL to control flight recordings on multiple applications, containers, and Kubernetes pods, with powerful filtering capacities. This article discusses the motivation for adding GraphQL support, shares some examples of queries along with expected results, and takes a look at the underlying web requests on the GraphQL endpoint.

    Why use GraphQL with Cryostat?

    Previous versions of Cryostat exposed flight recordings with a simple HTTP REST API that limited each request to a single conceptual action—starting one recording on one replica instance, for example. But Cryostat serves developers who create microservices architectures running large numbers of instances in multiple scaled replicas, and each replicated instance can have many flight recordings running for various purposes.

    Thus, a developer who wanted to start an identical recording on 12 replicas of a simple container needed to make 12 API requests. Even worse, a developer starting an identical recording on 10 replicas across 10 microservices—a common use case—needed to make 10x10=100 API requests.

    Clearly, Cryostat needs a flexible and powerful API for managing all these conditions. GraphQL is a simple but capable language for issuing queries on groups of carefully chosen instances. Reducing multiple actions to a single API request improves overall performance significantly, due to reduced network traffic overhead. As an additional benefit, developers can write much shorter and simpler queries to perform complex actions, rather than writing custom clients that parse API JSON responses and perform actions iteratively on response data.

    Queries for target JVMs and the active or archived recordings that belong to them, as well as recordings present in the general Cryostat archives, can combine with mutations to start, stop, archive, and delete active or archived recordings to create powerful queries for building automation around Cryostat and JDK Flight Recorder.

    Example queries

    Cryostat accepts queries formatted in GraphQL at its /api/beta/graphql endpoint. If you are completely unfamiliar with GraphQL, I suggest you take a brief look at its documentation to gain a better understanding of which parts in the examples in this article are just GraphQL syntax and concepts, versus Cryostat-specific behavior.

    Here is our first simple query:

    query {
        targetNodes {
                name
                nodeType
                labels
                target {
                    alias
                    serviceUri
                }
        }
    }

    This asks Cryostat for the targetNodes result, which is a query that returns all of the JVM targets that Cryostat is aware of. The response is an array of those objects. Since the query specifies various fields like name and nodeType, the objects within the array contain only those fields.

    Here is another, more advanced query:

    query {
    environmentNodes(filter: { name: "my-app-pod-abcd1234" }) {
                descendantTargets {
                    doStartRecording(recording: {
                        name: "myrecording",
                    template: "Profiling",
                    templateType: "TARGET",
                            duration: 30
                       }) {
                          name
                          state
                    }
                }
        }
    }

    This asks Cryostat for the environmentNodes result, which is a query that returns all of the nodes in the deployment graph that Cryostat is aware of but that are not JVM target applications. In a Red Hat OpenShift context, results would include the Deployments or DeploymentConfigs, for example, and the Pods that belong to them.

    The previous query used a name-based filter, selecting only the nodes with the name my-app-pod-abcd1234. Let's assume that this string matches one pod within our project namespace. Upon that pod, the query performs the nested query descendantTargets, which yields an array of JVM target objects much like our previous example query.

    Upon each of those JVM targets, we perform the doStartRecording mutation. As its name suggests, this mutation causes Cryostat to start a new JDK Flight Recording on each of the JVM targets using the configuration provided. The response will contain simply the name and state of each of these recordings, which we can anticipate to be myrecording and RUNNING.

    The previous example shows the power and utility of the GraphQL API, where a single request can make Cryostat perform the complex action of communicating with OpenShift to determine all of the Cryostat-compatible JVMs that belong to the specific pod and start a recording on each JVM.

    Here is one final sample query:

    query {
        targetNodes(filter: { annotations: "PORT = 9093" }) {
                recordings {
                        active(filter: { labels: "mylabel = redhatdevelopers" }) {
                        doArchive {
                                name
                        }
                    }
                }
        }
    }

    If you are familiar with OpenShift, the labels filter here might look familiar to you. This label selector uses the same syntax as OpenShift's label selectors, and applies to Cryostat's recording labels as well as to the labels and annotations in the deployment graph.

    You can use expressions like mylabel = redhatdevelopers, env in (prod, stage), or !mylabel. You can also create a logical AND conjunction of multiple label selectors by passing them as an array in the filter:

    active(filter: { labels: ["mylabel = redhatdevelopers", "env in (prod, stage)"] })

    To better understand what Cryostat sees in your deployment graph for your particular namespace, check the Discover API endpoint with a command like:

     

    $ curl https://my-cryostat.openshift.example.com/api/v2.1/discovery | jq

    There are several different kinds of filters, which can be combined and applied to various nested queries. So a large number of possible semantic requests can be pieced together. Refer to Cryostat's GraphQL queries.graphqls and types.graphqls repositories to see all of the implemented queries and mutations, and learn which ones accept which kinds of filters. The names should be self-explanatory: Types ending in FilterInput are filters, and type fields starting with do are actually nested mutations that perform some action like starting a recording or copying a recording to the archives.

    API endpoint details

    The examples in this article show typical query payloads of a GraphQL endpoint, the behaviors that you can perform, and what the expected responses should be. In this section, we take a closer look at the specific details of how to make these requests.

    The primary GraphQL endpoint for Cryostat 2.1 is POST /api/beta/graphql. The POST requests sent to this path include a body string formatted like { query: "THE_QUERY" }, replacing THE_QUERY with the text of the query as given in the previous section's examples. Here's a concrete example of a request and its metadata:

    POST /api/beta/graphql HTTP/1.1
    Accept: application/json, */*;q=0.5
    Accept-Encoding: gzip, deflate
    Connection: keep-alive
    Content-Length: 171
    Content-Type: application/json
    Host: localhost:8181
    User-Agent: HTTPie/3.1.0
    
    {
        "query": "query {\n    targetNodes {\n        name\n        nodeType\n        labels\n        target {\n            alias\n            serviceUri\n        }\n    }\n}\n"
    }

    You can also use a GET /api/beta/graphql request with the same results:

    "/api/beta/graphql?query={targetNodes{name nodeType labels target{alias serviceUri}}}"
    HTTP/1.1 200 OK
    content-encoding: gzip
    content-length: 247
    content-type: application/json

    Taking GraphQL further

    In the previous section's examples, we explored some possible query filters. To play with the power of the GraphQL interface in the context of your environment, try the following exercise:

    1. Craft a GraphQL query that snapshots all of your JVM applications at once and copies the resulting recordings into the Cryostat archives.
    2. Execute your query by sending the request to Cryostat using cURL or your favorite HTTP client.
    3. Write a script wrapping around this API request and add it to your crontab to run at 5:00 PM every day.
    4. Combine this script with a Cryostat automated rule that automatically starts a new continuous monitoring recording on your JVM applications whenever they appear.

    Each of these pieces is simple in isolation, but together they form a powerful automation workflow.

    One final note: The standard API in older Cryostat versions still exists in 2.1, and there are even further additions to this API for actions and capabilities that are not suitable for GraphQL—new endpoints for downloading JDK Flight Recorder files using JWT tokens rather than Authorization headers.

    Last updated: September 26, 2024

    Related Posts

    • How to log into Cryostat 2.1 on OpenShift: SSO for all

    • How to build automated JFR rules with Cryostat 2.1's new UI

    • How to organize JFR data with recording labels in Cryostat 2.1

    Recent Posts

    • What's New in OpenShift GitOps 1.18

    • Beyond a single cluster with OpenShift Service Mesh 3

    • Kubernetes MCP server: AI-powered cluster management

    • Unlocking the power of OpenShift Service Mesh 3

    • Run DialoGPT-small on OpenShift AI for internal model testing

    What’s up next?

    The microservice architectural approach is more than just about technology: It reaches into the foundation of your organization to allow you to build truly scalable, adaptive, complex systems that help a business adapt to rapidly changing competitive markets. In Microservices for Java Developers, you'll get a hands-on introduction to frameworks and containers through a handful of familiar patterns.

    Get the free e-book
    Red Hat Developers logo LinkedIn YouTube Twitter Facebook

    Platforms

    • Red Hat AI
    • Red Hat Enterprise Linux
    • Red Hat OpenShift
    • Red Hat Ansible Automation Platform
    • See all products

    Build

    • Developer Sandbox
    • Developer Tools
    • Interactive Tutorials
    • API Catalog

    Quicklinks

    • Learning Resources
    • E-books
    • Cheat Sheets
    • Blog
    • Events
    • Newsletter

    Communicate

    • About us
    • Contact sales
    • Find a partner
    • Report a website issue
    • Site Status Dashboard
    • Report a security problem

    RED HAT DEVELOPER

    Build here. Go anywhere.

    We serve the builders. The problem solvers who create careers with code.

    Join us if you’re a developer, software engineer, web designer, front-end designer, UX designer, computer scientist, architect, tester, product manager, project manager or team lead.

    Sign me up

    Red Hat legal and privacy links

    • About Red Hat
    • Jobs
    • Events
    • Locations
    • Contact Red Hat
    • Red Hat Blog
    • Inclusion at Red Hat
    • Cool Stuff Store
    • Red Hat Summit
    © 2025 Red Hat

    Red Hat legal and privacy links

    • Privacy statement
    • Terms of use
    • All policies and guidelines
    • Digital accessibility

    Report a website issue