연습 - 클라우드 네이티브 애플리케이션에서 OpenTelemetry 데이터 사용

완료됨

이 연습에서는 앱에서 OpenTelemetry에서 생성된 모든 데이터를 더 잘 볼 수 있습니다. Microsoft Store 서비스에 진단 기능 추가를 완료합니다. 이를 바탕으로, 서비스에 Prometheus 및 Grafana를 eShopLite 추가하고 캡처되는 일부 메트릭을 살펴봅니다. 다음 단계는 Zipkin을 추가하고 분산 추적을 보는 것입니다. 마지막으로 앱에 Application Insights를 추가하고 이를 사용하여 데이터를 봅니다.

Prometheus 및 Grafana 추가

Prometheus 및 Grafana는 프로젝트에 쉽게 추가할 수 있는 Docker 이미지를 제공합니다. 솔루션의 루트에 있는 docker-compose.yml 파일에 포함합니다.

  1. 탐색기 창에서 docker-compose.yml 파일을 선택합니다.

  2. 이 YAML을 파일의 맨 아래에 추가합니다.

      prometheus:
        image: prom/prometheus
        container_name: prometheus
        command:
          - '--config.file=/etc/prometheus/prometheus.yml'
        ports:
          - 9090:9090
        restart: unless-stopped
        volumes:
          - ./prometheus:/etc/prometheus
    
      grafana:
        image: grafana/grafana
        container_name: grafana
        ports:
          - 3000:3000
        restart: unless-stopped
        environment:
          - GF_SECURITY_ADMIN_USER=admin
          - GF_SECURITY_ADMIN_PASSWORD=grafana
        volumes:
          - ./grafana/datasource:/etc/grafana/provisioning/datasources
    

위의 Docker yaml은 PrometheusGrafana의 두 가지 새로운 서비스를 추가합니다. Prometheus 섹션은 포트 9090에 응답하도록 컨테이너를 구성합니다. prometheus.yml 파일을 예상하는 prometheus 폴더를 매핑합니다. Grafana 섹션은 포트 3000에 응답하도록 컨테이너를 구성합니다. grafana 폴더 내에 세 개의 폴더를 매핑합니다.

Prometheus 구성

메트릭을 수집할 위치를 알 수 있도록 Prometheus를 구성해야 합니다. prometheus 폴더에 prometheus.yml 파일을 추가합니다.

  1. 탐색기 창에서 dotnet-observability 폴더를 마우스 오른쪽 단추로 클릭한 다음 새 폴더를 선택합니다.

  2. 이름 필드에 prometheus를 입력합니다.

  3. 탐색기 창에서 prometheus 폴더를 마우스 오른쪽 단추로 클릭한 다음 새 파일을 선택합니다.

  4. 이름 필드에 prometheus.yml 입력합니다.

  5. 파일 편집기에서 다음 YAML을 입력합니다.

    global:
      scrape_interval: 1s
    
    scrape_configs:
      - job_name: 'products'
        static_configs:
          - targets: ['backend:8080']
      - job_name: 'store'
        static_configs:
          - targets: ['frontend:8080']
    

    이전 YAML은 백 엔드프런트 엔드 서비스에서 메트릭을 긁어내도록 Prometheus를 구성합니다. 앱이 Docker에서 실행 중이므로 호스트 이름은 서비스 이름입니다.

  6. Ctrl+S를 선택하여 파일을 저장합니다.

Grafana를 구성하기

메트릭을 수집할 위치를 알 수 있도록 Grafana를 구성해야 합니다.

  1. 탐색기 창에서 dotnet-observability 폴더를 마우스 오른쪽 단추로 클릭한 다음 새 폴더를 선택합니다.

  2. 이름 필드에 grafana를 입력합니다.

  3. grafana 폴더를 마우스 오른쪽 단추로 클릭한 다음 새 폴더를 선택합니다.

  4. 이름 필드에 데이터 원본을 입력합니다.

  5. grafana 폴더를 마우스 오른쪽 단추로 클릭한 다음 새 폴더를 선택합니다.

  6. 이름 필드에 대시보드를 입력합니다.

  7. grafana 폴더를 확장하고 데이터 원본 폴더를 마우스 오른쪽 단추로 클릭한 다음 새 파일을 선택합니다.

  8. 이름 필드에 datasource.yml 입력합니다.

  9. 편집기 탭에서 다음 YAML을 입력합니다.

    apiVersion: 1
    
    datasources:
    - name: Prometheus
      type: prometheus
      url: http://prometheus:9090 
      isDefault: true
      access: proxy
      editable: true
    

    이전 YAML은 Prometheus를 데이터 원본으로 사용하도록 Grafana를 구성합니다.

  10. Ctrl+S를 선택하여 파일을 저장합니다.

