Partager via


Inspection des données de télémétrie avec la console

Bien que la console ne soit pas un moyen recommandé d’inspecter les données de télémétrie, il s’agit d’un moyen simple et rapide de commencer. Cet article vous montre comment générer des données de télémétrie dans la console pour l’inspection avec une configuration minimale du noyau.

Exportateur

Les exportateurs sont responsables de l’envoi de données de télémétrie à une destination. En savoir plus sur les exportateurs ici. Dans cet exemple, nous utilisons l’exportateur de console pour générer des données de télémétrie dans la console.

Prérequis

  • Déploiement d’une conversation Azure OpenAI terminée.
  • Dernier SDK .Net pour votre système d’exploitation.

Remarque

L’observabilité du noyau sémantique n’est pas encore disponible pour Java.

Programme d’installation

Créer une application console

Dans un terminal, exécutez la commande suivante pour créer une application console en C# :

dotnet new console -n TelemetryConsoleQuickstart

Accédez au répertoire du projet nouvellement créé une fois la commande terminée.

Installer les packages nécessaires

  • Noyau sémantique

    dotnet add package Microsoft.SemanticKernel
    
  • OpenTelemetry Console Exporter

    dotnet add package OpenTelemetry.Exporter.Console
    

Créer une application simple avec le noyau sémantique

Dans le répertoire du projet, ouvrez le Program.cs fichier avec votre éditeur favori. Nous allons créer une application simple qui utilise le noyau sémantique pour envoyer une invite à un modèle d’achèvement de conversation. Remplacez le contenu existant par le code suivant et renseignez les valeurs requises pour deploymentName, endpointet apiKey:

using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Logging;
using Microsoft.SemanticKernel;
using OpenTelemetry;
using OpenTelemetry.Logs;
using OpenTelemetry.Metrics;
using OpenTelemetry.Resources;
using OpenTelemetry.Trace;

namespace TelemetryConsoleQuickstart
{
    class Program
    {
        static async Task Main(string[] args)
        {
            // Telemetry setup code goes here

            IKernelBuilder builder = Kernel.CreateBuilder();
            // builder.Services.AddSingleton(loggerFactory);
            builder.AddAzureOpenAIChatCompletion(
                deploymentName: "your-deployment-name",
                endpoint: "your-azure-openai-endpoint",
                apiKey: "your-azure-openai-api-key"
            );

            Kernel kernel = builder.Build();

            var answer = await kernel.InvokePromptAsync(
                "Why is the sky blue in one sentence?"
            );

            Console.WriteLine(answer);
        }
    }
}

Ajouter des données de télémétrie

Si vous exécutez l’application console maintenant, vous devez vous attendre à voir une phrase expliquant pourquoi le ciel est bleu. Pour observer le noyau via la télémétrie, remplacez le // Telemetry setup code goes here commentaire par le code suivant :

var resourceBuilder = ResourceBuilder
    .CreateDefault()
    .AddService("TelemetryConsoleQuickstart");

// Enable model diagnostics with sensitive data.
AppContext.SetSwitch("Microsoft.SemanticKernel.Experimental.GenAI.EnableOTelDiagnosticsSensitive", true);

using var traceProvider = Sdk.CreateTracerProviderBuilder()
    .SetResourceBuilder(resourceBuilder)
    .AddSource("Microsoft.SemanticKernel*")
    .AddConsoleExporter()
    .Build();

using var meterProvider = Sdk.CreateMeterProviderBuilder()
    .SetResourceBuilder(resourceBuilder)
    .AddMeter("Microsoft.SemanticKernel*")
    .AddConsoleExporter()
    .Build();

using var loggerFactory = LoggerFactory.Create(builder =>
{
    // Add OpenTelemetry as a logging provider
    builder.AddOpenTelemetry(options =>
    {
        options.SetResourceBuilder(resourceBuilder);
        options.AddConsoleExporter();
        // Format log messages. This is default to false.
        options.IncludeFormattedMessage = true;
        options.IncludeScopes = true;
    });
    builder.SetMinimumLevel(LogLevel.Information);
});

