Skip to main content
Redhat Developers  Logo
  • Products

    Featured

    • Red Hat Enterprise Linux
      Red Hat Enterprise Linux Icon
    • Red Hat OpenShift AI
      Red Hat OpenShift AI
    • Red Hat Enterprise Linux AI
      Linux icon inside of a brain
    • Image mode for Red Hat Enterprise Linux
      RHEL image mode
    • Red Hat OpenShift
      Openshift icon
    • Red Hat Ansible Automation Platform
      Ansible icon
    • Red Hat Developer Hub
      Developer Hub
    • View All Red Hat Products
    • Linux

      • Red Hat Enterprise Linux
      • Image mode for Red Hat Enterprise Linux
      • Red Hat Universal Base Images (UBI)
    • Java runtimes & frameworks

      • JBoss Enterprise Application Platform
      • Red Hat build of OpenJDK
    • Kubernetes

      • Red Hat OpenShift
      • Microsoft Azure Red Hat OpenShift
      • Red Hat OpenShift Virtualization
      • Red Hat OpenShift Lightspeed
    • Integration & App Connectivity

      • Red Hat Build of Apache Camel
      • Red Hat Service Interconnect
      • Red Hat Connectivity Link
    • AI/ML

      • Red Hat OpenShift AI
      • Red Hat Enterprise Linux AI
    • Automation

      • Red Hat Ansible Automation Platform
      • Red Hat Ansible Lightspeed
    • Developer tools

      • Red Hat Trusted Software Supply Chain
      • Podman Desktop
      • Red Hat OpenShift Dev Spaces
    • Developer Sandbox

      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
    • Secure Development & Architectures

      • Security
      • Secure coding
    • Platform Engineering

      • DevOps
      • DevSecOps
      • Ansible automation for applications and services
    • Automated Data Processing

      • AI/ML
      • Data Science
      • Apache Kafka on Kubernetes
      • View All Technologies
    • Start exploring in the Developer Sandbox for free

      sandbox graphic
      Try Red Hat's products and technologies without setup or configuration.
    • Try at no cost
  • Learn

    Featured

    • Kubernetes & Cloud Native
      Openshift icon
    • Linux
      Rhel icon
    • Automation
      Ansible cloud icon
    • Java
      Java 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

    • API Catalog
    • Product Documentation
    • Legacy Documentation
    • Red Hat Learning

      Learning image
      Boost your technical skills to expert-level with the help of interactive lessons offered by various Red Hat Learning programs.
    • Explore Red Hat Learning
  • 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

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

Share:

    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

    • More Essential AI tutorials for Node.js Developers

    • How to run a fraud detection AI model on RHEL CVMs

    • How we use software provenance at Red Hat

    • Alternatives to creating bootc images from scratch

    • How to update OpenStack Services on OpenShift

    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

    Products

    • Red Hat Enterprise Linux
    • Red Hat OpenShift
    • Red Hat Ansible Automation Platform

    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

    Red Hat legal and privacy links

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

    Report a website issue