Joe's ES Training
      • Sharing URL Link copied
      • /edit
      • View mode
        • Edit mode
        • View mode
        • Book mode
        • Slide mode
        Edit mode View mode Book mode Slide mode
      • Customize slides
      • Note Permission
      • Read
        • Owners
        • Signed-in users
        • Everyone
        Owners Signed-in users Everyone
      • Write
        • Owners
        • Signed-in users
        • Everyone
        Owners Signed-in users Everyone
      • Engagement control Commenting, Suggest edit, Emoji Reply
    • Invite by email
      Invitee

      This note has no invitees

    • Publish Note

      Share your work with the world Congratulations! 🎉 Your note is out in the world Publish Note No publishing access yet

      Your note will be visible on your profile and discoverable by anyone.
      Your note is now live.
      This note is visible on your profile and discoverable online.
      Everyone on the web can find and read all notes of this public team.

      Your account was recently created. Publishing will be available soon, allowing you to share notes on your public page and in search results.

      Your team account was recently created. Publishing will be available soon, allowing you to share notes on your public page and in search results.

      Explore these features while you wait
      Complete general settings
      Bookmark and like published notes
      Write a few more notes
      Complete general settings
      Write a few more notes
      See published notes
      Unpublish note
      Please check the box to agree to the Community Guidelines.
      View profile
    • Commenting
      Permission
      Disabled Forbidden Owners Signed-in users Everyone
    • Enable
    • Permission
      • Forbidden
      • Owners
      • Signed-in users
      • Everyone
    • Suggest edit
      Permission
      Disabled Forbidden Owners Signed-in users Everyone
    • Enable
    • Permission
      • Forbidden
      • Owners
      • Signed-in users
    • Emoji Reply
    • Enable
    • Versions and GitHub Sync
    • Note settings
    • Note Insights New
    • Engagement control
    • Make a copy
    • Transfer ownership
    • Delete this note
    • Insert from template
    • Import from
      • Dropbox
      • Google Drive
      • Gist
      • Clipboard
    • Export to
      • Dropbox
      • Google Drive
      • Gist
    • Download
      • Markdown
      • HTML
      • Raw HTML
Menu Note settings Note Insights Versions and GitHub Sync Sharing URL Help
Menu
Options
Engagement control Make a copy Transfer ownership Delete this note
Import from
Dropbox Google Drive Gist Clipboard
Export to
Dropbox Google Drive Gist
Download
Markdown HTML Raw HTML
Back
Sharing URL Link copied
/edit
View mode
  • Edit mode
  • View mode
  • Book mode
  • Slide mode
Edit mode View mode Book mode Slide mode
Customize slides
Note Permission
Read
Owners
  • Owners
  • Signed-in users
  • Everyone
Owners Signed-in users Everyone
Write
Owners
  • Owners
  • Signed-in users
  • Everyone
