Skip to main content
Redhat Developers  Logo
  • AI

    Get started with AI

    • Red Hat AI
      Accelerate the development and deployment of enterprise AI solutions.
    • AI learning hub
      Explore learning materials and tools, organized by task.
    • AI interactive demos
      Click through scenarios with Red Hat AI, including training LLMs and more.
    • AI/ML learning paths
      Expand your OpenShift AI knowledge using these learning resources.
    • AI quickstarts
      Focused AI use cases designed for fast deployment on Red Hat AI platforms.
    • No-cost AI training
      Foundational Red Hat AI training.

    Featured resources

    • OpenShift AI learning
    • Open source AI for developers
    • AI product application development
    • Open source-powered AI/ML for hybrid cloud
    • AI and Node.js cheat sheet

    Red Hat AI Factory with NVIDIA

    • Red Hat AI Factory with NVIDIA is a co-engineered, enterprise-grade AI solution for building, deploying, and managing AI at scale across hybrid cloud environments.
    • Explore the solution
  • Learn

    Self-guided

    • Documentation
      Find answers, get step-by-step guidance, and learn how to use Red Hat products.
    • Learning paths
      Explore curated walkthroughs for common development tasks.
    • Guided learning
      Receive custom learning paths powered by our AI assistant.
    • See all learning

    Hands-on

    • Developer Sandbox
      Spin up Red Hat's products and technologies without setup or configuration.
    • Interactive labs
      Learn by doing in these hands-on, browser-based experiences.
    • Interactive demos
      Click through product features in these guided tours.

    Browse by topic

    • AI/ML
    • Automation
    • Java
    • Kubernetes
    • Linux
    • See all topics

    Training & certifications

    • Courses and exams
    • Certifications
    • Skills assessments
    • Red Hat Academy
    • Learning subscription
    • Explore training
  • Build

    Get started

    • Red Hat build of Podman Desktop
      A downloadable, local development hub to experiment with our products and builds.
    • Developer Sandbox
      Spin up Red Hat's products and technologies without setup or configuration.

    Download products

    • Access product downloads to start building and testing right away.
    • Red Hat Enterprise Linux
    • Red Hat AI
    • Red Hat OpenShift
    • Red Hat Ansible Automation Platform
    • See all products

    Featured

    • Red Hat build of OpenJDK
    • Red Hat JBoss Enterprise Application Platform
    • Red Hat OpenShift Dev Spaces
    • Red Hat Developer Toolset

    References

    • E-books
    • Documentation
    • Cheat sheets
    • Architecture center
  • Community

    Get involved

    • Events
    • Live AI events
    • Red Hat Summit
    • Red Hat Accelerators
    • Community discussions

    Follow along

    • Articles & blogs
    • Developer newsletter
    • Videos
    • Github

    Get help

    • Customer service
    • Customer support
    • Regional contacts
    • Find a partner

    Join the Red Hat Developer program

    • Download Red Hat products and project builds, access support documentation, learning content, and more.
    • Explore the benefits

How to get more from OpenShift Service Mesh monitoring