Enfin, supprimez les marques de commentaire de la ligne // builder.Services.AddSingleton(loggerFactory); pour ajouter la fabrique d’enregistreurs d’événements au générateur.

Dans l’extrait de code ci-dessus, nous créons d’abord un générateur de ressources pour créer des instances de ressources. Une ressource représente l’entité qui produit des données de télémétrie. Vous pouvez en savoir plus sur les ressources ici. Le générateur de ressources aux fournisseurs est facultatif. S’il n’est pas fourni, la ressource par défaut avec des attributs par défaut est utilisée.

Ensuite, nous allons activer les diagnostics avec des données sensibles. Il s’agit d’une fonctionnalité expérimentale qui vous permet d’activer les diagnostics pour les services IA dans le noyau sémantique. Avec cette option activée, vous verrez des données de télémétrie supplémentaires telles que les invites envoyées et les réponses reçues des modèles IA, qui sont considérées comme des données sensibles. Si vous ne souhaitez pas inclure de données sensibles dans vos données de télémétrie, vous pouvez utiliser un autre commutateur Microsoft.SemanticKernel.Experimental.GenAI.EnableOTelDiagnostics pour activer les diagnostics avec des données non sensibles, telles que le nom du modèle, le nom de l’opération et l’utilisation des jetons, etc.

Ensuite, nous créons un générateur de fournisseurs de suivi et un générateur de fournisseurs de compteurs. Un fournisseur est chargé de traiter les données de télémétrie et de les acheminer vers les exportateurs. Nous nous abonneons à la Microsoft.SemanticKernel* source pour recevoir des données de télémétrie à partir des espaces de noms du noyau sémantique. Nous ajoutons un exportateur de console au fournisseur de suivi et au fournisseur de compteurs. L’exportateur de console envoie des données de télémétrie à la console.

Enfin, nous créons une fabrique d’enregistreurs d’événements et ajoutons OpenTelemetry en tant que fournisseur de journalisation qui envoie des données de journalisation à la console. Nous définissons le niveau Information minimal du journal et incluons des messages et des étendues mis en forme dans la sortie du journal. La fabrique d’enregistreurs d’événements est ensuite ajoutée au générateur.

Important

Un fournisseur doit être un singleton et doit être actif pour toute la durée de vie de l’application. Le fournisseur doit être supprimé lorsque l’application est arrêtée.

Créer un environnement virtuel Python

python -m venv telemetry-console-quickstart

Activez l’environnement virtuel.

telemetry-console-quickstart\Scripts\activate

Installer les packages nécessaires

pip install semantic-kernel

Créer un script Python simple avec le noyau sémantique

Créez un script Python et ouvrez-le avec votre éditeur favori.

New-Item -Path telemetry_console_quickstart.py -ItemType file

Nous allons créer un script Python simple qui utilise le noyau sémantique pour envoyer une invite à un modèle d’achèvement de conversation. Remplacez le contenu existant par le code suivant et renseignez les valeurs requises pour deployment_name, endpointet api_key:

import asyncio
import logging

from opentelemetry._logs import set_logger_provider
from opentelemetry.metrics import set_meter_provider
from opentelemetry.sdk._logs import LoggerProvider, LoggingHandler
from opentelemetry.sdk._logs.export import BatchLogRecordProcessor, ConsoleLogExporter
from opentelemetry.sdk.metrics import MeterProvider
from opentelemetry.sdk.metrics.export import ConsoleMetricExporter, PeriodicExportingMetricReader
from opentelemetry.sdk.metrics.view import DropAggregation, View
from opentelemetry.sdk.resources import Resource
from opentelemetry.sdk.trace import TracerProvider
from opentelemetry.sdk.trace.export import BatchSpanProcessor, ConsoleSpanExporter
from opentelemetry.semconv.resource import ResourceAttributes
from opentelemetry.trace import set_tracer_provider

from semantic_kernel import Kernel
from semantic_kernel.connectors.ai.open_ai import AzureChatCompletion


# Telemetry setup code goes here

