Nueva publicación

Encontrar

Artículo
· 16 jun, 2025 Lectura de 8 min

Configuring OpenTelemetry in IRIS

Hello, dear members of our developer community!

In today's article, we're going to take a look at one of the latest remote monitoring features that have been added to the product for our IRIS instances. I'm talking about OpenTelemetry support.

What is OpenTelemetry?

OpenTelemetry is an open source framework that provides the necessary tools such as SDKs and standards to implement observability in systems and applications.

This observability extends to three types of data:

  1. Traces : control of the flow of information that flows along the solutions by including traces that allow us to identify where they are passing and under what conditions.
  2. Metrics : system status, performance, response latencies, resource usage, etc.
  3. Logs : included in systems for better understanding of events that occur.

OpenTelemetry uses the open OTLP standard, which defines how all previously defined telemetry should be serialized and transported. This telemetry can be sent via HTTP or gRPC.

Open Telemetry con IRIS

InterSystems IRIS leverages the features available through the OpenTelemetry SDK to allow the export of all telemetry generated by the configured instance. Where does this telemetry come from? 

  1. Metrics : These come from the information available to us from the REST API /api/monitor ( you can see the official documentation for this API here ).
  2. Logs : Messages that are recorded in the messages.log file and information that is stored in the audit database (if enabled).
  3. Traces : Traces defined by the user within the applications developed on the instance.

Well let's see how we would proceed to configure OpenTelemetry in an IRIS instance

Configuring IRIS with OpenTelemetry

For our configuration example, I used a project I have uploaded to GitHub that runs on Docker, but it wouldn't be too complicated to configure on an on-premise instance. You can find that project uploaded to OpenExchange associated with this article.

Before showing the different configurations, let's explain what elements will be part of our "monitoring ecosystem":

InterSystems IRIS

The IRIS instance will be responsible for generating the telemetry data we need to monitor.

OpenTelemetry Collector

It is a tool provided by OpenTelemetry that is responsible for collecting telemetry data from different sources. In our example, it will only be IRIS, but we could add as many as we needed.

Prometheus

Open-source tool used for system monitoring and alert generation. This tool will be responsible for receiving the metrics accumulated by OpenTelemetry Collector.

Jaeger

Open-source platform for managing and monitoring traces of microservices-based systems.

Configuration in Docker

As I mentioned earlier, I used a Docker deployment to simplify the example as much as possible. Let's analyze the docker-compose.yml file piece by piece for a better understanding.

IRIS Docker image

  iris:
    init: true
    container_name: iris
    build:
      context: .
      dockerfile: iris/Dockerfile
    ports:
      - 52774:52773
      - 51774:1972
    volumes:
    - ./iris/shared:/iris-shared
    environment:
    - ISC_DATA_DIRECTORY=/iris-shared/durable
    - OTEL_EXPORTER_OTLP_ENDPOINT=http://otel-collector:4318
    command: --check-caps false --ISCAgent false

As you can see, I'm defining the image to use in a Dockerfile, which isn't particularly interesting, so I won't bother explaining it here. The interesting part of this configuration is defining an environment variable called  OTEL_EXPORTER_OTLP_ENDPOINT  , which is the URL where our OpenTelemetry Collector will wait for IRIS to send all the metrics, traces, and logs it has.

Once we deploy our IRIS instance, we'll need to configure it to output metrics and logs regularly. To do this, we'll access the Monitor configuration from the management portal:

As you can see, we can enable both Metrics and Logs sending. In the case of traces, these are not sent at intervals, but rather as soon as the "End" method of the %Trace.Provider class instance is invoked. I won't go into further detail, but you can check  the official documentation here .

OpenTelemetry Collector Docker image

