Émettre des événements de trace en Java

Vous pouvez utiliser la classe com.snowflake.telemetry.Telemetry de la bibliothèque de l”API de télémétrie pour émettre des événements de trace à partir d’un gestionnaire de fonction ou de procédure écrit en Java. La classe Telemetry est incluse dans Snowflake.

Note

L’utilisation de la bibliothèque de télémétrie Snowflake ajoute d’autres bibliothèques à l’environnement d’exécution de votre fonction ou procédure. Pour plus d’informations, reportez-vous à Dépendances du paquet de télémétrie Snowflake.

Pour plus d’informations sur l’inclusion de la bibliothèque de télémétrie lors de l’empaquetage de votre code avec Maven, reportez-vous à Configuration de votre environnement Java et Scala pour l’utilisation de la classe de télémétrie.

Vous pouvez accéder aux données de trace stockées en exécutant une commande SELECT sur la table des événements. Pour plus d’informations, reportez-vous à Accès aux données de trace.

Note

Pour les lignes directrices à garder à l’esprit lors de l’ajout d’événements de trace, se référer à Lignes directrices générales pour l’ajout d’événements de trace.

Pour des informations générales sur la configuration de la journalisation et la récupération des messages dans Snowflake, reportez-vous à Enregistrement de messages à partir de fonctions et de procédures.

Avant de journaliser à partir d’un code, vous devez :

  • Mettre en place une table d’événements pour collecter les messages enregistrés par le code du gestionnaire.

    Pour plus d’informations, reportez-vous à Configuration d’une table d’événement.

  • Assurez-vous que le niveau de trace est défini de manière à ce que les données souhaitées soient stockées dans la table des événements.

    Pour plus d’informations, reportez-vous à Réglage du niveau de trace.

Ajout d’une prise en charge de l’API de télémétrie

Pour utiliser les méthodes Telemetry, vous devez mettre la bibliothèque de télémétrie Snowflake, qui est incluse dans Snowflake, à la disposition de votre code de gestionnaire.

  • Dans la clause PACKAGES de votre instruction CREATE PROCEDURE ou CREATE FUNCTION, incluez le paquet com.snowflake:telemetry. La clause PACKAGES rend l’API de télémétrie Snowflake incluse disponible pour votre code.

    Le code de l’exemple suivant utilise la clause PACKAGES pour référencer la bibliothèque de télémétrie ainsi que la bibliothèque Snowpark (qui est requise pour les procédures stockées écrites en Java - pour plus d’informations, voir Écriture de procédures stockées en Java).

    CREATE OR REPLACE PROCEDURE MYPROC(...)
      RETURNS ...
      LANGUAGE JAVA
      ...
      PACKAGES = ('com.snowflake:snowpark:latest', 'com.snowflake:telemetry:latest')
      ...
    
    Copy
  • Importez le paquet com.snowflake.telemetry dans le code de votre gestionnaire Java.

    import com.snowflake.telemetry.Telemetry;
    
    Copy

Ajout d’événements de trace

Vous pouvez ajouter des événements de trace en appelant la méthode Telemetry.addEvent et en indiquant le nom de l’événement. Il est également possible d’associer des attributs (paires clé-valeur) à un événement.

La méthode addEvent a les signatures suivantes :

public static void addEvent(String name)
public static void addEvent(String name, Attributes attributes)
Copy

Le code de l’exemple suivant ajoute un événement appelé testEvent et lui associe deux attributs : key et result.

// Adding an event without attributes.
Telemetry.addEvent("testEvent");

// Adding an event with attributes.
Attributes eventAttributes = Attributes.of(
  AttributeKey.stringKey("key"), "run",
  AttributeKey.longKey("result"), Long.valueOf(123));
Telemetry.addEvent("testEventWithAttributes", eventAttributes);
Copy

L’ajout de ces événements donne lieu à deux lignes dans la table des événements, chacune avec une valeur différente dans la colonne RECORD :

{
  "name": "testEvent"
}
Copy
{
  "name": "testEventWithAttributes"
}
Copy

La ligne d’événement testEventWithAttributes comprend les attributs suivants dans la colonne RECORD_ATTRIBUTES de la ligne :

{
  "key": "run",
  "result": 123
}
Copy

Ajout d’attributs de span

Vous pouvez définir des attributs (paires clé-valeur) associés aux spans en appelant la méthode Telemetry.setSpanAttribute.

La méthode setSpanAttribute a les signatures suivantes :

public static void setSpanAttribute(String key, boolean value)
public static void setSpanAttribute(String key, long value)
public static void setSpanAttribute(String key, double value)
public static void setSpanAttribute(String key, String value)
Copy

Pour plus de détails sur les spans, voir Comment Snowflake représente les événements de trace.