async def main():
    # Create a kernel and add a service
    kernel = Kernel()
    kernel.add_service(AzureChatCompletion(
        api_key="your-azure-openai-api-key",
        endpoint="your-azure-openai-endpoint",
        deployment_name="your-deployment-name"
    ))

    answer = await kernel.invoke_prompt("Why is the sky blue in one sentence?")
    print(answer)


if __name__ == "__main__":
    asyncio.run(main())

Ajouter des données de télémétrie

Variables d'environnement

Par défaut, le noyau n’émet pas d’étendues pour les connecteurs IA, car ces étendues portent gen_ai des attributs considérés comme expérimentaux. Pour activer la fonctionnalité, définissez la variable SEMANTICKERNEL_EXPERIMENTAL_GENAI_ENABLE_OTEL_DIAGNOSTICS d’environnement ou SEMANTICKERNEL_EXPERIMENTAL_GENAI_ENABLE_OTEL_DIAGNOSTICS_SENSITIVE sur true.

Important

Les invites et les achèvements sont considérés comme des données sensibles. Le noyau sémantique n’émet pas ces données à partir des connecteurs IA, sauf si la SEMANTICKERNEL_EXPERIMENTAL_GENAI_ENABLE_OTEL_DIAGNOSTICS_SENSITIVE variable d’environnement est définie truesur . Le paramètre SEMANTICKERNEL_EXPERIMENTAL_GENAI_ENABLE_OTEL_DIAGNOSTICS pour true émettre uniquement des données non sensibles telles que le nom du modèle, le nom de l’opération et l’utilisation des jetons.

Créez un fichier nommé .env dans le même répertoire que votre script et ajoutez le contenu suivant :

SEMANTICKERNEL_EXPERIMENTAL_GENAI_ENABLE_OTEL_DIAGNOSTICS_SENSITIVE=true

Code

Si vous exécutez le script maintenant, vous devez vous attendre à voir une phrase expliquant pourquoi le ciel est bleu. Pour observer le noyau via la télémétrie, remplacez le # Telemetry setup code goes here commentaire par le code suivant :

# Create a resource to represent the service/sample
resource = Resource.create({ResourceAttributes.SERVICE_NAME: "telemetry-console-quickstart"})


def set_up_logging():
    exporter = ConsoleLogExporter()

    # Create and set a global logger provider for the application.
    logger_provider = LoggerProvider(resource=resource)
    # Log processors are initialized with an exporter which is responsible
    # for sending the telemetry data to a particular backend.
    logger_provider.add_log_record_processor(BatchLogRecordProcessor(exporter))
    # Sets the global default logger provider
    set_logger_provider(logger_provider)

    # Create a logging handler to write logging records, in OTLP format, to the exporter.
    handler = LoggingHandler()
    # Add filters to the handler to only process records from semantic_kernel.
    handler.addFilter(logging.Filter("semantic_kernel"))
    # Attach the handler to the root logger. `getLogger()` with no arguments returns the root logger.
    # Events from all child loggers will be processed by this handler.
    logger = logging.getLogger()
    logger.addHandler(handler)
    logger.setLevel(logging.INFO)


def set_up_tracing():
    exporter = ConsoleSpanExporter()

    # Initialize a trace provider for the application. This is a factory for creating tracers.
    tracer_provider = TracerProvider(resource=resource)
    # Span processors are initialized with an exporter which is responsible
    # for sending the telemetry data to a particular backend.
    tracer_provider.add_span_processor(BatchSpanProcessor(exporter))
    # Sets the global default tracer provider
    set_tracer_provider(tracer_provider)


def set_up_metrics():
    exporter = ConsoleMetricExporter()

    # Initialize a metric provider for the application. This is a factory for creating meters.
    meter_provider = MeterProvider(
        metric_readers=[PeriodicExportingMetricReader(exporter, export_interval_millis=5000)],
        resource=resource,
        views=[
            # Dropping all instrument names except for those starting with "semantic_kernel"
            View(instrument_name="*", aggregation=DropAggregation()),
            View(instrument_name="semantic_kernel*"),
        ],
    )
    # Sets the global default meter provider
    set_meter_provider(meter_provider)


