#InterSystems IRIS for Health

0 Abonnés · 382 Publications

InterSystems IRIS for Health™ est la première et la seule plateforme de données au monde conçue spécifiquement pour le développement rapide d'applications de santé afin de gérer les données les plus critiques du monde. Elle comprend de puissantes fonctionnalités prêtes à l'emploi : traitement et analyse des transactions, modèle de données de santé extensible, développement de solutions basé sur FHIR, prise en charge des normes d'interopérabilité de santé, etc. Toutes ces fonctionnalités permettent aux développeurs de créer rapidement de la valeur et des applications révolutionnaires. En savoir plus.

Article Iryna Mykhailova · Nov 5, 2025 6m read

Salut!

C'est encore moi 😁. Dans l'article précédent Comment écrire un service API REST pour exporter le paquet FHIR généré au format JSON, nous avons généré une ressource DocumentReference, dont le contenu était encodé en Base64

Question!! Est-il possible d'écrire un service REST pour le décoder? Je voudrais vraiment savoir ce que contiennent les données du message🤔🤔🤔

Bien, allons-y!

1. Créez une nouvelle classe utilitaire datagen.utli.decodefhirjson.cls pour décoder les données contenues dans DocumentReference
 

Class datagen.utli.decodefhirjson Extends%RegisteredObject
{
}

2. Écrivez une fonction Python decodebase64docref pour 
a. parcourir le paquet FHIR
b. découvrir la ressource DocumentReference
  - récupérer le premier élément dans le contenu
   - récupérer la pièce jointe à partir de  contenu
     - récupérer les données à partir de la pièce jointe
c. décoder les données par Base64
 (pour cette partie, j'ai demandé l'aide de Chat-GPT😂🤫) 

Class datagen.utli.decodefhirjson Extends%RegisteredObject
{

ClassMethod decodebase64docref(fhirbundle = "") As%String [ Language = python ] { # w##class(datagen.utli.decodefhirjson).decodebase64docref() import base64 import json

def decode_discharge_summary(bundle_json):
    <span class="hljs-string">"""
    Extracts and decodes the Base64-encoded discharge summary note
    from a FHIR Bundle containing a DocumentReference.
    """</span>
    <span class="hljs-keyword">for</span> entry in bundle_json.get(<span class="hljs-string">"entry"</span>, []):
        resource = entry.get(<span class="hljs-string">"resource"</span>, {})
        <span class="hljs-keyword">if</span> resource.get(<span class="hljs-string">"resourceType"</span>) == <span class="hljs-string">"DocumentReference"</span>:
            # Traverse to the attachment
            content_list = resource.get(<span class="hljs-string">"content"</span>, [])
            <span class="hljs-keyword">if</span> not content_list:
                <span class="hljs-keyword">continue</span>
            attachment = content_list[<span class="hljs-number">0</span>].get(<span class="hljs-string">"attachment"</span>, {})
            base64_data = attachment.get(<span class="hljs-string">"data"</span>)
            <span class="hljs-keyword">if</span> base64_data:
                decoded_text = base64.b64decode(base64_data).decode(<span class="hljs-string">"utf-8"</span>)
                <span class="hljs-keyword">return</span> decoded_text
    <span class="hljs-keyword">return</span> None


# Example usage
# Load your FHIR Bundle JSON from a file or object
#with <span class="hljs-keyword">open</span>(<span class="hljs-string">"fhir_bundle.json"</span>, <span class="hljs-string">"r"</span>) <span class="hljs-keyword">as</span> f:
#    fhir_bundle = json.loads(f)
<span class="hljs-keyword">if</span> fhirbundle==<span class="hljs-string">""</span>:
    rtstr=f<span class="hljs-string">"&#x26a0;&#xfe0f; No input found - JSON string is required."</span>
    jsstr={<span class="hljs-string">"operation_outcome"</span> : rtstr}
    <span class="hljs-keyword">return</span> json.dumps(jsstr, indent=<span class="hljs-number">2</span>)

fhir_bundle = json.loads(fhirbundle)
decoded_note = decode_discharge_summary(fhir_bundle)

<span class="hljs-keyword">if</span> decoded_note:
    #<span class="hljs-keyword">print</span>(<span class="hljs-string">"&#x1f4dd; Decoded Discharge Summary:\n"</span>)
    #<span class="hljs-keyword">print</span>(decoded_note)
    rtstr=f<span class="hljs-string">"&#x1f4dd; Decoded Discharge Summary:\n {decoded_note}"</span>
<span class="hljs-keyword">else</span>:
    #<span class="hljs-keyword">print</span>(<span class="hljs-string">"&#x26a0;&#xfe0f; No DocumentReference with Base64 note found."</span>)
    rtstr=f<span class="hljs-string">"&#x26a0;&#xfe0f; No DocumentReference with Base64 note found."</span>
jsstr={<span class="hljs-string">"data"</span> : rtstr}
<span class="hljs-keyword">return</span> json.dumps(jsstr, indent=<span class="hljs-number">2</span>)

}

}

Pour tester cette fonction, j' essaie une astuce qui consiste à utiliser la fonction genfhirbundle pour générer un paquet FHIR dans une chaîne JSON,  comme expliqué dans l'article précédent Comment écrire un service API REST pour exporter le paquet FHIR généré au format JSON 

Générons un paquet FHIR et stockons-le dans une variable jsonstr

set jsonstr=##class(datagen.utli.genfhirjson).genfhirbundle(1)

Testons la fonction de décodage decodebase64docref  avec jsonstr

w##class(datagen.utli.decodefhirjson).decodebase64docref(jsonstr)

Bien 😉 Ça semble correct. Je peux désormais lire le message décodé.


Maintenant,  revenez à l'article précédent Comment écrire un service API REST pour exporter les données patient générées au format .csv

Nous aimerions ajouter une nouvelle fonction et mettre à jour le chemin d'accès pour la classe datagen.restservice .

1. Ajoutez une nouvelle fonction DecodeDocRef, qui est censée traiter le paquet FHIR  joint dans le corps au format JSON.

Par exemple, dans ce cas, nous prévoyons un POST.

Le contenu du corps est packagé par défaut sous la forme %CSP.BinaryStream et stocké dans la variable %request.Content, nous pouvons donc utiliser la fonction .Read()  à partir de la classe %CSP.BinaryStream pour lire le BinaryStream

ClassMethod DecodeDocRef() As%Status
{
    // récupération du corps - chaîne json#dim bistream As%CSP.BinaryStream =""set bistream=%request.Contentset jsstr=bistream.Read()
<span class="hljs-comment">//décodage des données de référence du document</span>
<span class="hljs-keyword">w</span> <span class="hljs-keyword">##class</span>(datagen.utli.decodefhirjson).decodebase64docref(jsstr)
<span class="hljs-keyword">return</span> <span class="hljs-built_in">$$$OK</span>

}

2. Ensuite, nous ajoutons un chemin d'accès pour le service REST et compilons😀

<Route Url="/decode/docref" Method="POST" Call="DecodeDocRef" />

La classe  datagen.restservice mise à jour se présentera comme suit.


Génial!! C'est tout ce qu'il y a à faire!😁

Nous allons vérifier cela dans Postman!!

COLLEZ le chemin d'accès  suivant

localhost/irishealth/csp/mpapp/decode/docref