December 21, 2023
Luis Falero Otiniano
Related topics:
Service mesh
Related products:
Red Hat OpenShift Service Mesh

    Red Hat OpenShift Service Mesh brings tracing and monitoring to your system with little effort. However, the information is basic. In this article, we will create three applications in the Quarkus, Node.Js, and Java languages to collect more detailed statistics with Jaeger, collect custom application specific metrics with Prometheus, and create new dashboards with Grafana.

    Jaeger

    Jaeger, installed by default in OpenShift Service Mesh, allows developers to configure their services to gather runtime statistics about their performance.

    It is important to understand the following terms:

    • Span: Represents a logical unit of work, which has a unique name, a start time, and the duration of execution.
    • Trace: This is an execution path of services in OpenShift Service Mesh. In other words, a trace is comprised of one or more spans (Figure 1).
    Spans Traces
    Figure 1: Architecture

    Enabling tracing in Quarkus applications

    To enable custom metrics for a Quarkus application, add the quarkus-smallrye-opentracing extension in the pom.xml file.

    <dependency>
      <groupId>io.quarkus</groupId>
      <artifactId>quarkus-smallrye-opentracing</artifactId>
    </dependency>

    To enable custom metrics for a Quarkus application, add the related properties in the application.properties file.

    opentracing.jaeger.service-name=app_name
    opentracing.jaeger.const-sampler.decision=true
    opentracing.jaeger.sampler.param=1
    opentracing.jaeger.log-spans=false
    opentracing.jaeger.http-sender.url=http://jaeger-collector.<namespace>.svc.cluster.local:14268/api/traces
    opentracing.jaeger.enable-b3-propagation=true

    Enabling tracing in Node.js applications

    To enable custom metrics for a Node.js application, add the jaeger-client and opentracing package.

    npm install --save jaeger-client opentracing

    This package has all the standard Jaeger metric types that you can use to instrument your custom tracing.

    const Jaeger = require("jaeger-client");
    const Opentracing = require("opentracing");
    const logger = Pino();
    module.exports = { create };

    Configure and initialize the Jaeger tracer.

    function create() {
      const config = {
        serviceName: "app_name",
        sampler: { type: "const", param: 1 },
        reporter: { logSpans: true, collectorEndpoint: "http://jaeger-collector.<namespace>.svc.cluster.local:14268/api/traces",
        }
      };
      const options = { logger };
      const tracer = Jaeger.initTracer(config, options);
      const codec = new Jaeger.ZipkinB3TextMapCodec({ urlEncoding: true });
      tracer.registerInjector(Opentracing.FORMAT_HTTP_HEADERS, codec);
      tracer.registerExtractor(Opentracing.FORMAT_HTTP_HEADERS, codec);
      return tracer;
    }

    This package has all the standard Jaeger metric types that you can use to instrument your custom tracing.

    const Fastify = require("fastify");
    const Opentracing = require("opentracing");
    const logger = Pino();
    module.exports = { create };

    Start a new span.

    function create(tracer) {
      const server = Fastify({ logger });
      server.addHook("onRequest", traceRequest);
      server.addHook("onResponse", traceResponse);
      return server;
    
    
      async function traceRequest(request) {
        const { method, originalUrl } = request.raw;
        const name = method + ":app_name";
        const span = tracer.startSpan(name);
        span.setTag(Opentracing.Tags.HTTP_URL, originalUrl);
        span.setTag(Opentracing.Tags.HTTP_METHOD, method);
        request.rootSpan = span;
      }
      async function traceResponse(request, reply) {
        request.rootSpan.setTag(
          Opentracing.Tags.HTTP_STATUS_CODE,
          reply.res.statusCode
        );
        request.rootSpan.finish();
      }
    }

    Enabling tracing in Java applications

    To enable custom metrics for a Java application, add the opentracing-spring-jaeger-cloud-starter extension in the pom.xml file.

    <dependency>
      <groupId>io.opentracing.contrib</groupId>
      <artifactId>opentracing-spring-jaeger-cloud-starter</artifactId>
    </dependency>

    To enable custom metrics for a Java application, add the related properties in the application.properties file.

    opentracing.jaeger.service-name=app_name
    opentracing.jaeger.const-sampler.decision=true
    opentracing.jaeger.sampler.param=1.0
    opentracing.jaeger.log-spans=false
    opentracing.jaeger.http-sender.url=http://jaeger-collector.<namespace>.svc.cluster.local:14268/api/traces
    opentracing.jaeger.enable-b3-propagation=true

    Visualizing traces and spans using the Jaeger web console

    In the first console, you can see only the service and the route that was consumed, as shown in Figure 2.

    istio_1
    Figure 2: Default tracing

    In the last console, the method that was consumed and the logs are shown in Figure 3.

    istio_2
    Figure 3: Trace using the library

    Prometheus and Grafana

    Prometheus is an open source systems monitoring and alerting toolkit which includes a time series database for storing metrics. OpenShift Service Mesh provides a default Prometheus instance which gathers metrics data from the Envoy proxies, the services in the service mesh, and the components in the control plane.

    Grafana is an open source graphical visualization tool used for creating operational dashboards. OpenShift Service Mesh provides a default Grafana instance with ready made dashboards for viewing data from the Envoy proxies, the services in the service mesh, and the components in the control plane.

    Collecting custom application metrics

    OpenShift Service Mesh collects several useful metrics high level understanding at the performance of the service mesh and the applications deployed on it. However, sometimes you might need to gather custom application specific metrics and display them in a Grafana dashboard. You must include the Prometheus client libraries in your application, and then create these custom metrics.

    Prometheus supports four types of metrics:

    • Counter: A cumulative metric whose value can only increase or reset to zero on restart. For example, you can use a counter to represent the number of requests served, errors, and tasks completed.
    • Gauge: A metric that can be incremented or decremented. For example, you can use a gauge to represent the number of processes or the number of concurrent users.
    • Histogram: Track the number and the sum of the values, allowing you to calculate the average of the values.
    • Summary: Similar to a histogram, but a summary also calculates configurable values over a sliding time window.

    Creating custom metrics for Quarkus applications

    To enable custom metrics for a Quarkus application, add the quarkus-smallrye-metrics extension in the pom.xml file.

    <dependency>
      <groupId>io.quarkus</groupId>
       <artifactId>quarkus-smallrye-metrics</artifactId>
    </dependency>

    Import the required metrics classes in your application from the org.eclipse.microprofile.metrics.* package.

    This package has all the standard Prometheus metric types that you can use to instrument your custom metrics.

    import org.eclipse.microprofile.metrics.MetricUnits;
    import org.eclipse.microprofile.metrics.annotation.Counted;
    import org.eclipse.microprofile.metrics.annotation.Gauge;
    import org.eclipse.microprofile.metrics.annotation.SimplyTimed;
    import org.eclipse.microprofile.metrics.annotation.Metered;

    Timed can be created by adding the @SimplyTimed annotation to methods:

    @SimplyTimed(
      name = "app_name:request_process_time",
      description = "A measure of how long it takes to process a request",
      unit = MetricUnits.MILLISECONDS
    )

    Counter can be created by adding the @Counted annotation to methods:

    @Counted(
      name = "app_name:request_placed",
      description = "Count of request placed"
    )

    Metered can be created by adding the @Metered annotation to methods:

    @Metered(
      name = "app_name:request_processed_rate",
      description = "Rate at which requests are placed",
      unit = MetricUnits.MINUTES, 
      absolute = true
    )

    Gauge can be created by adding the @Gauge annotation to methods:

    @Gauge(
      name = "app_name:order_process_rating",
      description = "Overall customer rating for the order process",
      unit = MetricUnits.NONE 
    )

    Creating custom metrics for Node.js applications

    To enable custom metrics for a Node.js application, add the prom-client package.

    npm install --save prom-client

    Import the prometheus-client package and initialize it. Then add a unique prefix to identify the standard metrics.

    const express = require('express');
    var prometheus = require('prom-client');
    const prefix = 'app_name_';
    prometheus.collectDefaultMetrics({ prefix });

    Counter can be created by adding the new prometheus.Counter annotation to methods:

    const requestPlaced = new prometheus.Counter({
      name: app_name:request_placed,
      help: 'Count of request placed'
    });

    Gauge can be created by adding the new prometheus.Gauge annotation to methods:

    const processRating = new prometheus.Gauge({
      name: app_name:order_process_rating,
      help: 'Overall customer rating for the order process'
    });

    Update the method to add the new constant variables.

    app.get('/method-name, async function (req, res) {  
      processRating.inc(); //You can then increment the counter
      requestPlaced.setToCurrentTime();   //You can know the overall rating
      const end = requestPlaced.startTimer();
      end();
      res.send('OK');
    });

    Add code to create a new HTTP GET endpoint called /metrics which will be used by Prometheus to collect metrics for this microservice.

    app.get('/metrics', function (req, res) {
      res.set('Content-Type', prometheus.register.contentType);
      res.send(prometheus.register.metrics());
    });

    Creating custom metrics for Java applications

    To enable custom metrics for a Java application,  add the micrometer-registry-prometheus extension in the pom.xml file.

    <dependency>
      <groupId>org.springframework.boot</groupId>
      <artifactId>spring-boot-starter-actuator</artifactId>
      <scope>compile</scope>
    </dependency>
    <dependency>
      <groupId>io.micrometer</groupId>
      <artifactId>micrometer-registry-prometheus</artifactId>
      <scope>runtime</scope>
    </dependency>

    To enable custom metrics for a Java application, add the related properties in the application.properties file.

    management.endpoints.enabled-by-default=true
    management.endpoints.web.exposure.include=*
    management.endpoint.health.show-details: always

    Import the required metrics classes in your application from the io.micrometer.core.* package.

    This package has all the standard Prometheus metric types that you can use to instrument your custom metrics.

    import io.micrometer.core.instrument.MeterRegistry;
    import io.micrometer.core.instrument.Gauge;
    import io.micrometer.core.annotation.Timed;

    Gauge can be created by adding the Gauge.builder method to constructor:

    public class OrderController {
      private List<Order> orderList;
      public Supplier<Number> orderCount() { return ()->orderList.size(); }
      public OrderController(MeterRegistry registry) {
        Gauge.builder("app_name:order_process_rating", orderCount()).     
          description("Overall customer rating for the order process").
          register(registry);
      }
    }

    Timed can be created by adding the @Timed annotation to methods:

    @Timed(
      value = "app_name:request_process_time",
      description = "A measure of how long it takes to process a request",
      percentiles = {0.5,0.9}
    )

    Enabling Prometheus metrics

    OpenShift Service Mesh does not collect metrics from applications by default. To enable Prometheus to collect metrics from your application, add the following annotations:

    spec:
     template:
       metadata:
         annotations:
           sidecar.istio.io/inject: "true"
           prometheus.io/scrape: "true"
           prometheus.io/port: "8080"
           prometheus.io/scheme: "http"

    Querying OpenShift Service Mesh metrics using Prometheus

    Figure 4 illustrates the newly created metric app_name:request_placed in Prometheus.

    prometheus_1
    Figure 4: First custom metric in Prometheus

    Figure 5 shows the newly created metric app_name:order_process_rating in Prometheus.

    prometheus_2
    Figure 5: Second custom metric in Prometheus

    Visualizing OpenShift Service Mesh metrics using Grafana

    Figure 6 illustrates the basic metrics in Grafana.

    graphana_1
    Figure 6: Metrics in Grafana by default

    Create a new dashboard to add the newly created metric app_name:request_placed in Grafana (Figure 7).

    graphana_2
    Figure 7: First custom metric in Grafana

    Create a new dashboard to add the newly created metric app_name:order_process_rating in Grafana (Figure 8).

    graphana_3
    Figure 8: Second custom metric in Grafana

    You can view the new dashboard created with the two metrics created (Figure 9).

    graphana_4
    Figure 9: New dashboard with custom metrics

    Summary

    Tracing helps you identify performance issues in microservices based applications. That's why you should add your applications Jaeger and OpenTracing libraries to enable tracing. Also, you can use Prometheus libraries to generate custom application metrics and Grafana to generate custom dashboards for your application metrics.

    Related Posts

    • Integrating Kubeflow with Red Hat OpenShift Service Mesh

    • 4 steps to run an application under OpenShift Service Mesh

    • Comparing OpenShift Service Mesh and Service Interconnect

    • Monitoring Node.js Applications on OpenShift with Prometheus

    Recent Posts

    • What GPU kernels mean for your distributed inference

    • Debugging image mode with Red Hat OpenShift 4.20: A practical guide

    • EvalHub: Because "looks good to me" isn't a benchmark

    • SQL Server HA on RHEL: Meet Pacemaker HA Agent v2 (tech preview)

    • Deploy with confidence: Continuous integration and continuous delivery for agentic AI

    What’s up next?

    GitOps has become a standard in deploying applications to Kubernetes, and many companies are adopting the methodology for their DevOps and cloud-native strategy. Download the GitOps Cookbook for useful recipes and examples for successful hands-on applications development and deployment with GitOps.

    Get the 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
    © 2026 Red Hat

    Red Hat legal and privacy links

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

    Chat Support

    Please log in with your Red Hat account to access chat support.