# This must be done before any other telemetry calls
set_up_logging()
set_up_tracing()
set_up_metrics()

Dans l’extrait de code ci-dessus, nous créons d’abord une ressource pour représenter le service. Une ressource représente l’entité qui produit des données de télémétrie. Vous pouvez en savoir plus sur les ressources ici. Nous créons ensuite trois fonctions pour configurer la journalisation, le suivi et les métriques. Chaque fonction crée un fournisseur pour les données de télémétrie respectives et ajoute un exportateur de console au fournisseur.

Enfin, nous appelons les trois fonctions pour configurer la journalisation, le suivi et les métriques. Cette opération doit être effectuée avant tout autre appel de télémétrie.

Remarque

L’observabilité du noyau sémantique n’est pas encore disponible pour Java.

Exécuter

Exécutez l’application console avec la commande suivante :

dotnet run

Exécutez le script Python avec la commande suivante :

python telemetry_console_quickstart.py

Remarque

L’observabilité du noyau sémantique n’est pas encore disponible pour Java.

Inspecter les données de télémétrie

Enregistrement de journaux

Vous devez voir plusieurs enregistrements de journal dans la sortie de la console. Ils ressemblent à ce qui suit :

LogRecord.Timestamp:               2024-09-12T21:48:35.2295938Z
LogRecord.TraceId:                 159d3f07664838f6abdad7af6a892cfa
LogRecord.SpanId:                  ac79a006da8a6215
LogRecord.TraceFlags:              Recorded
LogRecord.CategoryName:            Microsoft.SemanticKernel.KernelFunction
LogRecord.Severity:                Info
LogRecord.SeverityText:            Information
LogRecord.FormattedMessage:        Function InvokePromptAsync_290eb9bece084b00aea46b569174feae invoking.
LogRecord.Body:                    Function {FunctionName} invoking.
LogRecord.Attributes (Key:Value):
    FunctionName: InvokePromptAsync_290eb9bece084b00aea46b569174feae
    OriginalFormat (a.k.a Body): Function {FunctionName} invoking.

Resource associated with LogRecord:
service.name: TelemetryConsoleQuickstart
service.instance.id: a637dfc9-0e83-4435-9534-fb89902e64f8
telemetry.sdk.name: opentelemetry
telemetry.sdk.language: dotnet
telemetry.sdk.version: 1.9.0

Il existe deux parties pour chaque enregistrement de journal :

  • Enregistrement de journal lui-même : contient l’horodatage et l’espace de noms à partir desquels l’enregistrement du journal a été généré, la gravité et le corps de l’enregistrement du journal, ainsi que tous les attributs associés à l’enregistrement du journal.
  • Ressource associée à l’enregistrement de journal : contient des informations sur le service, l’instance et le Kit de développement logiciel (SDK) utilisés pour générer l’enregistrement du journal.

Activités

Remarque

Les activités dans .Net sont similaires aux étendues dans OpenTelemetry. Ils sont utilisés pour représenter une unité de travail dans l’application.

Vous devez voir plusieurs activités dans la sortie de la console. Ils ressemblent à ce qui suit :

Activity.TraceId:            159d3f07664838f6abdad7af6a892cfa
Activity.SpanId:             8c7c79bc1036eab3
Activity.TraceFlags:         Recorded
Activity.ParentSpanId:       ac79a006da8a6215
Activity.ActivitySourceName: Microsoft.SemanticKernel.Diagnostics
Activity.DisplayName:        chat.completions gpt-4o
Activity.Kind:               Client
Activity.StartTime:          2024-09-12T21:48:35.5717463Z
Activity.Duration:           00:00:02.3992014
Activity.Tags:
    gen_ai.operation.name: chat.completions
    gen_ai.system: openai
    gen_ai.request.model: gpt-4o
    gen_ai.response.prompt_tokens: 16
    gen_ai.response.completion_tokens: 29
    gen_ai.response.finish_reason: Stop
    gen_ai.response.id: chatcmpl-A6lxz14rKuQpQibmiCpzmye6z9rxC