avec le corps suivant (j'ai utilisé un paquet FHIR simplifié, vous pouvez tester le paquet complet😀)

{
    "resourceType": "Bundle",
    "type": "transaction",
    "id": "98bfce83-7eb1-4afe-bf2b-42916512244e",
    "meta": {
        "lastUpdated": "2025-10-13T05:49:07Z"
    },
    "entry": [
        {
            "fullUrl": "urn:uuid:5be1037d-a481-45ca-aea9-2034e27ebdcd",
            "resource": {
                "resourceType": "DocumentReference",
                "id": "5be1037d-a481-45ca-aea9-2034e27ebdcd",
                "status": "current",
                "type": {
                    "coding": [
                        {
                            "system": "http://loinc.org",
                            "code": "18842-5",
                            "display": "Discharge summary"
                        }
                    ]
                },
                "subject": {
                    "reference": "9e3a2636-4e87-4dee-b202-709d6f94ed18"
                },
                "author": [
                    {
                        "reference": "2aa54642-6743-4153-a171-7b8a8004ce5b"
                    }
                ],
                "context": {
                    "encounter": [
                        {
                            "reference": "98cd848b-251f-4d0b-bf36-e35c9fe68956"
                        }
                    ]
                },
                "content": [
                    {
                        "attachment": {
                            "contentType": "text/plain",
                            "language": "en",
                            "data": "RGlzY2hhcmdlIHN1bW1hcnkgZm9yIHBhdGllbnQgOWUzYTI2MzYtNGU4Ny00ZGVlLWIyMDItNzA5ZDZmOTRlZDE4LiBEaWFnbm9zaXM6IFN0YWJsZS4gRm9sbG93LXVwIGluIDIgd2Vla3Mu",
                            "title": "Discharge Summary Note"
                        }
                    }
                ]
            },
            "request": {
                "method": "POST",
                "url": "DocumentReference"
            }
        }
    ]
}

Ça marche parfaitement!!!😆😉

Merci infiniment à tous d'avoir pris le temps de lire cet article. 😘

0
0 10
InterSystems officiel Adeline Icard · Nov 4, 2025

InterSystems IRIS Adaptive Analytics version 2025.4.1 est désormais disponible sur la page de distribution des logiciels InterSystems. Cette version inclut AtScale 2025.4.1 et est compatible avec le fichier UDAF (User-Defined Aggregate Function) Adaptive Analytics existant (version 2024.1). Parmi les nouvelles fonctionnalités d'AtScale 2025 :

0
0 7
Article Iryna Mykhailova · Nov 3, 2025 13m read

Bonjour à tous,

Continuons à travailler sur la génération de données de test et l'exportation des résultats via une API REST. 😁

Ici, je souhaite réutiliser la classe `datagen.restservice` créée dans l'article précédent : « Écriture d'un service API REST pour exporter les données patient générées au format .csv ».

Cette fois-ci, nous prévoyons de générer un bundle FHIR incluant plusieurs ressources pour tester le référentiel FHIR.

Voici une référence si vous souhaitez en savoir plus sur FHIR : « The Concept of FHIR: A Healthcare Data Standard Designed for the Future ».

C'est parti ! 😆

0
0 10
Article Lorenzo Scalese · Oct 28, 2025 10m read

Le déploiement de nouvelles instances IRIS peut être une tâche fastidieuse, en particulier lors de la mise en place de plusieurs environnements avec des configurations en miroir.

J'ai fait face à ce problème très souvent et je souhaite partager mon expérience et mes recommandations concernant l'utilisation d'Ansible pour rationaliser le processus d'installation d'IRIS. Mon approche inclut également la gestion des tâches supplémentaires généralement effectuées avant et après l'installation d'IRIS.

Ce manuel suppose que vous disposez d'une compréhension de base du fonctionnement d'Ansible, je ne détaillerai donc pas ses principes fondamentaux. Toutefois, si vous avez des questions sur les points abordés ici, n'hésitez pas à les poser dans les commentaires ci-dessous.

Les exemples fournis dans ce manuel ont été testés à l'aide d' Ansible 3.6 sur un serveur Red Hat 8, avec IRIS 2023.1.1 et Red Hat 8 comme environnement client. D'autres versions d'Ansible, de Red Hat (ou d'autres variantes d'UNIX) et d'IRIS peuvent également fonctionner, mais les résultats peuvent varier.

Installation d'Ansible

Le serveur Ansible nécessite une distribution Linux. Nous utilisons Red Hat 8 dans cet article, mais d'autres distributions et versions Linux devraient également fonctionner.

Pour installer les paquets Ansible, il faut d'abord installer EPEL:

[ansible@auto01 ansible]$ yum install https://dl.fedoraproject.org/pub/epel/epel-release-latest-8.noarch.rpm

Ensuite, il faut installer Ansible:

[ansible@auto01 ansible]$ yum install ansible

En plus des paquets, Ansible nécessite un accès SSH aux serveurs distants. Je recommande de créer une paire de clés SSH, ce qui est plus sûr que l'utilisation de mots de passe traditionnels. De plus, l'utilisateur servant à se connecter aux serveurs distants doit disposer de privilèges administratifs (c'est-à-dire faire partie du groupe wheel).

Fichiers et dossiers

Pour préserver une structure organisée, je recommande les fichiers et dossiers suivants dans le répertoire ansible:

[ansible@auto01 ansible]$ ls -l
total 4
-rw-r--r--. 1 ansible ansible 247 Dec  500:57 ansible.cfg
drwxrwxr-x. 2 ansible ansible   6 Dec  500:56 files
drwxrwxr-x. 2 ansible ansible   6 Dec  500:56 inventory
drwxrwxr-x. 2 ansible ansible   6 Dec  500:56 library
drwxrwxr-x. 2 ansible ansible   6 Dec  500:56 playbooks
drwxrwxr-x. 2 ansible ansible   6 Dec  500:56 templates
drwxrwxr-x. 2 ansible ansible   6 Dec  500:56 vars
drwxrwxr-x. 2 ansible ansible   6 Dec  500:56 vault
Fichier/DossierDescription
ansible.cfgFichier de configuration d'Ansible. Contient des directives sur le comportement d'Ansible.
filesContient les fichiers supplémentaires nécessaires aux playbooks, tels que le fichier tar.gz d'installation d'IRIS.
inventoryContient les fichiers d'inventaire de l'hôte. Vous pouvez avoir un seul fichier d'inventaire volumineux ou plusieurs fichiers de moindre taille. Le fractionnement de l'inventaire nécessite davantage d'efforts lorsque vous exécutez des playbooks sur plusieurs hôtes.
libraryContient des fichiers de bibliothèque supplémentaires d'Ansible. Non requis pour ces exemples, mais utile pour de futures extensions.
playbooksContient tous les playbooks développés, y compris le playbook d'installation IRIS décrit ci-dessous.
templatesContient les fichiers modèles utilisés par les playbooks. Ceux-ci sont transférés vers les serveurs et instanciés avec les paramètres corrects.
varsContient les variables disponibles pour tous les playbooks.
vaultContient des variables sensibles accessibles uniquement via la commande ansible-vault. Utile pour gérer les mots de passe.

 

Après avoir configuré cette structure de dossiers, copiez le programme d'installation IRIS et la clé de licence IRIS dans le dossier files. Le résultat devrait apparaître comme suit:

[ansible@auto01 ansible]$ ls -l files/
total 759976
-rw-rw-r--. 1 ansible ansible 778207913 Dec  514:32 IRISHealth-2023.1.1.380.0.22870-lnxrh8x64.tar.gz
-rw-rw-r--. 1 ansible ansible      1160 Sep  519:13 iris.key

 

Inventaire

Pour exécuter des playbooks dans Ansible, il est nécessaire de définir l'inventaire des serveurs. Il existe plusieurs méthodes pour ce faire, et chacune présente ses propres avantages. Dans cet article, nous utiliserons un seul fichier pour définir tous les serveurs.

Le ficher servers.yml contiendra l'inventaire complet, répertoriant chaque serveur ainsi que les variables requises pour l'installation d'IRIS. Voici un exemple:

[ansible@auto01ansible]$catinventory/servers.yml 
---all:  hosts:test01.mydomain:      iris_user:irisusr      iris_group:irisgrp      mgr_user:irisown      mgr_group:irismgr      platform:lnxrh8x64      iris_cmd:iris      iris_instances:        - name:TEST01          superserver_port:51773          webserver_port:52773          binary_file:IRISHealth-2023.1.1.380.0.22870-lnxrh8x64          key_file:iris.key          install_dir:/test/iris          jrnpri_dir:/test/jrnpri          jrnsec_dir:/test/jrnsec          config_globals:16384          config_errlog:10000          config_routines:"0,128,0,128,0,1024"          config_gmheap:1048576          config_locksiz:128057344

 

Fichier coffre-fort

Pour sécuriser les mots de passe, créez un fichier coffre-fort contenant les mots de passe des comptes IRIS SuperUser et CSPSystem.

Pour modifier le fichier coffre-fort par défaut, utilisez la commande suivante:

[ansible@auto01ansible]$ansible-vaulteditvault/defaults.yml---# Default passwordsiris_user_passwd:"Ch4ngeTh!s"

 

Playbook

Pour effectuer une installation IRIS, il est nécessaire d'exécuter plusieurs tâches sur le serveur cible. Ces tâches sont regroupées et classées dans un fichier appelé playbook.
Un playbook consiste essentiellement en une liste de tâches qui sont exécutées de manière séquentielle sur les hôtes distants.

Vous trouverez ci-dessous le playbook que j'ai développé pour installer IRIS:

[ansible@auto01ansible]$catplaybooks/install_iris.yml## Playbook to install Iris#- hosts:all  become:yes  gather_facts:no  tasks:  - name:"Load default passwords"    include_vars:"../vault/defaults.yml"### PRE-INSTALL TASKS:  - name:"Install required packets"    yum:      name:"{{ item }}"      state:latest    loop:      -"httpd"      -"java-1.8.0-openjdk"      -"mod_auth_mellon"      -"mod_ssl"  - name:"Create iris group"    group:      name:"{{ iris_group }}"      gid:5005  - name:"Create iris mgr group"    group:      name:"{{ mgr_group }}"      gid:5006  - name:"Create iris owner user"    user:      name:"{{ mgr_user }}"      uid:5006      group:"{{ iris_group }}"      groups:"{{ mgr_group }}"  - name:"Create iris user"    user:      name:"{{ iris_user }}"      uid:5005      group:"{{ iris_group }}"  - name:"Create mgr folder"    file:      path:"{{ item.install_dir }}/mgr"      state:directory      owner:"{{ iris_user }}"      group:"{{ iris_group }}"      mode:0775    loop:"{{ iris_instances }}"    loop_control:      label:"{{ item.name }}"  - name:"Copy license key"    copy:      src:"../files/{{ item.key_file }}"      dest:"{{ item.install_dir }}/mgr/iris.key"      owner:"{{ iris_user }}"      group:"{{ iris_group }}"      backup:yes    loop:"{{ iris_instances }}"    loop_control:      label:"{{ item.name }}"  - name:"Create /install folder"    file:      path:"/install"      state:directory      mode:0777  - name:"Create Instances install folders"    file:      path:"/install/{{ item.name }}"      state:directory      mode:0777    loop:"{{ iris_instances }}"    loop_control:      label:"{{ item.name }}"  - name:"Copy IRIS installer"    copy:      src:"../files/{{ item.binary_file }}.tar.gz"      dest:"/install/{{ item.name }}/"    loop:"{{ iris_instances }}"    loop_control:      label:"{{ item.name }}"  - name:"Untar IRIS installer"    command:      cmd:"tar -xzf /install/{{ item.name }}/{{ item.binary_file }}.tar.gz"      chdir:"/install/{{ item.name }}/"    loop:"{{ iris_instances }}"    loop_control:      label:"{{ item.name }}"### IRIS INSTALL:  - name:"Install Iris"    command:      cmd:"./irisinstall_silent"      chdir:"/install/{{ item.name }}/{{ item.binary_file }}"    environment:      ISC_PACKAGE_INSTANCENAME:"{{ item.name }}"      ISC_PACKAGE_INSTALLDIR:"{{ item.install_dir }}"      ISC_PACKAGE_PLATFORM:"{{ platform }}"      ISC_PACKAGE_UNICODE:"Y"      ISC_PACKAGE_INITIAL_SECURITY:"Normal"      ISC_PACKAGE_MGRUSER:"{{ mgr_user }}"      ISC_PACKAGE_MGRGROUP:"{{ mgr_group }}"      ISC_PACKAGE_USER_PASSWORD:"{{ iris_user_passwd }}"      ISC_PACKAGE_CSPSYSTEM_PASSWORD:"{{ iris_user_passwd }}"      ISC_PACKAGE_IRISUSER:"{{ iris_user }}"      ISC_PACKAGE_IRISGROUP:"{{ iris_group }}"      ISC_PACKAGE_SUPERSERVER_PORT:"{{ item.superserver_port }}"      ISC_PACKAGE_WEBSERVER_PORT:"{{ item.webserver_port }}"      ISC_PACKAGE_CLIENT_COMPONENTS:"standard_install"      ISC_PACKAGE_STARTIRIS:"N"    loop:"{{ iris_instances }}"    loop_control:      label:"{{ item.name }}"  - name:"Remove installers"    file:      path:"/install/{{ item.name }}"      state:absent    loop:"{{ iris_instances }}"    loop_control:      label:"{{ item.name }}"### IRIS CUSTOMIZATIONS:  - name:"Change iris.cpf"    lineinfile:      path:"{{ item[0].install_dir }}/iris.cpf"      regexp:"{{ item[1].from }}"      line:"{{ item[1].to }}"      backup:yes    with_nested:      -"{{ iris_instances }}"      -[{from:"^TerminalPrompt=.*",to:"TerminalPrompt=8,3,2"},{from:"^FreezeOnError=0",to:"FreezeOnError=1"},{from:"^AutoParallel=.*",to:"AutoParallel=0"},{from:"^FastDistinct=.*",to:"FastDistinct=0"},{from:"^LockThreshold=.*",to:"LockThreshold=10000"},{from:"^EnsembleAutoStart=.*",to:"EnsembleAutoStart=1"},{from:"^MaxIRISTempSizeAtStart=.*",to:"MaxIRISTempSizeAtStart=300"}]    loop_control:      label:"{{ item[0].name }}: {{ item[1].to }}"  - name:"Change Journal Current Dir"    lineinfile:      path:"{{ item.install_dir }}/iris.cpf"      regexp:"^CurrentDirectory=.*"      line:"CurrentDirectory={{ item.jrnpri_dir }}"      backup:yes    loop:"{{ iris_instances }}"    loop_control:      label:"{{ item.name }}"  - name:"Change Journal Alternate Dir"    lineinfile:      path:"{{ item.install_dir }}/iris.cpf"      regexp:"^AlternateDirectory=.*"      line:"AlternateDirectory={{ item.jrnsec_dir }}"      backup:yes    loop:"{{ iris_instances }}"    loop_control:      label:"{{ item.name }}"  - name:"Change Journal Prefix name"    lineinfile:      path:"{{ item.install_dir }}/iris.cpf"      regexp:"^JournalFilePrefix=.*"      line:"JournalFilePrefix={{ item.name }}_"      backup:yes    loop:"{{ iris_instances }}"    loop_control:      label:"{{ item.name }}"  - name:"Change Globals memory"    lineinfile:      path:"{{ item.install_dir }}/iris.cpf"      regexp:"^globals=.*"      line:"globals=0,0,{{ item.config_globals }},0,0,0"      backup:yes    loop:"{{ iris_instances }}"    loop_control:      label:"{{ item.name }}"  - name:"Change errlog memory"    lineinfile:      path:"{{ item.install_dir }}/iris.cpf"      regexp:"^errlog=.*"      line:"errlog={{ item.config_errlog }}"      backup:yes    loop:"{{ iris_instances }}"    loop_control:      label:"{{ item.name }}"  - name:"Change routines memory"    lineinfile:      path:"{{ item.install_dir }}/iris.cpf"      regexp:"^routines=.*"      line:"routines={{ item.config_routines }}"      backup:yes    loop:"{{ iris_instances }}"    loop_control:      label:"{{ item.name }}"  - name:"Change gmheap memory"    lineinfile:      path:"{{ item.install_dir }}/iris.cpf"      regexp:"^gmheap=.*"      line:"gmheap={{ item.config_gmheap }}"      backup:yes    loop:"{{ iris_instances }}"    loop_control:      label:"{{ item.name }}"  - name:"Change locksiz memory"    lineinfile:      path:"{{ item.install_dir }}/iris.cpf"      regexp:"^locksiz=.*"      line:"locksiz={{ item.config_locksiz }}"      backup:yes    loop:"{{ iris_instances }}"    loop_control:      label:"{{ item.name }}"### START IRIS:  - name:"Start Iris"    command:"iris start {{ item.name }}"    loop:"{{ iris_instances }}"    loop_control:      label:"{{ item.name }}"...

Comme vous pouvez le constater, ce playbook comporte plusieurs tâches, dont la plupart sont explicites d'après leur nom. Les commentaires indiquent les tâches à effectuer avant l'installation, l'installation proprement dite et les personnalisations à effectuer après l'installation. Après avoir exécuté ce playbook, vous disposerez d'une nouvelle instance IRIS installée sur le système cible, dont la mémoire et d'autres paramètres auront été personnalisés.

Lancez l'installation!

Après avoir configuré l'inventaire, le ficheir coffre-fort et les playbooks, vous êtes prêt à exécuter l'installation IRIS à l'aide d'Ansible.
Pour ce faire, exécutez la commande suivante:

[ansible@auto01 ansible]$ ansible-playbook -K --ask-vault-pass -i inventory/servers.yml playbooks/install_iris.yml
BECOME password: 
Vault password: 

PLAY [all] ************************************************************************************************************************************************** . . .

Lorsque l'exécution du playbook est terminée, vous recevez un résumé de statuts des tâches qui vous permet de vérifier que tout a été exécuté avec succès.

Et voilà, vous venez d'installer IRIS à l'aide d'Ansible! 😁

0
0 14
InterSystems officiel Adeline Icard · Oct 24, 2025

Les versions de maintenance 2025.1.2 et 2024.1.5 de la plateforme de données InterSystems IRIS, d'InterSystems IRIS for Health et d'HealthShare Health Connect sont désormais disponibles en disponibilité générale (GA). Ces versions incluent les correctifs pour plusieurs alertes et avis publiés récemment, notamment :

0
0 15
Article Iryna Mykhailova · Oct 23, 2025 6m read

Salut,

C'est moi encore 😁. Je travaille actuellement à la génération de fausses données patients à des fins de test avec Chat-GPT et Python. J'aimerais également partager mon apprentissage. 😑

Tout d'abord, créer un service d'API REST personnalisé est facile en utilisant %CSP.REST.

Commençons ! 😂

1. Créez une classe datagen.restservice qui étend %CSP.REST.

Class datagen.restservice Extends%CSP.REST
{
Parameter CONTENTTYPE = "application/json";
}

2. Ajoutez une fonction genpatientcsv() pour générer les données du patient et les regrouper dans une chaîne csv

0
0 18
Article Sylvain Guilbaud · Oct 22, 2025 4m read

Bonjour à tous les membres de la communauté!

Beaucoup d'entre vous se souviennent certainement des fonctionnalités NLP disponibles dans IRIS sous le nom iKnow, qui ont été supprimées depuis peu de temps. Mais... Tout a-t-il été supprimé ? NON! Un petit village résiste à la suppression: les index iFind!

Vous vous demandez peut-être à quoi servent ces magnifiques index. C'est très simple : ils indexent le texte dans les colonnes String et Stream et accélèrent considérablement les requêtes.

À quoi servent les index %iFind?

Il s'agit d'un type d'index basé sur des cartes binaires. Ces index mappent chaque valeur unique d'une colonne dans une chaîne de bits, indiquant pour chaque ligne la disponibilité d'une valeur donnée. Vous trouverez plus de détails sur ces types d'index dans la documentation officielle .

Nous disposons de deux types d'index %iFind : minimal et basique, qui est une extension du type minimal.

%iFind.Index.Minimal

Prend en charge des recherches SQL de mots et d'expressions avec caractères génériques, des recherches approximatives et des expressions régulières. Ne prend pas en charge les recherches par cooccurrence ou par expressions positionnelles, ni la mise en évidence des résultats.

%iFind.Index.Basic

Prend en charge toutes les fonctionnalités de l'index minimal (recherche SQL de mots et d'expressions avec des caractères génériques) et ajoute la prise en charge de la cooccurrence, la recherche d'expressions positionnelles et la mise en évidence des résultats. Les fonctionnalités de cet index sont suffisantes pour la plupart des recherches en texte intégral courantes.

Comment définir un index %iFind?

Rien de plus simple, je vais vous montrer à l'aide d'un petit exemple tiré d'un développement que j'ai mis en place pour lire les informations relatives aux appels d'offres publics en Espagne:

Class Inquisidor.Object.Licitacion Extends (%Persistent, %XML.Adaptor) [ DdlAllowed ]
{

Property IdLicitacion As%String(MAXLEN = 200);Property Titulo As%String(MAXLEN = 2000);
...

Index IndexIdLicitation On IdLicitacion [ PrimaryKey ];
Index IndexTitulo On (Titulo) As%iFind.Index.Basic(INDEXOPTION = 0, LANGUAGE = "es");

Comme vous pouvez le voir, nous avons défini la propriété Titre sur laquelle nous voulons effectuer des recherches afin de trouver certaines offres. Voici un exemple des titres que nous allons avoir:

Service de maintenance et d'assistance de l'application informatique CIVITAS pour la gestion de la carte sanitaire individuelle de la Direction régionale de la santé de Castille-et-León.

Pour définir l'index %iFind, nous utiliserons la configuration %iFind.Index.Basic(INDEXOPTION = 0, LANGUAGE = "es") . Dans ce cas, il s'agit d'un index de base. Comme vous pouvez le voir, nous disposons d'une série de propriétés qui nous permettent de définir le fonctionnement de notre index. Voyons les propriétés disponibles:

  • IGNOREPUNCTUATION: Prend en charge 2 valeurs, 0 et 1. Par défaut, la valeur est 1 et les signes de ponctuation dans le texte sont ignorés.
  • INDEXOPTION: cette option peut également prendre les valeurs 0 et 1. Elle permet de spécifier si l'index autorisera la lemmatisation ou la décomposition des textes. En raison de la taille importante que cela peut nécessiter, cette option ne doit être activée que si cela est nécessaire (valeur 1).
  • LANGUAGE: permet de définir le dictionnaire à utiliser pour les recherches, dans notre exemple, l'espagnol.
  • LOWER: cette option peut prendre les valeurs 0 ou 1. Elle permet d'indiquer si l'index sera sensible à la casse (majuscules/minuscules). Par défaut, elle est définie sur 0, ce qui signifie qu'elle est ignorée.
  • USERDICTIONARY: cette option permet à l'index d'utiliser un dictionnaire utilisateur avant l'indexation.

Comment utiliszer l'index %iFind dans une requête?

Pour utiliser ce type d'index, nous devons utiliser la notation suivante:

SELECT * FROM Inquisidor_Object.Licitacion WHERE %ID%FIND search_index(IndexTitulo, ?)

Voyons comment fonctionne l'index. Dans mon exemple, j'ai une table contenant 800 000 enregistrements d'appels d'offres publics. Voyons le plan avec le LIKE traditionnel sur notre table:

Voyons maintenant le plan utilisant l'index:

Comme vous pouvez le constater, le rapport entre le temps de recherche normal et celui obtenu avec l'index %iFind est astronomique : 1239110280 pour la requête sans index contre 8323422 pour la requête indexée, soit une rapidité 150 fois supérieure.

Si vous souhaitez voir plus en détail le type de recherches permises par les index %iFind, vous trouverez here ici la documentation nécessaire.

J'espère que cela vous sera utile!

0
0 19
Article Iryna Mykhailova · Oct 21, 2025 2m read

Bonjour,

Je voulais partager avec vous une méthode pratique qui m'a été utile lors de mes développements sur Health Connect Cloud avec VS Code et GitBash. Lors de ces développements, si des modifications sont effectuées directement sur le serveur, comme des règles de routage ou des déploiements de composants, elles ne sont pas automatiquement incluses dans le contrôle de code source. Vous devez donc exporter les modifications depuis le serveur vers vos fichiers locaux et les envoyer vers votre dépôt distant. Je suis sûr qu'il existe des méthodes plus simples pour gérer ce problème, que je suis en train de tester, mais pour une solution rapide, j'ai pensé qu'il serait utile d'utiliser une méthode de pré-validation qui déclenche un rappel dans GitBash – voir ci-dessous.

0
0 16
Article Iryna Mykhailova · Oct 20, 2025 2m read

Rubrique FAQ InterSystems

Dans InterSystems IRIS, vous pouvez créer des tables liées à l'aide de commandes, au lieu d'utiliser System Explorer > SQL > Wizard > Linked Tables dans le Portail de gestion :

Pour créer une table liée, utilisez la méthode CreateLinkedTable de la classe %SYSTEM.SQL.Schema. Consultez la référence de la classe pour plus de détails.

Pour l'exécuter, procédez comme suit :

0
0 15
Article Iryna Mykhailova · Oct 17, 2025 1m read

Rubrique FAQ InterSystems

Certaines données, telles que les données du journal d'exécution, ne doivent pas être restaurées à leur état antérieur, même en cas de restauration lors d'une transaction. Pour ce faire, placez ces données dans la base de données IRISTEMP, qui ne sera pas restaurée.

Temporary Globals and the IRISTEMP Databas

0
0 16
Article Lorenzo Scalese · Sept 23, 2025 8m read

Mes clients me contactent régulièrement à propos du dimensionnement de la mémoire lorsqu'ils reçoivent des alertes indiquant que la mémoire libre est inférieure à un seuil ou lorsqu'ils constatent que la mémoire libre a soudainement diminué. Existe-t-il un problème? Leur application va-t-elle cesser de fonctionner parce qu'elle manque de mémoire pour exécuter les processus système et applicatifs? La réponse est presque toujours non, il est inutile de s'inquiéter. Mais cette réponse simple n'est généralement pas suffisante. Que se passe-t-il?

Considérez le graphique ci-dessous. Il montre le résultat de la métrique free dans vmstat. Il existe d'autres moyens d'afficher la mémoire libre d'un système, par exemple la commande free -m. Parfois, la mémoire libre disparaît progressivement au fil du temps. Le graphique ci-dessous est un exemple exagéré, mais il illustre bien ce qui se passe.

image

Comme vous pouvez le constater, vers 2 heures du matin, une partie de la mémoire est récupérée, puis chute soudainement à près de zéro. Ce système exécute l'application IntelliCare EHR sur la base de données InterSystems IRIS. Les informations vmstat proviennent d'un fichier HTML ^SystemPerformance qui collecte les métriques vmstat, iostat et plusieurs autres métriques système. Que se passe-t-il d'autre sur ce système ? Comme nous sommes en pleine nuit, je ne m'attends pas à ce qu'il se passe grand-chose à l'hôpital. Examinons iostat pour les volumes de la base de données.

image

On constate une augmentation soudaine des lectures au moment où la mémoire libre diminue. La baisse de la mémoire libre signalée correspond à un pic des lectures en gros blocs (taille de requête de 2048 Ko) indiqué dans iostat pour le disque de la base de données. Il s'agit très probablement d'un processus de sauvegarde ou d'une copie de fichiers. Bien sûr, corrélation n'est pas synonyme de causalité, mais cela vaut la peine d'être examiné et, en fin de compte, cela explique ce qui se passe.

Examinons d'autres résultats de ^SystemPerformance. La commande free -m est exécutée à la même fréquence que vmstat (par exemple, toutes les 5 secondes) et est accompagnée de la date et de l'heure, ce qui nous permet également de représenter graphiquement les compteurs dans free -m.

Les compteurs:

  • Memtotal – Total de RAM physique.
  • used – RAM activement utilisée (applications + système d'exploitation + cache).
  • free – RAM complètement inutilisée.
  • shared – Mémoire partagée entre les processus.
  • buf/cache – RAM utilisée pour les tampons et le cache, récupérable si nécessaire.
  • available – RAM disponible sans swap.
  • swaptotal – Espace de swap total sur le disque.
  • swapused – Espace de swap actuellement utilisé.
  • swapfree – Espace de swap inutilisé.

Pourquoi la mémoire libre diminue-t-elle à 2 heures du matin?

  • Les lectures séquentielles de grande taille remplissent le cache de page du système de fichiers, consommant temporairement de la mémoire qui apparaît comme "utilisée" dans free -m.
  • Linux utilise de manière agressive la mémoire inexploitée pour la mise en cache des E/S afin d'améliorer les performances.
  • Une fois la sauvegarde terminée (≈ 03h00), la mémoire est progressivement récupérée au fur et à mesure que les processus en ont besoin.
  • Vers 6 heures du matin, l'hôpital commence à s'activer et la mémoire est utilisée pour IRIS et d'autres processus.

Une mémoire libre insuffisante ne constitue pas une pénurie, mais plutôt une utilisation de la mémoire "libre" par le système à des fins de mise en cache. Il s'agit d'un comportement normal sous Linux! Le processus de sauvegarde lit de grandes quantités de données, que Linux met agressivement en cache dans la mémoire tampon/cache. Le noyau Linux convertit la mémoire "libre" en mémoire "cache" afin d'accélérer les opérations d'E/S.

Résumé

Le cache du système de fichiers est conçu pour être dynamique. Si la mémoire est requise par un processus, elle sera immédiatement récupérée. Il s'agit d'un élément normal de la gestion de la mémoire sous Linux.


Les Huge Pages ont-elles un impact?

Pour optimiser les performances et réserver de la mémoire pour la mémoire partagée IRIS, la meilleure pratique pour les déploiements IRIS en production sur des serveurs dotés d'une mémoire importante consiste à utiliser les Huge Pages de Linux. Pour IntelliCare, j'utilise généralement 8 Go de mémoire par noyau et environ 75 % de la mémoire pour la mémoire partagée d'IRIS (tampons Routine et Global, GMHEAP et autres structures de mémoire partagée). La répartition de la mémoire partagée dépend des exigences de l'application. Vos exigences peuvent être complètement différentes. Par exemple, en utilisant ce rapport CPU/mémoire, 25 % suffisent-ils pour les processus IRIS et les processus du système d'exploitation de votre application?

InterSystems IRIS utilise l'E/S directe pour les fichiers de base de données et les fichiers journaux, ce qui contourne le cache du système de fichiers. Ses segments de mémoire partagée (globales, routines, gmheap, etc.) sont alloués à partir de Huge Pages.

  • Ces pages immenses (huge pages) sont dédiées à la mémoire partagée IRIS et n'apparaissent pas comme "libres" ou "cache" dans free -m.
  • Once allocated, huge pages are not available for filesystem cache or user processes.

Cela explique pourquoi les métriques free -m semblent "insuffisantes" même si la base de données IRIS elle-même ne manque pas de mémoire.


Comment la mémoire libre pour un processus est-elle calculée?

À partir de ce qui précède, dans free -m, les lignes pertinentes sont les suivantes:

  • free – RAM totalement inutilisée.
  • available – RAM encore utilisable sans échange.

La disponibilité est un bon indicateur: elle inclut la mémoire cache et les tampons récupérables, indiquant ce qui est réellement disponible pour les nouveaux processus sans échange. Quels processus? Pour plus d'informations, consultez InterSystems Data Platforms and Performance Part 4 - Looking at Memory . Voici une liste simple: système d'exploitation, autres processus d'application non-IRIS et processus IRIS.

Examinons un graphique de la sortie free -m.

image

Bien que la valeur de la mémoire libre (free) chute à près de zéro pendant la sauvegarde, la valeur de la mémoire disponible (available) reste beaucoup plus élevée (plusieurs dizaines de Go). Cela signifie que le système pourrait fournir cette mémoire aux processus si nécessaire.

A quel endroit apparaissent les pages immenses dans la mémoire libre?

Par défaut, free -m n'affiche pas directement les pages immenses. Pour les voir, vous avez besoin des entrées /proc/meminfo telles que HugePages_Total, HugePages_Free et Hugepagesize.

Puisque le système d'exploitation réserve des pages immenses au démarrage, elles sont effectivement invisibles pour free -m. Elles sont verrouillées et isolées du pool de mémoire général.

Résumé

  • La "mémoire disponible" insuffisante constatée vers 02h00 est due au remplissage du cache de pages Linux par des lectures de sauvegarde. Il s'agit d'un comportement normal qui n'indique pas une pénurie de mémoire.
  • Les pages immenses réservées à IRIS ne sont pas affectées et continuent à servir efficacement la base de données.
  • La mémoire réellement disponible pour les applications est mieux mesurée par la colonne disponible, qui montre que le système dispose encore d'une marge suffisante.

Mais attendez, que se passe-t-il si je n'utilise pas les Huge Pages?

Généralement, on n'utilise pas les Huge Pages sur les systèmes non productifs ou à mémoire limitée. Les gains de performances des Huge Pages ne sont généralement pas significatifs en dessous de 64 Go, bien qu'il soit toujours recommandé d'utiliser les Huge Pages pour protéger la mémoire partagée IRIS.

A propos. J'ai vu des sites rencontrer des problèmes en allouant des pages immenses moins grandes que la mémoire partagée, ce qui oblige IRIS à essayer de démarrer avec des tampons globaux très petits ou à échouer au démarrage si memlock est utilisé (envisagez memlock=192 pour les systèmes de production).

Sans Huge Pages, les segments de mémoire partagée IRIS ( globales, routines, gmheap, etc.) sont alloués à partir de pages de mémoire normales du système d'exploitation. Cela apparaîtrait sous la mémoire "utilisée" dans free -m. Cela contribuerait également à réduire la mémoire "disponible", car cette mémoire ne peut pas être facilement récupérée.

  • utilisée – Beaucoup plus élevée, reflétant la mémoire partagée IRIS + le noyau + d'autres processus.
  • libre – Probablement moins suffisante, car plus de RAM est allouée en permanence à IRIS dans le pool régulier.
  • buf/cache – Augmenterait toujours pendant les sauvegardes, mais la marge apparente pour les processus semblerait plus restreinte, car la mémoire IRIS se trouve dans le même pool.
  • disponible – Plus proche de la véritable “mémoire libre + cache récupérable” moins la mémoire IRIS. Cela semblerait plus petit que dans votre configuration Huge Pages.

Alors, faut-il utiliser Huge Pages dans des systèmes de production?

OUI!

Pour la protection de la mémoire. La mémoire partagée IRIS est protégée contre:

  • Remplacement en cas de sollicitation de la mémoire.
  • Concurrence avec les opérations du système de fichiers telles que les sauvegardes et les copies de fichiers, comme nous l'avons vu dans cet exemple.

Autres remarques - trop profondément dans les détails...

Comment les données sont-elles collectées?

La commande utilisée dans ^SystemPerformance pour une collecte de 24 heures (17 280 secondes) avec des coches toutes les 5 secondes est la suivante:

free -m -s 5 -c 17280 | awk '{now=strftime(""%m/%d/%y %T""); print now "" "" $0; fflush()}' > ","/filepath/logs/20250315_000100_24hours_5sec_12.log

0
0 22
Article Lorenzo Scalese · Sept 18, 2025 5m read

IrisTest est un outil léger, puissant et facile à utiliser, conçu pour simplifier la génération de rapports de tests unitaires. Il comprend un interpréteur de commandes interactif et une API pour faciliter la communication, permettant aux développeurs de gérer et de générer facilement des rapports pour leurs tests dans des formats variés. Que vous déboguez ou créiez des rapports détaillés pour analyse, IrisTest rend le processus fluide et efficace!

Table des matières

  • Sommaire
  • Caractéristiques principales
  • Commandes shell
  • Utilisation
  • Formats de rapport
  • Installation
  • Configuration
  • Exemples
  • Commandes
  • Contribution
  • Licence

Sommaire

IrisTest est un outil en ligne de commande conçu pour générer des rapports de tests unitaires dans des formats variés avec une configuration minimale. Il est particulièrement pratique pour les développeurs et les testeurs qui recherchent un moyen efficace de suivre les résultats des cas de test, de générer des rapports et d'automatiser les workflows d'assurance qualité. Compatible avec une utilisation interactive et automatisation basée sur une API, IrisTest offre une flexibilité maximale.


Caractéristiques principales

  • 📊 Génération de rapports multiformats – Exportez vos rapports au format HTML, XML, JUnitXML, Allure, JSON, CSV, etc.
  • 🖥️ Interpréteur de commandes interactif – Pour exécuter des tests, gérer les configurations et afficher les résultats directement depuis l'interpréteur de commandes.
  • 🔌 Integration API – Pour automatiser vos workflows de génération de rapports de test.
  • ⚙️ Configuration simple – Pour personnaliser facilement les formats de sortie, les répertoires et les identifiants de test.
  • 🕒 Traçage de l'historique des commandes – Pour retracer vos actions avec les journaux d'historique de l'interpréteur de commandes.

Commandes de l'interpréteur de commandes

L'interpréteur de commandes interactif est l'endroit où IrisTest est le plus performant pour les opérations manuelles. Au lancement, une interface de l'interpréteur de commandes facile à utiliser s'affiche:

═════════════════════════════════════════════════════════════════════════════════════════════════
|| Bienvenue dans l'interpréteur de commandes iristest 0.1.0                                                                      ||
|| Saisissez “q” ou “quit” pour quitter l'interpréteur de commandes et “?” ou “help” pour afficher les commandes disponibles.     ||
||                                                                                                                                ||
|| ➤ Instance      : IRISHEALTH2025COM                                                                                            ||
|| ➤ System        : C11V344                                                                                                      ||
|| ➤ System Mode   : DEVELOPMENT                                                                                                  ||
|| ➤ Logged in     : _SYSTEM                                                                                                      ||
|| ➤ Session Start : 2025-07-27 13:07:52                                                                                          ||
════════════════════════════════════════════════════════════════════════════════════════════════════════════

Utilisation

Syntaxe de la commande

Pour exécuter IrisTest:

ziristest [OPTIONS]

Options disponibles

  • -i, --id <UnitTestId> – Définition d'un identifiant de test unique
  • -o, --output <FORMAT> – Sélection d'un ou plusieurs formats de rapport: html, xml, junitxml, allure, shell, json, csv, text
  • -d=<DIR>, --output-dir=<DIR> – Définition du répertoire de sortie (par exemple: ./reports)

Configuration

Vous pouvez configurer le chemin d'accès à chaque rapport IrisTest via

do##class(IrisTest.Report.Base).DefineFilePath("html", "C:\html\")

Affichage de la version et des paramètres d'IrisTest à l'aide de:

INFO

Exemples

Génération d'un rapport HTML unique:

ziristest --id=123 --output=html

Génération de plusieurs formats:

ziristest -i=123 -o=html,xml,junitxml

Enregistration dans un répertoire particulier:

ziristest -i=123 -o=html,xml,junitxml --output-dir=./reports

Commandes

CommandeDescription
CLEAREffacer l'écran de l'interpréteur de commandes
CONFIGAffichage de la configuration du système
DEL <ID>Suppression d'un cas de test
HELPAffichage du menu aide 
HISTAffichage de l'historique des commandes
HIST CLEAREffacement de l'historique des commandes
INFOAffichage de la version/date de l'interpréteur de commandes
RUNALLExécution de tous les cas de test disponibles
SHOW <ID>Affichage des résultats d'un test spécifique
SHOWALLAffichage de tous les résultats des tests
QUITSortie de l'interpréteur de commandes

Formats de rapport

FormatDescription
htmlRapport de test élégant, prêt à être utilisé dans un navigateur
xmlFormat XML standard
junitxmlCompatible avec les outils JUnit
allure Rapport de test compatible avec Allure
jsonDonnées structurées pour les API et les outils
csvDonnées simples prêtes à être utilisées dans un tableur
shellRésultat minimal, compatible avec les terminaux
textTexte brut pour les besoins élémentaires
0
0 22
Article Sylvain Guilbaud · Août 29, 2025 1m read

Rubrique FAQ InterSystems

Par défaut, l'ordre des colonnes d'une table est déterminé automatiquement par le système. Pour modifier cet ordre, définissez explicitement l'ordre de chaque propriété à l'aide du mot-clé SqlColumnNumber lors de la définition de la classe.

Exemple :

Property Name As %String [SqlColumnNumber = 2];

Veuillez consulter la documentation ci-dessous.

SqlColumnNumber

Si vous souhaitez modifier le nom de la table SQL, spécifiez SqlTableName. Si vous souhaitez modifier le nom de la colonne (nom du champ), spécifiez SqlFieldName.

0
0 16
Article Iryna Mykhailova · Août 28, 2025 12m read

Nous présentons ici le processus d'utilisation de la célèbre solution Jaeger pour tracer les applications InterSystems IRIS. Jaeger est un produit open source permettant de suivre et d'identifier des problèmes, en particulier dans les environnements distribués et de microservices. Ce backend de traçage, apparu chez Uber en 2015, a été inspiré par Dapper de Google et OpenZipkin de Twitter. Il a ensuite rejoint la Fondation Cloud Native Computing (CNCF) en tant que projet en incubation en 2017, avant d'obtenir le statut gradué en 2019. Ce guide vous montrera comment utiliser la solution Jaeger conteneurisée intégrée à IRIS.

Caractéristiques du Jaeger

  1. Surveillance des flux de transactions exécutés par une ou plusieurs applications et composants (services) dans des environnements conventionnels ou distribués:
  2. Identification précise des goulots d'étranglement dans les flux métier, y compris ceux qui sont distribués:
  3. Étude et optimisation des dépendances entre services, composants, classes et méthodes:
  4. Identification des indicateurs de performance pour découvrir les possibilités d'amélioration:

Composants Jaeger



Extrait de la documentation Jaeger: https://www.jaegertracing.io/docs/1.23/architecture/

  1. Client: Solutions, applications ou technologies (telles que IRIS) qui envoient des données de surveillance à Jaeger.
  2. Agent: Démon réseau qui surveille les segments envoyés via UDP, les regroupe et les transmet au collecteur. Il est conçu pour être déployé sur tous les hôtes en tant que composant d'infrastructure, en abstraisant le routage et la découverte des collecteurs depuis le client.
  3. Collecteur: Récepteur des traces provenant des agents Jaeger, qui les traite via un pipeline de traitement , lequel valide les traces, les indexe, effectue les transformations nécessaires, puis les stocke.
  4. Agent d'ingestion (facultatif): Si une file d'attente de messages telle qu'Apache Kafka tamponne les données entre le collecteur et le stockage, l'agent d'ingestion Jaeger lit les données dans Kafka et les écrit dans le stockage.
  5. Requête: Service qui récupère les traces du stockage et héberge une interface utilisateur pour les afficher.
  6. Interface utilisateur: L'interface Web Jaeger pour analyser et tracer les flux de transactions.

Aperçu d'Open Telemetry (OTel)

Étant donné qu'OpenTelemetry est la technologie exploitée par IRIS pour envoyer des données de traçage à Jaeger, il est important de comprendre son fonctionnement.
OpenTelemetry (alias OTel) est un framework d'observabilité open source et fournisseur neutre permettant d'instrumenter, de générer, de collecter et d'exporter des données de télémétrie telles que des traces, des métriques et des logs. Dans cet article, nous nous concentrerons sur la fonctionnalité traces.
L'unité fondamentale de données dans OpenTelemetry est le “signal”. L'objectif d'OpenTelemetry est de collecter, traiter et exporter ces signaux, qui sont des sorties système décrivant l'activité sous-jacente du système d'exploitation et des applications s'exécutant sur une plateforme. Un signal peut être quelque chose que vous souhaitez mesurer à un moment précis (par exemple, la température, l'utilisation de la mémoire) ou un événement qui traverse les composants de votre système distribué que vous souhaitez tracer. Vous pouvez regrouper différents signaux afin d'observer le fonctionnement interne d'une même technologie sous plusieurs angles (source: https://opentelemetry.io/docs/concepts/signals/). Cet article explique la manière d'émettre des signaux associés à des traces (le cheminement d'une requête dans votre application) depuis IRIS vers les collecteurs OTel.
OpenTelemetry est un excellent choix pour surveiller et tracer votre environnement IRIS et votre code source, car il est pris en charge par plus de 40 fournisseurs d'observabilité. Il est également intégré à de nombreuses bibliothèques, services et applications, et adopté par de nombreux utilisateurs finaux (source: https://opentelemetry.io/docs/).

  • Les microservices développés en Java, .NET, Python, NodeJS, InterSystems ObjectScript et des dizaines d'autres langages peuvent envoyer des données de télémétrie à un collecteur OTel à l'aide des points de terminaison et des ports distants (dans notre exemple, nous utiliserons un port HTTP).
  • Les composants de l'infrastructure peuvent également envoyer des données, notamment des données sur les performances, l'utilisation des ressources (processeur, mémoire, etc.) et d'autres informations pertinentes pour la surveillance de ces composants. Pour InterSystems IRIS, les données sont collectées par Prometheus à partir du point de terminaison /monitor et peuvent être transférées vers un collecteur OTel.
  • Les API et les outils de base de données peuvent également envoyer des données de télémétrie. Certains produits de base de données sont capables de le faire automatiquement (instrumentalisation).
  • Le collecteur OTel reçoit les données OTel et les stocke dans une base de données compatible et/ou les transmet à des outils de surveillance (par exemple, Jaeger).


Comment InterSystems IRIS envoie des données de surveillance à Jaeger

À partir de la version 2025, InterSystems a lancé la prise en charge d'OpenTelemetry (OTel) dans son API de surveillance. Cette nouvelle fonctionnalité inclut l'émission de données de télémétrie pour le traçage, la journalisation et les métriques d'environnement. Cet article traite de l'envoi de données de traçage à Jaeger via OTel. Vous trouverez plus de détails ici: https://docs.intersystems.com/irislatest/csp/docbook/DocBook.UI.Page.cls?KEY=AOTEL&ADJUST=1.
Bien que certains langages de programmation et certaines technologies prennent en charge la transmission automatique des données OTel (instrumentation automatique), pour IRIS, vous devez écrire des instructions de code spécifiques pour activer cette fonctionnalité. Téléchargez le code source de l'application exemple à partir de https://openexchange.intersystems.com/package/iris-telemetry-sample, ouvrez votre IDE et suivez les étapes ci-dessous:

1. Accédez à la classe dc.Sample.REST.TelemetryUtil. La méthode SetTracerProvider initialise un fournisseur de traceurs, ce qui vous permet de définir le nom et la version du service surveillé:

/// Définition du fournisseur de traceursClassMethod SetTracerProvider(ServiceName As%String, Version As%String) As%Status
{
    Set sc = $$$OKset attributes("service.name") = ServiceName
    set attributes("service.version") = Version
    Set tracerProv = ##class(%Trace.TracerProvider).%New(.attributes)
    Set sc = ##class(%Trace.Provider).SetTracerProvider(tracerProv)
    Quit sc
}

2. L'étape suivante consiste à récupérer l'instance du fournisseur de traceurs créée:
 

/// Obtention du fournisseur de traceursClassMethod GetTracerProvider() As%Trace.Provider
{
    Return##class(%Trace.Provider).GetTracerProvider()
}

3. Cet exemple va surveiller l'API PersonREST sur le point de terminaison /persons/all. Accédez à la classe dc.Sample.PersonREST (méthode de classe GetAllPersons):

/// Récupération de tous les enregistrements de dc.Sample.PersonClassMethod GetAllPersons() As%Status
{
<span class="hljs-keyword">#dim</span> tSC <span class="hljs-keyword">As</span> <span class="hljs-built_in">%Status</span> = <span class="hljs-built_in">$$$OK</span>
<span class="hljs-keyword">do</span> <span class="hljs-keyword">##class</span>(dc.Sample.REST.TelemetryUtil).SetTracerProvider(<span class="hljs-string">"Get.All.Persons"</span>, <span class="hljs-string">"1.0"</span>)
<span class="hljs-keyword">set</span> tracerProv = <span class="hljs-keyword">##class</span>(dc.Sample.REST.TelemetryUtil).GetTracerProvider()
<span class="hljs-keyword">set</span> tracer = tracerProv.GetTracer(<span class="hljs-string">"Get.All.Persons"</span>, <span class="hljs-string">"1.0"</span>)

4. Le fournisseur de traceurs vient de créer un service de surveillance appelé Get.All.Persons (version 1.0) et a obtenu l'instance de traceurs avec GetTracer.
5. L'exemple doit créer un racine Span comme suit:
 

set rootAttr("GetAllPersons") = 1set rootSpan = tracer.StartSpan("GetAllPersons", , "Server", .rootAttr)
    set rootScope = tracer.SetActiveSpan(rootSpan)

6. Les spans sont des éléments du flux de traçage. Chaque span doit être mappé à un élément du code source que vous souhaitez analyser.
7. SetActiveSpan est obligatoire pour définir le span actuel à surveiller.
8. À présent, l'exemple crée plusieurs spans descendants mappés à des éléments importants du flux:
 

set childSpan1 = tracer.StartSpan("Query.All.Persons")
    set child1Scope = tracer.SetActiveSpan(childSpan1)
    Try {
        Set rset = ##class(dc.Sample.Person).ExtentFunc()
        do childSpan1.SetStatus("Ok")
    } Catch Ex {
        do childSpan1.SetStatus("Error")
    }
    do childSpan1.End()
    kill childSpan1

9. Ce premier span des descendant surveille la requête pour toutes les personnes dans la base de données. Pour créer un span descendant, l'exemple utilise StartSpan avec un titre suggéré (Query.All.Persons). Le span actif doit ensuite être défini sur le span descendant actuel, ce que l'exemple réalise à l'aide de SetActiveSpan avec la référence childSpan1.
10. L'exemple exécute le code source métier (Set rset = ##class(dc.Sample.Person).ExtentFunc()). Si l'opération réussit, il définit le statut sur "Ok" ; sinon, il le définit sur "Error."
11. L'exemple termine la surveillance de ce morceau de code à l'aide de la méthode End et en supprimant la référence childSpan1.
12. Vous pouvez répéter cette procédure pour tous les autres segments de code que vous souhaitez examiner:

Pour surveiller la détection d'une personne par son ID (obtenir les détails de la personne):

set childSpan2 = tracer.StartSpan("Get.PersonByID")
set child2Scope = tracer.SetActiveSpan(childSpan2)
Set person = ##class(dc.Sample.Person).%OpenId(rset.ID)

       Pour observer le calcul de l'âge (classe dc.Sample.Person, méthode CalculateAge):
 

set tracerProv = ##class(dc.Sample.REST.TelemetryUtil).GetTracerProvider()
set tracer = tracerProv.GetTracer("Get.All.Persons", "1.0")
set childSpan1 = tracer.StartSpan("CalculateAge")
set child1Scope = tracer.SetActiveSpan(childSpan1)

Pour vérifier la définition du signe du zodiaque (classe dc.Sample.Person, méthode CalculateZodiacSign):
 

set tracerProv = ##class(dc.Sample.REST.TelemetryUtil).GetTracerProvider()
set tracer = tracerProv.GetTracer("Get.All.Persons", "1.0")
set childSpan1 = tracer.StartSpan("GetZodiacSign")
set child1Scope = tracer.SetActiveSpan(childSpan1)

 
Configuration des conteneurs IRIS et Jaeger

1. Créez le conteneur collecteur OTel (dans docker-composer.yml):
 

# --- 2. Collecteur OpenTelemetry ---  otel-collector:    image:otel/opentelemetry-collector-contrib:latest    command:["--config=/etc/otel-collector-config.yml"]    volumes:      -./otel-collector-config.yml:/etc/otel-collector-config.yml    ports:      -"4317:4317"# OTLP gRPC       -"4318:4318"# OTLP HTTP      -"9464:9464"# Métriques    depends_on:      -iris      -jaeger

2. Ajustez le fichier de configuration du collecteur OTel:

receivers:  otlp:    protocols:      grpc:        endpoint:"0.0.0.0:4317"      http:        endpoint:"0.0.0.0:4318"exporters:  otlp:    endpoint:jaeger:4317# Le nom du service « jaeger » de docker-compose pour le collecteur gRPC    tls:      insecure:true  prometheus:    endpoint:"0.0.0.0:9464"  debug:{}processors:  batch:# Processeur pour regrouper des traces en lots    send_batch_size:100    timeout:10sconnectors:  spanmetrics:# Connecteur SpanMetricsservice:  pipelines:    traces:      receivers:[otlp]      processors:[batch]# Les traces sont traitées pour générer des métriques      exporters:[otlp,spanmetrics]    metrics:      receivers:[otlp,spanmetrics]      exporters:[prometheus]    logs:      receivers:[otlp]      exporters:[debug]

3. Le collecteur OTel recevra les données de surveillance à l'adresse suivante:

http:        endpoint:"0.0.0.0:4318"

4. Le collecteur OTel enverra les exportateurs (Exporters) à Jaeger comme indiqué ci-dessous:

exporters:
  otlp:
    endpoint: jaeger:4317 # O nome do serviço 'jaeger' do docker-compose para o Collector gRPC
    tls:
      insecure: true

5. Le service OTel créera un pipeline pour recevoir et envoyer les données de surveillance:
 

service:  pipelines:    traces:      receivers:[otlp]      processors:[batch]      exporters:[otlp]

6. Dans le fichier docker-compose.yml, l'exemple va créer un conteneur IRIS, en définissant OTEL_EXPORTER_OTLP_ENDPOINT avec l'adresse du collecteur OTel:

iris:    build:      context:.      dockerfile:Dockerfile    restart:always    ports:      -51773:1972      -52773:52773      -53773    volumes:      -./:/home/irisowner/dev    environment:    -ISC_DATA_DIRECTORY=/home/irisowner/dev/durable    -OTEL_EXPORTER_OTLP_ENDPOINT=http://otel-collector:4318

 
7. Enfin, un conteneur Jaeger est créé pour recevoir les données du collecteur OTel et fournir une interface utilisateur permettant aux utilisateurs de surveiller et de tracer les données IRIS OTel:

jaeger:    image:jaegertracing/all-in-one:latest    ports:      -"16686:16686"# Jaeger UI      -"14269:14269"# Jaeger Metrics      -"14250:14250"# Jaeger Collector gRPC     environment:      -COLLECTOR_OTLP_ENABLED=true

 
Il existe des options de port supplémentaires pour Jaeger qui vous permettent de traiter plusieurs types de collecteurs. Vous trouverez ci-dessous la liste des ports exposés disponibles:

  • 6831/udp: Accepte les spans jaeger.thrift (Thrift compact)
  • 6832/udp: Accepte les spans jaeger.thrift (Thrift binaire)
  • 5778: Configuration Jaeger
  • 16686: Interface utilisateur Jaeger
  • 4317: Récepteur gRPC du protocole OpenTelemetry (OTLP)
  • 4318: Récepteur HTTP du protocole OpenTelemetry (OTLP)
  • 14250: Acceptation des spans model.proto via gRPC
  • 14268: Acceptation directe des spans jaeger.thrift via HTTP
  • 14269: Vérification de l'intégrité de Jaeger
  • 9411: Compatibilité Zipkin

Exécution de l'exemple

1. Copiez le code source de l'exemple: 

$ git clone https://github.com/yurimarx/iris-telemetry-sample.git

2. Ouvrez le terminal dans ce répertoire et exécutez le code ci-dessous:

$ docker-compose up -d --build

3. Créez quelques données de test simulées. Pour ce faire, ouvrez le terminal IRIS ou le terminal web sur /localhost:52773/terminal/ and call the following:

USER>do##class(dc.Sample.Person).AddTestData(10)

4. Ouvrez http://localhost:52773/swagger-ui/index.html et exécutez le point de terminaison /persons/all.

 

Analyse et traçage du code IRIS sur Jaeger

1. Accédez à Jaeger ici http://localhost:16686/search.

2. Sélectionnez Get.All.Persons dans le champ "Service", puis cliquez sur "Find Traces" (Rechercher les traces).


3. Cliquez sur la trace détectée pour afficher ses détails.


4. Observez la chronologie de la trace sélectionnée.


5. Dans le coin supérieur droit, sélectionnez "Trace Graph" :


6. Analysez les dépendances:


7. Cette analyse des dépendances est essentielle pour identifier les problèmes dans les systèmes/services distants au sein de votre environnement, en particulier si différents services distribués utilisent le même nom de service.
8. Maintenant, sélectionnez “Framegraph”:


9. Observez tous les composants du flux de transactions surveillé dans une table graphique:


10. Grâce à toutes ces ressources Jaeger, vous pouvez résoudre efficacement les problèmes de performances et identifier la source des erreurs.

 

Pour en savoir plus

Pour approfondir vos connaissances sur le traçage distribué, consultez les ressources externes suivantes:

  • Maîtrise du traçage distribué (Mastering Distributed Tracing) (2019) par Yuri Shkuro : article de blog rédigé par le créateur de Jaeger, qui explique l'histoire et les choix architecturaux à l'origine de Jaeger. Ce livre traite en détail de la conception et du fonctionnement de Jaeger, ainsi que du traçage distribué en général.
  • Suivez Jaeger pour un tour en HotROD: un tutoriel étape par étape qui montre comment utiliser Jaeger pour résoudre les problèmes de performances des applications.
  • Présentation de Jaeger : un (ancien) webinaire présentant Jaeger et ses capacités.
  • Tutoriel détaillé sur Jaeger: https://betterstack.com/community/guides/observability/jaeger-guide/ 
  • Évolution du traçage distribué au sein d'Uber.
  • Émettre des données de télémétrie vers un outil de surveillance compatible avec OpenTelemetry par la documentation InterSystems.
  • Observabilité moderne avec InterSystems IRIS & et OpenTelemetry: Une vidéo de démonstration sur la manière de travailler avec OpenTelemetry et IRIS: https://www.youtube.com/watch?v=NxA4nBe31nA
  • OpenTelemetry sur GitHub : Une collection d'API, de SDK et d'outils pour instrumenter, générer, collecter et exporter des données de télémétrie (métriques, journaux et traces) afin d'aider à analyser les performances et le comportement de logiciels: https://github.com/open-telemetry.
0
0 21
Article Sylvain Guilbaud · Août 14, 2025 3m read

Les données sont au cœur de la transformation numérique qui bouleverse le secteur de la santé. Ce changement radical nécessite de nouvelles bases pour gérer les énormes besoins en données des soins de santé modernes.

Le délai de mise sur le marché est crucial pour développer les prochaines avancées thérapeutiques, les connaissances génomiques et les flux de travail cliniques intelligents. Vous devez les mettre en œuvre dès maintenant.

0
0 13
Article Sylvain Guilbaud · Août 5, 2025 9m read

Bonjour, chers membres de notre communauté de développeurs!

Dans l'article d'aujourd'hui, nous allons examiner l'une des dernières fonctionnalités de télésurveillance de nos instances IRIS qui a été ajoutée au produit. Il s'agit de la compatibilité avec OpenTelemetry.

Que qu'est-ce que OpenTelemetry?

OpenTelemetry est un framework open source qui fournit les outils nécessaires, tels que des SDK et des normes, pour mettre en œuvre l'observabilité dans les systèmes et les applications.

Cette observabilité s'étend à trois types de données:

  1. Traces : contrôle du flux d'informations circulant dans les solutions grâce à l'inclusion de traces permettant d'identifier où elles passent et sous quelles conditions.
  2. Métriques : état du système, performances, latences dans les réponses, utilisation des ressources, etc.
  3. Journaux : inclus dans les systèmes pour une meilleure compréhension des événements qui se produisent.

OpenTelemetry utilise la norme ouverte OTLP qui définit comment toute la télémétrie précédemment définie doit être sérialisée et transportée. L'envoi de cette télémétrie peut être effectué via HTTP ou gRPC.

Open Telemetry avec IRIS

InterSystems IRIS exploite les fonctionnalités disponibles via OpenTelemetry SDK pour permettre l'exportation de toutes les données de télémétrie générées par l'instance configurée. D'où proviennent ces données de télémétrie? 

  1. Métriques : elles proviennent des informations dont nous disposons via l'API REST /api/monitor ( vous pouvez consulter la documentation officielle de cette API ici ).
  2. Journaux : messages enregistrés dans le fichier messages.log et informations stockées dans la base de données d'audit (si elle est activée).
  3. Traces : traces définies par l'utilisateur dans les applications développées dans l'instance.

Voyons maintenant comment configurer OpenTelemetry dans une instance IRIS

Configuration d'IRIS avec OpenTelemetry

Pour notre exemple de configuration, j'ai utilisé un projet que j'ai téléchargé sur GitHub et qui fonctionne sous Docker, mais il ne serait pas très compliqué de le configurer sur une instance installée sur site. Ce projet est disponible sur OpenExchange, associé à cet article.

Avant de présenter les différentes configurations, nous allons expliquer quels éléments feront partie de notre "écosystème de surveillance":

InterSystems IRIS

L'instance IRIS se chargera de générer les données de télémétrie que nous devons surveiller.

OpenTelemetry Collector

Il s'agit d'un outil fourni par OpenTelemetry chargé de collecter des données télémétriques provenant de différentes sources. Dans notre exemple, il s'agira uniquement d'IRIS, mais nous pourrions en ajouter autant que nécessaire.

Prometheus

Outil open source utilisé pour la surveillance des systèmes et la génération d'alertes. Cet outil sera chargé de recevoir les métriques accumulées par OpenTelemetry Collector.

Jaeger

Plateforme open source pour la gestion et la surveillance des traces des systèmes basés sur des microservices.

Configuration en Docker

Comme je l'ai mentionné précédemment, j'ai utilisé un déploiement en Docker afin de simplifier au maximum l'exemple. Analysons le fichier docker-compose.yml par parties pour mieux le comprendre.

Image d'IRIS Docker

  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-capsfalse--ISCAgentfalse

Comme vous pouvez le voir, je définis l'image à utiliser dans un fichier Dockerfile qui ne présente pas grand intérêt et je ne vais donc pas m'attarder dessus. Le point intéressant de cette configuration est la définition d'une variable d'environnement appelée  OTEL_EXPORTER_OTLP_ENDPOINT  , qui sera l'URL où notre OpenTelemetry Collector attendra qu'IRIS lui envoie toutes les métriques, traces et journaux dont il dispose.

Une fois que nous aurons déployé notre instance IRIS, nous devrons la configurer pour qu'elle émette régulièrement les métriques et les journaux. Pour ce faire, nous accéderons à la configuration du moniteur depuis le portail de gestion:

Comme vous pouvez le voir, nous pouvons activer l'envoi des métriques et des journaux. Dans le cas des traces, celles-ci ne sont pas envoyées à intervalles réguliers, mais dès que la méthode "End" de l'instance de la classe %Trace.Provider est invoquée. Je n'entrerai pas plus dans les détails, mais vous pouvez consulter  the official documentation ici la documentation officielle.

Image d'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

Voici l'image d'OpenTelemetry Collector. J'ai à nouveau défini un fichier Dockerfile pour indiquer où obtenir l'image (ce n'est pas obligatoire). Comme vous pouvez le voir, nous rendons trois ports accessibles:

  • 4317: port pour la réception des métriques, des traces et des journaux via gRPC.
  • 4318: port pour la réception des métriques, des traces et des journaux via HTTP.
  • 9464: port ouvert pour que des outils tiers puissent consulter les informations reçues par OpenTelemetry Collector.

Nous avons également déclaré un fichier de configuration,  otel-local-config.yml  (le nom est modifiable). Jetons un œil à son contenu:

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]

Que voyons-nous ici? C'est très simple, nous avons les sections suivantes: 

  • Récepteurs de données  , que nous avons appelés otlp dans notre cas, dans lesquels nous configurons l'adresse IP et les ports sur lesquels notre récepteur va attendre les informations provenant de systèmes tiers.
  • Exporteurs de données : où nous allons envoyer ou qui va extraire les données reçues dans l'OpenTelemetry Collector. Pour notre exemple, nous avons utilisé un exporteur déjà inclus dans OpenTelemetry, à savoir, Prometheus, which  qui se chargera d'obtenir les métriques dans l'instance locale de l'OpenTelemetry Collector sur le port 9464. Dans le cas de Jaeger , nous utilisons directement la capacité d'OpenTelemetry à envoyer des données directement à une IP (jaeger est le nom de l'instance au sein du réseau monté par Docker) qui correspondra à notre instance jaeger.
  • Services , où nous indiquerons lesquels des composants que nous avons configurés comme récepteurs et exporteurs se chargeront de la réception et de l'émission des métriques, des traces et des journaux. Comme vous pouvez le voir dans notre cas OpenTelemetry Collector sera le récepteur que nous utiliserons pour tout, Prometheus sera le récepteur des métriques et Jaeger, via OpenTelemetry Collector, sera le récepteur des traces.

Image de Prometheus Docker

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

Comme vous pouvez le constater, c'est très simple: notre image est à nouveau définie dans un fichier Dockerfile qui fait uniquement référence au nom de l'image, à un port 9090 où sera déployée l'interface web à laquelle nous pourrons accéder, et enfin à un fichier de configuration appelé  prometheus.yml 

Voyons ce que nous dit ce fichier prometheus.yml:

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

Nous avons la configuration suivante:

  • Scrape interval : intervalle de temps entre deux requêtes à OpenTelemetry Collector.
  • Scrape configs : lieu où nous donnons un nom à la tâche qui effectuera la recherche, ainsi que l'adresse IP et le port auxquels elle se connectera pour cette recherche.

Image de Jaeger Docker

Pour l'image de Jaeger, j'ai directement repris un exemple disponible sur notre cher 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

Le point le plus important, outre le port 16689 que nous utiliserons pour accéder à l'interface web, est la variable d'environnement COLLECTOR_OTLP_ENABLED, qui activera les ports par défaut de Jaeger pour permettre les connexions HTTP depuis OpenTelemetry Collector.  Ici  vous pouvez voir la liste des ports utilisés, mais je vous informe que le port 4317 est utilisé pour la transmission gRCP et le port 4318 pour le HTTP. Comme vous l'avez vu dans la configuration d'OpenTelemetry Collector, nous allons utiliser la connexion via gRCP.

Maintenant que tout est prêt, voyons comment cela fonctionne en démarrant le projet.

Émission des métriques, réception dans Prometheus

Nos instances sont désormais configurées et démarrées. Accédons à l'interface web fournie par Prometheus.  Dans notre exemple, nous l'avons mappée à http://localhost:9090 . Par défaut, elle nous indique où nous pouvons lancer des requêtes sur les métriques disponibles.

Si nous avons correctement configuré la connexion entre IRIS - OpenTelemetry Collector - Prometheus, depuis l'écran de requêtes de Prometheus, nous aurons accès à toutes les métriques standard disponibles dans IRIS, comme vous pouvez le voir dans la capture d'écran suivante en recherchant "iris_"

Si nous sélectionnons l'une d'entre elles, nous pouvons voir un graphique au fil du temps

Envoi de traces à Jaeger

Pour vérifier le fonctionnement de l'envoi des traces, nous allons utiliser la ressource la plus simple mise à notre disposition par IRIS, à savoir la méthode TestTraces() de la classe SYS.Monitor.OTel que vous pouvez consulter ici . Si vous souhaitez obtenir plus de détails, n'hésitez pas à me le faire savoir dans les commentaires et je me ferai un plaisir de rédiger un article à ce sujet.

Nous se limitons à exécuter la commande depuis la console à partir de l'espace de noms SYS:

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

Cela nous renverra une trace qui devrait avoir été reçue par Jaeger. Vérifions cela depuis son interface graphique affichée sur http://localhost:1668

Dans les filtres du menu de gauche, nous pouvons voir que nous avons un service appelé  irisotel , Ce service est utilisé par IRIS pour tester l'envoi de traces de test, d'où le nom de la trace reçue test_trace .

Et voilà! Notre instance est désormais prête à envoyer toutes les données métriques et traces que nous souhaitons. Je reste à votre disposition si vous souhaitez approfondir le sujet.

0
0 30
InterSystems officiel Adeline Icard · Juil 25, 2025

Les versions de maintenance 2025.1.1 de la plateforme de données InterSystems IRIS, d'InterSystems IRIS for Health et de HealthShare Health Connect sont désormais disponibles en disponibilité générale (GA). N'hésitez pas à partager vos commentaires via la Communauté des développeurs afin que nous puissions développer ensemble un produit plus performant.

Documentation

Vous trouverez les listes détaillées des modifications et les listes de contrôle des mises à niveau sur les pages suivantes :

0
0 23
InterSystems officiel Adeline Icard · Juil 24, 2025

InterSystems annonce la disponibilité générale d'InterSystems IRIS 2025.2

InterSystems a le plaisir d'annoncer la disponibilité générale (GA) de la version 2025.2 de la plateforme de données InterSystems IRIS. Il s'agit d'une version en livraison continue (CD). Veuillez noter que les versions GA d'InterSystems IRIS for Health et HealthShare Health Connect 2025.2 sont actuellement suspendues en raison de limitations de mise en miroir introduites par les mises à jour de sécurité (détails ci-dessous).

Points forts de la version

0
0 27
InterSystems officiel Adeline Icard · Juil 23, 2025
InterSystems Reports version 25.1 est désormais disponible sur le site de distribution de logiciels InterSystems, dans la section Composants. Le logiciel, baptisé InterSystems Reports Designer et InterSystems Reports Server, est disponible pour les systèmes d'exploitation Mac OSX, Windows et Linux.
Cette nouvelle version apporte des améliorations et des correctifs de notre partenaire Insightsoftware. InterSystems Reports 25.1 est optimisé par Logi Report version 25.1, qui inclut :

la prise en charge de la construction dynamique des objets lors de la distribution planifiée des rapports par

0
0 20
Article Sylvain Guilbaud · Juil 18, 2025 11m read

🛠️ Gestion des configurations d'InterSystems API Manager (IAM = Kong Gateway) en CI/CD

🔍 Contexte : configurations d'InterSystems IAM

Dans le cadre de l'intégration d'InterSystems IAM dans un environnement sécurisé et contrôlé, InterSystems IAM repose sur Kong Gateway pour gérer les API exposées. Kong agit comme une API Gateway moderne, capable de gérer l’authentification, la sécurité, la gestion du trafic, les plugins, et bien plus encore.

0
0 24
Article Developer Community Admin · Juil 14, 2025 17m read

Les fournisseurs de solutions numériques dans le domaine de la santé sont soumis à une pression croissante pour intégrer des systèmes complexes de données de santé tout en garantissant l'évolutivité, la sécurité et la conformité à des normes telles que HL7 FHIR. Les ressources FHIR (Fast Healthcare Interoperability Resources) ont révolutionné l'échange de données de santé en proposant un cadre normalisé qui permet à divers systèmes informatiques de santé de communiquer sans difficulté. Mais il ne suffit pas de se conformer aux normes FHIR pour surmonter les complexités de l'intégration des données de santé. Les partenaires de solutions doivent tirer parti de composants architecturaux avancés tels que les courtiers, les façades et les référentiels FHIR pour créer des solutions évolutives et efficaces. InterSystems offre toutes les fonctionnalités essentielles dont vous avez besoin pour mettre en œuvre FHIR pour vos données de santé, que ce soit sur site, dans un cloud public ou sous forme de service cloud géré par InterSystems.

Medical Science Hospital Lab Meeting healthcare

InterSystems IRIS for Health est une plateforme complète de développement numérique dans le domaine de la santé, fournissant tous les éléments nécessaires pour exploiter les données FHIR et développer des applications FHIR. La plateforme InterSystems comprend une une infrastructure de gestion des données fiable et efficace et implémente FHIR de manière transparente, permettant ainsi aux développeurs de créer des solutions de santé évolutives et interopérables.

Pour prendre en charge ces fonctionnalités, la plateforme InterSystems IRIS for Health comprend la suite complète de fonctionnalités robustes suivantes, conçues pour simplifier l'intégration de FHIR et optimiser l'interopérabilité:

  • Serveur FHIR – Un serveur FHIR entièrement conforme, prêt à l'emploi, qui peut également servir de frontal à une façade FHIR. Ce serveur peut accepter, traiter et convertir les requêtes FHIR aux formats hérités utilisés par le système sous-jacent, et inversement.
  • Bulk FHIR – Un ensemble unique de fonctionnalités pour importer et exporter de grands ensembles de données FHIR à des fins de recherche, d'analyse, de migration de données, etc. Bulk FHIR vous permet de récupérer facilement les principales ressources FHIR en une seule requête efficace et de gérer de grands ensembles de données sur plusieurs systèmes et emplacements.
  • Transformation FHIR – Un ensemble unique d'outils permettant une transformation transparente entre les ressources FHIR et les formats de données hérités (par exemple, HL7 v2, CDA, schémas personnalisés). La plateforme peut mapper ces formats hérités vers FHIR en temps réel, permettant ainsi une récupération et une mise à jour eficaces des données.
  • Constructeur FHIR SQL Builder – Un outil unique qui permet aux analystes et aux développeurs d'interroger en toute sécurité les données FHIR en temps réel à l'aide d'outils connus tels que ANSI SQL, Power BI ou Tableau. Encodées dans des graphes orientés complexes, les données FHIR ne peuvent pas être interrogées à l'aide du langage SQL standard. Avec FHIR SQL Builder, vous pouvez créer des schémas SQL personnalisés basés sur le référentiel FHIR lui-même, sans avoir à transférer les données vers un référentiel SQL supplémentaire, ce qui peut s'avérer coûteux.
  • Normalisation et accès aux données – Prise en charge de la normalisation des données, pour que les données récupérées à partir de systèmes existants soient structurées et accessibles au format FHIR. C'est essentiel pour garantir que les données provenant de différents systèmes puissent être agrégées et présentées de manière cohérente.
  • Modèle objet FHIR – La programmation de code personnalisé avec les classes de modèle FHIR, offrant la complétion de code et la prise en charge d'IntelliSense.

Composants, architectures et modèles FHIR

FHIR offre un cadre flexible et évolutif pour l'interopérabilité des données de santé. Pour tirer pleinement parti de FHIR, il est nécessaire de comprendre les composants, architectures et modèles clés qui permettent l'intégration et l'échange des données. À un niveau élevé, les capacités de FHIR sont organisées en composants suivants:

  • Un courtier FHIR sert en tant qu'intermédiaire multi-routage, rationalisant le flux et l'échange de données de santé entre différents systèmes. Il permet une interopérabilité transparente en gérant les transactions, en coordonnant des systèmes disparates et en garantissant que les données circulent de manière efficace et sécurisée. Pour les partenaires de solutions de santé numériques, les courtiers FHIR simplifient l'échange de données, agissant comme des "chambres de compensation" et facilitant l'intégration et la mise à l'échelle des applications dans un écosystème complexe, sans avoir besoin de récupérer des données FHIR supplémentaires dans une base de données.
  • Une façade FHIR agit comme une interface unique qui résume la complexité d'une base de données non FHIR sous-jacente, permettant ainsi aux développeurs de se concentrer sur les fonctionnalités de l'application plutôt que sur la gestion des données de bas niveau. La façade se trouve "devant" un système non FHIR unique afin que les opérations basées sur FHIR puissent fonctionner avec ce système.
  • Un référentiel FHIR fournit un magasin de données centralisé qui gère et fournit les données de santé au format FHIR natif et qui garantit l'intégrité, la sécurité et le contrôle d'accès des données. Un référentiel offre les avantages d'une intégration et d'une gestion plus faciles, ainsi que de meilleures performances et des requêtes et mises à jour plus efficaces.

Ensemble, ces composants FHIR permettent aux développeurs de créer des applications de soins de santé flexibles, performantes et sécurisées, améliorant ainsi les résultats pour les patients tout en réduisant les coûts de développement et de maintenance.

La pile FHIR d'InterSystems offre un choix aux développeurs FHIR, en tirant parti d'une expertise solide en matière d'intégration et de gestion des données pour prendre en charge tous les principaux modèles architecturaux FHIR qui combinent les composants FHIR précédents de différentes manières. La suite complète de fonctionnalités FHIR d'InterSystems facilite non seulement la conformité aux normes FHIR, mais améliore également l'interopérabilité des données entre différents systèmes. En combinant ses compétences techniques et sa connaissance approfondie du domaine, InterSystems aide les développeurs à naviguer dans les complexités de l'adoption de FHIR et à mettre en œuvre les solutions FHIR les mieux adaptées à leurs besoins.

FHIR Repository Diagram

La sécurité est un aspect essentiel de la gestion des données relatives aux soins de santé, et InterSystems fournit des outils robustes pour garantir la sécurité de ses interfaces FHIR. Ceux-ci incluent le contrôle d'accès basé sur les rôles (RBAC), la prise en charge OAuth2 pour FHIR et la journalisation des audits afin de garantir la conformité avec les réglementations en matière de soins de santé telles que HIPAA.

Examinons comment chacun de ces composants FHIR fonctionne avec le logiciel InterSystems afin de vous aider à choisir le modèle architectural le mieux adapté à vos besoins.

Courtiers FHIR

Un courtier FHIR est un intermédiaire multi-routage qui facilite l'échange de données rélatif aux soins de santé à l'aide de la norme FHIR. Il agit comme un connecteur entre des systèmes d'information de santé disparates, leur permettant de communiquer efficacement en convertissant et en acheminant les ressources FHIR. Un courtier FHIR est essentiel dans les environnements où plusieurs systèmes, tels que les dossiers médicaux électroniques (EHR) , les applications cliniques et les systèmes de gestion des patients, doivent partager des données de manière transparente tout en respectant la norme FHIR.

Les capacités du courtier FHIR d'InterSystems (InterSystems FHIR Broker) constituent la pierre angulaire d'une architecture FHIR en fournissant des outils robustes pour la conversion, la validation et l'agrégation des données. Cela facilite la mise en œuvre de solutions basées sur FHIR qui peuvent répondre à des défis spécifiques, tels que l'intégration de plusieurs systèmes hérités. Par exemple, un réseau hospitalier peut intégrer les données des patients provenant de divers systèmes EHR, et InterSystems FHIR Broker peut agréger les informations de ces systèmes, les normaliser au format FHIR et les présenter sous une vue unifiée. Les cliniciens peuvent alors accéder en temps réel à des informations complètes sur les patients, ce qui améliore la coordination des soins et réduit le risque d'erreurs. En outre, un courtier FHIR peut faciliter le partage sécurisé et évolutif des données pour la gestion de la santé de la population, permettant aux prestataires de soins de santé d'analyser les tendances et d'améliorer les résultats, par exemple pour les maladies cardiaques, le sevrage tabagique et l'obésité infantile, pour différentes populations de patients.

FHIR Broker Diagram

Le modèle de données InterSystems SDA (Architecture de document récapitulatif) est conçu pour rendrele processus de conversion des formats de données rélatives aux soins de santé hérités en normes modernes telles que FHIR plus efficace. SDA fournit une représentation unifiée des données pour divers formats de données de soins de santé hérités, tels que HL7 v2, CDA (Architecture de document clinique) ou des formats de fichiers plats personnalisés. Ce format intermédiaire comble le fossé entre les systèmes hérités hautement structurés et la structure plus modulaire et flexible de FHIR, et fonctionne idéalement dans le cadre d'une solution de courtier FHIR Broker.

SDA agit également comme une couche d'abstraction qui normalise les données provenant de différentes sources dans un format commun. Cette abstraction réduit la complexité de la conversion directe de chaque format en FHIR, car SDA fournit une structure normalisée.

Une fois converties au format SDA, les données peuvent être réutilisées dans plusieurs systèmes. La conversion au format SDA ne doit être effectuée qu'une seule fois pour chaque format hérité. À partir du format SDA, les données peuvent être exportées vers divers standards modernes, y compris FHIR, ce qui réduit le besoin de conversions multipoints.

InterSystems fournit des outils et des connecteurs intégrés qui facilitent la conversion des formats hérités vers SDA et de SDA vers FHIR. Cela inclut des mappages prédéfinis, des analyseurs syntaxiques et une logique de transformation. InterSystems prend également en charge les profils FHIR personnalisés, ce qui permet de convertir les données SDA en profils FHIR qui répondent à des exigences organisationnelles ou réglementaires spécifiques.

Façades FHIR

Une façade FHIR est un modèle architectural utilisé dans les systèmes de santé pour fournir une interface conforme à FHIR au-dessus d'un système existant non conforme à FHIR. Elle agit comme une interface habilitante qui expose les données et les services des systèmes hérités non FHIR dans un format FHIR standardisé, permettant ainsi l'interopérabilité avec les applications de soins de santé modernes sans avoir besoin de modifier profondément les systèmes hérités sous-jacents. Contrairement à un courtier FHIR qui coordonne plusieurs systèmes, une façade FHIR se place "devant" un seul système non FHIR.

De nombreux systèmes de soins de santé reposent sur des normes plus anciennes telles que HL7 v2, CDA (Architecture de document clinique) ou des formats de données personnalisés incompatibles avec FHIR. Les façades FHIR fournissent une solution en convertissant à la demande les données dans des formats plus anciens au format FHIR, répondant ainsi aux normes d'interopérabilité modernes et s'intégrant à de nouvelles applications, telles que les systèmes de dossiers médicaux électroniques (DME), les échanges d'informations de santé (HIE) et les applications pour patients.

Réussite des clients grâce à InterSystems et FHIR

Leumit Health Services, une organisation de soins de santé en Israël, cherchait à améliorer le partage des données entre les payeurs et les prestataires afin de faciliter l'accès aux soins pour ses membres.

En collaboration avec des experts locaux dans la mise en œuvre de HL7 FHIR et un centre médical local, Leumit a développé une solution intégrant leurs systèmes individuels via une façade FHIR. Avec cette solution, l'enregistrement des patients a été automatisé: l'éligibilité est déterminée immédiatement et sur place grâce au partage de données basé sur FHIR via InterSystems IRIS for Health.

Principales caractéristiques d'une façade FHIR

  • Conversion des données en temps réel – Une façade FHIR convertit les données en temps réel, transformant les requêtes et les réponses entre le format natif du système existant et les ressources FHIR.
  • Aucune interruption des systèmes existants – Le système sous-jacent continue de fonctionner comme d'habitude, tandis que la façade gère les interactions FHIR, minimisant ainsi le besoin de modifications coûteuses et perturbatrices de l'infrastructure existante.
  • Modernisation progressive – Une façade FHIR permet aux organisations de se moderniser progressivement en exposant une API conforme à FHIR pour une utilisation externe sans avoir à réviser les systèmes existants en une seule étape.
  • Interopérabilité – En transformant les formats hérités en FHIR, une façade FHIR permet l'interopérabilité avec d'autres systèmes, applications et plateformes de soins de santé qui nécessitent la conformité FHIR.

InterSystems IRIS for Health offre un ensemble idéal d'outils et de technologies pour la mise en œuvre d'une façade FHIR, car elle supporte nativement FHIR et les conversions de données FHIR.

FHIR Facade Diagram

InterSystems IRIS for Health prend en charge l'utilisation de profils et d'extensions FHIR personnalisés, permettant ainsi aux organisations d'adapter la façade FHIR à leurs besoins spécifiques. Grâce à cette flexibilité, la façade FHIR peut s'adapter aux exigences régionales ou organisationnelles en matière d'échange de données tout en respectant les normes FHIR.

Référentiels FHIR

Un référentiel FHIR offre un moyen plus pratique et plus efficace de gérer les données de soins de santé qu'une façade FHIR. Si les deux approches visent à fournir une interopérabilité et à faciliter l'utilisation du FHIR, un référentiel FHIR offre de nombreux avantages en termes de gestion des données, de performances et de facilité d'intégration. Un référentiel FHIR stocke, gère et fournit des données de soins de santé au format FHIR natif, offrant ainsi une plateforme centralisée où les données peuvent être interrogées et mises à jour efficacement. Cela contraste avec une façade FHIR, qui sert en tant que frontal pour les systèmes existants, traduisant en temps réel les formats non FHIR vers le format FHIR.

Le référentiel FHIR d'InterSystems est spécialement conçu pour stocker et gérer les données au format FHIR et élimine le besoin de conversion des données en temps réel. En stockant nativement les ressources FHIR, le référentiel peut traiter plus efficacement les requêtes et les mises à jour FHIR complexes.

Les requêtes directes vers les référentiels FHIR, sans besoin de mappages intermédiaires, sont particulièrement utiles pour les recherches complexes, telles que les requêtes sur les dossiers de patients qui couvrent plusieurs ressources FHIR (par exemple, Patient, Condition, Observation). Toutes les données sont stockées au même endroit au format FHIR. Cela améliore la cohérence, l'efficacité et la fiabilité du stockage et de l'accès aux données.

Les référentiels FHIR d'InterSystems sont conçus pour s'adapter efficacement à la croissance des organisations de soins de santé et à l'augmentation des volumes de données. Étant donné qu'un référentiel stocke des données FHIR préconverties, le système est optimisé pour offrir des performances élevées lors du traitement de requêtes simultanées provenant de plusieurs systèmes. InterSystems dispose d'un laboratoire d'évolutivité pour évaluer les performances FHIR. Ce laboratoire exécute régulièrement une suite complète de tests de performance FHIR, qui montrent une amélioration notable des requêtes de recherche FHIR complexes. De simples recherches dans le référentiel permettent de récupérer plus de 160 000 ressources FHIR par seconde, avec des performances similaires dans des cas plus exigeants (Jamieson & Banand, 2024).¹

InterSystems fournit un référentiel FHIR entièrement conforme et prêt à l'emploi. Cela élimine le besoin d'une configuration complexe et permet aux organismes de santé de déployer rapidement un référentiel FHIR conforme aux normes FHIR les plus récentes. Cette pile prend en charge toutes les principales interactions FHIR, y compris la création, la récupération, la mise à jour et la suppression de ressources. InterSystems veille à ce que son référentiel FHIR reste conforme aux normes FHIR en constante évolution, en offrant une prise en charge des dernières ressources et fonctionnalités FHIR. Cela garantit la compatibilité avec d'autres systèmes basés sur FHIR et la pérennité face à l'évolution des normes de soins de santé.

Extension de la puissance des référentiels FHIR avec InterSystems IRIS

Le référentiel FHIR intégré s'intègre de manière native à la plateforme de données InterSystems IRIS for Health, ce qui permet une interaction transparente avec d'autres systèmes et applications de soins de santé. Cela facilite l'ingestion, le stockage et la récupération des ressources FHIR sans complexité supplémentaire.

InterSystems IRIS for Health contient une base de données multimodèle et prend en charge des modèles avancés d'analyse, d'IA et d'apprentissage automatique. Le référentiel FHIR de cette plateforme peut servir de base à la création de solutions analytiques qui exploitent des données de soins de santé structurées et normalisées. L'outil unique FHIR SQL Builder d'InterSystems permet aux développeurs de "projeter" des ressources FHIR dans un format relationnel, ce qui facilite l'utilisation d'outils ANSI SQL ou BI pour l'analyse. Comme cette plateforme est une véritable base de données multimodèle, elle peut effectuer ces projections en temps réel, ce qui permet aux utilisateurs d'analyse de disposer en permanence d'informations à jour sans avoir à dupliquer leurs données dans un entrepôt de données.

InterSystems IRIS for Health permet aux organisations d'appliquer des analyses de santé publique, de pronostiquer les résultats des patients et d'optimiser les opérations cliniques en stockant et en interrogeant les données au format FHIR.

Pourquoi choisir les solutions FHIR d'InterSystems?

Lorsque vous développez un courtier FHIR, une façade FHIR ou un référentiel FHIR, le choix de la pile technologique peut avoir un impact significatif sur votre réussite. Découvrez pourquoi la pile FHIR d'InterSystems est la solution idéale:

  • Prise en charge complète et évolutive de FHIR – Prise en charge complète et évolutive de FHIR – InterSystems fournit une prise en charge complète des normes FHIR les plus récentes dans toutes les versions. Avec une expérience éprouvée dans le traitement de grands volumes de données cliniques, la plateforme InterSystems IRIS for Health est conçue pour être évolutive. Lorsque vous développez un simple courtier FHIR ou un référentiel FHIR complexe, InterSystems vous garantit une évolutivité efficace sans compromettre les performances, même dans des environnements à haut volume. Notre coordinateur InterSystems Bulk FHIR unique permet l'exportation en masse depuis d'autres serveurs FHIR et DME prenant en charge Bulk FHIR, ce qui facilite la gestion de toutes vos données FHIR en un seul endroit.
  • Intégration transparente avec les systèmes existants – L'un des plus grands défis dans le domaine des technologies de l'information appliquées aux soins de santé est l'intégration de nouvelles solutions aux systèmes existants. La pile FHIR d'InterSystems offre une passerelle transparente entre les applications modernes basées sur FHIR et les normes HL7 v2, HL7 v3 et CDA plus anciennes. Cette interopérabilité garantit une communication continue dans tout l'environnement informatique de votre organisation sans avoir à réorganiser votre infrastructure existante, ce qui la rend idéale pour les façades FHIR et nos services uniques de conversion FHIR.
  • Performance et fiabilité éprouvées – Dans le domaine de la santé, la fiabilité est incontournable. InterSystems a une solide réputation en matière de performances de niveau entreprise, avec une haute disponibilité et une faible latence. La pile FHIR est construite sur InterSystems IRIS for Health, la plateforme de données spécialement conçue pour les charges de travail de soins de santé. Elle garantit une disponibilité constante et un échange de données en temps réel efficace, que vous gériez un référentiel FHIR ou que vous serviez de courtier FHIR.
  • Gestion avancée des données et sécurité – La sécurité des données et la confidentialité des patients sont primordiales dans le domaine des soins de santé. FHIR Stack d'InterSystems offre des fonctionnalités de sécurité robustes et intégrées pour protéger les données de soins de santé sensibles. Il est entièrement conforme à la norme HIPAA et à d'autres normes globales, fournissant des contrôles d'accès basés sur les rôles, la journalisation des audits et des capacités de chiffrement. Pour les organisations qui créent des référentiels FHIR, cette conformité est synonyme de tranquillité d'esprit lors du stockage et de l'échange de grands ensembles de données.
  • Outils de développement et de personnalisation étendus – Grâce à des environnements de développement complets, comprenant des API, des SDK et FHIR SQL Builder, InterSystems vous aide à personnaliser et à étendre votre solution FHIR en fonction de vos besoins spécifiques. Que vous ayez besoin d'un courtier FHIR léger ou d'un référentiel FHIR riche en fonctionnalités, nos outils et nos services d'assistance robustes permettent une personnalisation rapide, réduisant ainsi les délais de mise sur le marché.
  • Soutien exceptionnel aux fournisseurs et écosystème – InterSystems est réputé pour son assistance clientèle exceptionnelle, qui comprend un accès 24 h/24 et 7 j/7 à des ressources techniques et à une vaste communauté de développeurs. Notre solide écosystème de partenaires et de solutions vous garantit de ne jamais travailler de manière isolée. Que vous ayez besoin de conseils sur les meilleures pratiques pour les façades FHIR ou d'une assistance technique pour votre référentiel FHIR, vous pouvez toujours compter sur notre aide.

Plus d'articles sur le sujet:

Source: Rationalisation de l'intégration des données de santé avec FHIR

0
0 24
Article Iryna Mykhailova · Juil 4, 2025 3m read

Une qualité de service (QoS) est attribuée à tous les pods. Trois niveaux de priorité sont attribués aux pods d'un nœud. Ces niveaux sont les suivants :

1) Garanti : Priorité élevée

2) Évolutif : Priorité moyenne

3) Meilleur effort : Priorité faible

Il s'agit d'indiquer au kubelet quelles sont vos priorités sur un nœud donné si des ressources doivent être récupérées. Ce superbe GIF d'Anvesh Muppeda ci-dessous l'explique.

Si des ressources doivent être libérées, les pods avec une QoS « Meilleur effort » seront d'abord évincés, puis ceux avec une QoS « Évolutif », et enfin ceux avec une QoS garantie. L'idée est qu'en évinçant les pods de priorité inférieure, nous récupérerons suffisamment de ressources sur le nœud pour éviter d'avoir à évincer les pods avec une QoS garantie.

0
0 30
Article Guillaume Rongier · Juil 2, 2025 4m read

Bonjour chers ingénieurs interface et développeurs d'applications,     

Saviez-vous que Python peut être utilisé dans des productions ou des intégrations?

L'interface utilisateur de configuration de production est low-code, mais dans de nombreux projets, vous pouvez arriver au point où il est nécessaire d'écrire du code. Comme nous l'avons vu dans le cours Architecture d'intégration, les Business Process comportent de nombreux emplacements où insérer du code, notamment l'éditeur BPL (pour les Business Process BPL) et l'éditeur DTL (pour les transformations de données).

😯 À partir d'InterSystems IRIS 2025.1, Python et InterSystems ObjectScript sont tous deux pris en charge dans les éditeurs BPL et DTL. 😄 Vous pouvez choisir entre ces langues selon vos préférences personnelles, et pas selon des besoins techniques. 😍

Rédaction du code Python dans l'éditeur BPL

Python est pris en charge dans l'éditeur BPL depuis InterSystems IRIS 2024.1. Examinons un Business Process BPL:

Business Process BPL comprend les activités suivantes (dans l'ordre) : activité Début, activité Affectation, activité Code avec un logo Python, activité If avec un logo Python, activité Transformation du côté vrai de l'activité If, et activité Fin.

Dans l'activité <code>, GetWinningBid, remarquez l'icône Python. En ouvrant cette activité <code>, on peut voir que le champ intitulé Code contient des instructions Python! Ces instructions utilisent la bibliothèque intégrée iris pour ouvrir un objet d'un ID donné.

Une activité Code provenant d'un éditeur BPL. Le langage est défini sur Python. Le code indique # Utilisation du corps de la requête pour ouvrir l'objet Bid avec l'ID donné. New line. bidID = request.id. New line. context.winningBid = iris.cls("AuctionServer.Bid")._OpenId(bidID).

Vous pouvez définir le langage pour l'ensemble du BPL (Python ou ObjectScript) via le paramètre Language dans l'onglet General u BPL, puis utiliser le menu déroulant Language Override (Remplacement du language) dans un champ de code donné pour remplacer la valeur par défaut du BPL.

L'activité <code> n'est pas la seule activité qui analyse le code dans un Business Process BPL. L'activité <code> analyse les instructions de code complètes, mais autres champs des activités BPL acceptent également des expressions de code. Vous pouvez les reconnaître grâce au menu déroulant Language Override (Remplacement du langage), où vous pouvez remplacer la valeur par défaut de BPL. 

Par exemple, l'activité <if>, qui crée un flux logique conditionnel, a un champ appelé Condition qui accepte des expressions de code. Il a un champ correspondant appelé Condition Language Override (Remplacement du langage de condition). Dans cet exemple, ce champ est défini sur Python.

Lorsque Python n'était pas encore pris en charge dans ces domaines, les ingénieurs d'interface devaient savoir comment écrire des expressions logiques dans ObjectScript. Par exemple, vous deviez savoir que || signifie Or, et && signifie And. Vous pouvez désormais utiliser Python, dont la syntaxe pour les expressions logiques est plus proche du langage naturel.

Dans l'éditeur BPL, s'il vous faut importer des paquetages Python, vous pouvez le faire sous les instructions Python From/Import dans l'onglet General.

Rédaction du code Python dans l'éditeur DTL 

Python est également pris en charge dans les champs de code de l'éditeur DTL depuis InterSystems IRIS 2025.1. Les utilisations courantes du code personnalisé dans DTL sont le formatage de chaînes et les calculs.

Une transformation de données DTL convertissant un objet source, AuctionServer.Bid, into a target object, AuctionServer.Order

Si vous devez importer des paquetages Python dans l'éditeur DTL, recherchez l'onglet Paramètres Transformation et utilisez le champ d' instruction Python From / Import. Le langage par défaut pour les expressions de code peut également être défini dans l'onglet d'instructions Transformation .

Dans l'onglet Paramètres de transformation du DTL, le langage est défini sur Python et le champ des instructions Python From / Import contient la mention from numpy import random.

Pour trouver les champs d'analyse de code des actions DTL, il suffit de rechercher tout champ associé à une liste déroulante Language Override. Par exemple, dans l'action <code> du DTL, vous pouvez écrire des instructions de code complètes. Les actions telles que Set, If, Trace et autres prennent en charge les expressions de code, qui peuvent être écrites en Python ou en ObjectScript.

Une activité de code issue d'une transformation de données DTL, avec le langage défini sur Python. Le contenu du champ de code indique bidders = [bid.User for bid in source.Lot.Bids()]. New line. bidders = set(bidders). New line. target.NumOutbid = (len(bidders) - 1).

Flux de travail axés sur le code

Si vous maîtrisez le processus d'édition de productions via un code, vous pouvez modifier les fichiers BPL et DTL via leurs fichiers de configuration. Cette méthode n'est pas aussi simple que les interfaces de l'éditeur, mais elle est très intuitive pour les programmeurs expérimentés.

Vous pouvez également utiliser Python pour écrire des méthodes dans des fonctions utilitaires personnalisées et des composants personnalisés, tels que des opérations commerciales et des services commerciaux (à l'exception des méthodes de rappel callback methods, comme défini dans la documentation).

Récapitulatif 

  • L'éditeur DTL et l'éditeur BPL prennent désormais en charge le code et les expressions Python. 
  • Si nécessaire, indiquez les paquetages que vous souhaitez importer via les paramètres généraux de BPL ou DTL. 
  • Vous pouvez définir un langage par défaut pour chaque DTL/BPL et remplacer des champs spécifiques si nécessaire.

Rejoignez la conversation!

  • Avez-vous déjà utilisé Python pour créer des intégrations personnalisées? 
  • Quelles questions avez-vous au sujet de la prise en charge de Python dans les intégrations?
  • Ajoutez vos commentaires ci-dessous!
0
0 28
Article Iryna Mykhailova · Juin 17, 2025 5m read

Lorsque nous créons un référentiel FHIR dans IRIS, nous avons un point de terminaison pour accéder à l'information, créer de nouvelles ressources, etc. Mais il y a certaines ressources dans FHIR que nous n'aurons probablement pas dans notre référentiel, par exemple, la ressource Binary (cette ressource renvoie des documents, comme des PDF par exemple).

J'ai créé un exemple dans lequel, quand une ressource est demandée via "Binary", l'endpoint FHIR renvoie une réponse, comme si elle existait dans le référentiel. 

Tout d'abord, nous avons besoin du Namespace (espace de noms) et du FHIR endpoint (point d'accès FHIR). Ensuite, nous devons configurer une production d'interopérabilité - Interoperability production - qui sera connectée à l'endpoint FHIR. Cette production devrait contenir les éléments suivants:

  • Business Operation:
    • HS.Util.Trace.Operations (Ceci est évidemment facultatif, mais peut s'avérer très utile)
    • HS.FHIRServer.Interop.Operation, avec la propriété TraceOperations configurée à *FULL*
  • Business Service:
    • HS.FHIRServer.Interop.Service, avec la propriété TraceOperations configurée à *FULL* et Target Config Name configurée à  HS.FHIRServer.Interop.Operation name

La production se présente comme suit:

Après avoir créé cette production, nous devons la connecter avec l'endpoint FHIR. Il faut donc éditer l'endpoint FHIR et configurer le paramètre Service Config Name avec le nom du Business Service:

Maintenant, si nous commençons à envoyer des requêtes au référentiel FHIR, nous verrons toutes les traces dans l'Afficheur de messages:

Nous pouvons maintenant établir un Business Process pour contrôler ce qu'il convient de faire avec des chemins d'accès spécifiques.

Dans cet exemple, nous avons un Business Process qui reçoit toutes les demandes (maintenant le Business Service est connecté à ce Business Process, au lieu du Business Operation) et 2 nouvelles Business Operations qui effectuent d'autres actions dont nous parlerons plus tard:

Jetons un coup d'œil au Business Process appelé FHIRRouter:

En regardant, nous verrons que, si RequestPath contient "Binary/", alors nous ferons quelque chose avec cette requête: générer notre réponse Binary personnalisée. Sinon, nous enverrons la demande au référentiel FHIR directement.

Jetons un coup d'œil à la séquence appelée "Generate Binary":

Tout d'abord, nous créons une nouvelle instance de HS.FHIRServer.Interop.Response. Nous obtenons document ID à partir du chemin d'accès: Request Path. Comment? Chaque fois que quelqu'un veut une ressource binaire, elle doit être demandée avec l'identifiant du document dans le chemin de l'URL, quelque chose comme ceci: ..../fhir/r4/Binary/XXXXX. Ainsi, pour extraire l'identifiant du document du chemin d'accès, nous utilisons l'expression suivante:

$Replace(request.Request.RequestPath,"Binary/","")

(Ce n'est pas vraiment raffiné, mais cela fonctionne).

Si nous avons un identifiant de document, nous faisons appel à un Business Operation appelée Find pour rechercher le nom de fichier associé à cet identifiant de document:

En fait, cette recherche deBusiness OperationFind renvoie toujours le même nom de fichier:

L'exemple ci-dessus montre ce que nous pouvons faire.

Si nous avons un nom de fichier, alors, nous appelons un autre Business Operation appelé File pour obtenir le contenu de ce fichier, encodé en base64:

And finally, we can return 2 kind of responses:

  • Si nous n'avons pas de contenu de fichier (puisque nous n 'avons pas d 'identifiant de document ou que nous ne trouvons pas le nom de fichier ou le contenu associé), nous renvoyons une réponse 404, avec cette réponse personnalisée:
 set json = {
    "resourceType": "OperationOutcome",
    "issue": [
        {
            "severity": "error",
            "code": "not-found",
            "diagnostics": "<HSFHIRErr>ResourceNotFound",
            "details": {
                "text": "No resource with type 'Binary'"
            }
        }
    ]
 }
 set json.issue.%Get(0).details.text = json.issue.%Get(0).details.text_" and id '"_context.docId_"'"
 set qs = ##class(HS.SDA3.QuickStream).%New()
 do qs.Write(json.%ToJSON())
 set response.QuickStreamId = qs.%Id()
 set response.ContentType = "application/fhir+json"
 set response.CharSet = "UTF-8"
  • Si nous avons le contenu du fichier, nous renvoyons une réponse 200 avec cette réponse personnalisée:
 set json = {
  "resourceType": "Binary",
  "id": "",
  "contentType": "application/pdf",
  "securityContext": {
    "reference": "DocumentReference/"
  },
  "data": ""
 }
 set json.id = context.docId
 set json.securityContext.reference = json.securityContext.reference_json.id
 set json.data = context.content.Read(context.content.Size)
 
 set qs = ##class(HS.SDA3.QuickStream).%New()
 do qs.Write(json.%ToJSON())
 set response.QuickStreamId = qs.%Id()
 set response.ContentType = "application/fhir+json"
 set response.CharSet = "UTF-8"

La clé ici est de créer un HS.SDA3.QuickStream, qui contient l'objet JSON. Et d'ajouter ce QuickStream à la réponse.

Et maintenant, si nous testons notre point d'accès, si nous demandons un document de type Binary, nous verrons la réponse:

Et si nous requérons un document de type Binary qui n'existe pas (vous pouvez le tester sans spécifier l'identifiant du document), nous obtiendrons la réponse 404:

En résumé, en connectant notre endpoint FHIR avec l'interopérabilité, nous pouvons faire tout ce que nous voulons, avec toutes les capacités d'InterSystems IRIS.

0
0 24
InterSystems officiel Adeline Icard · Juin 10, 2025

InterSystems a publié de nouvelles mises à jour afin de corriger un défaut affectant les versions antérieures les plus récentes (2025.1.0, 2024.1.4, 2023.1.6 et 2022.1.7), pour les gammes de produits prises en charge suivantes :

  • InterSystems IRIS
  • InterSystems IRIS for Health
  • HealthShare Health Connect

Ce problème pouvait entraîner des erreurs <PROTECT> inattendues ou des anomalies d'accès lors de l'utilisation de fonctionnalités telles que :

0
0 33
Article Developer Community Admin · Juin 2, 2025 6m read

Le déplacement d'InterSystems IRIS et d'InterSystems IRIS for Health d'un environnement sur site vers le cloud offre de nombreux avantages aux Fournisseurs d'applications et de solutions. Ces avantages comprennent notamment la simplification des opérations, l'accès à des ressources flexibles et une résilience accrue. Les entreprises n'ont plus à se soucier des contraintes physiques et des dépenses liées à la maintenance d'une infrastructure sur site, telles que les besoins en énergie et en espace, ainsi que le coût élevé du matériel informatique.

L'un des avantages les plus convaincants est la possibilité d'accélérer la vitesse de commercialisation. En supprimant la charge liée à la maintenance de l'infrastructure, les environnements cloud permettent des cycles de développement et de déploiement plus rapides, ce qui permet aux entreprises de réagir rapidement aux demandes et aux opportunités du marché. Les coûts opérationnels sont également réduits, car les entreprises peuvent sadapter leurs ressources à la hausse ou à la baisse en fonction de leurs besoins réels, ce qui se traduit par une utilisation plus efficace du capital. De plus, la migration vers le cloud peut contribuer à réduire l'empreinte carbone en optimisant la consommation d'énergie grâce à une infrastructure cloud partagée.

Le déplacement vers le cloud peut impliquer des changements importants. Les entreprises peuvent bénéficier d'une orientation plus opérationnelle, en gérant et en optimisant en permanence les ressources cloud. Cette évolution peut nécessiter des changements dans les modèles commerciaux, une redéfinition des marges et des stratégies d'expansion ou de réduction des activités. Bien qu'ils nécessitent des investissements plus importants, ces changements peuvent améliorer la flexibilité et l'avantage compétitif sur le marché.

Choix architecturaux dans la migration vers le cloud

Lorsqu'elles envisagent la migration vers le cloud la plus simple, les entreprises doivent choisir un ou plusieurs services (AWS, Azure, Google ou autre) pour déplacer une application existante sur site vers l'un des clouds publics. Elles sont alors confrontées à un choix architectural important : migrer entièrement vers le cloud ou créer un cluster hybride sur site et dans le cloud. InterSystems IRIS et InterSystems IRIS for Health prennent tous deux entièrement en charge ces deux options. Un cluster hybride miroite l'instance sur site vers le cloud de manière asynchrone. Cette alternative peut être utile dans des situations telles que celles où l'OLTP continue de fonctionner sur site, mais où l'instance cloud fournit une prise en charge pour l'analyse, la création de rapports et d'autres opérations en lecture seule.

Options de migration

Chaque choix architectural pour la migration vers le cloud a ses avantages et ses limites,  il est donc essentiel pour les entreprises d'évaluer leurs besoins et leurs objectifs spécifiques lors de la planification d'une stratégie cloud. La première étape consiste à choisir entre une migration complète vers le cloud ou une configuration hybride.

Choix migratoireNombre de  déploiements InterSystems IRIS après la migrationCaractéristiques
Lift & Shift: migration complète vers le cloud1Configuration sur site locale transférée vers une architecture cloud
Cluster hybride : sur site plus copie miroir dans le cloud ("cluster étendu")2Cluster sur site mis en miroir vers une copie cloud en lecture seule mise à jour de manière asynchrone

Le choix Lift & Shift permet de profiter des avantages du cloud tout en conservant la propriété d'une seule copie d'InterSystems IRIS.

Le choix Hybrid combine la stabilité et la familiarité des systèmes sur site avec la flexibilité et l'évolutivité du cloud.

Consultez notre documentation en ligne pour plus d'informations sur la mise en miroir Mirroring.

Architecture multitenant ou monotenant avec InterSystems IRIS

Bien que la migration ne nécessite aucune modification de votre méthode de mutualisation, le cloud offre de puissantes options d'évolutivité et de facturation. Pour cette raison, vous souhaiterez peut-être réévaluer votre modèle de mutualisation. Pour toutes nos offres, lors du déploiement d'applications InterSystems IRIS dans le cloud, les entreprises peuvent choisir entre les architectures suivantes pour plusieurs utilisateurs:

  • Mono-tenant: Déploiements multiples ; un pour chacun de vos utilisateurs.
  • Multi-tenant: Plusieurs utilisateurs sur un seul déploiement.

Chaque architecture présente des avantages et des inconvénients distincts. Cela est particulièrement important pour les fournisseurs d'applications et de solutions qui ont développé des solutions à l'aide de la technologie InterSystems IRIS, que ce soit pour un grand nombre d'utilisateurs, dans le cadre d'une expansion majeure ou pour l'hébergement de données sensibles ou réglementées.

Évolutivité des ressources et des opérations

  • Multi-tenant: L'évolutivité d'un environnement multi-tenant implique l'ajout de ressources à une instance partagée unique pour chaque utilisateur (tenant), ce qui peut s'avérer plus rentable et plus simple à gérer. Cependant, les performances d'un tenant peuvent affecter celles des autres si les ressources allouées sont insuffisantes, ce qui peut entraîner des contention de ressources.
  • Mono-tenant: Faire évoluer un environnement mono-tenant signifie provisionner davantage de ressources pour chaque utilisateur individuellement. Bien que cela offre des performances plus prévisibles, le besoin d'infrastructure supplémentaire et les frais généraux liés à la gestion peuvent rendre ce choix plus complexe à faire évoluer.

Isolation des données

  • Multi-tenant: Dans une configuration multi-tenant, plusieurs tenants partagent la même instance de l'application et de la base de données. L'isolation des données est assurée par un partitionnement au niveau logiciel, qui garantit la sécurité et la séparation des données de chaque tenant. Cette approche peut être efficace en termes d'utilisation des ressources, mais elle peut nécessiter des mesures de sécurité rigoureuses pour prévenir les violations de données.
  • Mono-tenant: Avec une architecture mono-tenant, chaque utilisateur dispose d'une instance distincte de l'application et de la base de données. Cette configuration fournit un niveau plus élevé d'isolation des données, car les données de chaque tenant résident dans un environnement distinct. Ce choix peut être plus sûr et plus facile à gérer, facilitant la conformité aux réglementations en matière de protection des données. 

Méthodes de migration

Plusieurs approches sont disponibles pour migrer votre solution InterSystems IRIS de vos sites vers le service cloud de votre choix.

Les deux méthodes les plus courantes sont décrites ci-dessous. Elles commencent toutes deux par la même étape, qui consiste à miroiter un déploiement existant vers le cloud, mais elles divergent ensuite.

Choisir entre miroir et lift-and-shift

Les méthodes du miroir et du lift-and-shift commencent toutes deux par la copie de votre InterSystems IRIS existant depuis votre environnement sur site vers une plateforme cloud. Une fois la copie cloud synchronisée avec l'instance sur site, vous choisissez définitivement où se termine le chemin de migration:

  • Miroir: vous continuez à utiliser l'instance sur site comme instance principale et l'instance cloud comme instance de sauvegarde et pour les opérations en lecture seule, telles que l'analyse et l'apprentissage automatique. L'instance cloud est asynchrone, mais mise à jour régulièrement.
  • Lift-and-shift: Une fois l'instance principale sur site et les instances secondaires basées sur le cloud synchronisées, les opérations de "basculement" s'effectuent depuis l'instance sur site vers la copie dans le cloud, qui devient alors l'instance principale pour toutes les opérations (et pas seulement en lecture seule). À ce stade, le déploiement sur site peut être archivé sous forme de sauvegarde instantanée.

La mise en miroir de votre instance InterSystems IRIS locale existante vers le cloud est le moyen le plus courant, le plus résilient et le plus simple de migrer votre déploiement sur site. Pour plus d'informations, consultez le Guide de migration du serveur Server Migration Guide dans notre documentation en ligne.


Plus d'articles sur le sujet:

Source: Déplacement d'InterSystems IRIS vers le cloud

0
0 38
Article Sylvain Guilbaud · Mai 30, 2025 3m read

Kong fournit en open source un outil de gestion de ses configurations (écrit en Go), appelé decK (pour declarative Kong)

  • Vérifiez que decK reconnaît votre installation Kong Gateway via deck gateway ping
deck gateway ping   
Successfully connected to Kong!
Kong version:  3.4.3.11
  • Exporter la configuration de Kong Gateway dans un fichier "kong.yaml" via deck gateway dump
deck gateway dump -o kong.yaml
  • Après avoir modifié les adresses IP dans le fichier kong.yaml, afficher les différences via deck gateway diff
0
0 25