prometheus에 대한 메트릭을 노출하도록 ASP.NET Core 앱 업데이트

이제 진단 프로젝트는 메트릭을 콘솔에 노출하도록만 구성됩니다. 대신 Prometheus에 메트릭을 노출하도록 프로젝트를 업데이트합니다.

  1. 아래쪽의 터미널 창에서 진단 폴더로 이동합니다.

  2. 다음 명령을 실행합니다.

    cd .\eShopLite\Diagnostics\ 
    
  3. 패키지를 제거합니다.OpenTelemetry.Exporter.Console

    dotnet remove package OpenTelemetry.Exporter.Console
    
  4. OpenTelemetry.Exporter.Prometheus.AspNetCore 패키지를 추가합니다.

    dotnet add package OpenTelemetry.Exporter.Prometheus.AspNetCore --prerelease
    
  5. 탐색기 창에서 진단 폴더를 확장한 다음, DiagnosticServiceCollectionExtensions.cs 선택합니다.

  6. 콘솔 내보내기를 .AddConsoleExporter(); 다음 코드로 바꿉다.

    .AddPrometheusExporter();
    
  7. 파일의 맨 아래에 마지막 }코드 앞에 다음 코드를 추가합니다.

    public static void MapObservability(this IEndpointRouteBuilder routes)
    {
      routes.MapPrometheusScrapingEndpoint();
    }
    

    이 코드는 앱과 함께 이 엔드포인트를 포함하는 모든 서비스에 Prometheus 스크래핑 엔드포인트를 추가합니다. 이렇게 하면 Prometheus에서 http://service/metrics로부터 메트릭을 수집할 수 있습니다.

  8. Ctrl+S를 선택하여 파일을 저장합니다.

Store 서비스에서 메트릭 노출

앱은 현재 Products 서비스에 대한 메트릭을 노출하도록 구성됩니다. 스토어 서비스에 대한 메트릭도 노출하도록 앱을 업데이트합니다.

  1. 탐색기 창의 솔루션 탐색기에서 스토어 프로젝트를 마우스 오른쪽 단추로 클릭한 다음 프로젝트 참조 추가를 선택합니다.

  2. 진단을 선택합니다.

  3. 탐색기 창에서 스토어 폴더를 확장한 다음, Program.cs 선택합니다.

  4. 코드 주석 // Add observability code here아래에서 Diagnostics 메서드에 대한 호출을 추가합니다.

    builder.Services.AddObservability("Store", builder.Configuration);
    
  5. 메서드 앞에 app.Run() 다음 코드를 추가합니다.

    app.MapObservability();
    

    이 메서드는 Prometheus 스크래핑 엔드포인트를 Store 서비스에 추가합니다.

  6. Ctrl+S를 선택하여 파일을 저장합니다.

  7. 탐색기 창에서 Product 폴더를 확장한 다음 Program.cs 선택합니다.

  8. 메서드 앞에 app.Run() 다음 코드를 추가합니다.

    app.MapObservability();
    

    이 메서드는 Prometheus 스크래핑 엔드포인트를 Products 서비스에 추가합니다.

  9. Ctrl+S를 선택하여 파일을 저장합니다.

새로운 관찰 기능 테스트