Activity.Events:
    gen_ai.content.prompt [9/12/2024 9:48:35 PM +00:00]
        gen_ai.prompt: [{"role": "user", "content": "Why is the sky blue in one sentence?"}]
    gen_ai.content.completion [9/12/2024 9:48:37 PM +00:00]
        gen_ai.completion: [{"role": "Assistant", "content": "The sky appears blue because shorter blue wavelengths of sunlight are scattered in all directions by the gases and particles in the Earth\u0027s atmosphere more than other colors."}]
Resource associated with Activity:
    service.name: TelemetryConsoleQuickstart
    service.instance.id: a637dfc9-0e83-4435-9534-fb89902e64f8
    telemetry.sdk.name: opentelemetry
    telemetry.sdk.language: dotnet
    telemetry.sdk.version: 1.9.0

Il existe deux parties pour chaque activité :

  • L’activité elle-même : contient l’ID d’étendue et l’ID d’étendue parent que les outils APM utilisent pour générer les traces, la durée de l’activité et toutes les balises et événements associés à l’activité.
  • Ressource associée à l’activité : contient des informations sur le service, l’instance et le SDK utilisés pour générer l’activité.

Important

Les attributs auxquels prêter une attention supplémentaire sont ceux qui commencent par gen_ai. Il s’agit des attributs spécifiés dans les conventions sémantiques GenAI.

Métriques

Vous devez voir plusieurs enregistrements de métriques dans la sortie de la console. Ils ressemblent à ce qui suit :

Metric Name: semantic_kernel.connectors.openai.tokens.prompt, Number of prompt tokens used, Unit: {token}, Meter: Microsoft.SemanticKernel.Connectors.OpenAI
(2024-09-12T21:48:37.9531072Z, 2024-09-12T21:48:38.0966737Z] LongSum
Value: 16

Ici, vous pouvez voir le nom, la description, l’unité, l’intervalle de temps, le type, la valeur de la métrique et le compteur auquel appartient la métrique.

Remarque

La métrique ci-dessus est une métrique compteur. Pour obtenir la liste complète des types de métriques, voir ici. Selon le type de métrique, la sortie peut varier.

Journaux d’activité

Vous devez voir plusieurs enregistrements de journal dans la sortie de la console. Ils ressemblent à ce qui suit :

{
    "body": "Function SyVCcBjaULqEhItH invoking.",
    "severity_number": "<SeverityNumber.INFO: 9>",
    "severity_text": "INFO",
    "attributes": {
        "code.filepath": "C:\\tmp\\telemetry-console-quickstart\\Lib\\site-packages\\semantic_kernel\\functions\\kernel_function_log_messages.py",
        "code.function": "log_function_invoking",
        "code.lineno": 19
    },
    "dropped_attributes": 0,
    "timestamp": "2024-09-13T17:55:45.504983Z",
    "observed_timestamp": "2024-09-13T17:55:45.504983Z",
    "trace_id": "0xe23e2c10785ea61ffc9f28be19482a80",
    "span_id": "0x686bd592e27661d7",
    "trace_flags": 1,
    "resource": {
        "attributes": {
            "telemetry.sdk.language": "python",
            "telemetry.sdk.name": "opentelemetry",
            "telemetry.sdk.version": "1.27.0",
            "service.name": "telemetry-console-quickstart"
        },
        "schema_url": ""
    }
}

Étendues

Vous devez voir plusieurs étendues dans la sortie de la console. Ils ressemblent à ce qui suit :