otel-collector:
    build:
      context: .
      dockerfile: open-telemetry/Dockerfile
    container_name: otel-collector
    command: ["--config=/otel-local-config.yml"]
    volumes:
      - ./open-telemetry/otel-collector-config.yml:/otel-local-config.yml
    ports:
      - 4317:4317      # OTLP gRPC receiver
      - 4318:4318    # OTLP HTTP receiver
      - 9464:9464      # Metrics
    depends_on:
      - iris

Here we have the OpenTelemetry Collector image. Again, I've defined a Dockerfile to determine where to get the image from (this wouldn't be necessary). As you can see, we're making three ports accessible:

  • 4317: port for receiving metrics, traces and logs via gRPC.
  • 4318: port for receiving metrics, traces and logs via HTTP.
  • 9464: Open port for third-party tools to query information received by OpenTelemetry Collector.

We've also declared a configuration file,  otel-local-config.yml  (the name is modifiable). Let's take a look inside:

receivers:
  otlp:
    protocols:
      grpc:
        endpoint: "0.0.0.0:4317"
      http:
        endpoint: "0.0.0.0:4318"
exporters:
  otlp:
    endpoint: jaeger:4317
    tls:
      insecure: true
  prometheus:
    endpoint: "0.0.0.0:9464"
  debug: {}
service:
  pipelines:
    traces:
      receivers: [otlp]
      exporters: [otlp]
    metrics:
      receivers: [otlp]
      exporters: [prometheus]
    logs:
      receivers: [otlp]
      exporters: [debug]

What are we looking at here? Quite simply, we have the following sections: 

  • Data receivers  , in our case we called it OTLP, in which we configure the IP and ports on which our receiver will wait for information from third-party systems.
  • Data exporters : where we're going to send or who's going to extract the data received by the OpenTelemetry Collector. For our example, we've used an exporter already included in OpenTelemetry, Prometheus, which  will be responsible for obtaining the metrics from the local OpenTelemetry Collector instance on port 9464. In the case of Jaeger , we're directly using OpenTelemetry's ability to send data directly to an IP (Jaeger is the name of the instance within the network set up by Docker) that will correspond to our Jaeger instance.
  • Services , where we'll specify which of the components we've configured as receivers and exporters will be responsible for receiving and sending metrics, traces, and logs. As you can see, in our case, the OpenTelemetry Collector will be the receiver we'll use for everything, Prometheus will be the metrics receiver, and Jaeger, through OpenTelemetry Collector, will be the trace receiver.

Prometheus Docker image

Let's take a look at its configuration in Docker:

prometheus:
    build:
      context: .
      dockerfile: prometheus/Dockerfile
    container_name: prometheus
    volumes:
      - ./prometheus/prometheus.yml:/etc/prometheus/prometheus.yml
    ports:
      - 9090:9090

As you can see it is very simple, we have our image defined again in a Dockerfile that only refers to the name of the image, a port 9090 where the web interface that we can access will be deployed and finally a configuration file called  prometheus.yml 

Let's see what this prometheus.yml file tells us:

global:
  scrape_interval: 15s
scrape_configs:
  - job_name: 'otel-collector'
    static_configs:
      - targets: ['otel-collector:9464']

We have the following configuration:

  • Scrape interval: the time interval between queries to the OpenTelemetry Collector.
  • Scrape configs: where we give a name to the task that will perform the search and the IP and port to which it will connect for said search.

Jaeger Docker image

For the Jaeger image I have directly taken an example available in our beloved GPT chat:

jaeger:
    image: jaegertracing/all-in-one:latest
    container_name: jaeger
    environment:
      - COLLECTOR_OTLP_ENABLED=true
    ports:
      - 16686:16686    # Jaeger UI
      - 14250:14250    # OTLP gRPC receiver

The most important point, apart from port 16689, which we'll use to access the web interface, is the COLLECTOR_OTLP_ENABLED environment variable, which enables Jaeger's default ports to allow HTTP connections from OpenTelemetry Collector.  Here  you can see the list of ports it uses, but I can tell you in advance that it's 4317 for gRCP transmission and 4318 for HTTP. As you've seen in the OpenTelemetry Collector configuration, we'll be using the gRCP connection.