이제 앱에 추가한 새로운 관찰 기능을 테스트합니다.

  1. 아래쪽의 터미널 창에서 dotnet-observability/eShopLite 폴더로 이동합니다.

    cd ..
    
  2. 앱 컨테이너를 업데이트합니다.

    dotnet publish /p:PublishProfile=DefaultContainer 
    
  3. dotnet-observability 폴더로 이동하여 Docker를 사용하여 앱을 시작합니다.

    cd ..
    docker compose up
    
  4. 포트 탭에서 Prometheus용 브라우저에서 열기(9090)를 선택합니다. Visual Studio Code에서 로컬로 실행하는 경우 브라우저를 열고 새 탭에서 Prometheus 앱 http://localhost:9090으로 이동합니다.

  5. 위쪽 메뉴에서 상태를 선택한 다음 대상을 선택합니다.

    eShopLite 앱의 상태를 보여 주는 구성된 Prometheus 앱을 보여 주는 스크린샷

    제품스토어 서비스가 UP으로 나열됩니다.

  6. 포트 탭에서 Grafana (3000)브라우저에서 열기를 선택합니다. Visual Studio Code에서 로컬로 실행하는 경우 브라우저를 열고 새 탭에서 Grafana 앱 http://localhost:3000으로 이동합니다.

  7. 사용자 이름 관리자를 입력합니다.

  8. 암호 grafana를 입력합니다.

  9. 첫 번째 대시보드 만들기를 선택합니다.

  10. 대시보드 가져오기를 선택합니다.

  11. 새 탭에서 GitHub 로 이동하여 ASP.NET Core 대시보드 json 파일을 엽니다.

  12. RAW 파일을 복사합니다.

  13. JSON을 대시보드 JSON 모델을 통해 가져오기 텍스트 상자에 붙여넣습니다.

  14. 로드를 선택합니다.

  15. Prometheus 데이터 원본 드롭다운에서 Prometheus를 선택합니다.

  16. 가져오기를 선택합니다.

    Grafana의 ASP.NET 대시보드를 보여 주는 스크린샷

    제품스토어 서비스에 대한 메트릭을 보여 주는 대시보드가 표시됩니다. 두 서비스 중 하나로 변경하려면 작업을 선택하십시오.

  17. 터미널 창에서 Ctrl+C를 선택하여 앱을 중지합니다.

Zipkin 추가

이제 Zipkin을 추가하여 앱의 추적 기능을 확장합니다. 이전과 마찬가지로 앱에 Zipkin 컨테이너를 추가하고 OpenTelemetry 수집기에 연결하도록 구성합니다. 그런 다음 앱에 OpenTelemetry Zipkin 내보내기를 추가합니다.

  1. 탐색기 창에서 dotnet-observability 폴더 내의 docker-compose.yml 파일을 선택합니다.

  2. prometheuszipkindepends_onfrontend을 위해 추가합니다.

    depends_on: 
      - backend
      - prometheus
      - zipkin 
    
  3. prometheus에 대해 depends_onbackend을 추가하세요.

     depends_on: 
       - prometheus
    
  4. 환경 변수를 Zipkin을 위해 BOTHfrontendbackend에 추가하십시오.

    environment: 
      - ZIPKIN_URL=http://zipkin:9411    
    

    두 서비스는 다음과 같습니다.

    frontend:
      image: storeimage
      build:
        context: .
        dockerfile: ./eShopLite/Store/Dockerfile
      environment: 
        - ProductEndpoint=http://backend:8080
        - ZIPKIN_URL=http://zipkin:9411
      ports:
        - "32000:8080"
      depends_on: 
        - backend
        - prometheus
        - zipkin
    
    backend:
      image: productservice
      build: 
        context: .
        dockerfile: ./eShopLite/Products/Dockerfile
      environment: 
        - ZIPKIN_URL=http://zipkin:9411
    
      ports: 
        - "32001:8080"
      depends_on: 
        - prometheus    
    
  5. 이 YAML을 파일의 맨 아래에 추가합니다.

      zipkin:
        image: openzipkin/zipkin
        ports:
          - 9411:9411
    

    이전 YAML은 앱에 Zipkin 컨테이너를 추가합니다. 포트 9411에서 응답하도록 Zipkin 컨테이너를 구성합니다.

  6. Ctrl+S를 선택하여 파일을 저장합니다.

  7. 터미널 창에서 진단 폴더로 이동합니다.

    cd ./eShopLite/Diagnostics/
    
  8. Zipkin 내보내기 패키지를 추가합니다.

    dotnet add package OpenTelemetry.Exporter.Zipkin --prerelease
    
  9. 탐색기 창에서 진단 폴더를 확장한 다음, DiagnosticServiceCollectionExtensions.cs 선택합니다.

  10. 추적 공급자의 맨 아래에 Zipkin을 추가합니다.

    // add the tracing providers
    .WithTracing(tracing =>
    {
      tracing.SetResourceBuilder(resource)
                  .AddAspNetCoreInstrumentation()
                  .AddHttpClientInstrumentation()
                  .AddSqlClientInstrumentation()
                  .AddZipkinExporter(zipkin =>
                  {
                    var zipkinUrl = configuration["ZIPKIN_URL"] ?? "http://zipkin:9411";
                    zipkin.Endpoint = new Uri($"{zipkinUrl}/api/v2/spans");
                  });
    });
    
  11. Ctrl+S를 선택하여 파일을 저장합니다.

  12. 아래쪽의 터미널 창에서 dotnet-observability/eShopLite 폴더로 이동합니다.

    cd ..
    
  13. 앱 컨테이너를 업데이트합니다.

    dotnet publish /p:PublishProfile=DefaultContainer 
    
  14. dotnet-observability 폴더로 이동하여 Docker를 사용하여 앱을 시작합니다.

    cd ..
    docker compose up
    
  15. 포트 탭에서 Prometheus용 브라우저에서 열기(9090)를 선택합니다. Visual Studio Code에서 로컬로 실행하는 경우 새 브라우저 탭을 열고 Zipkin 앱 http://localhost:9411으로 이동합니다.

  16. 메뉴에서 종속성을 선택합니다.

    제품 서비스에 요청을 보내는 eShopLite 앱 스토어의 종속성을 보여 주는 Zipkin을 보여 주는 스크린샷

  17. 터미널 창에서 Ctrl+C를 선택하여 앱을 중지합니다.