{
    "name": "chat.completions gpt-4o",
    "context": {
        "trace_id": "0xe23e2c10785ea61ffc9f28be19482a80",
        "span_id": "0x8b20e9655610c3c9",
        "trace_state": "[]"
    },
    "kind": "SpanKind.INTERNAL",
    "parent_id": "0x686bd592e27661d7",
    "start_time": "2024-09-13T17:55:45.515198Z",
    "end_time": "2024-09-13T17:55:46.469471Z",
    "status": {
        "status_code": "UNSET"
    },
    "attributes": {
        "gen_ai.operation.name": "chat.completions",
        "gen_ai.system": "openai",
        "gen_ai.request.model": "gpt-4o",
        "gen_ai.response.id": "chatcmpl-A74oD7WGDjawnZ44SJZrj9fKrEv1B",
        "gen_ai.response.finish_reason": "FinishReason.STOP",
        "gen_ai.response.prompt_tokens": 16,
        "gen_ai.response.completion_tokens": 29
    },
    "events": [
        {
            "name": "gen_ai.content.prompt",
            "timestamp": "2024-09-13T17:55:45.515198Z",
            "attributes": {
                "gen_ai.prompt": "[{\"role\": \"user\", \"content\": \"Why is the sky blue in one sentence?\"}]"
            }
        },
        {
            "name": "gen_ai.content.completion",
            "timestamp": "2024-09-13T17:55:46.469471Z",
            "attributes": {
                "gen_ai.completion": "[{\"role\": \"assistant\", \"content\": \"The sky appears blue because shorter blue wavelengths of sunlight are scattered in all directions by the molecules and particles in the atmosphere more effectively than other colors.\"}]"
            }
        }
    ],
    "links": [],
    "resource": {
        "attributes": {
            "telemetry.sdk.language": "python",
            "telemetry.sdk.name": "opentelemetry",
            "telemetry.sdk.version": "1.27.0",
            "service.name": "telemetry-console-quickstart"
        },
        "schema_url": ""
    }
}

Attention aux attributs qui commencent par gen_ai. Il s’agit des attributs spécifiés dans les conventions sémantiques GenAI. Ils fournissent des informations utiles sur les demandes envoyées et les réponses reçues des modèles IA.

Métriques

Vous devez voir plusieurs enregistrements de métriques dans la sortie de la console. Ils ressemblent à ce qui suit :

{
    "resource_metrics": [
        {
            "resource": {
                "attributes": {
                    "telemetry.sdk.language": "python",
                    "telemetry.sdk.name": "opentelemetry",
                    "telemetry.sdk.version": "1.27.0",
                    "service.name": "telemetry-console-quickstart"
                },
                "schema_url": ""
            },
            "scope_metrics": [
                {
                    "scope": {
                        "name": "semantic_kernel.functions.kernel_function",
                        "version": null,
                        "schema_url": "",
                        "attributes": null
                    },
                    "metrics": [
                        {
                            "name": "semantic_kernel.function.invocation.duration",
                            "description": "Measures the duration of a function's execution",
                            "unit": "s",
                            "data": {
                                "data_points": [
                                    {
                                        "attributes": {
                                            "semantic_kernel.function.name": "SyVCcBjaULqEhItH"
                                        },
                                        "start_time_unix_nano": 1726250146470468300,
                                        "time_unix_nano": 1726250146478526600,
                                        "count": 1,
                                        "sum": 0.9650602999900002,
                                        "bucket_counts": [
                                            0,
                                            1,
                                            0,
                                            0,
                                            0,
                                            0,
                                            0,
                                            0,
                                            0,
                                            0,
                                            0,
                                            0,
                                            0,
                                            0,
                                            0,
                                            0
                                        ],
                                        "explicit_bounds": [
                                            0.0,
                                            5.0,
                                            10.0,
                                            25.0,
                                            50.0,
                                            75.0,
                                            100.0,
                                            250.0,
                                            500.0,
                                            750.0,
                                            1000.0,
                                            2500.0,
                                            5000.0,
                                            7500.0,
                                            10000.0
                                        ],
                                        "min": 0.9650602999900002,
                                        "max": 0.9650602999900002
                                    }
                                ],
                                "aggregation_temporality": 2
                            }
                        }
                    ],
                    "schema_url": ""
                }
            ],
            "schema_url": ""
        }
    ]
}

La mesure indiquée ci-dessus est une métrique d’histogramme. Pour obtenir la liste complète des types de métriques, voir ici.

Remarque

L’observabilité du noyau sémantique n’est pas encore disponible pour Java.

Étapes suivantes

Maintenant que vous avez correctement généré des données de télémétrie dans la console, vous pouvez en savoir plus sur l’utilisation des outils APM pour visualiser et analyser les données de télémétrie.