Le code de l’exemple suivant crée quatre attributs et définit leurs valeurs :

// Setting span attributes.
Telemetry.setSpanAttribute("example.boolean", true);
Telemetry.setSpanAttribute("example.long", 2L);
Telemetry.setSpanAttribute("example.double", 2.5);
Telemetry.setSpanAttribute("example.string", "testAttribute");
Copy

La définition de ces attributs se traduit par les éléments suivants dans la colonne RECORD_ATTRIBUTES de la table des événements :

{
  "example.boolean": true,
  "example.long": 2,
  "example.double": 2.5,
  "example.string": "testAttribute"
}
Copy

Exemples Java

Exemple de procédure stockée

CREATE OR REPLACE PROCEDURE do_tracing()
RETURNS STRING
LANGUAGE JAVA
RUNTIME_VERSION = '11'
PACKAGES=('com.snowflake:snowpark:latest', 'com.snowflake:telemetry:latest')
HANDLER = 'ProcedureHandler.run'
AS
$$
import com.snowflake.snowpark_java.Session;
import com.snowflake.telemetry.Telemetry;
import io.opentelemetry.api.common.AttributeKey;
import io.opentelemetry.api.common.Attributes;

public class ProcedureHandler {

  public String run(Session session) {

    // Set span attribute.
    Telemetry.setSpanAttribute("example.proc.do_tracing", "begin");

    // Add an event without attributes.
    Telemetry.addEvent("run_method_start");

    // Add an event with attributes.
    Attributes eventAttributes = Attributes.of(
      AttributeKey.stringKey("example.method.name"), "run",
      AttributeKey.longKey("example.long"), Long.valueOf(123));
    Telemetry.addEvent("event_with_attributes", eventAttributes);

    // Set span attribute.
    Telemetry.setSpanAttribute("example.proc.do_tracing", "complete");

    return "SUCCESS";
  }
}
$$;
Copy

Exemple UDF

CREATE OR REPLACE FUNCTION add_two_numbers(A FLOAT, B FLOAT) RETURNS FLOAT
LANGUAGE JAVA
PACKAGES=('com.snowflake:telemetry:latest')
HANDLER = 'ScalarFunctionHandler.run'
AS
$$
import com.snowflake.telemetry.Telemetry;
import io.opentelemetry.api.common.AttributeKey;
import io.opentelemetry.api.common.Attributes;
import io.opentelemetry.api.common.AttributesBuilder;

class ScalarFunctionHandler {

  public static Double run(Double d0, Double d1) {

    // Set span attribute.
    Telemetry.setSpanAttribute("example.func.add_two_numbers", "begin");

    // Add an event without attributes.
    Telemetry.addEvent("run_method_start");

    // Add an event with attributes.
    Attributes eventAttributes = Attributes.of(
      AttributeKey.stringKey("example.method.name"), "run",
      AttributeKey.longKey("example.long"), Long.valueOf(123));
    Telemetry.addEvent("event_with_attributes", eventAttributes);

    Double response = d0 == null || d1 == null ? null : (d0 + d1);

    // Set span attribute.
    Telemetry.setSpanAttribute("example.func.add_two_numbers.response", response);
    Telemetry.setSpanAttribute("example.func.add_two_numbers", "complete");

    return response;
  }
}
$$;
Copy

Exemple UDTF

CREATE OR REPLACE FUNCTION digits_of_number(x int)
RETURNS TABLE(result int)
LANGUAGE JAVA
PACKAGES=('com.snowflake:telemetry:latest')
HANDLER = 'TableFunctionHandler'
AS
$$
import com.snowflake.telemetry.Telemetry;
import io.opentelemetry.api.common.AttributeKey;
import io.opentelemetry.api.common.Attributes;
import io.opentelemetry.api.common.AttributesBuilder;
import java.util.stream.Stream;

public class TableFunctionHandler {

  public TableFunctionHandler() {
    // Set span attribute.
    Telemetry.setSpanAttribute("example.func.digits_of_number", "begin");
  }

  static class OutputRow {
    public int result;

    public OutputRow(int result) {
      this.result = result;
    }
  }

  public static Class getOutputClass() {
    return OutputRow.class;
  }

  public Stream<OutputRow> process(int input) {

    // Add an event with attributes.
    Attributes eventAttributes = Attributes.of(
      AttributeKey.longKey("example.received.value"), Long.valueOf(input));
    Telemetry.addEvent("digits_of_number", eventAttributes);

    Stream.Builder<OutputRow> stream = Stream.builder();
    while (input > 0) {

      stream.add(new OutputRow(input %10));
      input /= 10;
    }

    // Set span attribute.
    Telemetry.setSpanAttribute("example.func.digits_of_number", "complete");

    return stream.build();
  }
}
$$;
Copy