Well, with everything ready, let's see it in operation by starting the project.

Emitting metrics, receiving in Prometheus

Now that we have our instances configured and running, let's access the web interface provided by Prometheus.  In our example, we have mapped it to http://localhost:9090 . By default, it will show us where we can run queries on the available metrics.

If we have correctly configured the connection between IRIS - OpenTelemetry Collector - Prometheus, from the Prometheus query screen we will have access to all the standard IRIS metrics available as you can see in the following screenshot searching for "iris_"

If we select any of them we will be able to see a graph over time:

Sending traces to Jaeger

To check the operation of sending traces we are going to use the simplest resource that IRIS provides us, which is the TestTraces() method of the SYS.Monitor.OTel class that you can consult here . If you have any particular interest in seeing it in more detail, let me know in the comments and I will be happy to write an article about it.

We simply execute the command from the SYS namespace via console:

%SYS>do ##class(SYS.Monitor.OTel).TestTraces()

This will send us a trace that should have reached Jaeger, let's check it from its graphical interface displayed at http://localhost:1668

In the filters on the left menu we can see that we have a service called  irisotel , this service is the one used by IRIS to test the sending of test traces, hence the name of the received trace test_trace .

Well, that's it! We've now got our instance ready to send all the metrics and trace data we need. I'm available if you'd like to dig deeper into the topic.

2 comentarios
Comentarios (2)2
Inicie sesión o regístrese para continuar
Resumen
· 16 jun, 2025

InterSystems Developers Publications, Week June 09 - 15, 2025, Digest

Articles
#InterSystems IRIS
#InterSystems IRIS for Health
Announcements
#InterSystems IRIS
#Learning Portal
#Job Opportunity
#InterSystems IRIS for Health
#HealthShare
#Summit
Questions
#InterSystems IRIS
#HealthShare
#InterSystems IRIS for Health
June 09 - 15, 2025Week at a GlanceInterSystems Developer Community
Artículo
· 16 jun, 2025 Lectura de 8 min

Configurando OpenTelemetry en IRIS

¡Hola, estimados miembros de nuestra comunidad de desarrolladores!

En el artículo de hoy vamos a echar un vistazo a una de las últimas funcionalidades de telemonitorización de nuestras instancias de IRIS que se han añadido al producto. Estoy hablando de la compatibilidad con OpenTelemetry.

¿Qué es OpenTelemetry?

OpenTelemetry es un framework open source que proporciona las herramientas necesarias como SDKs y estándares para implementar la observabilidad en sistemas y aplicaciones.

Esta observabilidad se extiende a tres tipos de datos:

  1. Trazas: control del flujo de la información que fluye a lo largo de las soluciones mediante la inclusión de trazas que permitan identificar por donde están pasando y en qué condiciones.
  2. Métricas: situación del sistema, rendimiento del mismo, latencias en las respuestas, uso de recursos, etc.
  3. Logs: incluidos en los sistemas para una mejor comprensión de los eventos que ocurren.

OpenTelemetry hace uso del estándar abierto OTLP que define como se debe serializar y transportar toda la telemetría anteriormente definida, el envío de esta telemetría puede realizarse mediante HTTP o gRPC.

Open Telemetry con IRIS

InterSystems IRIS aprovecha las funcionalidades disponibles por OpenTelemetry SDK para permitir la exportación de toda la telemetría que genera la instancia configurada. ¿De donde procede dicha telemetría? 

  1. Métricas: proceden de la información que tenemos disponible desde la API REST /api/monitor (aquí podéis ver la documentación oficial de dicha API).
  2. Logs: mensajes que se registran en el archivo messages.log e información que se almacena en la base de datos de auditoría (si está activada).
  3. Trazas: trazas definidas por el usuario dentro de las aplicaciones desarrolladas en la instancia.

Pues bien veamos como procederíamos a configurar OpenTelemetry en una instancia de IRIS