Owners Signed-in users Everyone
Engagement control Commenting, Suggest edit, Emoji Reply
  • Invite by email
    Invitee

    This note has no invitees

  • Publish Note

    Share your work with the world Congratulations! 🎉 Your note is out in the world Publish Note No publishing access yet

    Your note will be visible on your profile and discoverable by anyone.
    Your note is now live.
    This note is visible on your profile and discoverable online.
    Everyone on the web can find and read all notes of this public team.

    Your account was recently created. Publishing will be available soon, allowing you to share notes on your public page and in search results.

    Your team account was recently created. Publishing will be available soon, allowing you to share notes on your public page and in search results.

    Explore these features while you wait
    Complete general settings
    Bookmark and like published notes
    Write a few more notes
    Complete general settings
    Write a few more notes
    See published notes
    Unpublish note
    Please check the box to agree to the Community Guidelines.
    View profile
    Engagement control
    Commenting
    Permission
    Disabled Forbidden Owners Signed-in users Everyone
    Enable
    Permission
    • Forbidden
    • Owners
    • Signed-in users
    • Everyone
    Suggest edit
    Permission
    Disabled Forbidden Owners Signed-in users Everyone
    Enable
    Permission
    • Forbidden
    • Owners
    • Signed-in users
    Emoji Reply
    Enable
    Import from Dropbox Google Drive Gist Clipboard
       Owned this note    Owned this note      
    Published Linked with GitHub
    • Any changes
      Be notified of any changes
    • Mention me
      Be notified of mention me
    • Unsubscribe
    # Elastic Observability 實作體驗營 (2023.09 update) :::info **本頁面縮網址:** https://hackmd.io/@estraining/DevOpsDaysTaipei2022 **講者:** [喬叔 (Joe Wu)](https://training.onedoggo.com/about-me) **Facebook 粉絲頁:** [喬叔 - Elastic Stack 技術交流](https://www.facebook.com/Joe.ElasticStack/) ::: ## 行前準備 ### 操作電腦需求 - 最少 **16GB** 以上的 RAM - 最少 30GB 以上的 Disk Space - MacOS, Linux, Windows 皆可,但請不要用太舊的作業系統 :::danger :exclamation:請注意,由於這次工作坊執行的 docker containers 數量眾多,記憶體的要求較高,如果記憶體不到 16GB 的話幾乎很難順利運作,若是要開雲端主機的話,可以參考 - [如果要使用雲端主機,可以設定-SSH-Tunnel-來存取](#如果要使用雲端主機,可以設定-SSH-Tunnel-來存取) 的設定方式。 ::: ### 準備執行環境 請先在電腦中安裝以下所需的執行環境: - Docker - Docker Compose ([安裝說明](https://docs.docker.com/compose/install/)) - Python3 ([安裝說明](https://github.com/elastic/apm-integration-testing#python-3)) - Git (會簡單的 `git clone`, `git pull`, `git checkout` 即可。) ### 準備好 Docker Images 這次的工作坊,使用的是 Elastic 在 GitHub 所提供的 [apm-integration-testing](https://github.com/elastic/apm-integration-testing) 開源專案。 因為在操作時會需要 build Docker image 以及下載一些 Elastic Stack 的 Docker images,為了避免工作坊的時間被佔用在處理 build & download,建議請大家先完成以下的步驟。 :::danger :exclamation:請注意,喬叔有特別為了這次工作坊進行一些準備,所以請直接到喬叔 fork 出來的 GitHub 專案進行下載 [https://github.com/joecwu/apm-integration-testing/](https://github.com/joecwu/apm-integration-testing/),不要下載到 Elastic 官方版的哦! ::: 1. 取得 apm-integration-testing 的檔案。 可使用 `git clone` 的指令,或是直接[下載 Zip 壓縮檔](https://github.com/joecwu/apm-integration-testing/archive/refs/heads/main.zip)。 ``` git clone https://github.com/joecwu/apm-integration-testing.git ``` 2. 準備好 Docker Images 有以下兩種選擇,自行 build 或是直接抓喬叔準備好的 docker images. 2-1. **自行 build:** 在專案的根路徑下,執行以下 `compose.py build` 的指令,以建立及下載所需要使用到的 Docker images: Mac or Linux: ``` ./scripts/compose.py build --release --with-opbeans-java --with-opbeans-ruby --with-opbeans-python --with-opbeans-go --with-opbeans-node --with-opbeans-rum --with-filebeat --with-metricbeat --with-heartbeat 8.9.0 ``` Windows: ``` python .\scripts\compose.py build --release --with-opbeans-java --with-opbeans-ruby --with-opbeans-python --with-opbeans-go --with-opbeans-node --with-opbeans-rum --with-filebeat --with-metricbeat --with-heartbeat 8.9.0 ``` 2-2. **直接使用喬叔 build 好的 docker image** **Mac M1**: ``` docker-compose -f ./docker-compose-arm64.yml pull ``` **Linux**: ``` docker-compose -f ./docker-compose-linux.yml pull ``` **Windows**: ``` docker-compose -f ./docker-compose-windows.yml pull ``` :::danger 其他平台需自行 build,否則 `opbeans-go` 和 `opbeans-rum` 會無法成功執行。 ::: 3. 確認 Docker Images 已被成功建置及下載。 使用 `docker images` 指令,確認有存在下列 Docker Images. ![](https://i.imgur.com/wSSnE7D.png) 4. 多確認是否能正常運作 Docker Cotainers 使用自行 build,請用:`docker-compose up -d` 若是使用另外的 yml 檔,請指定 `-f` 參數:`docker-compose -f ./docker-compose-linux.yml up -d` 請確認 containers 都能正常運作 (狀態為 `healthy`),若有問題,可先參考 [FAQ](#FAQ) ## Elastic APM Integration Test 簡介 [APM Integration Testing](https://github.com/elastic/apm-integration-testing) 是一個公開在 GitHub 的開放原始碼的專案,這個專案主要語言是用 Python 撰寫,並且使用 Docker 來運作 Elastic Stack 的各種服務以及 opbeans 這個 Demo 專用的庫存管理系統,讓我們能夠擁有一個 Elastic APM 所需要執行的情境,並且能夠將當中的某些元件替換成真實運作的版本,可以協助開發人員進行 debug,或是協助整合測試 (Integration Test) 所需使用的複雜的環境。 ### 包含的角色 以下幾種角色,是 APM Integration Testing 的 Docker Containers 運作起來時,裡面有的角色: - Elastic Stack - Elasticsearch - Kibana - APM Server - Heartbeat - Filebeat - Metricbeat - Packetbeat - opbeans 庫存管理系統的各種語言版本的實作,並且埋入 APM Agent - opbeans-go - opbeans-java - opbeans-ruby - opbeans-dotnet - opbeans-node - opbeans-python - opbeans-php - opbeans 所使用到的 Database 或是 Cache 等服務 - PostgreSQL - Redis - 針對 opbeans 庫存管理的系統,使用 [apm-agent-rum-js](https://github.com/elastic/apm-agent-rum-js),實作 Real User Monitoring - opbeans-rum - 自動模擬存取流量的 opbeans-load-generator - 專門製造錯誤情況發生,讓壓測能更擬真的 Dyno. (僅支援 opbeans-python) ### 運作示範 下圖是 Kibana > Observability > Trace > Service Map 的截圖。 :::warning 請留意,每個 opbeans 即是一個完整的 web 專案,本身就可以獨立運作,但是當 apm-integration-testing 透過 docker-compose 啟動時,如果同時執行超過一種以上的 `opbeans-XXX`,會在執行時隨機存取其他 `opbeans-XXX`,創造出 service 與 service 之間互相溝通的存取,以模擬多層次或是分散式架構系統的運作情境。 ::: ![18-apm-tools-service-map](https://i.imgur.com/bR93Z78.png) ## 任務一:將 apm-integration-test 運作起來 ### 1. 準備執行環境 請確認電腦已安裝好下列必要的執行環境: - Docker - Docker Compose ([安裝說明](https://docs.docker.com/compose/install/)) - Python3 ([安裝說明](https://github.com/joecwu/apm-integration-testing#python-3)) ### 2. 安裝指令 #### 2.1 自行 build & start 透過執行 `compose.py start` 產生並執行 `docker-compose.yml`。 Mac or Linux: ``` ./scripts/compose.py start --release --with-opbeans-java --with-opbeans-ruby --with-opbeans-python --with-opbeans-go --with-opbeans-node --with-opbeans-rum --with-filebeat --with-metricbeat --with-heartbeat 8.9.0 ``` Windows: ``` python .\scripts\compose.py start --release --with-opbeans-java --with-opbeans-ruby --with-opbeans-python --with-opbeans-go --with-opbeans-node --with-opbeans-rum --with-filebeat --with-metricbeat --with-heartbeat 8.9.0 ``` :::warning 如果系統資源不足,跑不動太多的 Containers 的話,可以減少一些 `--with-opbeans-{XXX}`。 建議最少要啟動 `opbeans-node` 及 `opbeans-rum`。 例如: Mac or Linux: ``` ./scripts/compose.py start --release --with-opbeans-python --with-opbeans-go --with-opbeans-node --with-opbeans-rum --with-filebeat --with-metricbeat --with-heartbeat 8.9.0 ``` Windows: ``` python .\scripts\compose.py start --release --with-opbeans-python --with-opbeans-go --with-opbeans-node --with-opbeans-rum --with-filebeat --with-metricbeat --with-heartbeat 8.9.0 ``` ::: :::info 由於 `opbeans-dotnet` .Net 的版本在 Apple M1 系列 CPU 建置時可能會有問題,所以我們這次直接略過不使用 `opbeans-dotnet` 版本,若你是 Windows 的環境,且硬體資源充足,想嘗試的話,還是可以加入 `--with-opbeans-dotnet` ::: #### 2.2 直接拉 Docker Image (略過 build) :::warning 請記得拉最新的 main branch 的 code ::: **Mac M1**: ``` docker-compose -f ./docker-compose-arm64.yml up -d ``` **Linux**: ``` docker-compose -f ./docker-compose-linux.yml up -d ``` **Windows**: ``` docker-compose -f ./docker-compose-windows.yml up -d ``` :::danger 其他平台需自行 build,否則 `opbeans-go` 和 `opbeans-rum` 會無法成功執行。 ::: ### 3. 確認安裝完成 使用 `docker-compose ps -a` 或是 `docker ps -a` 查看執行中的 containers。 ### 4. 登入 Kibana Kibana: http://localhost:5601 預設管理者帳號:`admin` 預設密碼:`changeme` ![](https://i.imgur.com/dfaZlLt.png) ### 5. 查看 Kibana > Stack Monitoring 進入 [Kibana > Stack Monitoring](http://localhost:5601/app/monitoring),可以成功查看 Elasticsearch Cluster 正常的運作,同時也有 Kibana 正在運作中。 ![](https://i.imgur.com/bcEG3uS.png) ## 任務二:收集 Opbeans 各服務所產生的 Logs ### 1. 設定 `filebeat.yml` 修改 `./docker/filebeat/filebeat.yml` 在 **## autodiscover** 的區塊裡,填加以下的設定。 ```yaml filebeat.autodiscover: providers: - type: docker templates: - condition: contains: docker.container.name: "opbeans-" config: - type: container paths: - "/var/lib/docker/containers/*/${data.docker.container.id}-json.log" include_lines: ['^{'] tail_files: true processors: - add_tags: tags: [json] target: "parser_type" - decode_json_fields: fields: - message target: "" overwrite_keys: true add_error_key: true - drop_fields: fields: - service - event - url - error - copy_fields: fields: - from: docker.container.labels.org_label-schema_name to: event.dataset fail_on_error: false ignore_missing: true fields_under_root: true - condition: contains: docker.container.name: "opbeans-" config: - type: container paths: - "/var/lib/docker/containers/*/${data.docker.container.id}-json.log" tail_files: true multiline.pattern: '^[[:blank:]]' multiline.negate: false multiline.match: after exclude_lines: ['^{'] processors: - add_tags: tags: [no_json] target: "parser_type" - copy_fields: fields: - from: docker.container.labels.org_label-schema_name to: event.dataset fail_on_error: false ignore_missing: true - condition: contains: docker.container.name: "kibana" config: - type: container paths: - "/var/lib/docker/containers/*/${data.docker.container.id}-json.log" tail_files: true json.add_error_key: true json.overwrite_keys: true json.keys_under_root: true processors: - copy_fields: fields: - from: docker.container.labels.org_label-schema_name to: event.dataset fail_on_error: false ignore_missing: true - condition: contains: docker.container.name: "elasticsearch" config: - type: container paths: - "/var/lib/docker/containers/*/${data.docker.container.id}-json.log" tail_files: true json.add_error_key: true json.overwrite_keys: true json.keys_under_root: true processors: - copy_fields: fields: - from: docker.container.labels.org_label-schema_name to: event.dataset fail_on_error: false ignore_missing: true - condition: contains: docker.container.name: "metricbeat" config: - type: container paths: - "/var/lib/docker/containers/*/${data.docker.container.id}-json.log" tail_files: true json.add_error_key: true json.overwrite_keys: true json.keys_under_root: true processors: - copy_fields: fields: - from: docker.container.labels.org_label-schema_name to: event.dataset fail_on_error: false ignore_missing: true - condition: contains: docker.container.name: "heartbeat" config: - type: container paths: - "/var/lib/docker/containers/*/${data.docker.container.id}-json.log" tail_files: true json.add_error_key: true json.overwrite_keys: true json.keys_under_root: true processors: - copy_fields: fields: - from: docker.container.labels.org_label-schema_name to: event.dataset fail_on_error: false ignore_missing: true - condition: contains: docker.container.name: "filebeat" config: - type: container paths: - "/var/lib/docker/containers/*/${data.docker.container.id}-json.log" tail_files: true json.add_error_key: true json.overwrite_keys: true json.keys_under_root: true processors: - copy_fields: fields: - from: docker.container.labels.org_label-schema_name to: event.dataset fail_on_error: false ignore_missing: true - condition: contains: docker.container.name: "apm-server" config: - type: container paths: - "/var/lib/docker/containers/*/${data.docker.container.id}-json.log" tail_files: true json.add_error_key: true json.overwrite_keys: true json.keys_under_root: true processors: - rename: fields: - from: "error" to: "error_apm_server" ignore_missing: false fail_on_error: true - copy_fields: fields: - from: docker.container.labels.org_label-schema_name to: event.dataset fail_on_error: false ignore_missing: true - condition: contains: docker.container.image: redis config: - module: redis log: input: type: container paths: - /var/lib/docker/containers/*/${data.docker.container.id}-json.log - condition: contains: docker.container.image: "postgres" config: - module: postgresql log: input: type: container paths: - "/var/lib/docker/containers/*/${data.docker.container.id}-json.log" - condition: and: - not: contains: docker.container.name: "apm-server" - not: contains: docker.container.name: "filebeat" - not: contains: docker.container.name: "heartbeat" - not: contains: docker.container.name: "kibana" - not: contains: docker.container.name: "metricbeat" - not: contains: docker.container.name: "opbeans-" - not: contains: docker.container.name: "postgres" config: - type: container paths: - "/var/lib/docker/containers/*/${data.docker.container.id}-json.log" tail_files: true processors: - copy_fields: fields: - from: docker.container.labels.org_label-schema_name to: event.dataset fail_on_error: false ignore_missing: true ``` ### 2. 重新啟動 Filebeat ``` docker-compose restart filebeat ``` ### 3. 查看 Log 以確認 Filebeat 運作是否正常 (Optional) ``` docker-compose logs -f filebeat ``` ### 4. 進入 Kibana 查看 Containers 的 Logs。 接下來,可以進入 Kibana (http://localhost:5601) 在 Observability > Logs > Stream (http://localhost:5601/app/logs/stream) 查看是否 Log 有成功傳送到 Elasticsearch 中。 :::info 可以在搜尋框中,嘗試打入 `event.dataset: opbeans-`,**自動完成**的功能會列出目前有的 `event.dataset` 的值供選取,如果有成功將 `opbeans-node`, `opbeans-python`, `opbeans-go`...這些服務的 Logs 收集到,就可以針對這些服務進行篩選。 ::: ![](https://i.imgur.com/nc3xagl.png) ## 任務三:收集 Opbeans 各服務所產生的 Metrics ### 1. 設定 `metricbeat.yml` 修改 `./docker/metricbeat/metricbeat.yml` 在 `metricbeat.monitors` 的部份配置以下設定: ```yaml metricbeat.modules: - module: golang metricsets: ["expvar", "heap"] period: 10s hosts: ["${APM_SERVER_PPROF_HOST:apm-server:6060}"] heap.path: "/debug/vars" expvar: namespace: "apm-server" path: "/debug/vars" - module: docker metricsets: ["container", "cpu", "diskio", "healthcheck", "info", "memory", "network"] hosts: ["unix:///var/run/docker.sock"] period: 10s ``` 在 `metricbeat.autodiscover` 的部份配置以下設定: ```yaml metricbeat.autodiscover: providers: - type: docker hints.enabled: true templates: - condition: contains: docker.container.image: "redis" config: - module: redis metricsets: ["info", "keyspace"] hosts: "${data.host}:6379" - condition: contains: docker.container.image: "postgres" config: - module: postgresql metricsets: ["database", "bgwriter", "activity"] hosts: ["postgres://${data.host}:5432?sslmode=disable"] password: verysecure username: postgres - condition: contains: docker.container.image: "kafka" config: - module: kafka metricsets: ["consumergroup", "partition"] period: 10s hosts: "${data.host}:9092" - condition: contains: docker.container.image: "logstash" config: - module: logstash metricsets: ["node", "node_stats"] period: 10s hosts: "${data.host}:9600" ``` ### 2. 重新啟動 Metricbeat ``` docker-compose restart metricbeat ``` ### 3. 從 Kibana 以確認 Metricbeat 運作是否正常 接下來,可以進入 Kibana 在 Observability > Infrastructure > Inventory (http://localhost:5601/app/metrics/inventory) ,切換 Show 為 `Docker Containers` 查看是否 Metricbeat 有成功傳送資料到 Elasticsearch 中。 ![](https://i.imgur.com/oM42cN8.png) ## 任務四:收集 Opbeans 各服務所產生的 Traces :::warning 這個部份由於需要改 Code,這次 Workshop 時間有限,不在這邊練習,目前執行的版本,已經都實作好 APM Agents 的部份,同時 APM Server 也透過 Elastic Agent 在運作了。 ::: 除了參考 Elastic 官方 [APM 的說明文件](https://www.elastic.co/guide/en/apm/index.html),可以配合從 [Elastic GitHub 搜尋 `opbeans-`](https://github.com/elastic?q=opbeans-&type=all&language=&sort=) ,查看目前所執行的 opbeans 各種語系專案的實作方式。 例如 `opbeans-node` 的 NodeJS 的 [`server.js`](https://github.com/elastic/opbeans-node/blob/main/server.js) 實作參考。 ## 任務五:監控 Opbeans 的服務運作狀態 (Uptime) ### 設定 `heartbeat.yml` 修改 `./docker/heartbeat/heartbeat.yml` 在 `heartbeat.monitors` 的部份配置以下設定: ```yaml heartbeat.monitors: - type: http name: onedoggo training web schedule: '@every 60s' urls: ["https://training.onedoggo.com/"] check.response.status: 200 tags: ["3rdParty"] fields: env: production - type: http name: "opbeans web" schedule: '@every 10s' urls: [ "http://opbeans-node:3000", "http://opbeans-java:3000", "http://opbeans-python:3000", "http://opbeans-go:3000", "http://opbeans-ruby:3000" ] check.response.status: 200 tags: ["web", "opbeans"] fields: env: production ``` 另外在 `heartbeat.autodiscover` 的部份配置以下設定: ```yaml heartbeat.autodiscover: providers: - type: docker templates: - condition: contains: docker.container.image: redis config: - type: tcp name: "${data.docker.container.name}" hosts: ["${data.host}:${data.port}"] schedule: "@every 1s" timeout: 1s tags: ["DB", "container"] - condition: and: - contains: docker.container.image: opbeans - not: contains: docker.container.name: opbeans-load-generator config: - type: http name: "${data.docker.container.name}" urls: ["http://${data.host}:${data.port}"] schedule: "@every 5s" timeout: 1s tags: ["opbeans","container"] ``` ### 重新啟動 Heartbeat ``` docker-compoes restart heartbeat ``` ### 從 Kibana 以確認 Heartbeat 運作是否正常 接下來,可以進入 Kibana 在 Observability > Uptime > Monitors (http://localhost:5601/app/uptime) 查看是否 Heartbeat 的 monitors 有成功傳送到 Elasticsearch 中。 ### 加強版設定 增加 `heartbeat.monitors` 的配置: - 從 container 外部對於 Redis 的監控 - 從 container 外部存取 opbeans web 的監控 ```yaml heartbeat.monitors: - type: http name: onedoggo training web schedule: '@every 60s' urls: ["https://training.onedoggo.com/"] check.response.status: 200 tags: ["3rdParty"] fields: env: production - type: http name: "opbeans web" schedule: '@every 10s' urls: [ "http://opbeans-node:3000", "http://opbeans-java:3000", "http://opbeans-python:3000", "http://opbeans-go:3000", "http://opbeans-ruby:3000" ] check.response.status: 200 tags: ["web", "opbeans"] fields: env: production # - type: http # name: "opbeans web public access" # schedule: '@every 10s' # urls: [ ## localhost 要換成 IP,否則 Docker Container 內部存取 localhost 會是錯誤的。 # "http://localhost:3000", # "http://localhost:3001", # "http://localhost:3002", # "http://localhost:3003", # "http://localhost:8000" # ] # check.response.status: 200 # tags: ["web", "opbeans"] # fields: # env: production - type: tcp name: redis healthcheck schedule: '@every 5s' hosts: ["redis:6379"] tags: ["DB"] fields: env: production ``` ## 任務六:設定異常時的主動通知 - Alert ### 1. Service Level Indicator & Objective - 1 建立新的 Alert,選擇 Rule Type 為 **Uptime monitor status**,並依照需求填入設定。 依需求建立 `Web Uptime SLI-1` ![](https://i.imgur.com/7tSfu14.png) Actions 的部份,以 Index 為例,建立新的 Index Connector: ![](https://i.imgur.com/kOkfuBW.png) **Document to index** 的 index document 簡單範例: ``` { "rule_id": "{{rule.id}}", "rule_name": "{{rule.name}}", "alert_id": "{{alert.id}}", "context_message": "{{context.message}}" } ``` ![](https://i.imgur.com/0gEq5JH.png) ### 2. Service Level Indicator & Objective - 2 建立新的 Alert,選擇 Rule Type 為 **APM Latency threshold**,並依照需求填入設定。 依需求建立 `Web Latency SLI-2-1` ![](https://i.imgur.com/NjNxnF0.png) 依需求建立 `Web Latency SLI-2-2` ![](https://i.imgur.com/yW9mRH9.png) **Document to index** 的 index document 使用一樣的簡單範例: ``` { "rule_id": "{{rule.id}}", "rule_name": "{{rule.name}}", "alert_id": "{{alert.id}}", "context_message": "{{context.message}}" } ``` ### 3. 建立完成後,可以在 Manage Rules 的頁面查看結果。 在 [Kibana > Alert > Manage Rules (右上角)](http://localhost:5601/app/observability/alerts/rules) 可以查看 Rules 設定結果。 ![](https://i.imgur.com/qflb4f8.png) ## 使用 Elastic Observability 查找問題的技巧 ### 別忘記內建的 Dashboard - [Metricbeat Docker] Overview ECS - [Filebeat PostgreSQL] Overview ECS - [Metricbeat PostgreSQL] Database Overview ### 利用 Machine Learning - Logs - Anomalies: 主要是針對 log entry rates (輸入率) 來進行異常的判斷。 - Categories: 依照收集到的 Logs 進行分類,前且顯示總數量、Datasets 的來源、並且借由 Trend (趨勢) 的變化及數量來快速判斷異常的狀況。 ### ## FAQ ### 使用 Apple M2 (ARM64/v8) 無法順利執行 `opbeans-xxx` 的 containers 該怎麼辦? 若使用 Docker Desktop,請先將 Rosetta 模擬 AMD64 的功能啟用。 ![](https://hackmd.io/_uploads/HyfACtHCn.png) ### 執行 `composer.py` 時 Docker build 出現 `GPG error` docker 出現 GPG error: At least one invalid signature was encountered 相關問題及解決辦法。 > There are a few reasons why you encounter these errors: > > There might be an issue with the existing cache and/or disc space. In order to fix it you need to clear the APT cache by executing: sudo apt-get clean and sudo apt-get update. > > The same goes with existing docker images. Execute: docker image prune -f and docker container prune -f in order to remove unused data and free disc space. > > If you don’t care about the security risks, you can try to run the apt-get command with the --allow-unauthenticated or --allow-insecure-repositories flag. According to the docs: > > Ignore if packages can’t be authenticated and don’t prompt about it. This can be useful while working with local repositories, but is a huge security risk if data authenticity isn’t ensured in another way by the user itself. > > Finally, on MacOS, where Docker runs inside a dedicated VM, you may need to increase the disk available to Docker from the Docker Desktop application (Settings -> Resources -> Advanced -> Disk image size). :::danger 執行以下指令會將你的 Docker 環境清空,包含 images, dangling build caches, containers,請確認後再操作。 ::: ``` docker container prune docker image prune -a docker system prune docker system df ``` ### 啟動時,容器異常中止 查看 docker-compose logs `{container_name}` 時,發現以下的錯誤: ``` exec /usr/bin/dumb-init: exec format error ``` 這代表該 Docker Image 不是用對應的 platform 所建置,需自行 build imgae 才能使用。 ### 啟動時,發生 `unhealthy` 的錯誤 ``` ERROR: for opbeans-node Container "907fc7a0c9be" is unhealthy. ERROR: for opbeans-load-generator Container "24e4d86c54ed" is unhealthy. ERROR: Encountered errors while bringing up the project. Traceback (most recent call last): File "/Users/joecwu/projects/joecwu/apm-integration-testing/./scripts/compose.py", line 31, in <module> main() File "/Users/joecwu/projects/joecwu/apm-integration-testing/./scripts/compose.py", line 17, in main setup() File "/Users/joecwu/projects/joecwu/apm-integration-testing/scripts/modules/cli.py", line 213, in __call__ self.args.func() File "/Users/joecwu/projects/joecwu/apm-integration-testing/scripts/modules/cli.py", line 590, in start_handler self.build_start_handler("start") File "/Users/joecwu/projects/joecwu/apm-integration-testing/scripts/modules/cli.py", line 782, in build_start_handler self.run_docker_compose_process(docker_compose_cmd + up_params) File "/Users/joecwu/projects/joecwu/apm-integration-testing/scripts/modules/cli.py", line 476, in run_docker_compose_process subprocess.check_call(docker_compose_cmd) File "/Users/joecwu/.pyenv/versions/3.9.2/lib/python3.9/subprocess.py", line 373, in check_call raise CalledProcessError(retcode, cmd) subprocess.CalledProcessError: Command '['docker-compose', '-f', '/Users/joecwu/projects/joecwu/apm-integration-testing/docker-compose.yml', 'up', '-d']' returned non-zero exit status 1. ``` 有可能是當下某一些有相依性的 service 還沒有正常的啟動,可以先重新使用 `docker-compose` 啟動一次試試,看看是否有改善。 ``` docker-compose up -d ``` 若是依然有服務沒辦法正常啟動,可使用 `docker ps -a` 查看沒有正常啟動的服務是哪些,並進一步使用 `docker logs {{DockerContainerName}}` 查看錯誤訊息。 ### `opbeans-dotnet` 在 Apple M1 無法啟動 使用 `docker logs localtesting_8.9.0_opbeans-dotnet` 查看,發現以下錯誤: ``` Failed to resolve full path of the current executable [/proc/self/exe] ``` :::warning 在這次 Workshop 中,若是使用 Apple M1,我們先不啟用 `opbeans-dotnet` ::: ### 如果已經啟動過,但想要清空環境,重新再來 先清除所有正在運作中的 containers,以下方式二擇一: 1. 使用 `composer.py` ``` ./scripts/compose.py stop ``` 2. 使用 `docker-compose` ``` docker-compose down ``` 如果有需要,可以一併刪除已產生的 docker volume. ``` docker volume rm apm-integration-testing_esdata docker volume rm apm-integration-testing_pgdata ``` ### 如果要使用雲端主機,可以設定 SSH Tunnel 來存取 `~/.ssh/config` 的參考設定如下: ``` Host gcptunnel HostName <my.gcp.host.ip> IdentityFile ~/.ssh/google_compute_engine <--- yours may differ User jamie <--- yours probably differs Compression yes ExitOnForwardFailure no LocalForward 3000 127.0.0.1:3000 LocalForward 3001 127.0.0.1:3001 LocalForward 3002 127.0.0.1:3002 LocalForward 3003 127.0.0.1:3003 LocalForward 3004 127.0.0.1:80 LocalForward 5601 127.0.0.1:5601 LocalForward 8000 127.0.0.1:8000 LocalForward 9200 127.0.0.1:9200 LocalForward 9222 127.0.0.1:9222 ``` 以上述的例子,設定完成後,執行 `ssh gcptunnel` 即可將本機的 port 轉接到雲端主機。 ## 參考資料 - 喬叔帶你上手 Elastic Stack - 探索與實踐 Observability 系列 - [使用 APM-Integratoin-Testing 建立 Elastic APM 的模擬環境](https://training.onedoggo.com/tech-sharing/uncle-joe-teach-es-elastc-observability/traces-guan-cha-ying-yong-cheng-shi-de-xiao-neng-ping-jing/shi-yong-apmintegratointesting-jian-li-elastic-apm-de-mo-ni-huan-jing) - Elastic Demo Site: - [https://demo.elastic.co](https://demo.elastic.co) - Observability: [https://demo.elastic.co/app/observability/overview](https://demo.elastic.co/app/observability/overview) :::success 以上有關 `.yaml` 檔的修改,已 commit 在喬叔 GitHub 的 `2022-devopsdays-workshop` branch 之中,可以直接 `git checkout 2022-devopsdays-workshop`,或是[點此](https://github.com/joecwu/apm-integration-testing/archive/refs/heads/2022-devopsdays-workshop.zip)下載。 :::

    Import from clipboard

    Paste your markdown or webpage here...

    Advanced permission required

    Your current role can only read. Ask the system administrator to acquire write and comment permission.

    This team is disabled

    Sorry, this team is disabled. You can't edit this note.

    This note is locked

    Sorry, only owner can edit this note.

    Reach the limit

    Sorry, you've reached the max length this note can be.
    Please reduce the content or divide it to more notes, thank you!

    Import from Gist

    Import from Snippet

    or

    Export to Snippet

    Are you sure?

    Do you really want to delete this note?
    All users will lose their connection.

    Create a note from template

    Create a note from template

    Oops...
    This template has been removed or transferred.
    Upgrade
    All
    • All
    • Team
    No template.

    Create a template

    Upgrade

    Delete template

    Do you really want to delete this template?
    Turn this template into a regular note and keep its content, versions, and comments.

    This page need refresh

    You have an incompatible client version.
    Refresh to update.
    New version available!
    See releases notes here
    Refresh to enjoy new features.
    Your user state has changed.
    Refresh to load new user state.

    Sign in

    Forgot password
    or
    Sign in via Google Sign in via Facebook Sign in via X(Twitter) Sign in via GitHub Sign in via Dropbox Sign in with Wallet
    Wallet ( )
    Connect another wallet

    New to HackMD? Sign up

    By signing in, you agree to our terms of service.

    Help

    • English
    • 中文
    • Français
    • Deutsch
    • 日本語
    • Español
    • Català
    • Ελληνικά
    • Português
    • italiano
    • Türkçe
    • Русский
    • Nederlands
    • hrvatski jezik
    • język polski
    • Українська
    • हिन्दी
    • svenska
    • Esperanto
    • dansk

    Documents

    Help & Tutorial

    How to use Book mode

    Slide Example

    API Docs

    Edit in VSCode

    Install browser extension

    Contacts

    Feedback

    Discord

    Send us email

    Resources

    Releases

    Pricing

    Blog

    Policy

    Terms

    Privacy

    Cheatsheet

    Syntax Example Reference
    # Header Header 基本排版
    - Unordered List
    • Unordered List
    1. Ordered List
    1. Ordered List
    - [ ] Todo List
    • Todo List
    > Blockquote
    Blockquote
    **Bold font** Bold font
    *Italics font* Italics font
    ~~Strikethrough~~ Strikethrough
    19^th^ 19th
    H~2~O H2O
    ++Inserted text++ Inserted text
    ==Marked text== Marked text
    [link text](https:// "title") Link
    ![image alt](https:// "title") Image
    `Code` Code 在筆記中貼入程式碼
    ```javascript
    var i = 0;
    ```
    var i = 0;
    :smile: :smile: Emoji list
    {%youtube youtube_id %} Externals
    $L^aT_eX$ LaTeX
    :::info
    This is a alert area.
    :::

    This is a alert area.

    Versions and GitHub Sync
    Get Full History Access

    • Edit version name
    • Delete

    revision author avatar     named on  

    More Less

    Note content is identical to the latest version.
    Compare
      Choose a version
      No search result
      Version not found
    Sign in to link this note to GitHub
    Learn more
    This note is not linked with GitHub
     

    Feedback

    Submission failed, please try again

    Thanks for your support.

    On a scale of 0-10, how likely is it that you would recommend HackMD to your friends, family or business associates?

    Please give us some advice and help us improve HackMD.

     

    Thanks for your feedback

    Remove version name

    Do you want to remove this version name and description?

    Transfer ownership

    Transfer to
      Warning: is a public team. If you transfer note to this team, everyone on the web can find and read this note.

        Link with GitHub

        Please authorize HackMD on GitHub
        • Please sign in to GitHub and install the HackMD app on your GitHub repo.
        • HackMD links with GitHub through a GitHub App. You can choose which repo to install our App.
        Learn more  Sign in to GitHub

        Push the note to GitHub Push to GitHub Pull a file from GitHub

          Authorize again
         

        Choose which file to push to

        Select repo
        Refresh Authorize more repos
        Select branch
        Select file
        Select branch
        Choose version(s) to push
        • Save a new version and push
        • Choose from existing versions
        Include title and tags
        Available push count

        Pull from GitHub

         
        File from GitHub
        File from HackMD

        GitHub Link Settings

        File linked

        Linked by
        File path
        Last synced branch
        Available push count

        Danger Zone

        Unlink
        You will no longer receive notification when GitHub file changes after unlink.

        Syncing

        Push failed

        Push successfully