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

완료됨

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

프로메테우스와 Grafana 추가

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

  1. Visual Studio Code의 탐색기 창에서 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.yml 파일을 prometheus 폴더에 추가합니다.

  1. Visual Studio Code의 탐색기 창에서 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. Visual Studio Code의 탐색기 창에서 dotnet-observability 폴더를 마우스 오른쪽 단추로 클릭한 다음 새 폴더를 선택합니다.

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

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

  4. 이름 필드에 datasource를 입력합니다.

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

  6. 이름 필드에 dashboard를 입력합니다.

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

  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. Visual Studio Code의 하단에 있는 터미널 창에서 Diagnostics 폴더로 이동합니다.

  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. 탐색기 창에서 Diagnostics 폴더를 확장한 다음 DiagnosticServiceCollectionExtensions.cs를 선택합니다.

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

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

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

    이 코드는 앱에 이를 포함하는 모든 서비스에 Prometheus 스크래핑 엔드포인트를 추가합니다. 이를 통해 Prometheus는 http://service/metrics에서 메트릭을 스크랩할 수 있습니다.

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

저장소 서비스에 메트릭 노출

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

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

  2. 진단을 선택합니다.

  3. 탐색기 창에서 Store 폴더를 확장한 다음 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 앱을 보여 주는 스크린샷

    ProductsStore 서비스가 UP으로 표시되어야 합니다.

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

  7. 사용자 이름 admin을 입력합니다.

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

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

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

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

  12. 원시 파일을 복사합니다.

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

  14. 로드를 선택합니다.

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

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

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

    ProductsStore 서비스에 대한 메트릭을 표시하는 대시보드가 표시됩니다. 두 서비스 간에 변경하려면 작업을 선택합니다.

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

Zipkin 추가

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

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

  2. frontenddepends_onprometheuszipkin을 추가합니다.

    depends_on: 
      - backend
      - prometheus
      - zipkin 
    
  3. backend에 대해 depends_onprometheus를 추가합니다.

     depends_on: 
       - prometheus
    
  4. frontendbackend 둘 다에 Zipkin용 환경 변수를 추가합니다.

    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. 탐색기 창에서 Diagnostics 폴더를 확장한 다음 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. Visual Studio Code의 터미널 창에서 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. Visual Studio Code의 탐색기 창에서 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. 탐색 창에서 Diagnostics 폴더를 선택한 다음 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를 눌러 앱을 중지합니다.