Configurando IRIS con OpenTelemetry

Para nuestro ejemplo de configuración he utilizado un proyecto que tengo subido en un github que corre en Docker, pero no seria muy complicado configurarlo en una instancia instalada on-premise. Tenéis dicho proyecto subido en OpenExchange asociado a este artículo.

Antes de mostrar las distintas configuraciones vamos a explicar que elementos van a formar parte de nuestro "ecosistema de monitorización":

InterSystems IRIS

La instancia de IRIS será la encargada de generar los datos de telemetría que necesitamos monitorizar.

OpenTelemetry Collector

Es una herramienta proporcionada por OpenTelemetry encargada de recopilar datos telemétricos de diferentes orígenes, en nuestro ejemplo sólo será IRIS, pero podríamos añadir tantos como necesitáramos.

Prometheus

Herramienta open-source utilizada para la monitorización de sistemas y generación de alertas. Esta herramienta será la responsable de la recepción de las métricas acumuladas por OpenTelemetry Collector.

Jaeger

Plataforma open-source para la gestión y monitorización de trazas de sistemas basados en microservicios.

Configuración en Docker

Como he comentado anteriormente, he usado un despliegue en Docker para simplificar el ejemplo lo máximo posible. Analicemos el fichero docker-compose.yml por partes para su mejor comprensión.

Imagen de IRIS

  iris:
    init: true
    container_name: iris
    build:
      context: .
      dockerfile: iris/Dockerfile
    ports:
      - 52774:52773
      - 51774:1972
    volumes:
    - ./iris/shared:/iris-shared
    environment:
    - ISC_DATA_DIRECTORY=/iris-shared/durable
    - OTEL_EXPORTER_OTLP_ENDPOINT=http://otel-collector:4318
    command: --check-caps false --ISCAgent false

Como véis estoy definiendo la imagen a usar en un fichero Dockerfile que no tiene mayor interés y por lo tanto no me molestaré en explicarlo. El punto interesante de esta configuración será la definición de una variable de entorno llamada OTEL_EXPORTER_OTLP_ENDPOINT que será la URL donde nuestro OpenTelemetry Collector estará esperando que IRIS le envíe todas las métricas, trazas y logs de los que dispone.

Una vez que despleguemos nuestra instancia de IRIS tendremos que configurarla para que emita las métricas y los logs de forma regular, para ello accederemos desde el portal de gestión a la configuración de Monitor:

Como podéis ver podemos habilitar tanto el envío de Métricas como el de Logs, en el caso de las trazas estas no se envían en intervalos, sino que se enviarán en cuanto se invoque el método de "End" de la instancia de la clase %Trace.Provider, no entraré más en detalle, pero podéis revisar aquí la documentación oficial.

Imagen de OpenTelemetry Collector

otel-collector:
    build:
      context: .
      dockerfile: open-telemetry/Dockerfile
    container_name: otel-collector
    command: ["--config=/otel-local-config.yml"]
    volumes:
      - ./open-telemetry/otel-collector-config.yml:/otel-local-config.yml
    ports:
      - 4317:4317      # OTLP gRPC receiver
      - 4318:4318    # OTLP HTTP receiver
      - 9464:9464      # Metrics
    depends_on:
      - iris

Aquí tenemos la imagen de OpenTelemetry Collector, nuevamente he definido un Dockerfile para definir de donde obtener la imagen (no sería necesario). Como véis estamos haciendo accesibles 3 puertos:

  • 4317: puerto para la recepción de métricas, trazas y logs vía gRPC.
  • 4318: puerto para la recepción de métricas, trazas y logs vía HTTP.
  • 9464: puerto abierto para que terceras herramientas consulten la información recibida por OpenTelemetry Collector.

También hemos declarado un archivo de configuración otel-local-config.yml (el nombre es modificable). Echemos un vistazo a su interior:

receivers:
  otlp:
    protocols:
      grpc:
        endpoint: "0.0.0.0:4317"
      http:
        endpoint: "0.0.0.0:4318"
exporters:
  otlp:
    endpoint: jaeger:4317
    tls:
      insecure: true
  prometheus:
    endpoint: "0.0.0.0:9464"
  debug: {}
service:
  pipelines:
    traces:
      receivers: [otlp]
      exporters: [otlp]
    metrics:
      receivers: [otlp]
      exporters: [prometheus]
    logs:
      receivers: [otlp]
      exporters: [debug]

¿Qué estamos viendo aquí? Muy sencillo, tenemos las siguiente secciones: 

  • Receptores de datos, en nuestro caso lo hemos llamado otlp, en el que configuramos la IP y los puertos en los que nuestro receptor va a esperar la información de terceros sistemas.
  • Exportadores de datos, a donde vamos a enviar o quién va a extraer los datos que sean recibidos en el OpenTelemetry Collector. Para nuestro ejemplo hemos usado un exporter ya incluido en OpenTelemetry como es prometheus que se encargará de obtener las métricas en la instancia local del OpenTelemetry Collector en el puerto 9464. Para el caso de jaeger estamos usando directamente la capacidad de OpenTelemetry de remitir datos directamente a una IP (jaeger es el nombre de la instancia dentro de la red montada por Docker) que corresponderá con nuestra instancia de jaeger.
  • Servicios, donde indicaremos quienes de los componentes que hemos configurado como receptores y exportadores se van a hacer cargo de la recepción y emisión de métricas, trazas y logs. Cómo podéis ver en nuestro caso, el OpenTelemetry Collector será el receptor que usaremos para todo, Prometheus será el receptor de las métricas y Jaeger, mediante OpenTelemetry Collector, será el receptor de las trazas.

Imagen de Prometheus

Echemos un vistazo a su configuración en Docker:

prometheus:
    build:
      context: .
      dockerfile: prometheus/Dockerfile
    container_name: prometheus
    volumes:
      - ./prometheus/prometheus.yml:/etc/prometheus/prometheus.yml
    ports:
      - 9090:9090

Cómo podéis observar es muy sencillo, tenemos nuestra imagen definida nuevamente en un archivo Dockerfile que únicamente hace referencia al nombre de la imagen, un puerto 9090 donde se desplegará la interfaz web a la que podremos acceder y finalmente un archivo de configuración llamado prometheus.yml 

Veamos que nos cuenta ese archivo prometheus.yml:

global:
  scrape_interval: 15s
scrape_configs:
  - job_name: 'otel-collector'
    static_configs:
      - targets: ['otel-collector:9464']

Tenemos la siguiente configuración:

  • Scrape interval: con el intervalo de tiempo entre consulta y consulta al OpenTelemetry Collector.
  • Scrape configs: donde damos un nombre a la tarea que realizará la búsqueda y la IP y el puerto al que se conectará para dicha búsqueda.

Imagen de Jaeger

Para la imagen de Jaeger he cogido directamente un ejemplo disponible en nuestro querido chatGPT:

jaeger:
    image: jaegertracing/all-in-one:latest
    container_name: jaeger
    environment:
      - COLLECTOR_OTLP_ENABLED=true
    ports:
      - 16686:16686    # Jaeger UI
      - 14250:14250    # OTLP gRPC receiver

El punto más relevante, a parte del puerto 16689 que es el que usaremos para acceder a la interfaz web, es la variable de entorno COLLECTOR_OTLP_ENABLED, la cual nos habilitará los puertos por defecto de Jaeger para permitir las conexiones HTTP desde OpenTelemetry Collector. Aquí podéis ver la lista de puertos que usa, pero ya os adelanto que es 4317 para la transmisión gRCP y el 4318 para la HTTP, como habéis visto en la configuración de OpenTelemetry Collector, vamos a hacer uso de la conexión vía gRCP.

Pues bien, con todo preparado, veámoslo en funcionamiento arrancando el proyecto.