Application Insights 추가

마지막 단계는 앱에 Application Insights를 추가하는 것입니다.

Azure에서 Application Insights 리소스 만들기

  1. 터미널 창에서 Azure에 로그인합니다.

    az login --use-device-code
    
  2. 선택한 Azure 구독을 봅니다.

    az account show -o table
    

    잘못된 구독을 선택한 경우 az account set 명령을 사용하여 올바른 구독을 선택합니다.

  3. Application Insights에 대한 확장을 추가합니다.

    az extension add -n application-insights
    
  4. Application Insights 리소스를 만듭니다.

    az monitor app-insights component create --app eShopLiteInsights --___location eastus --kind web -g eShopLite
    

    다음 출력이 표시됩니다.

    {
      "appId": "00001111-aaaa-2222-bbbb-3333cccc4444",
      "applicationId": "eShopLiteInsights",
      "applicationType": "web",
      "connectionString": "InstrumentationKey=00000000-0000-0000-0000-000000000000;IngestionEndpoint=https://eastus-2.in.applicationinsights.azure.com/;LiveEndpoint=https://eastus.livediagnostics.monitor.azure.com/",
      "creationDate": "2023-11-10T16:50:00.950726+00:00",
      "disableIpMasking": null,
      "etag": "\"3a02952a-0000-0100-0000-654e5f380000\"",
      "flowType": "Bluefield",
      "hockeyAppId": null,
      "hockeyAppToken": null,
      "id": "/subscriptions/aaaa0a0a-bb1b-cc2c-dd3d-eeeeee4e4e4e/resourceGroups/eShopLite/providers/microsoft.insights/components/eShopLiteInsights",
      "immediatePurgeDataOn30Days": null,
      "ingestionMode": "ApplicationInsights",
      "instrumentationKey": "00000000-0000-0000-0000-000000000000",
      "kind": "web",
      "___location": "eastus",
      "name": "eShopLiteInsights",
      "privateLinkScopedResources": null,
      "provisioningState": "Succeeded",
      "publicNetworkAccessForIngestion": "Enabled",
      "publicNetworkAccessForQuery": "Enabled",
      "requestSource": "rest",
      "resourceGroup": "eShopLite",
      "retentionInDays": 90,
      "samplingPercentage": null,
      "tags": {},
      "tenantId": "aaaabbbb-0000-cccc-1111-dddd2222eeee",
      "type": "microsoft.insights/components"
    }
    

    앞에서 반환된 JSON에서 connectionString를 제외하고 복사합니다. 다음은 그 예입니다.

    InstrumentationKey=b851fa75-85a2-42f7-bb6f-413725d9d8ba;IngestionEndpoint=https://eastus-2.in.applicationinsights.azure.com/;LiveEndpoint=https://eastus.livediagnostics.monitor.azure.com/

  5. 탐색기 창에서 docker-compose.yml 파일을 선택합니다.

  6. 진단 프로젝트에서 Application Insights에 연결하는 데 사용하는 환경 변수를 추가합니다. 이 YAML을 Store 서비스에 추가합니다.

    environment:
      - APPLICATIONINSIGHTS_CONNECTION_STRING=InstrumentationKey=b851fa75-85a2-42f7-bb6f-413725d9d8ba;IngestionEndpoint=https://eastus-2.in.applicationinsights.azure.com/;LiveEndpoint=https://eastus.livediagnostics.monitor.azure.com/
    

    이전 연결 문자열을 Azure CLI에서 복사한 연결 문자열로 바꿉다.

  7. Products 서비스에 대해 다음 단계를 반복합니다. 최종 YAML은 다음과 같습니다.

      frontend:
        image: storeimage
        build:
          context: .
          dockerfile: ./eShopLite/Store/Dockerfile
        environment: 
          - ProductEndpoint=http://backend:8080
          - ZIPKIN_URL=http://zipkin:9411
          - APPLICATIONINSIGHTS_CONNECTION_STRING=InstrumentationKey=b851fa75-85a2-42f7-bb6f-413725d9d8ba;IngestionEndpoint=https://eastus-2.in.applicationinsights.azure.com/;LiveEndpoint=https://eastus.livediagnostics.monitor.azure.com/
        ports:
          - "32000:8080"
        depends_on: 
          - backend
          - prometheus
          - zipkin
    
      backend:
        image: productservice
        build: 
          context: .
          dockerfile: ./eShopLite/Products/Dockerfile
        environment: 
          - ZIPKIN_URL=http://zipkin:9411
          - APPLICATIONINSIGHTS_CONNECTION_STRING=InstrumentationKey=b851fa75-85a2-42f7-bb6f-413725d9d8ba;IngestionEndpoint=https://eastus-2.in.applicationinsights.azure.com/;LiveEndpoint=https://eastus.livediagnostics.monitor.azure.com/
    
    
  8. Ctrl+S를 선택하여 파일을 저장합니다.

  9. 터미널 창에서 진단 폴더로 이동합니다.

    cd .\eShopLite\Diagnostics\ 
    
  10. Application Insights 내보내기 패키지를 추가합니다.

    dotnet add package Azure.Monitor.OpenTelemetry.AspNetCore --prerelease
    
  11. 탐색 창에서 진단 폴더를 선택한 다음, DiagnosticServiceCollectionExtensions.cs 선택합니다.

  12. 파일 맨 위에 다음 using 문을 추가합니다.

    using Azure.Monitor.OpenTelemetry.AspNetCore;
    
  13. var otelBuilder = services.AddOpenTelemetry(); 후에 이 코드를 추가합니다.

    if (!string.IsNullOrEmpty(configuration["APPLICATIONINSIGHTS_CONNECTION_STRING"]))
    {
      otelBuilder.UseAzureMonitor();
    }
    
  14. Ctrl+S를 선택하여 파일을 저장합니다.

  15. 아래쪽의 터미널 창에서 dotnet-observability/eShopLite 폴더로 이동합니다.

    cd ..
    
  16. 앱 컨테이너를 업데이트합니다.

    dotnet publish /p:PublishProfile=DefaultContainer 
    
  17. dotnet-observability 폴더로 이동하여 Docker를 사용하여 앱을 시작합니다.

    cd ..
    docker compose up
    
  18. Azure CLI에 로그인하는 데 사용한 것과 동일한 자격 증명을 사용하여 Azure Portal에 로그인합니다.

  19. Azure Portal에서 리소스 그룹을 선택합니다.

  20. eShopLite 리소스 그룹을 선택합니다.

  21. eShopLiteInsights Application Insights 리소스를 선택합니다.

  22. 애플리케이션 대시보드를 선택합니다.

    eShopLite 앱의 상태를 보여 주는 Application Insights를 보여 주는 스크린샷

  23. 메트릭에 대한 변경 내용을 보려면 앱으로 이동하여 재고를 eShopLite 변경합니다. 그런 다음 Application Insights 대시보드를 새로 고칩니다.

  24. 터미널 창에서 Ctrl+C를 눌러 앱을 중지합니다.