Emitiendo métricas, recepción en Prometheus

Ya tenemos nuestras instancias configuradas y arrancadas, accedamos a la la interfaz web que nos proporciona Prometheus, en nuestro ejemplo lo hemos mapeado a http://localhost:9090 , por defecto se nos mostrará donde podemos lanzar consultas sobre las métricas disponibles.

Si hemos configurado correctamente la conexión entre IRIS - OpenTelemetry Collector - Prometheus, desde la pantalla de consultas de Prometheus tendremos acceso a todas las métricas estándar disponibles de IRIS como podéis ver en el siguiente pantallazo buscando por "iris_"

Si seleccionamos cualquiera de ellas podremos ver un gráfico a lo largo del tiempo:

Enviando trazas a Jaeger

Para comprobar el funcionamiento del envío de trazas vamos a usar el recurso más sencillo que nos pone a disposición IRIS, que es el método TestTraces() de la clase SYS.Monitor.OTel que podéis consultar aquí, si tenéis algún interés particular en verlo más en detalle comentádmelo en los comentarios y estaré encantado de escribir un artículo al respecto.

Nos limitamos a ejecutar por consola el comando desde el namespace SYS:

%SYS>do ##class(SYS.Monitor.OTel).TestTraces()

Esto nos remitirá una traza que deberá haber llegado a Jaeger, comprobémoslo desde su interfaz gráfica desplegada en http://localhost:16686

En los filtros del menú de la izquierda podemos ver que tenemos un servicio llamado irisotel, este servicio es el usado por IRIS para probar el envío de trazas de prueba, de ahí el nombre de la traza recibida test_trace.

¡Pues ya estaría! Ya tenemos nuestra instancia preparada para el envío de todos los datos de métricas y trazas que deseamos. Estoy a vuestra disposición si queréis profundizar más en el tema.

2 comentarios
Comentarios (2)1
Inicie sesión o regístrese para continuar
Anuncio
· 16 jun, 2025

InterSystems EMPI (formerly HealthShare Patient Index) – Virtual July 9-11, 2025 / Registration space available

InterSystems EMPI (formerly HealthShare Patient Index) – Virtual  July 9-11, 2025

  • Configure, tune, and work with InterSystems EMPI, an Enterprise Master Person Index
  • This 3-day course teaches the installation, configuration, and use of InterSystems EMPI™ (formerly HealthShare® Patient Index).
  • Starting with version 2025.1, HealthShare Patient Index has been renamed to InterSystems EMPI, but the core functionality remains the same.
  • Day one focuses on person identification issues, and the tools that can be used for reviewing records identified by the system for human attention. This session is appropriate for both technical staff and administrative staff who manage person identification issues.
  • Day two starts with installation, and in the course of two days moves through the initial configuration of a system, the process for onboarding additional data sources, data flow, and utility programs.
  • This course is applicable to users of both InterSystems EMPI (version 2025.1 and later) and HealthShare Patient Index (prior to version 2025.1).

SELF REGISTER HERE

Comentarios (0)1
Inicie sesión o regístrese para continuar
Anuncio
· 16 jun, 2025

[Video] It's CLEAR - Re-Imagining the Digital Front Door

Hi Community,

Enjoy the new video on InterSystems Developers YouTube:

⏯ It's CLEAR - Re-Imagining the Digital Front Door @ Global Summit 2024

Our new partnership with CLEAR provides exciting new capabilities for a variety of use cases, such as the patient registration and check-in process. See how to utilize CLEAR-verified digital identities and the InterSystems Health Gateway Service to eliminate the clipboard.  

Presenters:
🗣 @Alex MacLeod, Director, Healthcare Solution Innovation, InterSystems
🗣 Jason Sherwin, Senior Director of Business Development, CLEAR

Press play for insights, and subscribe to stay one step ahead.

Comentarios (0)1
Inicie sesión o regístrese para continuar